Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 4e9f8537

History | View | Annotate | Download (185.4 kB)

1
/*
2
 *  MIPS32 emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6
 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22

    
23
#include <stdarg.h>
24
#include <stdlib.h>
25
#include <stdio.h>
26
#include <string.h>
27
#include <inttypes.h>
28

    
29
#include "cpu.h"
30
#include "exec-all.h"
31
#include "disas.h"
32

    
33
//#define MIPS_DEBUG_DISAS
34
//#define MIPS_DEBUG_SIGN_EXTENSIONS
35
//#define MIPS_SINGLE_STEP
36

    
37
#ifdef USE_DIRECT_JUMP
38
#define TBPARAM(x)
39
#else
40
#define TBPARAM(x) (long)(x)
41
#endif
42

    
43
enum {
44
#define DEF(s, n, copy_size) INDEX_op_ ## s,
45
#include "opc.h"
46
#undef DEF
47
    NB_OPS,
48
};
49

    
50
static uint16_t *gen_opc_ptr;
51
static uint32_t *gen_opparam_ptr;
52

    
53
#include "gen-op.h"
54

    
55
/* MIPS major opcodes */
56
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
57

    
58
enum {
59
    /* indirect opcode tables */
60
    OPC_SPECIAL  = (0x00 << 26),
61
    OPC_REGIMM   = (0x01 << 26),
62
    OPC_CP0      = (0x10 << 26),
63
    OPC_CP1      = (0x11 << 26),
64
    OPC_CP2      = (0x12 << 26),
65
    OPC_CP3      = (0x13 << 26),
66
    OPC_SPECIAL2 = (0x1C << 26),
67
    OPC_SPECIAL3 = (0x1F << 26),
68
    /* arithmetic with immediate */
69
    OPC_ADDI     = (0x08 << 26),
70
    OPC_ADDIU    = (0x09 << 26),
71
    OPC_SLTI     = (0x0A << 26),
72
    OPC_SLTIU    = (0x0B << 26),
73
    OPC_ANDI     = (0x0C << 26),
74
    OPC_ORI      = (0x0D << 26),
75
    OPC_XORI     = (0x0E << 26),
76
    OPC_LUI      = (0x0F << 26),
77
    OPC_DADDI    = (0x18 << 26),
78
    OPC_DADDIU   = (0x19 << 26),
79
    /* Jump and branches */
80
    OPC_J        = (0x02 << 26),
81
    OPC_JAL      = (0x03 << 26),
82
    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
83
    OPC_BEQL     = (0x14 << 26),
84
    OPC_BNE      = (0x05 << 26),
85
    OPC_BNEL     = (0x15 << 26),
86
    OPC_BLEZ     = (0x06 << 26),
87
    OPC_BLEZL    = (0x16 << 26),
88
    OPC_BGTZ     = (0x07 << 26),
89
    OPC_BGTZL    = (0x17 << 26),
90
    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
91
    /* Load and stores */
92
    OPC_LDL      = (0x1A << 26),
93
    OPC_LDR      = (0x1B << 26),
94
    OPC_LB       = (0x20 << 26),
95
    OPC_LH       = (0x21 << 26),
96
    OPC_LWL      = (0x22 << 26),
97
    OPC_LW       = (0x23 << 26),
98
    OPC_LBU      = (0x24 << 26),
99
    OPC_LHU      = (0x25 << 26),
100
    OPC_LWR      = (0x26 << 26),
101
    OPC_LWU      = (0x27 << 26),
102
    OPC_SB       = (0x28 << 26),
103
    OPC_SH       = (0x29 << 26),
104
    OPC_SWL      = (0x2A << 26),
105
    OPC_SW       = (0x2B << 26),
106
    OPC_SDL      = (0x2C << 26),
107
    OPC_SDR      = (0x2D << 26),
108
    OPC_SWR      = (0x2E << 26),
109
    OPC_LL       = (0x30 << 26),
110
    OPC_LLD      = (0x34 << 26),
111
    OPC_LD       = (0x37 << 26),
112
    OPC_SC       = (0x38 << 26),
113
    OPC_SCD      = (0x3C << 26),
114
    OPC_SD       = (0x3F << 26),
115
    /* Floating point load/store */
116
    OPC_LWC1     = (0x31 << 26),
117
    OPC_LWC2     = (0x32 << 26),
118
    OPC_LDC1     = (0x35 << 26),
119
    OPC_LDC2     = (0x36 << 26),
120
    OPC_SWC1     = (0x39 << 26),
121
    OPC_SWC2     = (0x3A << 26),
122
    OPC_SDC1     = (0x3D << 26),
123
    OPC_SDC2     = (0x3E << 26),
124
    /* MDMX ASE specific */
125
    OPC_MDMX     = (0x1E << 26),
126
    /* Cache and prefetch */
127
    OPC_CACHE    = (0x2F << 26),
128
    OPC_PREF     = (0x33 << 26),
129
    /* Reserved major opcode */
130
    OPC_MAJOR3B_RESERVED = (0x3B << 26),
131
};
132

    
133
/* MIPS special opcodes */
134
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
135

    
136
enum {
137
    /* Shifts */
138
    OPC_SLL      = 0x00 | OPC_SPECIAL,
139
    /* NOP is SLL r0, r0, 0   */
140
    /* SSNOP is SLL r0, r0, 1 */
141
    /* EHB is SLL r0, r0, 3 */
142
    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
143
    OPC_SRA      = 0x03 | OPC_SPECIAL,
144
    OPC_SLLV     = 0x04 | OPC_SPECIAL,
145
    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
146
    OPC_SRAV     = 0x07 | OPC_SPECIAL,
147
    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
148
    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
149
    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
150
    OPC_DSLL     = 0x38 | OPC_SPECIAL,
151
    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
152
    OPC_DSRA     = 0x3B | OPC_SPECIAL,
153
    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
154
    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
155
    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
156
    /* Multiplication / division */
157
    OPC_MULT     = 0x18 | OPC_SPECIAL,
158
    OPC_MULTU    = 0x19 | OPC_SPECIAL,
159
    OPC_DIV      = 0x1A | OPC_SPECIAL,
160
    OPC_DIVU     = 0x1B | OPC_SPECIAL,
161
    OPC_DMULT    = 0x1C | OPC_SPECIAL,
162
    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
163
    OPC_DDIV     = 0x1E | OPC_SPECIAL,
164
    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
165
    /* 2 registers arithmetic / logic */
166
    OPC_ADD      = 0x20 | OPC_SPECIAL,
167
    OPC_ADDU     = 0x21 | OPC_SPECIAL,
168
    OPC_SUB      = 0x22 | OPC_SPECIAL,
169
    OPC_SUBU     = 0x23 | OPC_SPECIAL,
170
    OPC_AND      = 0x24 | OPC_SPECIAL,
171
    OPC_OR       = 0x25 | OPC_SPECIAL,
172
    OPC_XOR      = 0x26 | OPC_SPECIAL,
173
    OPC_NOR      = 0x27 | OPC_SPECIAL,
174
    OPC_SLT      = 0x2A | OPC_SPECIAL,
175
    OPC_SLTU     = 0x2B | OPC_SPECIAL,
176
    OPC_DADD     = 0x2C | OPC_SPECIAL,
177
    OPC_DADDU    = 0x2D | OPC_SPECIAL,
178
    OPC_DSUB     = 0x2E | OPC_SPECIAL,
179
    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
180
    /* Jumps */
181
    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
182
    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
183
    /* Traps */
184
    OPC_TGE      = 0x30 | OPC_SPECIAL,
185
    OPC_TGEU     = 0x31 | OPC_SPECIAL,
186
    OPC_TLT      = 0x32 | OPC_SPECIAL,
187
    OPC_TLTU     = 0x33 | OPC_SPECIAL,
188
    OPC_TEQ      = 0x34 | OPC_SPECIAL,
189
    OPC_TNE      = 0x36 | OPC_SPECIAL,
190
    /* HI / LO registers load & stores */
191
    OPC_MFHI     = 0x10 | OPC_SPECIAL,
192
    OPC_MTHI     = 0x11 | OPC_SPECIAL,
193
    OPC_MFLO     = 0x12 | OPC_SPECIAL,
194
    OPC_MTLO     = 0x13 | OPC_SPECIAL,
195
    /* Conditional moves */
196
    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
197
    OPC_MOVN     = 0x0B | OPC_SPECIAL,
198

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

    
201
    /* Special */
202
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
203
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
204
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
205
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
206
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
207

    
208
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
209
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
210
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
211
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
212
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
213
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
214
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
215
};
216

    
217
/* REGIMM (rt field) opcodes */
218
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
219

    
220
enum {
221
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
222
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
223
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
224
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
225
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
226
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
227
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
228
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
229
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
230
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
231
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
232
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
233
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
234
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
235
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
236
};
237

    
238
/* Special2 opcodes */
239
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
240

    
241
enum {
242
    /* Multiply & xxx operations */
243
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
244
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
245
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
246
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
247
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
248
    /* Misc */
249
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
250
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
251
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
252
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
253
    /* Special */
254
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
255
};
256

    
257
/* Special3 opcodes */
258
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
259

    
260
enum {
261
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
262
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
263
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
264
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
265
    OPC_INS      = 0x04 | OPC_SPECIAL3,
266
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
267
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
268
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
269
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
270
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
271
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
272
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
273
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
274
};
275

    
276
/* BSHFL opcodes */
277
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
278

    
279
enum {
280
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
281
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
282
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
283
};
284

    
285
/* DBSHFL opcodes */
286
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
287

    
288
enum {
289
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
290
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
291
};
292

    
293
/* Coprocessor 0 (rs field) */
294
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
295

    
296
enum {
297
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
298
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
299
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
300
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
301
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
302
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
303
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
304
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
305
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
306
    OPC_C0       = (0x10 << 21) | OPC_CP0,
307
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
308
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
309
};
310

    
311
/* MFMC0 opcodes */
312
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
313

    
314
enum {
315
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
316
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
317
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
318
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
319
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
320
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
321
};
322

    
323
/* Coprocessor 0 (with rs == C0) */
324
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
325

    
326
enum {
327
    OPC_TLBR     = 0x01 | OPC_C0,
328
    OPC_TLBWI    = 0x02 | OPC_C0,
329
    OPC_TLBWR    = 0x06 | OPC_C0,
330
    OPC_TLBP     = 0x08 | OPC_C0,
331
    OPC_RFE      = 0x10 | OPC_C0,
332
    OPC_ERET     = 0x18 | OPC_C0,
333
    OPC_DERET    = 0x1F | OPC_C0,
334
    OPC_WAIT     = 0x20 | OPC_C0,
335
};
336

    
337
/* Coprocessor 1 (rs field) */
338
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
339

    
340
enum {
341
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
342
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
343
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
344
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
345
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
346
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
347
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
348
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
349
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
350
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
351
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
352
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
353
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
354
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
355
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
356
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
357
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
358
    OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
359
};
360

    
361
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
362
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
363

    
364
enum {
365
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
366
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
367
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
368
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
369
};
370

    
371
enum {
372
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
373
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
374
};
375

    
376
enum {
377
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
378
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
379
};
380

    
381
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
382

    
383
enum {
384
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
385
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
386
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
387
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
388
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
389
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
390
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
391
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
392
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
393
};
394

    
395
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
396

    
397
enum {
398
    OPC_LWXC1   = 0x00 | OPC_CP3,
399
    OPC_LDXC1   = 0x01 | OPC_CP3,
400
    OPC_LUXC1   = 0x05 | OPC_CP3,
401
    OPC_SWXC1   = 0x08 | OPC_CP3,
402
    OPC_SDXC1   = 0x09 | OPC_CP3,
403
    OPC_SUXC1   = 0x0D | OPC_CP3,
404
    OPC_PREFX   = 0x0F | OPC_CP3,
405
    OPC_ALNV_PS = 0x1E | OPC_CP3,
406
    OPC_MADD_S  = 0x20 | OPC_CP3,
407
    OPC_MADD_D  = 0x21 | OPC_CP3,
408
    OPC_MADD_PS = 0x26 | OPC_CP3,
409
    OPC_MSUB_S  = 0x28 | OPC_CP3,
410
    OPC_MSUB_D  = 0x29 | OPC_CP3,
411
    OPC_MSUB_PS = 0x2E | OPC_CP3,
412
    OPC_NMADD_S = 0x30 | OPC_CP3,
413
    OPC_NMADD_D = 0x31 | OPC_CP3,
414
    OPC_NMADD_PS= 0x36 | OPC_CP3,
415
    OPC_NMSUB_S = 0x38 | OPC_CP3,
416
    OPC_NMSUB_D = 0x39 | OPC_CP3,
417
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
418
};
419

    
420

    
421
const unsigned char *regnames[] =
422
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
423
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
424
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
425
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
426

    
427
/* Warning: no function for r0 register (hard wired to zero) */
428
#define GEN32(func, NAME)                        \
429
static GenOpFunc *NAME ## _table [32] = {        \
430
NULL,       NAME ## 1, NAME ## 2, NAME ## 3,     \
431
NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,     \
432
NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,   \
433
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
434
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
435
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
436
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
437
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
438
};                                               \
439
static inline void func(int n)                   \
440
{                                                \
441
    NAME ## _table[n]();                         \
442
}
443

    
444
/* General purpose registers moves */
445
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
446
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
447
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
448

    
449
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
450
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
451

    
452
/* Moves to/from shadow registers */
453
GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);
454
GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);
455

    
456
static const char *fregnames[] =
457
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
458
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
459
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
460
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
461

    
462
#define FGEN32(func, NAME)                       \
463
static GenOpFunc *NAME ## _table [32] = {        \
464
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
465
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
466
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
467
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
468
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
469
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
470
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
471
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
472
};                                               \
473
static inline void func(int n)                   \
474
{                                                \
475
    NAME ## _table[n]();                         \
476
}
477

    
478
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
479
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
480

    
481
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
482
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
483

    
484
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
485
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
486

    
487
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
488
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
489

    
490
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
491
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
492

    
493
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
494
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
495

    
496
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
497
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
498

    
499
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
500
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
501

    
502
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
503
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
504

    
505
#define FOP_CONDS(type, fmt)                                            \
506
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
507
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
508
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
509
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
510
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
511
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
512
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
513
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
514
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
515
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
516
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
517
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
518
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
519
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
520
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
521
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
522
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
523
};                                                                      \
524
static inline void gen_cmp ## type ## _ ## fmt(int n, long cc)          \
525
{                                                                       \
526
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
527
}
528

    
529
FOP_CONDS(, d)
530
FOP_CONDS(abs, d)
531
FOP_CONDS(, s)
532
FOP_CONDS(abs, s)
533
FOP_CONDS(, ps)
534
FOP_CONDS(abs, ps)
535

    
536
typedef struct DisasContext {
537
    struct TranslationBlock *tb;
538
    target_ulong pc, saved_pc;
539
    uint32_t opcode;
540
    uint32_t fp_status;
541
    /* Routine used to access memory */
542
    int mem_idx;
543
    uint32_t hflags, saved_hflags;
544
    int bstate;
545
    target_ulong btarget;
546
} DisasContext;
547

    
548
enum {
549
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
550
                      * exception condition
551
                      */
552
    BS_STOP     = 1, /* We want to stop translation for any reason */
553
    BS_BRANCH   = 2, /* We reached a branch condition     */
554
    BS_EXCP     = 3, /* We reached an exception condition */
555
};
556

    
557
#ifdef MIPS_DEBUG_DISAS
558
#define MIPS_DEBUG(fmt, args...)                                              \
559
do {                                                                          \
560
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
561
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
562
                ctx->pc, ctx->opcode , ##args);                               \
563
    }                                                                         \
564
} while (0)
565
#else
566
#define MIPS_DEBUG(fmt, args...) do { } while(0)
567
#endif
568

    
569
#define MIPS_INVAL(op)                                                        \
570
do {                                                                          \
571
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
572
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
573
} while (0)
574

    
575
#define GEN_LOAD_REG_TN(Tn, Rn)                                               \
576
do {                                                                          \
577
    if (Rn == 0) {                                                            \
578
        glue(gen_op_reset_, Tn)();                                            \
579
    } else {                                                                  \
580
        glue(gen_op_load_gpr_, Tn)(Rn);                                       \
581
    }                                                                         \
582
} while (0)
583

    
584
#define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
585
do {                                                                          \
586
    if (Rn == 0) {                                                            \
587
        glue(gen_op_reset_, Tn)();                                            \
588
    } else {                                                                  \
589
        glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
590
    }                                                                         \
591
} while (0)
592

    
593
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
594
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
595
do {                                                                          \
596
    if (Imm == 0) {                                                           \
597
        glue(gen_op_reset_, Tn)();                                            \
598
    } else if ((int32_t)Imm == Imm) {                                         \
599
        glue(gen_op_set_, Tn)(Imm);                                           \
600
    } else {                                                                  \
601
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
602
    }                                                                         \
603
} while (0)
604
#else
605
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
606
do {                                                                          \
607
    if (Imm == 0) {                                                           \
608
        glue(gen_op_reset_, Tn)();                                            \
609
    } else {                                                                  \
610
        glue(gen_op_set_, Tn)(Imm);                                           \
611
    }                                                                         \
612
} while (0)
613
#endif
614

    
615
#define GEN_STORE_TN_REG(Rn, Tn)                                              \
616
do {                                                                          \
617
    if (Rn != 0) {                                                            \
618
        glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
619
    }                                                                         \
620
} while (0)
621

    
622
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
623
do {                                                                          \
624
    if (Rn != 0) {                                                            \
625
        glue(glue(gen_op_store_, Tn),_srsgpr)(Rn);                            \
626
    }                                                                         \
627
} while (0)
628

    
629
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
630
do {                                                                          \
631
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
632
} while (0)
633

    
634
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
635
do {                                                                          \
636
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
637
} while (0)
638

    
639
static inline void gen_save_pc(target_ulong pc)
640
{
641
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
642
    if (pc == (int32_t)pc) {
643
        gen_op_save_pc(pc);
644
    } else {
645
        gen_op_save_pc64(pc >> 32, (uint32_t)pc);
646
    }
647
#else
648
    gen_op_save_pc(pc);
649
#endif
650
}
651

    
652
static inline void gen_save_btarget(target_ulong btarget)
653
{
654
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
655
    if (btarget == (int32_t)btarget) {
656
        gen_op_save_btarget(btarget);
657
    } else {
658
        gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
659
    }
660
#else
661
    gen_op_save_btarget(btarget);
662
#endif
663
}
664

    
665
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
666
{
667
#if defined MIPS_DEBUG_DISAS
668
    if (loglevel & CPU_LOG_TB_IN_ASM) {
669
            fprintf(logfile, "hflags %08x saved %08x\n",
670
                    ctx->hflags, ctx->saved_hflags);
671
    }
672
#endif
673
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
674
        gen_save_pc(ctx->pc);
675
        ctx->saved_pc = ctx->pc;
676
    }
677
    if (ctx->hflags != ctx->saved_hflags) {
678
        gen_op_save_state(ctx->hflags);
679
        ctx->saved_hflags = ctx->hflags;
680
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
681
        case MIPS_HFLAG_BR:
682
            gen_op_save_breg_target();
683
            break;
684
        case MIPS_HFLAG_BC:
685
            gen_op_save_bcond();
686
            /* fall through */
687
        case MIPS_HFLAG_BL:
688
            /* bcond was already saved by the BL insn */
689
            /* fall through */
690
        case MIPS_HFLAG_B:
691
            gen_save_btarget(ctx->btarget);
692
            break;
693
        }
694
    }
695
}
696

    
697
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
698
{
699
    ctx->saved_hflags = ctx->hflags;
700
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
701
    case MIPS_HFLAG_BR:
702
        gen_op_restore_breg_target();
703
        break;
704
    case MIPS_HFLAG_B:
705
        ctx->btarget = env->btarget;
706
        break;
707
    case MIPS_HFLAG_BC:
708
    case MIPS_HFLAG_BL:
709
        ctx->btarget = env->btarget;
710
        gen_op_restore_bcond();
711
        break;
712
    }
713
}
714

    
715
static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
716
{
717
#if defined MIPS_DEBUG_DISAS
718
    if (loglevel & CPU_LOG_TB_IN_ASM)
719
            fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
720
#endif
721
    save_cpu_state(ctx, 1);
722
    if (err == 0)
723
        gen_op_raise_exception(excp);
724
    else
725
        gen_op_raise_exception_err(excp, err);
726
    ctx->bstate = BS_EXCP;
727
}
728

    
729
static inline void generate_exception (DisasContext *ctx, int excp)
730
{
731
    generate_exception_err (ctx, excp, 0);
732
}
733

    
734
static inline void check_cp0_enabled(DisasContext *ctx)
735
{
736
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
737
        generate_exception_err(ctx, EXCP_CpU, 1);
738
}
739

    
740
static inline void check_cp1_enabled(DisasContext *ctx)
741
{
742
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
743
        generate_exception_err(ctx, EXCP_CpU, 1);
744
}
745

    
746
static inline void check_cp1_64bitmode(DisasContext *ctx)
747
{
748
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64)))
749
        generate_exception(ctx, EXCP_RI);
750
}
751

    
752
/*
753
 * Verify if floating point register is valid; an operation is not defined
754
 * if bit 0 of any register specification is set and the FR bit in the
755
 * Status register equals zero, since the register numbers specify an
756
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
757
 * in the Status register equals one, both even and odd register numbers
758
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
759
 *
760
 * Multiple 64 bit wide registers can be checked by calling
761
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
762
 */
763
void check_cp1_registers(DisasContext *ctx, int regs)
764
{
765
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
766
        generate_exception(ctx, EXCP_RI);
767
}
768

    
769
/* This code generates a "reserved instruction" exception if the
770
   CPU does not support the instruction set corresponding to flags. */
771
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
772
{
773
    if (unlikely(!(env->insn_flags & flags)))
774
        generate_exception(ctx, EXCP_RI);
775
}
776

    
777
/* This code generates a "reserved instruction" exception if the
778
   CPU is not MIPS MT capable. */
779
static inline void check_mips_mt(CPUState *env, DisasContext *ctx)
780
{
781
    if (unlikely(!(env->CP0_Config3 & (1 << CP0C3_MT))))
782
        generate_exception(ctx, EXCP_RI);
783
}
784

    
785
/* This code generates a "reserved instruction" exception if 64-bit
786
   instructions are not enabled. */
787
static inline void check_mips_64(DisasContext *ctx)
788
{
789
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
790
        generate_exception(ctx, EXCP_RI);
791
}
792

    
793
#if defined(CONFIG_USER_ONLY)
794
#define op_ldst(name)        gen_op_##name##_raw()
795
#define OP_LD_TABLE(width)
796
#define OP_ST_TABLE(width)
797
#else
798
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
799
#define OP_LD_TABLE(width)                                                    \
800
static GenOpFunc *gen_op_l##width[] = {                                       \
801
    &gen_op_l##width##_user,                                                  \
802
    &gen_op_l##width##_kernel,                                                \
803
}
804
#define OP_ST_TABLE(width)                                                    \
805
static GenOpFunc *gen_op_s##width[] = {                                       \
806
    &gen_op_s##width##_user,                                                  \
807
    &gen_op_s##width##_kernel,                                                \
808
}
809
#endif
810

    
811
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
812
OP_LD_TABLE(d);
813
OP_LD_TABLE(dl);
814
OP_LD_TABLE(dr);
815
OP_ST_TABLE(d);
816
OP_ST_TABLE(dl);
817
OP_ST_TABLE(dr);
818
OP_LD_TABLE(ld);
819
OP_ST_TABLE(cd);
820
OP_LD_TABLE(wu);
821
#endif
822
OP_LD_TABLE(w);
823
OP_LD_TABLE(wl);
824
OP_LD_TABLE(wr);
825
OP_ST_TABLE(w);
826
OP_ST_TABLE(wl);
827
OP_ST_TABLE(wr);
828
OP_LD_TABLE(h);
829
OP_LD_TABLE(hu);
830
OP_ST_TABLE(h);
831
OP_LD_TABLE(b);
832
OP_LD_TABLE(bu);
833
OP_ST_TABLE(b);
834
OP_LD_TABLE(l);
835
OP_ST_TABLE(c);
836
OP_LD_TABLE(wc1);
837
OP_ST_TABLE(wc1);
838
OP_LD_TABLE(dc1);
839
OP_ST_TABLE(dc1);
840
OP_LD_TABLE(uxc1);
841
OP_ST_TABLE(uxc1);
842

    
843
/* Load and store */
844
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
845
                      int base, int16_t offset)
846
{
847
    const char *opn = "ldst";
848

    
849
    if (base == 0) {
850
        GEN_LOAD_IMM_TN(T0, offset);
851
    } else if (offset == 0) {
852
        gen_op_load_gpr_T0(base);
853
    } else {
854
        gen_op_load_gpr_T0(base);
855
        gen_op_set_T1(offset);
856
        gen_op_addr_add();
857
    }
858
    /* Don't do NOP if destination is zero: we must perform the actual
859
       memory access. */
860
    switch (opc) {
861
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
862
    case OPC_LWU:
863
        op_ldst(lwu);
864
        GEN_STORE_TN_REG(rt, T0);
865
        opn = "lwu";
866
        break;
867
    case OPC_LD:
868
        op_ldst(ld);
869
        GEN_STORE_TN_REG(rt, T0);
870
        opn = "ld";
871
        break;
872
    case OPC_LLD:
873
        op_ldst(lld);
874
        GEN_STORE_TN_REG(rt, T0);
875
        opn = "lld";
876
        break;
877
    case OPC_SD:
878
        GEN_LOAD_REG_TN(T1, rt);
879
        op_ldst(sd);
880
        opn = "sd";
881
        break;
882
    case OPC_SCD:
883
        save_cpu_state(ctx, 1);
884
        GEN_LOAD_REG_TN(T1, rt);
885
        op_ldst(scd);
886
        GEN_STORE_TN_REG(rt, T0);
887
        opn = "scd";
888
        break;
889
    case OPC_LDL:
890
        GEN_LOAD_REG_TN(T1, rt);
891
        op_ldst(ldl);
892
        GEN_STORE_TN_REG(rt, T1);
893
        opn = "ldl";
894
        break;
895
    case OPC_SDL:
896
        GEN_LOAD_REG_TN(T1, rt);
897
        op_ldst(sdl);
898
        opn = "sdl";
899
        break;
900
    case OPC_LDR:
901
        GEN_LOAD_REG_TN(T1, rt);
902
        op_ldst(ldr);
903
        GEN_STORE_TN_REG(rt, T1);
904
        opn = "ldr";
905
        break;
906
    case OPC_SDR:
907
        GEN_LOAD_REG_TN(T1, rt);
908
        op_ldst(sdr);
909
        opn = "sdr";
910
        break;
911
#endif
912
    case OPC_LW:
913
        op_ldst(lw);
914
        GEN_STORE_TN_REG(rt, T0);
915
        opn = "lw";
916
        break;
917
    case OPC_SW:
918
        GEN_LOAD_REG_TN(T1, rt);
919
        op_ldst(sw);
920
        opn = "sw";
921
        break;
922
    case OPC_LH:
923
        op_ldst(lh);
924
        GEN_STORE_TN_REG(rt, T0);
925
        opn = "lh";
926
        break;
927
    case OPC_SH:
928
        GEN_LOAD_REG_TN(T1, rt);
929
        op_ldst(sh);
930
        opn = "sh";
931
        break;
932
    case OPC_LHU:
933
        op_ldst(lhu);
934
        GEN_STORE_TN_REG(rt, T0);
935
        opn = "lhu";
936
        break;
937
    case OPC_LB:
938
        op_ldst(lb);
939
        GEN_STORE_TN_REG(rt, T0);
940
        opn = "lb";
941
        break;
942
    case OPC_SB:
943
        GEN_LOAD_REG_TN(T1, rt);
944
        op_ldst(sb);
945
        opn = "sb";
946
        break;
947
    case OPC_LBU:
948
        op_ldst(lbu);
949
        GEN_STORE_TN_REG(rt, T0);
950
        opn = "lbu";
951
        break;
952
    case OPC_LWL:
953
        GEN_LOAD_REG_TN(T1, rt);
954
        op_ldst(lwl);
955
        GEN_STORE_TN_REG(rt, T1);
956
        opn = "lwl";
957
        break;
958
    case OPC_SWL:
959
        GEN_LOAD_REG_TN(T1, rt);
960
        op_ldst(swl);
961
        opn = "swr";
962
        break;
963
    case OPC_LWR:
964
        GEN_LOAD_REG_TN(T1, rt);
965
        op_ldst(lwr);
966
        GEN_STORE_TN_REG(rt, T1);
967
        opn = "lwr";
968
        break;
969
    case OPC_SWR:
970
        GEN_LOAD_REG_TN(T1, rt);
971
        op_ldst(swr);
972
        opn = "swr";
973
        break;
974
    case OPC_LL:
975
        op_ldst(ll);
976
        GEN_STORE_TN_REG(rt, T0);
977
        opn = "ll";
978
        break;
979
    case OPC_SC:
980
        save_cpu_state(ctx, 1);
981
        GEN_LOAD_REG_TN(T1, rt);
982
        op_ldst(sc);
983
        GEN_STORE_TN_REG(rt, T0);
984
        opn = "sc";
985
        break;
986
    default:
987
        MIPS_INVAL(opn);
988
        generate_exception(ctx, EXCP_RI);
989
        return;
990
    }
991
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
992
}
993

    
994
/* Load and store */
995
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
996
                      int base, int16_t offset)
997
{
998
    const char *opn = "flt_ldst";
999

    
1000
    if (base == 0) {
1001
        GEN_LOAD_IMM_TN(T0, offset);
1002
    } else if (offset == 0) {
1003
        gen_op_load_gpr_T0(base);
1004
    } else {
1005
        gen_op_load_gpr_T0(base);
1006
        gen_op_set_T1(offset);
1007
        gen_op_addr_add();
1008
    }
1009
    /* Don't do NOP if destination is zero: we must perform the actual
1010
       memory access. */
1011
    switch (opc) {
1012
    case OPC_LWC1:
1013
        op_ldst(lwc1);
1014
        GEN_STORE_FTN_FREG(ft, WT0);
1015
        opn = "lwc1";
1016
        break;
1017
    case OPC_SWC1:
1018
        GEN_LOAD_FREG_FTN(WT0, ft);
1019
        op_ldst(swc1);
1020
        opn = "swc1";
1021
        break;
1022
    case OPC_LDC1:
1023
        op_ldst(ldc1);
1024
        GEN_STORE_FTN_FREG(ft, DT0);
1025
        opn = "ldc1";
1026
        break;
1027
    case OPC_SDC1:
1028
        GEN_LOAD_FREG_FTN(DT0, ft);
1029
        op_ldst(sdc1);
1030
        opn = "sdc1";
1031
        break;
1032
    default:
1033
        MIPS_INVAL(opn);
1034
        generate_exception(ctx, EXCP_RI);
1035
        return;
1036
    }
1037
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1038
}
1039

    
1040
/* Arithmetic with immediate operand */
1041
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1042
                           int rt, int rs, int16_t imm)
1043
{
1044
    target_ulong uimm;
1045
    const char *opn = "imm arith";
1046

    
1047
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1048
        /* If no destination, treat it as a NOP.
1049
           For addi, we must generate the overflow exception when needed. */
1050
        MIPS_DEBUG("NOP");
1051
        return;
1052
    }
1053
    uimm = (uint16_t)imm;
1054
    switch (opc) {
1055
    case OPC_ADDI:
1056
    case OPC_ADDIU:
1057
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1058
    case OPC_DADDI:
1059
    case OPC_DADDIU:
1060
#endif
1061
    case OPC_SLTI:
1062
    case OPC_SLTIU:
1063
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1064
        /* Fall through. */
1065
    case OPC_ANDI:
1066
    case OPC_ORI:
1067
    case OPC_XORI:
1068
        GEN_LOAD_REG_TN(T0, rs);
1069
        GEN_LOAD_IMM_TN(T1, uimm);
1070
        break;
1071
    case OPC_LUI:
1072
        GEN_LOAD_IMM_TN(T0, imm << 16);
1073
        break;
1074
    case OPC_SLL:
1075
    case OPC_SRA:
1076
    case OPC_SRL:
1077
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1078
    case OPC_DSLL:
1079
    case OPC_DSRA:
1080
    case OPC_DSRL:
1081
    case OPC_DSLL32:
1082
    case OPC_DSRA32:
1083
    case OPC_DSRL32:
1084
#endif
1085
        uimm &= 0x1f;
1086
        GEN_LOAD_REG_TN(T0, rs);
1087
        GEN_LOAD_IMM_TN(T1, uimm);
1088
        break;
1089
    }
1090
    switch (opc) {
1091
    case OPC_ADDI:
1092
        save_cpu_state(ctx, 1);
1093
        gen_op_addo();
1094
        opn = "addi";
1095
        break;
1096
    case OPC_ADDIU:
1097
        gen_op_add();
1098
        opn = "addiu";
1099
        break;
1100
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1101
    case OPC_DADDI:
1102
        save_cpu_state(ctx, 1);
1103
        gen_op_daddo();
1104
        opn = "daddi";
1105
        break;
1106
    case OPC_DADDIU:
1107
        gen_op_dadd();
1108
        opn = "daddiu";
1109
        break;
1110
#endif
1111
    case OPC_SLTI:
1112
        gen_op_lt();
1113
        opn = "slti";
1114
        break;
1115
    case OPC_SLTIU:
1116
        gen_op_ltu();
1117
        opn = "sltiu";
1118
        break;
1119
    case OPC_ANDI:
1120
        gen_op_and();
1121
        opn = "andi";
1122
        break;
1123
    case OPC_ORI:
1124
        gen_op_or();
1125
        opn = "ori";
1126
        break;
1127
    case OPC_XORI:
1128
        gen_op_xor();
1129
        opn = "xori";
1130
        break;
1131
    case OPC_LUI:
1132
        opn = "lui";
1133
        break;
1134
    case OPC_SLL:
1135
        gen_op_sll();
1136
        opn = "sll";
1137
        break;
1138
    case OPC_SRA:
1139
        gen_op_sra();
1140
        opn = "sra";
1141
        break;
1142
    case OPC_SRL:
1143
        switch ((ctx->opcode >> 21) & 0x1f) {
1144
        case 0:
1145
            gen_op_srl();
1146
            opn = "srl";
1147
            break;
1148
        case 1:
1149
            /* rotr is decoded as srl on non-R2 CPUs */
1150
            if (env->insn_flags & ISA_MIPS32R2) {
1151
                gen_op_rotr();
1152
                opn = "rotr";
1153
            } else {
1154
                gen_op_srl();
1155
                opn = "srl";
1156
            }
1157
            break;
1158
        default:
1159
            MIPS_INVAL("invalid srl flag");
1160
            generate_exception(ctx, EXCP_RI);
1161
            break;
1162
        }
1163
        break;
1164
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1165
    case OPC_DSLL:
1166
        gen_op_dsll();
1167
        opn = "dsll";
1168
        break;
1169
    case OPC_DSRA:
1170
        gen_op_dsra();
1171
        opn = "dsra";
1172
        break;
1173
    case OPC_DSRL:
1174
        switch ((ctx->opcode >> 21) & 0x1f) {
1175
        case 0:
1176
            gen_op_dsrl();
1177
            opn = "dsrl";
1178
            break;
1179
        case 1:
1180
            /* drotr is decoded as dsrl on non-R2 CPUs */
1181
            if (env->insn_flags & ISA_MIPS32R2) {
1182
                gen_op_drotr();
1183
                opn = "drotr";
1184
            } else {
1185
                gen_op_dsrl();
1186
                opn = "dsrl";
1187
            }
1188
            break;
1189
        default:
1190
            MIPS_INVAL("invalid dsrl flag");
1191
            generate_exception(ctx, EXCP_RI);
1192
            break;
1193
        }
1194
        break;
1195
    case OPC_DSLL32:
1196
        gen_op_dsll32();
1197
        opn = "dsll32";
1198
        break;
1199
    case OPC_DSRA32:
1200
        gen_op_dsra32();
1201
        opn = "dsra32";
1202
        break;
1203
    case OPC_DSRL32:
1204
        switch ((ctx->opcode >> 21) & 0x1f) {
1205
        case 0:
1206
            gen_op_dsrl32();
1207
            opn = "dsrl32";
1208
            break;
1209
        case 1:
1210
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1211
            if (env->insn_flags & ISA_MIPS32R2) {
1212
                gen_op_drotr32();
1213
                opn = "drotr32";
1214
            } else {
1215
                gen_op_dsrl32();
1216
                opn = "dsrl32";
1217
            }
1218
            break;
1219
        default:
1220
            MIPS_INVAL("invalid dsrl32 flag");
1221
            generate_exception(ctx, EXCP_RI);
1222
            break;
1223
        }
1224
        break;
1225
#endif
1226
    default:
1227
        MIPS_INVAL(opn);
1228
        generate_exception(ctx, EXCP_RI);
1229
        return;
1230
    }
1231
    GEN_STORE_TN_REG(rt, T0);
1232
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1233
}
1234

    
1235
/* Arithmetic */
1236
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1237
                       int rd, int rs, int rt)
1238
{
1239
    const char *opn = "arith";
1240

    
1241
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1242
       && opc != OPC_DADD && opc != OPC_DSUB) {
1243
        /* If no destination, treat it as a NOP.
1244
           For add & sub, we must generate the overflow exception when needed. */
1245
        MIPS_DEBUG("NOP");
1246
        return;
1247
    }
1248
    GEN_LOAD_REG_TN(T0, rs);
1249
    GEN_LOAD_REG_TN(T1, rt);
1250
    switch (opc) {
1251
    case OPC_ADD:
1252
        save_cpu_state(ctx, 1);
1253
        gen_op_addo();
1254
        opn = "add";
1255
        break;
1256
    case OPC_ADDU:
1257
        gen_op_add();
1258
        opn = "addu";
1259
        break;
1260
    case OPC_SUB:
1261
        save_cpu_state(ctx, 1);
1262
        gen_op_subo();
1263
        opn = "sub";
1264
        break;
1265
    case OPC_SUBU:
1266
        gen_op_sub();
1267
        opn = "subu";
1268
        break;
1269
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1270
    case OPC_DADD:
1271
        save_cpu_state(ctx, 1);
1272
        gen_op_daddo();
1273
        opn = "dadd";
1274
        break;
1275
    case OPC_DADDU:
1276
        gen_op_dadd();
1277
        opn = "daddu";
1278
        break;
1279
    case OPC_DSUB:
1280
        save_cpu_state(ctx, 1);
1281
        gen_op_dsubo();
1282
        opn = "dsub";
1283
        break;
1284
    case OPC_DSUBU:
1285
        gen_op_dsub();
1286
        opn = "dsubu";
1287
        break;
1288
#endif
1289
    case OPC_SLT:
1290
        gen_op_lt();
1291
        opn = "slt";
1292
        break;
1293
    case OPC_SLTU:
1294
        gen_op_ltu();
1295
        opn = "sltu";
1296
        break;
1297
    case OPC_AND:
1298
        gen_op_and();
1299
        opn = "and";
1300
        break;
1301
    case OPC_NOR:
1302
        gen_op_nor();
1303
        opn = "nor";
1304
        break;
1305
    case OPC_OR:
1306
        gen_op_or();
1307
        opn = "or";
1308
        break;
1309
    case OPC_XOR:
1310
        gen_op_xor();
1311
        opn = "xor";
1312
        break;
1313
    case OPC_MUL:
1314
        gen_op_mul();
1315
        opn = "mul";
1316
        break;
1317
    case OPC_MOVN:
1318
        gen_op_movn(rd);
1319
        opn = "movn";
1320
        goto print;
1321
    case OPC_MOVZ:
1322
        gen_op_movz(rd);
1323
        opn = "movz";
1324
        goto print;
1325
    case OPC_SLLV:
1326
        gen_op_sllv();
1327
        opn = "sllv";
1328
        break;
1329
    case OPC_SRAV:
1330
        gen_op_srav();
1331
        opn = "srav";
1332
        break;
1333
    case OPC_SRLV:
1334
        switch ((ctx->opcode >> 6) & 0x1f) {
1335
        case 0:
1336
            gen_op_srlv();
1337
            opn = "srlv";
1338
            break;
1339
        case 1:
1340
            /* rotrv is decoded as srlv on non-R2 CPUs */
1341
            if (env->insn_flags & ISA_MIPS32R2) {
1342
                gen_op_rotrv();
1343
                opn = "rotrv";
1344
            } else {
1345
                gen_op_srlv();
1346
                opn = "srlv";
1347
            }
1348
            break;
1349
        default:
1350
            MIPS_INVAL("invalid srlv flag");
1351
            generate_exception(ctx, EXCP_RI);
1352
            break;
1353
        }
1354
        break;
1355
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1356
    case OPC_DSLLV:
1357
        gen_op_dsllv();
1358
        opn = "dsllv";
1359
        break;
1360
    case OPC_DSRAV:
1361
        gen_op_dsrav();
1362
        opn = "dsrav";
1363
        break;
1364
    case OPC_DSRLV:
1365
        switch ((ctx->opcode >> 6) & 0x1f) {
1366
        case 0:
1367
            gen_op_dsrlv();
1368
            opn = "dsrlv";
1369
            break;
1370
        case 1:
1371
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1372
            if (env->insn_flags & ISA_MIPS32R2) {
1373
                gen_op_drotrv();
1374
                opn = "drotrv";
1375
            } else {
1376
                gen_op_dsrlv();
1377
                opn = "dsrlv";
1378
            }
1379
            break;
1380
        default:
1381
            MIPS_INVAL("invalid dsrlv flag");
1382
            generate_exception(ctx, EXCP_RI);
1383
            break;
1384
        }
1385
        break;
1386
#endif
1387
    default:
1388
        MIPS_INVAL(opn);
1389
        generate_exception(ctx, EXCP_RI);
1390
        return;
1391
    }
1392
    GEN_STORE_TN_REG(rd, T0);
1393
 print:
1394
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1395
}
1396

    
1397
/* Arithmetic on HI/LO registers */
1398
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1399
{
1400
    const char *opn = "hilo";
1401

    
1402
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1403
        /* Treat as NOP. */
1404
        MIPS_DEBUG("NOP");
1405
        return;
1406
    }
1407
    switch (opc) {
1408
    case OPC_MFHI:
1409
        gen_op_load_HI(0);
1410
        GEN_STORE_TN_REG(reg, T0);
1411
        opn = "mfhi";
1412
        break;
1413
    case OPC_MFLO:
1414
        gen_op_load_LO(0);
1415
        GEN_STORE_TN_REG(reg, T0);
1416
        opn = "mflo";
1417
        break;
1418
    case OPC_MTHI:
1419
        GEN_LOAD_REG_TN(T0, reg);
1420
        gen_op_store_HI(0);
1421
        opn = "mthi";
1422
        break;
1423
    case OPC_MTLO:
1424
        GEN_LOAD_REG_TN(T0, reg);
1425
        gen_op_store_LO(0);
1426
        opn = "mtlo";
1427
        break;
1428
    default:
1429
        MIPS_INVAL(opn);
1430
        generate_exception(ctx, EXCP_RI);
1431
        return;
1432
    }
1433
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1434
}
1435

    
1436
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1437
                        int rs, int rt)
1438
{
1439
    const char *opn = "mul/div";
1440

    
1441
    GEN_LOAD_REG_TN(T0, rs);
1442
    GEN_LOAD_REG_TN(T1, rt);
1443
    switch (opc) {
1444
    case OPC_DIV:
1445
        gen_op_div();
1446
        opn = "div";
1447
        break;
1448
    case OPC_DIVU:
1449
        gen_op_divu();
1450
        opn = "divu";
1451
        break;
1452
    case OPC_MULT:
1453
        gen_op_mult();
1454
        opn = "mult";
1455
        break;
1456
    case OPC_MULTU:
1457
        gen_op_multu();
1458
        opn = "multu";
1459
        break;
1460
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1461
    case OPC_DDIV:
1462
        gen_op_ddiv();
1463
        opn = "ddiv";
1464
        break;
1465
    case OPC_DDIVU:
1466
        gen_op_ddivu();
1467
        opn = "ddivu";
1468
        break;
1469
    case OPC_DMULT:
1470
        gen_op_dmult();
1471
        opn = "dmult";
1472
        break;
1473
    case OPC_DMULTU:
1474
        gen_op_dmultu();
1475
        opn = "dmultu";
1476
        break;
1477
#endif
1478
    case OPC_MADD:
1479
        gen_op_madd();
1480
        opn = "madd";
1481
        break;
1482
    case OPC_MADDU:
1483
        gen_op_maddu();
1484
        opn = "maddu";
1485
        break;
1486
    case OPC_MSUB:
1487
        gen_op_msub();
1488
        opn = "msub";
1489
        break;
1490
    case OPC_MSUBU:
1491
        gen_op_msubu();
1492
        opn = "msubu";
1493
        break;
1494
    default:
1495
        MIPS_INVAL(opn);
1496
        generate_exception(ctx, EXCP_RI);
1497
        return;
1498
    }
1499
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1500
}
1501

    
1502
static void gen_cl (DisasContext *ctx, uint32_t opc,
1503
                    int rd, int rs)
1504
{
1505
    const char *opn = "CLx";
1506
    if (rd == 0) {
1507
        /* Treat as NOP. */
1508
        MIPS_DEBUG("NOP");
1509
        return;
1510
    }
1511
    GEN_LOAD_REG_TN(T0, rs);
1512
    switch (opc) {
1513
    case OPC_CLO:
1514
        gen_op_clo();
1515
        opn = "clo";
1516
        break;
1517
    case OPC_CLZ:
1518
        gen_op_clz();
1519
        opn = "clz";
1520
        break;
1521
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
1522
    case OPC_DCLO:
1523
        gen_op_dclo();
1524
        opn = "dclo";
1525
        break;
1526
    case OPC_DCLZ:
1527
        gen_op_dclz();
1528
        opn = "dclz";
1529
        break;
1530
#endif
1531
    default:
1532
        MIPS_INVAL(opn);
1533
        generate_exception(ctx, EXCP_RI);
1534
        return;
1535
    }
1536
    gen_op_store_T0_gpr(rd);
1537
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1538
}
1539

    
1540
/* Traps */
1541
static void gen_trap (DisasContext *ctx, uint32_t opc,
1542
                      int rs, int rt, int16_t imm)
1543
{
1544
    int cond;
1545

    
1546
    cond = 0;
1547
    /* Load needed operands */
1548
    switch (opc) {
1549
    case OPC_TEQ:
1550
    case OPC_TGE:
1551
    case OPC_TGEU:
1552
    case OPC_TLT:
1553
    case OPC_TLTU:
1554
    case OPC_TNE:
1555
        /* Compare two registers */
1556
        if (rs != rt) {
1557
            GEN_LOAD_REG_TN(T0, rs);
1558
            GEN_LOAD_REG_TN(T1, rt);
1559
            cond = 1;
1560
        }
1561
        break;
1562
    case OPC_TEQI:
1563
    case OPC_TGEI:
1564
    case OPC_TGEIU:
1565
    case OPC_TLTI:
1566
    case OPC_TLTIU:
1567
    case OPC_TNEI:
1568
        /* Compare register to immediate */
1569
        if (rs != 0 || imm != 0) {
1570
            GEN_LOAD_REG_TN(T0, rs);
1571
            GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1572
            cond = 1;
1573
        }
1574
        break;
1575
    }
1576
    if (cond == 0) {
1577
        switch (opc) {
1578
        case OPC_TEQ:   /* rs == rs */
1579
        case OPC_TEQI:  /* r0 == 0  */
1580
        case OPC_TGE:   /* rs >= rs */
1581
        case OPC_TGEI:  /* r0 >= 0  */
1582
        case OPC_TGEU:  /* rs >= rs unsigned */
1583
        case OPC_TGEIU: /* r0 >= 0  unsigned */
1584
            /* Always trap */
1585
            gen_op_set_T0(1);
1586
            break;
1587
        case OPC_TLT:   /* rs < rs           */
1588
        case OPC_TLTI:  /* r0 < 0            */
1589
        case OPC_TLTU:  /* rs < rs unsigned  */
1590
        case OPC_TLTIU: /* r0 < 0  unsigned  */
1591
        case OPC_TNE:   /* rs != rs          */
1592
        case OPC_TNEI:  /* r0 != 0           */
1593
            /* Never trap: treat as NOP. */
1594
            return;
1595
        default:
1596
            MIPS_INVAL("trap");
1597
            generate_exception(ctx, EXCP_RI);
1598
            return;
1599
        }
1600
    } else {
1601
        switch (opc) {
1602
        case OPC_TEQ:
1603
        case OPC_TEQI:
1604
            gen_op_eq();
1605
            break;
1606
        case OPC_TGE:
1607
        case OPC_TGEI:
1608
            gen_op_ge();
1609
            break;
1610
        case OPC_TGEU:
1611
        case OPC_TGEIU:
1612
            gen_op_geu();
1613
            break;
1614
        case OPC_TLT:
1615
        case OPC_TLTI:
1616
            gen_op_lt();
1617
            break;
1618
        case OPC_TLTU:
1619
        case OPC_TLTIU:
1620
            gen_op_ltu();
1621
            break;
1622
        case OPC_TNE:
1623
        case OPC_TNEI:
1624
            gen_op_ne();
1625
            break;
1626
        default:
1627
            MIPS_INVAL("trap");
1628
            generate_exception(ctx, EXCP_RI);
1629
            return;
1630
        }
1631
    }
1632
    save_cpu_state(ctx, 1);
1633
    gen_op_trap();
1634
    ctx->bstate = BS_STOP;
1635
}
1636

    
1637
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1638
{
1639
    TranslationBlock *tb;
1640
    tb = ctx->tb;
1641
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1642
        if (n == 0)
1643
            gen_op_goto_tb0(TBPARAM(tb));
1644
        else
1645
            gen_op_goto_tb1(TBPARAM(tb));
1646
        gen_save_pc(dest);
1647
        gen_op_set_T0((long)tb + n);
1648
    } else {
1649
        gen_save_pc(dest);
1650
        gen_op_reset_T0();
1651
    }
1652
    gen_op_exit_tb();
1653
}
1654

    
1655
/* Branches (before delay slot) */
1656
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1657
                                int rs, int rt, int32_t offset)
1658
{
1659
    target_ulong btarget = -1;
1660
    int blink = 0;
1661
    int bcond = 0;
1662

    
1663
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1664
#ifdef MIPS_DEBUG_DISAS
1665
        if (loglevel & CPU_LOG_TB_IN_ASM) {
1666
            fprintf(logfile,
1667
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
1668
                    ctx->pc);
1669
        }
1670
#endif
1671
        generate_exception(ctx, EXCP_RI);
1672
        return;
1673
    }
1674

    
1675
    /* Load needed operands */
1676
    switch (opc) {
1677
    case OPC_BEQ:
1678
    case OPC_BEQL:
1679
    case OPC_BNE:
1680
    case OPC_BNEL:
1681
        /* Compare two registers */
1682
        if (rs != rt) {
1683
            GEN_LOAD_REG_TN(T0, rs);
1684
            GEN_LOAD_REG_TN(T1, rt);
1685
            bcond = 1;
1686
        }
1687
        btarget = ctx->pc + 4 + offset;
1688
        break;
1689
    case OPC_BGEZ:
1690
    case OPC_BGEZAL:
1691
    case OPC_BGEZALL:
1692
    case OPC_BGEZL:
1693
    case OPC_BGTZ:
1694
    case OPC_BGTZL:
1695
    case OPC_BLEZ:
1696
    case OPC_BLEZL:
1697
    case OPC_BLTZ:
1698
    case OPC_BLTZAL:
1699
    case OPC_BLTZALL:
1700
    case OPC_BLTZL:
1701
        /* Compare to zero */
1702
        if (rs != 0) {
1703
            gen_op_load_gpr_T0(rs);
1704
            bcond = 1;
1705
        }
1706
        btarget = ctx->pc + 4 + offset;
1707
        break;
1708
    case OPC_J:
1709
    case OPC_JAL:
1710
        /* Jump to immediate */
1711
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
1712
        break;
1713
    case OPC_JR:
1714
    case OPC_JALR:
1715
        /* Jump to register */
1716
        if (offset != 0 && offset != 16) {
1717
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1718
               others are reserved. */
1719
            MIPS_INVAL("jump hint");
1720
            generate_exception(ctx, EXCP_RI);
1721
            return;
1722
        }
1723
        GEN_LOAD_REG_TN(T2, rs);
1724
        break;
1725
    default:
1726
        MIPS_INVAL("branch/jump");
1727
        generate_exception(ctx, EXCP_RI);
1728
        return;
1729
    }
1730
    if (bcond == 0) {
1731
        /* No condition to be computed */
1732
        switch (opc) {
1733
        case OPC_BEQ:     /* rx == rx        */
1734
        case OPC_BEQL:    /* rx == rx likely */
1735
        case OPC_BGEZ:    /* 0 >= 0          */
1736
        case OPC_BGEZL:   /* 0 >= 0 likely   */
1737
        case OPC_BLEZ:    /* 0 <= 0          */
1738
        case OPC_BLEZL:   /* 0 <= 0 likely   */
1739
            /* Always take */
1740
            ctx->hflags |= MIPS_HFLAG_B;
1741
            MIPS_DEBUG("balways");
1742
            break;
1743
        case OPC_BGEZAL:  /* 0 >= 0          */
1744
        case OPC_BGEZALL: /* 0 >= 0 likely   */
1745
            /* Always take and link */
1746
            blink = 31;
1747
            ctx->hflags |= MIPS_HFLAG_B;
1748
            MIPS_DEBUG("balways and link");
1749
            break;
1750
        case OPC_BNE:     /* rx != rx        */
1751
        case OPC_BGTZ:    /* 0 > 0           */
1752
        case OPC_BLTZ:    /* 0 < 0           */
1753
            /* Treat as NOP. */
1754
            MIPS_DEBUG("bnever (NOP)");
1755
            return;
1756
        case OPC_BLTZAL:  /* 0 < 0           */
1757
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1758
            gen_op_store_T0_gpr(31);
1759
            MIPS_DEBUG("bnever and link");
1760
            return;
1761
        case OPC_BLTZALL: /* 0 < 0 likely */
1762
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1763
            gen_op_store_T0_gpr(31);
1764
            /* Skip the instruction in the delay slot */
1765
            MIPS_DEBUG("bnever, link and skip");
1766
            ctx->pc += 4;
1767
            return;
1768
        case OPC_BNEL:    /* rx != rx likely */
1769
        case OPC_BGTZL:   /* 0 > 0 likely */
1770
        case OPC_BLTZL:   /* 0 < 0 likely */
1771
            /* Skip the instruction in the delay slot */
1772
            MIPS_DEBUG("bnever and skip");
1773
            ctx->pc += 4;
1774
            return;
1775
        case OPC_J:
1776
            ctx->hflags |= MIPS_HFLAG_B;
1777
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
1778
            break;
1779
        case OPC_JAL:
1780
            blink = 31;
1781
            ctx->hflags |= MIPS_HFLAG_B;
1782
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
1783
            break;
1784
        case OPC_JR:
1785
            ctx->hflags |= MIPS_HFLAG_BR;
1786
            MIPS_DEBUG("jr %s", regnames[rs]);
1787
            break;
1788
        case OPC_JALR:
1789
            blink = rt;
1790
            ctx->hflags |= MIPS_HFLAG_BR;
1791
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1792
            break;
1793
        default:
1794
            MIPS_INVAL("branch/jump");
1795
            generate_exception(ctx, EXCP_RI);
1796
            return;
1797
        }
1798
    } else {
1799
        switch (opc) {
1800
        case OPC_BEQ:
1801
            gen_op_eq();
1802
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1803
                       regnames[rs], regnames[rt], btarget);
1804
            goto not_likely;
1805
        case OPC_BEQL:
1806
            gen_op_eq();
1807
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1808
                       regnames[rs], regnames[rt], btarget);
1809
            goto likely;
1810
        case OPC_BNE:
1811
            gen_op_ne();
1812
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1813
                       regnames[rs], regnames[rt], btarget);
1814
            goto not_likely;
1815
        case OPC_BNEL:
1816
            gen_op_ne();
1817
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1818
                       regnames[rs], regnames[rt], btarget);
1819
            goto likely;
1820
        case OPC_BGEZ:
1821
            gen_op_gez();
1822
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1823
            goto not_likely;
1824
        case OPC_BGEZL:
1825
            gen_op_gez();
1826
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1827
            goto likely;
1828
        case OPC_BGEZAL:
1829
            gen_op_gez();
1830
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1831
            blink = 31;
1832
            goto not_likely;
1833
        case OPC_BGEZALL:
1834
            gen_op_gez();
1835
            blink = 31;
1836
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1837
            goto likely;
1838
        case OPC_BGTZ:
1839
            gen_op_gtz();
1840
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1841
            goto not_likely;
1842
        case OPC_BGTZL:
1843
            gen_op_gtz();
1844
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1845
            goto likely;
1846
        case OPC_BLEZ:
1847
            gen_op_lez();
1848
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1849
            goto not_likely;
1850
        case OPC_BLEZL:
1851
            gen_op_lez();
1852
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1853
            goto likely;
1854
        case OPC_BLTZ:
1855
            gen_op_ltz();
1856
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1857
            goto not_likely;
1858
        case OPC_BLTZL:
1859
            gen_op_ltz();
1860
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1861
            goto likely;
1862
        case OPC_BLTZAL:
1863
            gen_op_ltz();
1864
            blink = 31;
1865
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1866
        not_likely:
1867
            ctx->hflags |= MIPS_HFLAG_BC;
1868
            gen_op_set_bcond();
1869
            break;
1870
        case OPC_BLTZALL:
1871
            gen_op_ltz();
1872
            blink = 31;
1873
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1874
        likely:
1875
            ctx->hflags |= MIPS_HFLAG_BL;
1876
            gen_op_set_bcond();
1877
            gen_op_save_bcond();
1878
            break;
1879
        default:
1880
            MIPS_INVAL("conditional branch/jump");
1881
            generate_exception(ctx, EXCP_RI);
1882
            return;
1883
        }
1884
    }
1885
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
1886
               blink, ctx->hflags, btarget);
1887

    
1888
    ctx->btarget = btarget;
1889
    if (blink > 0) {
1890
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1891
        gen_op_store_T0_gpr(blink);
1892
    }
1893
}
1894

    
1895
/* special3 bitfield operations */
1896
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1897
                       int rs, int lsb, int msb)
1898
{
1899
    GEN_LOAD_REG_TN(T1, rs);
1900
    switch (opc) {
1901
    case OPC_EXT:
1902
        if (lsb + msb > 31)
1903
            goto fail;
1904
        gen_op_ext(lsb, msb + 1);
1905
        break;
1906
    case OPC_DEXTM:
1907
        if (lsb + msb > 63)
1908
            goto fail;
1909
        gen_op_ext(lsb, msb + 1 + 32);
1910
        break;
1911
    case OPC_DEXTU:
1912
        if (lsb + msb > 63)
1913
            goto fail;
1914
        gen_op_ext(lsb + 32, msb + 1);
1915
        break;
1916
    case OPC_DEXT:
1917
        gen_op_ext(lsb, msb + 1);
1918
        break;
1919
    case OPC_INS:
1920
        if (lsb > msb)
1921
            goto fail;
1922
        GEN_LOAD_REG_TN(T0, rt);
1923
        gen_op_ins(lsb, msb - lsb + 1);
1924
        break;
1925
    case OPC_DINSM:
1926
        if (lsb > msb)
1927
            goto fail;
1928
        GEN_LOAD_REG_TN(T0, rt);
1929
        gen_op_ins(lsb, msb - lsb + 1 + 32);
1930
        break;
1931
    case OPC_DINSU:
1932
        if (lsb > msb)
1933
            goto fail;
1934
        GEN_LOAD_REG_TN(T0, rt);
1935
        gen_op_ins(lsb + 32, msb - lsb + 1);
1936
        break;
1937
    case OPC_DINS:
1938
        if (lsb > msb)
1939
            goto fail;
1940
        GEN_LOAD_REG_TN(T0, rt);
1941
        gen_op_ins(lsb, msb - lsb + 1);
1942
        break;
1943
    default:
1944
fail:
1945
        MIPS_INVAL("bitops");
1946
        generate_exception(ctx, EXCP_RI);
1947
        return;
1948
    }
1949
    GEN_STORE_TN_REG(rt, T0);
1950
}
1951

    
1952
/* CP0 (MMU and control) */
1953
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1954
{
1955
    const char *rn = "invalid";
1956

    
1957
    if (sel != 0)
1958
        check_insn(env, ctx, ISA_MIPS32);
1959

    
1960
    switch (reg) {
1961
    case 0:
1962
        switch (sel) {
1963
        case 0:
1964
            gen_op_mfc0_index();
1965
            rn = "Index";
1966
            break;
1967
        case 1:
1968
            check_mips_mt(env, ctx);
1969
            gen_op_mfc0_mvpcontrol();
1970
            rn = "MVPControl";
1971
            break;
1972
        case 2:
1973
            check_mips_mt(env, ctx);
1974
            gen_op_mfc0_mvpconf0();
1975
            rn = "MVPConf0";
1976
            break;
1977
        case 3:
1978
            check_mips_mt(env, ctx);
1979
            gen_op_mfc0_mvpconf1();
1980
            rn = "MVPConf1";
1981
            break;
1982
        default:
1983
            goto die;
1984
        }
1985
        break;
1986
    case 1:
1987
        switch (sel) {
1988
        case 0:
1989
            gen_op_mfc0_random();
1990
            rn = "Random";
1991
            break;
1992
        case 1:
1993
            check_mips_mt(env, ctx);
1994
            gen_op_mfc0_vpecontrol();
1995
            rn = "VPEControl";
1996
            break;
1997
        case 2:
1998
            check_mips_mt(env, ctx);
1999
            gen_op_mfc0_vpeconf0();
2000
            rn = "VPEConf0";
2001
            break;
2002
        case 3:
2003
            check_mips_mt(env, ctx);
2004
            gen_op_mfc0_vpeconf1();
2005
            rn = "VPEConf1";
2006
            break;
2007
        case 4:
2008
            check_mips_mt(env, ctx);
2009
            gen_op_mfc0_yqmask();
2010
            rn = "YQMask";
2011
            break;
2012
        case 5:
2013
            check_mips_mt(env, ctx);
2014
            gen_op_mfc0_vpeschedule();
2015
            rn = "VPESchedule";
2016
            break;
2017
        case 6:
2018
            check_mips_mt(env, ctx);
2019
            gen_op_mfc0_vpeschefback();
2020
            rn = "VPEScheFBack";
2021
            break;
2022
        case 7:
2023
            check_mips_mt(env, ctx);
2024
            gen_op_mfc0_vpeopt();
2025
            rn = "VPEOpt";
2026
            break;
2027
        default:
2028
            goto die;
2029
        }
2030
        break;
2031
    case 2:
2032
        switch (sel) {
2033
        case 0:
2034
            gen_op_mfc0_entrylo0();
2035
            rn = "EntryLo0";
2036
            break;
2037
        case 1:
2038
            check_mips_mt(env, ctx);
2039
            gen_op_mfc0_tcstatus();
2040
            rn = "TCStatus";
2041
            break;
2042
        case 2:
2043
            check_mips_mt(env, ctx);
2044
            gen_op_mfc0_tcbind();
2045
            rn = "TCBind";
2046
            break;
2047
        case 3:
2048
            check_mips_mt(env, ctx);
2049
            gen_op_mfc0_tcrestart();
2050
            rn = "TCRestart";
2051
            break;
2052
        case 4:
2053
            check_mips_mt(env, ctx);
2054
            gen_op_mfc0_tchalt();
2055
            rn = "TCHalt";
2056
            break;
2057
        case 5:
2058
            check_mips_mt(env, ctx);
2059
            gen_op_mfc0_tccontext();
2060
            rn = "TCContext";
2061
            break;
2062
        case 6:
2063
            check_mips_mt(env, ctx);
2064
            gen_op_mfc0_tcschedule();
2065
            rn = "TCSchedule";
2066
            break;
2067
        case 7:
2068
            check_mips_mt(env, ctx);
2069
            gen_op_mfc0_tcschefback();
2070
            rn = "TCScheFBack";
2071
            break;
2072
        default:
2073
            goto die;
2074
        }
2075
        break;
2076
    case 3:
2077
        switch (sel) {
2078
        case 0:
2079
            gen_op_mfc0_entrylo1();
2080
            rn = "EntryLo1";
2081
            break;
2082
        default:
2083
            goto die;
2084
        }
2085
        break;
2086
    case 4:
2087
        switch (sel) {
2088
        case 0:
2089
            gen_op_mfc0_context();
2090
            rn = "Context";
2091
            break;
2092
        case 1:
2093
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2094
            rn = "ContextConfig";
2095
//            break;
2096
        default:
2097
            goto die;
2098
        }
2099
        break;
2100
    case 5:
2101
        switch (sel) {
2102
        case 0:
2103
            gen_op_mfc0_pagemask();
2104
            rn = "PageMask";
2105
            break;
2106
        case 1:
2107
            check_insn(env, ctx, ISA_MIPS32R2);
2108
            gen_op_mfc0_pagegrain();
2109
            rn = "PageGrain";
2110
            break;
2111
        default:
2112
            goto die;
2113
        }
2114
        break;
2115
    case 6:
2116
        switch (sel) {
2117
        case 0:
2118
            gen_op_mfc0_wired();
2119
            rn = "Wired";
2120
            break;
2121
        case 1:
2122
            check_insn(env, ctx, ISA_MIPS32R2);
2123
            gen_op_mfc0_srsconf0();
2124
            rn = "SRSConf0";
2125
            break;
2126
        case 2:
2127
            check_insn(env, ctx, ISA_MIPS32R2);
2128
            gen_op_mfc0_srsconf1();
2129
            rn = "SRSConf1";
2130
            break;
2131
        case 3:
2132
            check_insn(env, ctx, ISA_MIPS32R2);
2133
            gen_op_mfc0_srsconf2();
2134
            rn = "SRSConf2";
2135
            break;
2136
        case 4:
2137
            check_insn(env, ctx, ISA_MIPS32R2);
2138
            gen_op_mfc0_srsconf3();
2139
            rn = "SRSConf3";
2140
            break;
2141
        case 5:
2142
            check_insn(env, ctx, ISA_MIPS32R2);
2143
            gen_op_mfc0_srsconf4();
2144
            rn = "SRSConf4";
2145
            break;
2146
        default:
2147
            goto die;
2148
        }
2149
        break;
2150
    case 7:
2151
        switch (sel) {
2152
        case 0:
2153
            check_insn(env, ctx, ISA_MIPS32R2);
2154
            gen_op_mfc0_hwrena();
2155
            rn = "HWREna";
2156
            break;
2157
        default:
2158
            goto die;
2159
        }
2160
        break;
2161
    case 8:
2162
        switch (sel) {
2163
        case 0:
2164
            gen_op_mfc0_badvaddr();
2165
            rn = "BadVaddr";
2166
            break;
2167
        default:
2168
            goto die;
2169
       }
2170
        break;
2171
    case 9:
2172
        switch (sel) {
2173
        case 0:
2174
            gen_op_mfc0_count();
2175
            rn = "Count";
2176
            break;
2177
        /* 6,7 are implementation dependent */
2178
        default:
2179
            goto die;
2180
        }
2181
        break;
2182
    case 10:
2183
        switch (sel) {
2184
        case 0:
2185
            gen_op_mfc0_entryhi();
2186
            rn = "EntryHi";
2187
            break;
2188
        default:
2189
            goto die;
2190
        }
2191
        break;
2192
    case 11:
2193
        switch (sel) {
2194
        case 0:
2195
            gen_op_mfc0_compare();
2196
            rn = "Compare";
2197
            break;
2198
        /* 6,7 are implementation dependent */
2199
        default:
2200
            goto die;
2201
        }
2202
        break;
2203
    case 12:
2204
        switch (sel) {
2205
        case 0:
2206
            gen_op_mfc0_status();
2207
            rn = "Status";
2208
            break;
2209
        case 1:
2210
            check_insn(env, ctx, ISA_MIPS32R2);
2211
            gen_op_mfc0_intctl();
2212
            rn = "IntCtl";
2213
            break;
2214
        case 2:
2215
            check_insn(env, ctx, ISA_MIPS32R2);
2216
            gen_op_mfc0_srsctl();
2217
            rn = "SRSCtl";
2218
            break;
2219
        case 3:
2220
            check_insn(env, ctx, ISA_MIPS32R2);
2221
            gen_op_mfc0_srsmap();
2222
            rn = "SRSMap";
2223
            break;
2224
        default:
2225
            goto die;
2226
       }
2227
        break;
2228
    case 13:
2229
        switch (sel) {
2230
        case 0:
2231
            gen_op_mfc0_cause();
2232
            rn = "Cause";
2233
            break;
2234
        default:
2235
            goto die;
2236
       }
2237
        break;
2238
    case 14:
2239
        switch (sel) {
2240
        case 0:
2241
            gen_op_mfc0_epc();
2242
            rn = "EPC";
2243
            break;
2244
        default:
2245
            goto die;
2246
        }
2247
        break;
2248
    case 15:
2249
        switch (sel) {
2250
        case 0:
2251
            gen_op_mfc0_prid();
2252
            rn = "PRid";
2253
            break;
2254
        case 1:
2255
            check_insn(env, ctx, ISA_MIPS32R2);
2256
            gen_op_mfc0_ebase();
2257
            rn = "EBase";
2258
            break;
2259
        default:
2260
            goto die;
2261
       }
2262
        break;
2263
    case 16:
2264
        switch (sel) {
2265
        case 0:
2266
            gen_op_mfc0_config0();
2267
            rn = "Config";
2268
            break;
2269
        case 1:
2270
            gen_op_mfc0_config1();
2271
            rn = "Config1";
2272
            break;
2273
        case 2:
2274
            gen_op_mfc0_config2();
2275
            rn = "Config2";
2276
            break;
2277
        case 3:
2278
            gen_op_mfc0_config3();
2279
            rn = "Config3";
2280
            break;
2281
        /* 4,5 are reserved */
2282
        /* 6,7 are implementation dependent */
2283
        case 6:
2284
            gen_op_mfc0_config6();
2285
            rn = "Config6";
2286
            break;
2287
        case 7:
2288
            gen_op_mfc0_config7();
2289
            rn = "Config7";
2290
            break;
2291
        default:
2292
            goto die;
2293
        }
2294
        break;
2295
    case 17:
2296
        switch (sel) {
2297
        case 0:
2298
            gen_op_mfc0_lladdr();
2299
            rn = "LLAddr";
2300
            break;
2301
        default:
2302
            goto die;
2303
        }
2304
        break;
2305
    case 18:
2306
        switch (sel) {
2307
        case 0 ... 7:
2308
            gen_op_mfc0_watchlo(sel);
2309
            rn = "WatchLo";
2310
            break;
2311
        default:
2312
            goto die;
2313
        }
2314
        break;
2315
    case 19:
2316
        switch (sel) {
2317
        case 0 ...7:
2318
            gen_op_mfc0_watchhi(sel);
2319
            rn = "WatchHi";
2320
            break;
2321
        default:
2322
            goto die;
2323
        }
2324
        break;
2325
    case 20:
2326
        switch (sel) {
2327
        case 0:
2328
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
2329
            check_insn(env, ctx, ISA_MIPS3);
2330
            gen_op_mfc0_xcontext();
2331
            rn = "XContext";
2332
            break;
2333
#endif
2334
        default:
2335
            goto die;
2336
        }
2337
        break;
2338
    case 21:
2339
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2340
        switch (sel) {
2341
        case 0:
2342
            gen_op_mfc0_framemask();
2343
            rn = "Framemask";
2344
            break;
2345
        default:
2346
            goto die;
2347
        }
2348
        break;
2349
    case 22:
2350
        /* ignored */
2351
        rn = "'Diagnostic"; /* implementation dependent */
2352
        break;
2353
    case 23:
2354
        switch (sel) {
2355
        case 0:
2356
            gen_op_mfc0_debug(); /* EJTAG support */
2357
            rn = "Debug";
2358
            break;
2359
        case 1:
2360
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2361
            rn = "TraceControl";
2362
//            break;
2363
        case 2:
2364
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2365
            rn = "TraceControl2";
2366
//            break;
2367
        case 3:
2368
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
2369
            rn = "UserTraceData";
2370
//            break;
2371
        case 4:
2372
//            gen_op_mfc0_debug(); /* PDtrace support */
2373
            rn = "TraceBPC";
2374
//            break;
2375
        default:
2376
            goto die;
2377
        }
2378
        break;
2379
    case 24:
2380
        switch (sel) {
2381
        case 0:
2382
            gen_op_mfc0_depc(); /* EJTAG support */
2383
            rn = "DEPC";
2384
            break;
2385
        default:
2386
            goto die;
2387
        }
2388
        break;
2389
    case 25:
2390
        switch (sel) {
2391
        case 0:
2392
            gen_op_mfc0_performance0();
2393
            rn = "Performance0";
2394
            break;
2395
        case 1:
2396
//            gen_op_mfc0_performance1();
2397
            rn = "Performance1";
2398
//            break;
2399
        case 2:
2400
//            gen_op_mfc0_performance2();
2401
            rn = "Performance2";
2402
//            break;
2403
        case 3:
2404
//            gen_op_mfc0_performance3();
2405
            rn = "Performance3";
2406
//            break;
2407
        case 4:
2408
//            gen_op_mfc0_performance4();
2409
            rn = "Performance4";
2410
//            break;
2411
        case 5:
2412
//            gen_op_mfc0_performance5();
2413
            rn = "Performance5";
2414
//            break;
2415
        case 6:
2416
//            gen_op_mfc0_performance6();
2417
            rn = "Performance6";
2418
//            break;
2419
        case 7:
2420
//            gen_op_mfc0_performance7();
2421
            rn = "Performance7";
2422
//            break;
2423
        default:
2424
            goto die;
2425
        }
2426
        break;
2427
    case 26:
2428
       rn = "ECC";
2429
       break;
2430
    case 27:
2431
        switch (sel) {
2432
        /* ignored */
2433
        case 0 ... 3:
2434
            rn = "CacheErr";
2435
            break;
2436
        default:
2437
            goto die;
2438
        }
2439
        break;
2440
    case 28:
2441
        switch (sel) {
2442
        case 0:
2443
        case 2:
2444
        case 4:
2445
        case 6:
2446
            gen_op_mfc0_taglo();
2447
            rn = "TagLo";
2448
            break;
2449
        case 1:
2450
        case 3:
2451
        case 5:
2452
        case 7:
2453
            gen_op_mfc0_datalo();
2454
            rn = "DataLo";
2455
            break;
2456
        default:
2457
            goto die;
2458
        }
2459
        break;
2460
    case 29:
2461
        switch (sel) {
2462
        case 0:
2463
        case 2:
2464
        case 4:
2465
        case 6:
2466
            gen_op_mfc0_taghi();
2467
            rn = "TagHi";
2468
            break;
2469
        case 1:
2470
        case 3:
2471
        case 5:
2472
        case 7:
2473
            gen_op_mfc0_datahi();
2474
            rn = "DataHi";
2475
            break;
2476
        default:
2477
            goto die;
2478
        }
2479
        break;
2480
    case 30:
2481
        switch (sel) {
2482
        case 0:
2483
            gen_op_mfc0_errorepc();
2484
            rn = "ErrorEPC";
2485
            break;
2486
        default:
2487
            goto die;
2488
        }
2489
        break;
2490
    case 31:
2491
        switch (sel) {
2492
        case 0:
2493
            gen_op_mfc0_desave(); /* EJTAG support */
2494
            rn = "DESAVE";
2495
            break;
2496
        default:
2497
            goto die;
2498
        }
2499
        break;
2500
    default:
2501
       goto die;
2502
    }
2503
#if defined MIPS_DEBUG_DISAS
2504
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2505
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2506
                rn, reg, sel);
2507
    }
2508
#endif
2509
    return;
2510

    
2511
die:
2512
#if defined MIPS_DEBUG_DISAS
2513
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2514
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2515
                rn, reg, sel);
2516
    }
2517
#endif
2518
    generate_exception(ctx, EXCP_RI);
2519
}
2520

    
2521
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2522
{
2523
    const char *rn = "invalid";
2524

    
2525
    if (sel != 0)
2526
        check_insn(env, ctx, ISA_MIPS32);
2527

    
2528
    switch (reg) {
2529
    case 0:
2530
        switch (sel) {
2531
        case 0:
2532
           gen_op_mtc0_index();
2533
            rn = "Index";
2534
            break;
2535
        case 1:
2536
            check_mips_mt(env, ctx);
2537
            gen_op_mtc0_mvpcontrol();
2538
            rn = "MVPControl";
2539
            break;
2540
        case 2:
2541
            check_mips_mt(env, ctx);
2542
            /* ignored */
2543
            rn = "MVPConf0";
2544
            break;
2545
        case 3:
2546
            check_mips_mt(env, ctx);
2547
            /* ignored */
2548
            rn = "MVPConf1";
2549
            break;
2550
        default:
2551
            goto die;
2552
        }
2553
        break;
2554
    case 1:
2555
        switch (sel) {
2556
        case 0:
2557
            /* ignored */
2558
            rn = "Random";
2559
            break;
2560
        case 1:
2561
            check_mips_mt(env, ctx);
2562
            gen_op_mtc0_vpecontrol();
2563
            rn = "VPEControl";
2564
            break;
2565
        case 2:
2566
            check_mips_mt(env, ctx);
2567
            gen_op_mtc0_vpeconf0();
2568
            rn = "VPEConf0";
2569
            break;
2570
        case 3:
2571
            check_mips_mt(env, ctx);
2572
            gen_op_mtc0_vpeconf1();
2573
            rn = "VPEConf1";
2574
            break;
2575
        case 4:
2576
            check_mips_mt(env, ctx);
2577
            gen_op_mtc0_yqmask();
2578
            rn = "YQMask";
2579
            break;
2580
        case 5:
2581
            check_mips_mt(env, ctx);
2582
            gen_op_mtc0_vpeschedule();
2583
            rn = "VPESchedule";
2584
            break;
2585
        case 6:
2586
            check_mips_mt(env, ctx);
2587
            gen_op_mtc0_vpeschefback();
2588
            rn = "VPEScheFBack";
2589
            break;
2590
        case 7:
2591
            check_mips_mt(env, ctx);
2592
            gen_op_mtc0_vpeopt();
2593
            rn = "VPEOpt";
2594
            break;
2595
        default:
2596
            goto die;
2597
        }
2598
        break;
2599
    case 2:
2600
        switch (sel) {
2601
        case 0:
2602
            gen_op_mtc0_entrylo0();
2603
            rn = "EntryLo0";
2604
            break;
2605
        case 1:
2606
            check_mips_mt(env, ctx);
2607
            gen_op_mtc0_tcstatus();
2608
            rn = "TCStatus";
2609
            break;
2610
        case 2:
2611
            check_mips_mt(env, ctx);
2612
            gen_op_mtc0_tcbind();
2613
            rn = "TCBind";
2614
            break;
2615
        case 3:
2616
            check_mips_mt(env, ctx);
2617
            gen_op_mtc0_tcrestart();
2618
            rn = "TCRestart";
2619
            break;
2620
        case 4:
2621
            check_mips_mt(env, ctx);
2622
            gen_op_mtc0_tchalt();
2623
            rn = "TCHalt";
2624
            break;
2625
        case 5:
2626
            check_mips_mt(env, ctx);
2627
            gen_op_mtc0_tccontext();
2628
            rn = "TCContext";
2629
            break;
2630
        case 6:
2631
            check_mips_mt(env, ctx);
2632
            gen_op_mtc0_tcschedule();
2633
            rn = "TCSchedule";
2634
            break;
2635
        case 7:
2636
            check_mips_mt(env, ctx);
2637
            gen_op_mtc0_tcschefback();
2638
            rn = "TCScheFBack";
2639
            break;
2640
        default:
2641
            goto die;
2642
        }
2643
        break;
2644
    case 3:
2645
        switch (sel) {
2646
        case 0:
2647
            gen_op_mtc0_entrylo1();
2648
            rn = "EntryLo1";
2649
            break;
2650
        default:
2651
            goto die;
2652
        }
2653
        break;
2654
    case 4:
2655
        switch (sel) {
2656
        case 0:
2657
            gen_op_mtc0_context();
2658
            rn = "Context";
2659
            break;
2660
        case 1:
2661
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2662
            rn = "ContextConfig";
2663
//            break;
2664
        default:
2665
            goto die;
2666
        }
2667
        break;
2668
    case 5:
2669
        switch (sel) {
2670
        case 0:
2671
            gen_op_mtc0_pagemask();
2672
            rn = "PageMask";
2673
            break;
2674
        case 1:
2675
            check_insn(env, ctx, ISA_MIPS32R2);
2676
            gen_op_mtc0_pagegrain();
2677
            rn = "PageGrain";
2678
            break;
2679
        default:
2680
            goto die;
2681
        }
2682
        break;
2683
    case 6:
2684
        switch (sel) {
2685
        case 0:
2686
            gen_op_mtc0_wired();
2687
            rn = "Wired";
2688
            break;
2689
        case 1:
2690
            check_insn(env, ctx, ISA_MIPS32R2);
2691
            gen_op_mtc0_srsconf0();
2692
            rn = "SRSConf0";
2693
            break;
2694
        case 2:
2695
            check_insn(env, ctx, ISA_MIPS32R2);
2696
            gen_op_mtc0_srsconf1();
2697
            rn = "SRSConf1";
2698
            break;
2699
        case 3:
2700
            check_insn(env, ctx, ISA_MIPS32R2);
2701
            gen_op_mtc0_srsconf2();
2702
            rn = "SRSConf2";
2703
            break;
2704
        case 4:
2705
            check_insn(env, ctx, ISA_MIPS32R2);
2706
            gen_op_mtc0_srsconf3();
2707
            rn = "SRSConf3";
2708
            break;
2709
        case 5:
2710
            check_insn(env, ctx, ISA_MIPS32R2);
2711
            gen_op_mtc0_srsconf4();
2712
            rn = "SRSConf4";
2713
            break;
2714
        default:
2715
            goto die;
2716
        }
2717
        break;
2718
    case 7:
2719
        switch (sel) {
2720
        case 0:
2721
            check_insn(env, ctx, ISA_MIPS32R2);
2722
            gen_op_mtc0_hwrena();
2723
            rn = "HWREna";
2724
            break;
2725
        default:
2726
            goto die;
2727
        }
2728
        break;
2729
    case 8:
2730
        /* ignored */
2731
        rn = "BadVaddr";
2732
        break;
2733
    case 9:
2734
        switch (sel) {
2735
        case 0:
2736
            gen_op_mtc0_count();
2737
            rn = "Count";
2738
            break;
2739
        /* 6,7 are implementation dependent */
2740
        default:
2741
            goto die;
2742
        }
2743
        /* Stop translation as we may have switched the execution mode */
2744
        ctx->bstate = BS_STOP;
2745
        break;
2746
    case 10:
2747
        switch (sel) {
2748
        case 0:
2749
            gen_op_mtc0_entryhi();
2750
            rn = "EntryHi";
2751
            break;
2752
        default:
2753
            goto die;
2754
        }
2755
        break;
2756
    case 11:
2757
        switch (sel) {
2758
        case 0:
2759
            gen_op_mtc0_compare();
2760
            rn = "Compare";
2761
            break;
2762
        /* 6,7 are implementation dependent */
2763
        default:
2764
            goto die;
2765
        }
2766
        /* Stop translation as we may have switched the execution mode */
2767
        ctx->bstate = BS_STOP;
2768
        break;
2769
    case 12:
2770
        switch (sel) {
2771
        case 0:
2772
            gen_op_mtc0_status();
2773
            /* BS_STOP isn't good enough here, hflags may have changed. */
2774
            gen_save_pc(ctx->pc + 4);
2775
            ctx->bstate = BS_EXCP;
2776
            rn = "Status";
2777
            break;
2778
        case 1:
2779
            check_insn(env, ctx, ISA_MIPS32R2);
2780
            gen_op_mtc0_intctl();
2781
            /* Stop translation as we may have switched the execution mode */
2782
            ctx->bstate = BS_STOP;
2783
            rn = "IntCtl";
2784
            break;
2785
        case 2:
2786
            check_insn(env, ctx, ISA_MIPS32R2);
2787
            gen_op_mtc0_srsctl();
2788
            /* Stop translation as we may have switched the execution mode */
2789
            ctx->bstate = BS_STOP;
2790
            rn = "SRSCtl";
2791
            break;
2792
        case 3:
2793
            check_insn(env, ctx, ISA_MIPS32R2);
2794
            gen_op_mtc0_srsmap();
2795
            /* Stop translation as we may have switched the execution mode */
2796
            ctx->bstate = BS_STOP;
2797
            rn = "SRSMap";
2798
            break;
2799
        default:
2800
            goto die;
2801
        }
2802
        break;
2803
    case 13:
2804
        switch (sel) {
2805
        case 0:
2806
            gen_op_mtc0_cause();
2807
            rn = "Cause";
2808
            break;
2809
        default:
2810
            goto die;
2811
        }
2812
        /* Stop translation as we may have switched the execution mode */
2813
        ctx->bstate = BS_STOP;
2814
        break;
2815
    case 14:
2816
        switch (sel) {
2817
        case 0:
2818
            gen_op_mtc0_epc();
2819
            rn = "EPC";
2820
            break;
2821
        default:
2822
            goto die;
2823
        }
2824
        break;
2825
    case 15:
2826
        switch (sel) {
2827
        case 0:
2828
            /* ignored */
2829
            rn = "PRid";
2830
            break;
2831
        case 1:
2832
            check_insn(env, ctx, ISA_MIPS32R2);
2833
            gen_op_mtc0_ebase();
2834
            rn = "EBase";
2835
            break;
2836
        default:
2837
            goto die;
2838
        }
2839
        break;
2840
    case 16:
2841
        switch (sel) {
2842
        case 0:
2843
            gen_op_mtc0_config0();
2844
            rn = "Config";
2845
            /* Stop translation as we may have switched the execution mode */
2846
            ctx->bstate = BS_STOP;
2847
            break;
2848
        case 1:
2849
            /* ignored, read only */
2850
            rn = "Config1";
2851
            break;
2852
        case 2:
2853
            gen_op_mtc0_config2();
2854
            rn = "Config2";
2855
            /* Stop translation as we may have switched the execution mode */
2856
            ctx->bstate = BS_STOP;
2857
            break;
2858
        case 3:
2859
            /* ignored, read only */
2860
            rn = "Config3";
2861
            break;
2862
        /* 4,5 are reserved */
2863
        /* 6,7 are implementation dependent */
2864
        case 6:
2865
            /* ignored */
2866
            rn = "Config6";
2867
            break;
2868
        case 7:
2869
            /* ignored */
2870
            rn = "Config7";
2871
            break;
2872
        default:
2873
            rn = "Invalid config selector";
2874
            goto die;
2875
        }
2876
        break;
2877
    case 17:
2878
        switch (sel) {
2879
        case 0:
2880
            /* ignored */
2881
            rn = "LLAddr";
2882
            break;
2883
        default:
2884
            goto die;
2885
        }
2886
        break;
2887
    case 18:
2888
        switch (sel) {
2889
        case 0 ... 7:
2890
            gen_op_mtc0_watchlo(sel);
2891
            rn = "WatchLo";
2892
            break;
2893
        default:
2894
            goto die;
2895
        }
2896
        break;
2897
    case 19:
2898
        switch (sel) {
2899
        case 0 ... 7:
2900
            gen_op_mtc0_watchhi(sel);
2901
            rn = "WatchHi";
2902
            break;
2903
        default:
2904
            goto die;
2905
        }
2906
        break;
2907
    case 20:
2908
        switch (sel) {
2909
        case 0:
2910
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
2911
            check_insn(env, ctx, ISA_MIPS3);
2912
            gen_op_mtc0_xcontext();
2913
            rn = "XContext";
2914
            break;
2915
#endif
2916
        default:
2917
            goto die;
2918
        }
2919
        break;
2920
    case 21:
2921
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2922
        switch (sel) {
2923
        case 0:
2924
            gen_op_mtc0_framemask();
2925
            rn = "Framemask";
2926
            break;
2927
        default:
2928
            goto die;
2929
        }
2930
        break;
2931
    case 22:
2932
        /* ignored */
2933
        rn = "Diagnostic"; /* implementation dependent */
2934
        break;
2935
    case 23:
2936
        switch (sel) {
2937
        case 0:
2938
            gen_op_mtc0_debug(); /* EJTAG support */
2939
            /* BS_STOP isn't good enough here, hflags may have changed. */
2940
            gen_save_pc(ctx->pc + 4);
2941
            ctx->bstate = BS_EXCP;
2942
            rn = "Debug";
2943
            break;
2944
        case 1:
2945
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
2946
            rn = "TraceControl";
2947
            /* Stop translation as we may have switched the execution mode */
2948
            ctx->bstate = BS_STOP;
2949
//            break;
2950
        case 2:
2951
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2952
            rn = "TraceControl2";
2953
            /* Stop translation as we may have switched the execution mode */
2954
            ctx->bstate = BS_STOP;
2955
//            break;
2956
        case 3:
2957
            /* Stop translation as we may have switched the execution mode */
2958
            ctx->bstate = BS_STOP;
2959
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
2960
            rn = "UserTraceData";
2961
            /* Stop translation as we may have switched the execution mode */
2962
            ctx->bstate = BS_STOP;
2963
//            break;
2964
        case 4:
2965
//            gen_op_mtc0_debug(); /* PDtrace support */
2966
            /* Stop translation as we may have switched the execution mode */
2967
            ctx->bstate = BS_STOP;
2968
            rn = "TraceBPC";
2969
//            break;
2970
        default:
2971
            goto die;
2972
        }
2973
        break;
2974
    case 24:
2975
        switch (sel) {
2976
        case 0:
2977
            gen_op_mtc0_depc(); /* EJTAG support */
2978
            rn = "DEPC";
2979
            break;
2980
        default:
2981
            goto die;
2982
        }
2983
        break;
2984
    case 25:
2985
        switch (sel) {
2986
        case 0:
2987
            gen_op_mtc0_performance0();
2988
            rn = "Performance0";
2989
            break;
2990
        case 1:
2991
//            gen_op_mtc0_performance1();
2992
            rn = "Performance1";
2993
//            break;
2994
        case 2:
2995
//            gen_op_mtc0_performance2();
2996
            rn = "Performance2";
2997
//            break;
2998
        case 3:
2999
//            gen_op_mtc0_performance3();
3000
            rn = "Performance3";
3001
//            break;
3002
        case 4:
3003
//            gen_op_mtc0_performance4();
3004
            rn = "Performance4";
3005
//            break;
3006
        case 5:
3007
//            gen_op_mtc0_performance5();
3008
            rn = "Performance5";
3009
//            break;
3010
        case 6:
3011
//            gen_op_mtc0_performance6();
3012
            rn = "Performance6";
3013
//            break;
3014
        case 7:
3015
//            gen_op_mtc0_performance7();
3016
            rn = "Performance7";
3017
//            break;
3018
        default:
3019
            goto die;
3020
        }
3021
       break;
3022
    case 26:
3023
        /* ignored */
3024
        rn = "ECC";
3025
        break;
3026
    case 27:
3027
        switch (sel) {
3028
        case 0 ... 3:
3029
            /* ignored */
3030
            rn = "CacheErr";
3031
            break;
3032
        default:
3033
            goto die;
3034
        }
3035
       break;
3036
    case 28:
3037
        switch (sel) {
3038
        case 0:
3039
        case 2:
3040
        case 4:
3041
        case 6:
3042
            gen_op_mtc0_taglo();
3043
            rn = "TagLo";
3044
            break;
3045
        case 1:
3046
        case 3:
3047
        case 5:
3048
        case 7:
3049
            gen_op_mtc0_datalo();
3050
            rn = "DataLo";
3051
            break;
3052
        default:
3053
            goto die;
3054
        }
3055
        break;
3056
    case 29:
3057
        switch (sel) {
3058
        case 0:
3059
        case 2:
3060
        case 4:
3061
        case 6:
3062
            gen_op_mtc0_taghi();
3063
            rn = "TagHi";
3064
            break;
3065
        case 1:
3066
        case 3:
3067
        case 5:
3068
        case 7:
3069
            gen_op_mtc0_datahi();
3070
            rn = "DataHi";
3071
            break;
3072
        default:
3073
            rn = "invalid sel";
3074
            goto die;
3075
        }
3076
       break;
3077
    case 30:
3078
        switch (sel) {
3079
        case 0:
3080
            gen_op_mtc0_errorepc();
3081
            rn = "ErrorEPC";
3082
            break;
3083
        default:
3084
            goto die;
3085
        }
3086
        break;
3087
    case 31:
3088
        switch (sel) {
3089
        case 0:
3090
            gen_op_mtc0_desave(); /* EJTAG support */
3091
            rn = "DESAVE";
3092
            break;
3093
        default:
3094
            goto die;
3095
        }
3096
        /* Stop translation as we may have switched the execution mode */
3097
        ctx->bstate = BS_STOP;
3098
        break;
3099
    default:
3100
       goto die;
3101
    }
3102
#if defined MIPS_DEBUG_DISAS
3103
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3104
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3105
                rn, reg, sel);
3106
    }
3107
#endif
3108
    return;
3109

    
3110
die:
3111
#if defined MIPS_DEBUG_DISAS
3112
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3113
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3114
                rn, reg, sel);
3115
    }
3116
#endif
3117
    generate_exception(ctx, EXCP_RI);
3118
}
3119

    
3120
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
3121
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3122
{
3123
    const char *rn = "invalid";
3124

    
3125
    if (sel != 0)
3126
        check_insn(env, ctx, ISA_MIPS64);
3127

    
3128
    switch (reg) {
3129
    case 0:
3130
        switch (sel) {
3131
        case 0:
3132
            gen_op_mfc0_index();
3133
            rn = "Index";
3134
            break;
3135
        case 1:
3136
            check_mips_mt(env, ctx);
3137
            gen_op_mfc0_mvpcontrol();
3138
            rn = "MVPControl";
3139
            break;
3140
        case 2:
3141
            check_mips_mt(env, ctx);
3142
            gen_op_mfc0_mvpconf0();
3143
            rn = "MVPConf0";
3144
            break;
3145
        case 3:
3146
            check_mips_mt(env, ctx);
3147
            gen_op_mfc0_mvpconf1();
3148
            rn = "MVPConf1";
3149
            break;
3150
        default:
3151
            goto die;
3152
        }
3153
        break;
3154
    case 1:
3155
        switch (sel) {
3156
        case 0:
3157
            gen_op_mfc0_random();
3158
            rn = "Random";
3159
            break;
3160
        case 1:
3161
            check_mips_mt(env, ctx);
3162
            gen_op_mfc0_vpecontrol();
3163
            rn = "VPEControl";
3164
            break;
3165
        case 2:
3166
            check_mips_mt(env, ctx);
3167
            gen_op_mfc0_vpeconf0();
3168
            rn = "VPEConf0";
3169
            break;
3170
        case 3:
3171
            check_mips_mt(env, ctx);
3172
            gen_op_mfc0_vpeconf1();
3173
            rn = "VPEConf1";
3174
            break;
3175
        case 4:
3176
            check_mips_mt(env, ctx);
3177
            gen_op_dmfc0_yqmask();
3178
            rn = "YQMask";
3179
            break;
3180
        case 5:
3181
            check_mips_mt(env, ctx);
3182
            gen_op_dmfc0_vpeschedule();
3183
            rn = "VPESchedule";
3184
            break;
3185
        case 6:
3186
            check_mips_mt(env, ctx);
3187
            gen_op_dmfc0_vpeschefback();
3188
            rn = "VPEScheFBack";
3189
            break;
3190
        case 7:
3191
            check_mips_mt(env, ctx);
3192
            gen_op_mfc0_vpeopt();
3193
            rn = "VPEOpt";
3194
            break;
3195
        default:
3196
            goto die;
3197
        }
3198
        break;
3199
    case 2:
3200
        switch (sel) {
3201
        case 0:
3202
            gen_op_dmfc0_entrylo0();
3203
            rn = "EntryLo0";
3204
            break;
3205
        case 1:
3206
            check_mips_mt(env, ctx);
3207
            gen_op_mfc0_tcstatus();
3208
            rn = "TCStatus";
3209
            break;
3210
        case 2:
3211
            check_mips_mt(env, ctx);
3212
            gen_op_mfc0_tcbind();
3213
            rn = "TCBind";
3214
            break;
3215
        case 3:
3216
            check_mips_mt(env, ctx);
3217
            gen_op_dmfc0_tcrestart();
3218
            rn = "TCRestart";
3219
            break;
3220
        case 4:
3221
            check_mips_mt(env, ctx);
3222
            gen_op_dmfc0_tchalt();
3223
            rn = "TCHalt";
3224
            break;
3225
        case 5:
3226
            check_mips_mt(env, ctx);
3227
            gen_op_dmfc0_tccontext();
3228
            rn = "TCContext";
3229
            break;
3230
        case 6:
3231
            check_mips_mt(env, ctx);
3232
            gen_op_dmfc0_tcschedule();
3233
            rn = "TCSchedule";
3234
            break;
3235
        case 7:
3236
            check_mips_mt(env, ctx);
3237
            gen_op_dmfc0_tcschefback();
3238
            rn = "TCScheFBack";
3239
            break;
3240
        default:
3241
            goto die;
3242
        }
3243
        break;
3244
    case 3:
3245
        switch (sel) {
3246
        case 0:
3247
            gen_op_dmfc0_entrylo1();
3248
            rn = "EntryLo1";
3249
            break;
3250
        default:
3251
            goto die;
3252
        }
3253
        break;
3254
    case 4:
3255
        switch (sel) {
3256
        case 0:
3257
            gen_op_dmfc0_context();
3258
            rn = "Context";
3259
            break;
3260
        case 1:
3261
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3262
            rn = "ContextConfig";
3263
//            break;
3264
        default:
3265
            goto die;
3266
        }
3267
        break;
3268
    case 5:
3269
        switch (sel) {
3270
        case 0:
3271
            gen_op_mfc0_pagemask();
3272
            rn = "PageMask";
3273
            break;
3274
        case 1:
3275
            check_insn(env, ctx, ISA_MIPS32R2);
3276
            gen_op_mfc0_pagegrain();
3277
            rn = "PageGrain";
3278
            break;
3279
        default:
3280
            goto die;
3281
        }
3282
        break;
3283
    case 6:
3284
        switch (sel) {
3285
        case 0:
3286
            gen_op_mfc0_wired();
3287
            rn = "Wired";
3288
            break;
3289
        case 1:
3290
            check_insn(env, ctx, ISA_MIPS32R2);
3291
            gen_op_mfc0_srsconf0();
3292
            rn = "SRSConf0";
3293
            break;
3294
        case 2:
3295
            check_insn(env, ctx, ISA_MIPS32R2);
3296
            gen_op_mfc0_srsconf1();
3297
            rn = "SRSConf1";
3298
            break;
3299
        case 3:
3300
            check_insn(env, ctx, ISA_MIPS32R2);
3301
            gen_op_mfc0_srsconf2();
3302
            rn = "SRSConf2";
3303
            break;
3304
        case 4:
3305
            check_insn(env, ctx, ISA_MIPS32R2);
3306
            gen_op_mfc0_srsconf3();
3307
            rn = "SRSConf3";
3308
            break;
3309
        case 5:
3310
            check_insn(env, ctx, ISA_MIPS32R2);
3311
            gen_op_mfc0_srsconf4();
3312
            rn = "SRSConf4";
3313
            break;
3314
        default:
3315
            goto die;
3316
        }
3317
        break;
3318
    case 7:
3319
        switch (sel) {
3320
        case 0:
3321
            check_insn(env, ctx, ISA_MIPS32R2);
3322
            gen_op_mfc0_hwrena();
3323
            rn = "HWREna";
3324
            break;
3325
        default:
3326
            goto die;
3327
        }
3328
        break;
3329
    case 8:
3330
        switch (sel) {
3331
        case 0:
3332
            gen_op_dmfc0_badvaddr();
3333
            rn = "BadVaddr";
3334
            break;
3335
        default:
3336
            goto die;
3337
        }
3338
        break;
3339
    case 9:
3340
        switch (sel) {
3341
        case 0:
3342
            gen_op_mfc0_count();
3343
            rn = "Count";
3344
            break;
3345
        /* 6,7 are implementation dependent */
3346
        default:
3347
            goto die;
3348
        }
3349
        break;
3350
    case 10:
3351
        switch (sel) {
3352
        case 0:
3353
            gen_op_dmfc0_entryhi();
3354
            rn = "EntryHi";
3355
            break;
3356
        default:
3357
            goto die;
3358
        }
3359
        break;
3360
    case 11:
3361
        switch (sel) {
3362
        case 0:
3363
            gen_op_mfc0_compare();
3364
            rn = "Compare";
3365
            break;
3366
        /* 6,7 are implementation dependent */
3367
        default:
3368
            goto die;
3369
        }
3370
        break;
3371
    case 12:
3372
        switch (sel) {
3373
        case 0:
3374
            gen_op_mfc0_status();
3375
            rn = "Status";
3376
            break;
3377
        case 1:
3378
            check_insn(env, ctx, ISA_MIPS32R2);
3379
            gen_op_mfc0_intctl();
3380
            rn = "IntCtl";
3381
            break;
3382
        case 2:
3383
            check_insn(env, ctx, ISA_MIPS32R2);
3384
            gen_op_mfc0_srsctl();
3385
            rn = "SRSCtl";
3386
            break;
3387
        case 3:
3388
            check_insn(env, ctx, ISA_MIPS32R2);
3389
            gen_op_mfc0_srsmap();
3390
            rn = "SRSMap";
3391
            break;
3392
        default:
3393
            goto die;
3394
        }
3395
        break;
3396
    case 13:
3397
        switch (sel) {
3398
        case 0:
3399
            gen_op_mfc0_cause();
3400
            rn = "Cause";
3401
            break;
3402
        default:
3403
            goto die;
3404
        }
3405
        break;
3406
    case 14:
3407
        switch (sel) {
3408
        case 0:
3409
            gen_op_dmfc0_epc();
3410
            rn = "EPC";
3411
            break;
3412
        default:
3413
            goto die;
3414
        }
3415
        break;
3416
    case 15:
3417
        switch (sel) {
3418
        case 0:
3419
            gen_op_mfc0_prid();
3420
            rn = "PRid";
3421
            break;
3422
        case 1:
3423
            check_insn(env, ctx, ISA_MIPS32R2);
3424
            gen_op_mfc0_ebase();
3425
            rn = "EBase";
3426
            break;
3427
        default:
3428
            goto die;
3429
        }
3430
        break;
3431
    case 16:
3432
        switch (sel) {
3433
        case 0:
3434
            gen_op_mfc0_config0();
3435
            rn = "Config";
3436
            break;
3437
        case 1:
3438
            gen_op_mfc0_config1();
3439
            rn = "Config1";
3440
            break;
3441
        case 2:
3442
            gen_op_mfc0_config2();
3443
            rn = "Config2";
3444
            break;
3445
        case 3:
3446
            gen_op_mfc0_config3();
3447
            rn = "Config3";
3448
            break;
3449
       /* 6,7 are implementation dependent */
3450
        default:
3451
            goto die;
3452
        }
3453
        break;
3454
    case 17:
3455
        switch (sel) {
3456
        case 0:
3457
            gen_op_dmfc0_lladdr();
3458
            rn = "LLAddr";
3459
            break;
3460
        default:
3461
            goto die;
3462
        }
3463
        break;
3464
    case 18:
3465
        switch (sel) {
3466
        case 0 ... 7:
3467
            gen_op_dmfc0_watchlo(sel);
3468
            rn = "WatchLo";
3469
            break;
3470
        default:
3471
            goto die;
3472
        }
3473
        break;
3474
    case 19:
3475
        switch (sel) {
3476
        case 0 ... 7:
3477
            gen_op_mfc0_watchhi(sel);
3478
            rn = "WatchHi";
3479
            break;
3480
        default:
3481
            goto die;
3482
        }
3483
        break;
3484
    case 20:
3485
        switch (sel) {
3486
        case 0:
3487
            check_insn(env, ctx, ISA_MIPS3);
3488
            gen_op_dmfc0_xcontext();
3489
            rn = "XContext";
3490
            break;
3491
        default:
3492
            goto die;
3493
        }
3494
        break;
3495
    case 21:
3496
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3497
        switch (sel) {
3498
        case 0:
3499
            gen_op_mfc0_framemask();
3500
            rn = "Framemask";
3501
            break;
3502
        default:
3503
            goto die;
3504
        }
3505
        break;
3506
    case 22:
3507
        /* ignored */
3508
        rn = "'Diagnostic"; /* implementation dependent */
3509
        break;
3510
    case 23:
3511
        switch (sel) {
3512
        case 0:
3513
            gen_op_mfc0_debug(); /* EJTAG support */
3514
            rn = "Debug";
3515
            break;
3516
        case 1:
3517
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3518
            rn = "TraceControl";
3519
//            break;
3520
        case 2:
3521
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3522
            rn = "TraceControl2";
3523
//            break;
3524
        case 3:
3525
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3526
            rn = "UserTraceData";
3527
//            break;
3528
        case 4:
3529
//            gen_op_dmfc0_debug(); /* PDtrace support */
3530
            rn = "TraceBPC";
3531
//            break;
3532
        default:
3533
            goto die;
3534
        }
3535
        break;
3536
    case 24:
3537
        switch (sel) {
3538
        case 0:
3539
            gen_op_dmfc0_depc(); /* EJTAG support */
3540
            rn = "DEPC";
3541
            break;
3542
        default:
3543
            goto die;
3544
        }
3545
        break;
3546
    case 25:
3547
        switch (sel) {
3548
        case 0:
3549
            gen_op_mfc0_performance0();
3550
            rn = "Performance0";
3551
            break;
3552
        case 1:
3553
//            gen_op_dmfc0_performance1();
3554
            rn = "Performance1";
3555
//            break;
3556
        case 2:
3557
//            gen_op_dmfc0_performance2();
3558
            rn = "Performance2";
3559
//            break;
3560
        case 3:
3561
//            gen_op_dmfc0_performance3();
3562
            rn = "Performance3";
3563
//            break;
3564
        case 4:
3565
//            gen_op_dmfc0_performance4();
3566
            rn = "Performance4";
3567
//            break;
3568
        case 5:
3569
//            gen_op_dmfc0_performance5();
3570
            rn = "Performance5";
3571
//            break;
3572
        case 6:
3573
//            gen_op_dmfc0_performance6();
3574
            rn = "Performance6";
3575
//            break;
3576
        case 7:
3577
//            gen_op_dmfc0_performance7();
3578
            rn = "Performance7";
3579
//            break;
3580
        default:
3581
            goto die;
3582
        }
3583
        break;
3584
    case 26:
3585
       rn = "ECC";
3586
       break;
3587
    case 27:
3588
        switch (sel) {
3589
        /* ignored */
3590
        case 0 ... 3:
3591
            rn = "CacheErr";
3592
            break;
3593
        default:
3594
            goto die;
3595
        }
3596
        break;
3597
    case 28:
3598
        switch (sel) {
3599
        case 0:
3600
        case 2:
3601
        case 4:
3602
        case 6:
3603
            gen_op_mfc0_taglo();
3604
            rn = "TagLo";
3605
            break;
3606
        case 1:
3607
        case 3:
3608
        case 5:
3609
        case 7:
3610
            gen_op_mfc0_datalo();
3611
            rn = "DataLo";
3612
            break;
3613
        default:
3614
            goto die;
3615
        }
3616
        break;
3617
    case 29:
3618
        switch (sel) {
3619
        case 0:
3620
        case 2:
3621
        case 4:
3622
        case 6:
3623
            gen_op_mfc0_taghi();
3624
            rn = "TagHi";
3625
            break;
3626
        case 1:
3627
        case 3:
3628
        case 5:
3629
        case 7:
3630
            gen_op_mfc0_datahi();
3631
            rn = "DataHi";
3632
            break;
3633
        default:
3634
            goto die;
3635
        }
3636
        break;
3637
    case 30:
3638
        switch (sel) {
3639
        case 0:
3640
            gen_op_dmfc0_errorepc();
3641
            rn = "ErrorEPC";
3642
            break;
3643
        default:
3644
            goto die;
3645
        }
3646
        break;
3647
    case 31:
3648
        switch (sel) {
3649
        case 0:
3650
            gen_op_mfc0_desave(); /* EJTAG support */
3651
            rn = "DESAVE";
3652
            break;
3653
        default:
3654
            goto die;
3655
        }
3656
        break;
3657
    default:
3658
        goto die;
3659
    }
3660
#if defined MIPS_DEBUG_DISAS
3661
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3662
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3663
                rn, reg, sel);
3664
    }
3665
#endif
3666
    return;
3667

    
3668
die:
3669
#if defined MIPS_DEBUG_DISAS
3670
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3671
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3672
                rn, reg, sel);
3673
    }
3674
#endif
3675
    generate_exception(ctx, EXCP_RI);
3676
}
3677

    
3678
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3679
{
3680
    const char *rn = "invalid";
3681

    
3682
    if (sel != 0)
3683
        check_insn(env, ctx, ISA_MIPS64);
3684

    
3685
    switch (reg) {
3686
    case 0:
3687
        switch (sel) {
3688
        case 0:
3689
            gen_op_mtc0_index();
3690
            rn = "Index";
3691
            break;
3692
        case 1:
3693
            check_mips_mt(env, ctx);
3694
            gen_op_mtc0_mvpcontrol();
3695
            rn = "MVPControl";
3696
            break;
3697
        case 2:
3698
            check_mips_mt(env, ctx);
3699
            /* ignored */
3700
            rn = "MVPConf0";
3701
            break;
3702
        case 3:
3703
            check_mips_mt(env, ctx);
3704
            /* ignored */
3705
            rn = "MVPConf1";
3706
            break;
3707
        default:
3708
            goto die;
3709
        }
3710
        break;
3711
    case 1:
3712
        switch (sel) {
3713
        case 0:
3714
            /* ignored */
3715
            rn = "Random";
3716
            break;
3717
        case 1:
3718
            check_mips_mt(env, ctx);
3719
            gen_op_mtc0_vpecontrol();
3720
            rn = "VPEControl";
3721
            break;
3722
        case 2:
3723
            check_mips_mt(env, ctx);
3724
            gen_op_mtc0_vpeconf0();
3725
            rn = "VPEConf0";
3726
            break;
3727
        case 3:
3728
            check_mips_mt(env, ctx);
3729
            gen_op_mtc0_vpeconf1();
3730
            rn = "VPEConf1";
3731
            break;
3732
        case 4:
3733
            check_mips_mt(env, ctx);
3734
            gen_op_mtc0_yqmask();
3735
            rn = "YQMask";
3736
            break;
3737
        case 5:
3738
            check_mips_mt(env, ctx);
3739
            gen_op_mtc0_vpeschedule();
3740
            rn = "VPESchedule";
3741
            break;
3742
        case 6:
3743
            check_mips_mt(env, ctx);
3744
            gen_op_mtc0_vpeschefback();
3745
            rn = "VPEScheFBack";
3746
            break;
3747
        case 7:
3748
            check_mips_mt(env, ctx);
3749
            gen_op_mtc0_vpeopt();
3750
            rn = "VPEOpt";
3751
            break;
3752
        default:
3753
            goto die;
3754
        }
3755
        break;
3756
    case 2:
3757
        switch (sel) {
3758
        case 0:
3759
            gen_op_mtc0_entrylo0();
3760
            rn = "EntryLo0";
3761
            break;
3762
        case 1:
3763
            check_mips_mt(env, ctx);
3764
            gen_op_mtc0_tcstatus();
3765
            rn = "TCStatus";
3766
            break;
3767
        case 2:
3768
            check_mips_mt(env, ctx);
3769
            gen_op_mtc0_tcbind();
3770
            rn = "TCBind";
3771
            break;
3772
        case 3:
3773
            check_mips_mt(env, ctx);
3774
            gen_op_mtc0_tcrestart();
3775
            rn = "TCRestart";
3776
            break;
3777
        case 4:
3778
            check_mips_mt(env, ctx);
3779
            gen_op_mtc0_tchalt();
3780
            rn = "TCHalt";
3781
            break;
3782
        case 5:
3783
            check_mips_mt(env, ctx);
3784
            gen_op_mtc0_tccontext();
3785
            rn = "TCContext";
3786
            break;
3787
        case 6:
3788
            check_mips_mt(env, ctx);
3789
            gen_op_mtc0_tcschedule();
3790
            rn = "TCSchedule";
3791
            break;
3792
        case 7:
3793
            check_mips_mt(env, ctx);
3794
            gen_op_mtc0_tcschefback();
3795
            rn = "TCScheFBack";
3796
            break;
3797
        default:
3798
            goto die;
3799
        }
3800
        break;
3801
    case 3:
3802
        switch (sel) {
3803
        case 0:
3804
            gen_op_mtc0_entrylo1();
3805
            rn = "EntryLo1";
3806
            break;
3807
        default:
3808
            goto die;
3809
        }
3810
        break;
3811
    case 4:
3812
        switch (sel) {
3813
        case 0:
3814
            gen_op_mtc0_context();
3815
            rn = "Context";
3816
            break;
3817
        case 1:
3818
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3819
            rn = "ContextConfig";
3820
//           break;
3821
        default:
3822
            goto die;
3823
        }
3824
        break;
3825
    case 5:
3826
        switch (sel) {
3827
        case 0:
3828
            gen_op_mtc0_pagemask();
3829
            rn = "PageMask";
3830
            break;
3831
        case 1:
3832
            check_insn(env, ctx, ISA_MIPS32R2);
3833
            gen_op_mtc0_pagegrain();
3834
            rn = "PageGrain";
3835
            break;
3836
        default:
3837
            goto die;
3838
        }
3839
        break;
3840
    case 6:
3841
        switch (sel) {
3842
        case 0:
3843
            gen_op_mtc0_wired();
3844
            rn = "Wired";
3845
            break;
3846
        case 1:
3847
            check_insn(env, ctx, ISA_MIPS32R2);
3848
            gen_op_mtc0_srsconf0();
3849
            rn = "SRSConf0";
3850
            break;
3851
        case 2:
3852
            check_insn(env, ctx, ISA_MIPS32R2);
3853
            gen_op_mtc0_srsconf1();
3854
            rn = "SRSConf1";
3855
            break;
3856
        case 3:
3857
            check_insn(env, ctx, ISA_MIPS32R2);
3858
            gen_op_mtc0_srsconf2();
3859
            rn = "SRSConf2";
3860
            break;
3861
        case 4:
3862
            check_insn(env, ctx, ISA_MIPS32R2);
3863
            gen_op_mtc0_srsconf3();
3864
            rn = "SRSConf3";
3865
            break;
3866
        case 5:
3867
            check_insn(env, ctx, ISA_MIPS32R2);
3868
            gen_op_mtc0_srsconf4();
3869
            rn = "SRSConf4";
3870
            break;
3871
        default:
3872
            goto die;
3873
        }
3874
        break;
3875
    case 7:
3876
        switch (sel) {
3877
        case 0:
3878
            check_insn(env, ctx, ISA_MIPS32R2);
3879
            gen_op_mtc0_hwrena();
3880
            rn = "HWREna";
3881
            break;
3882
        default:
3883
            goto die;
3884
        }
3885
        break;
3886
    case 8:
3887
        /* ignored */
3888
        rn = "BadVaddr";
3889
        break;
3890
    case 9:
3891
        switch (sel) {
3892
        case 0:
3893
            gen_op_mtc0_count();
3894
            rn = "Count";
3895
            break;
3896
        /* 6,7 are implementation dependent */
3897
        default:
3898
            goto die;
3899
        }
3900
        /* Stop translation as we may have switched the execution mode */
3901
        ctx->bstate = BS_STOP;
3902
        break;
3903
    case 10:
3904
        switch (sel) {
3905
        case 0:
3906
            gen_op_mtc0_entryhi();
3907
            rn = "EntryHi";
3908
            break;
3909
        default:
3910
            goto die;
3911
        }
3912
        break;
3913
    case 11:
3914
        switch (sel) {
3915
        case 0:
3916
            gen_op_mtc0_compare();
3917
            rn = "Compare";
3918
            break;
3919
        /* 6,7 are implementation dependent */
3920
        default:
3921
            goto die;
3922
        }
3923
        /* Stop translation as we may have switched the execution mode */
3924
        ctx->bstate = BS_STOP;
3925
        break;
3926
    case 12:
3927
        switch (sel) {
3928
        case 0:
3929
            gen_op_mtc0_status();
3930
            /* BS_STOP isn't good enough here, hflags may have changed. */
3931
            gen_save_pc(ctx->pc + 4);
3932
            ctx->bstate = BS_EXCP;
3933
            rn = "Status";
3934
            break;
3935
        case 1:
3936
            check_insn(env, ctx, ISA_MIPS32R2);
3937
            gen_op_mtc0_intctl();
3938
            /* Stop translation as we may have switched the execution mode */
3939
            ctx->bstate = BS_STOP;
3940
            rn = "IntCtl";
3941
            break;
3942
        case 2:
3943
            check_insn(env, ctx, ISA_MIPS32R2);
3944
            gen_op_mtc0_srsctl();
3945
            /* Stop translation as we may have switched the execution mode */
3946
            ctx->bstate = BS_STOP;
3947
            rn = "SRSCtl";
3948
            break;
3949
        case 3:
3950
            check_insn(env, ctx, ISA_MIPS32R2);
3951
            gen_op_mtc0_srsmap();
3952
            /* Stop translation as we may have switched the execution mode */
3953
            ctx->bstate = BS_STOP;
3954
            rn = "SRSMap";
3955
            break;
3956
        default:
3957
            goto die;
3958
        }
3959
        break;
3960
    case 13:
3961
        switch (sel) {
3962
        case 0:
3963
            gen_op_mtc0_cause();
3964
            rn = "Cause";
3965
            break;
3966
        default:
3967
            goto die;
3968
        }
3969
        /* Stop translation as we may have switched the execution mode */
3970
        ctx->bstate = BS_STOP;
3971
        break;
3972
    case 14:
3973
        switch (sel) {
3974
        case 0:
3975
            gen_op_mtc0_epc();
3976
            rn = "EPC";
3977
            break;
3978
        default:
3979
            goto die;
3980
        }
3981
        break;
3982
    case 15:
3983
        switch (sel) {
3984
        case 0:
3985
            /* ignored */
3986
            rn = "PRid";
3987
            break;
3988
        case 1:
3989
            check_insn(env, ctx, ISA_MIPS32R2);
3990
            gen_op_mtc0_ebase();
3991
            rn = "EBase";
3992
            break;
3993
        default:
3994
            goto die;
3995
        }
3996
        break;
3997
    case 16:
3998
        switch (sel) {
3999
        case 0:
4000
            gen_op_mtc0_config0();
4001
            rn = "Config";
4002
            /* Stop translation as we may have switched the execution mode */
4003
            ctx->bstate = BS_STOP;
4004
            break;
4005
        case 1:
4006
            /* ignored */
4007
            rn = "Config1";
4008
            break;
4009
        case 2:
4010
            gen_op_mtc0_config2();
4011
            rn = "Config2";
4012
            /* Stop translation as we may have switched the execution mode */
4013
            ctx->bstate = BS_STOP;
4014
            break;
4015
        case 3:
4016
            /* ignored */
4017
            rn = "Config3";
4018
            break;
4019
        /* 6,7 are implementation dependent */
4020
        default:
4021
            rn = "Invalid config selector";
4022
            goto die;
4023
        }
4024
        break;
4025
    case 17:
4026
        switch (sel) {
4027
        case 0:
4028
            /* ignored */
4029
            rn = "LLAddr";
4030
            break;
4031
        default:
4032
            goto die;
4033
        }
4034
        break;
4035
    case 18:
4036
        switch (sel) {
4037
        case 0 ... 7:
4038
            gen_op_mtc0_watchlo(sel);
4039
            rn = "WatchLo";
4040
            break;
4041
        default:
4042
            goto die;
4043
        }
4044
        break;
4045
    case 19:
4046
        switch (sel) {
4047
        case 0 ... 7:
4048
            gen_op_mtc0_watchhi(sel);
4049
            rn = "WatchHi";
4050
            break;
4051
        default:
4052
            goto die;
4053
        }
4054
        break;
4055
    case 20:
4056
        switch (sel) {
4057
        case 0:
4058
            check_insn(env, ctx, ISA_MIPS3);
4059
            gen_op_mtc0_xcontext();
4060
            rn = "XContext";
4061
            break;
4062
        default:
4063
            goto die;
4064
        }
4065
        break;
4066
    case 21:
4067
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4068
        switch (sel) {
4069
        case 0:
4070
            gen_op_mtc0_framemask();
4071
            rn = "Framemask";
4072
            break;
4073
        default:
4074
            goto die;
4075
        }
4076
        break;
4077
    case 22:
4078
        /* ignored */
4079
        rn = "Diagnostic"; /* implementation dependent */
4080
        break;
4081
    case 23:
4082
        switch (sel) {
4083
        case 0:
4084
            gen_op_mtc0_debug(); /* EJTAG support */
4085
            /* BS_STOP isn't good enough here, hflags may have changed. */
4086
            gen_save_pc(ctx->pc + 4);
4087
            ctx->bstate = BS_EXCP;
4088
            rn = "Debug";
4089
            break;
4090
        case 1:
4091
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4092
            /* Stop translation as we may have switched the execution mode */
4093
            ctx->bstate = BS_STOP;
4094
            rn = "TraceControl";
4095
//            break;
4096
        case 2:
4097
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4098
            /* Stop translation as we may have switched the execution mode */
4099
            ctx->bstate = BS_STOP;
4100
            rn = "TraceControl2";
4101
//            break;
4102
        case 3:
4103
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4104
            /* Stop translation as we may have switched the execution mode */
4105
            ctx->bstate = BS_STOP;
4106
            rn = "UserTraceData";
4107
//            break;
4108
        case 4:
4109
//            gen_op_mtc0_debug(); /* PDtrace support */
4110
            /* Stop translation as we may have switched the execution mode */
4111
            ctx->bstate = BS_STOP;
4112
            rn = "TraceBPC";
4113
//            break;
4114
        default:
4115
            goto die;
4116
        }
4117
        break;
4118
    case 24:
4119
        switch (sel) {
4120
        case 0:
4121
            gen_op_mtc0_depc(); /* EJTAG support */
4122
            rn = "DEPC";
4123
            break;
4124
        default:
4125
            goto die;
4126
        }
4127
        break;
4128
    case 25:
4129
        switch (sel) {
4130
        case 0:
4131
            gen_op_mtc0_performance0();
4132
            rn = "Performance0";
4133
            break;
4134
        case 1:
4135
//            gen_op_mtc0_performance1();
4136
            rn = "Performance1";
4137
//            break;
4138
        case 2:
4139
//            gen_op_mtc0_performance2();
4140
            rn = "Performance2";
4141
//            break;
4142
        case 3:
4143
//            gen_op_mtc0_performance3();
4144
            rn = "Performance3";
4145
//            break;
4146
        case 4:
4147
//            gen_op_mtc0_performance4();
4148
            rn = "Performance4";
4149
//            break;
4150
        case 5:
4151
//            gen_op_mtc0_performance5();
4152
            rn = "Performance5";
4153
//            break;
4154
        case 6:
4155
//            gen_op_mtc0_performance6();
4156
            rn = "Performance6";
4157
//            break;
4158
        case 7:
4159
//            gen_op_mtc0_performance7();
4160
            rn = "Performance7";
4161
//            break;
4162
        default:
4163
            goto die;
4164
        }
4165
        break;
4166
    case 26:
4167
        /* ignored */
4168
        rn = "ECC";
4169
        break;
4170
    case 27:
4171
        switch (sel) {
4172
        case 0 ... 3:
4173
            /* ignored */
4174
            rn = "CacheErr";
4175
            break;
4176
        default:
4177
            goto die;
4178
        }
4179
        break;
4180
    case 28:
4181
        switch (sel) {
4182
        case 0:
4183
        case 2:
4184
        case 4:
4185
        case 6:
4186
            gen_op_mtc0_taglo();
4187
            rn = "TagLo";
4188
            break;
4189
        case 1:
4190
        case 3:
4191
        case 5:
4192
        case 7:
4193
            gen_op_mtc0_datalo();
4194
            rn = "DataLo";
4195
            break;
4196
        default:
4197
            goto die;
4198
        }
4199
        break;
4200
    case 29:
4201
        switch (sel) {
4202
        case 0:
4203
        case 2:
4204
        case 4:
4205
        case 6:
4206
            gen_op_mtc0_taghi();
4207
            rn = "TagHi";
4208
            break;
4209
        case 1:
4210
        case 3:
4211
        case 5:
4212
        case 7:
4213
            gen_op_mtc0_datahi();
4214
            rn = "DataHi";
4215
            break;
4216
        default:
4217
            rn = "invalid sel";
4218
            goto die;
4219
        }
4220
        break;
4221
    case 30:
4222
        switch (sel) {
4223
        case 0:
4224
            gen_op_mtc0_errorepc();
4225
            rn = "ErrorEPC";
4226
            break;
4227
        default:
4228
            goto die;
4229
        }
4230
        break;
4231
    case 31:
4232
        switch (sel) {
4233
        case 0:
4234
            gen_op_mtc0_desave(); /* EJTAG support */
4235
            rn = "DESAVE";
4236
            break;
4237
        default:
4238
            goto die;
4239
        }
4240
        /* Stop translation as we may have switched the execution mode */
4241
        ctx->bstate = BS_STOP;
4242
        break;
4243
    default:
4244
        goto die;
4245
    }
4246
#if defined MIPS_DEBUG_DISAS
4247
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4248
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4249
                rn, reg, sel);
4250
    }
4251
#endif
4252
    return;
4253

    
4254
die:
4255
#if defined MIPS_DEBUG_DISAS
4256
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4257
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4258
                rn, reg, sel);
4259
    }
4260
#endif
4261
    generate_exception(ctx, EXCP_RI);
4262
}
4263
#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
4264

    
4265
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4266
                     int u, int sel, int h)
4267
{
4268
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4269

    
4270
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4271
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4272
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4273
        gen_op_set_T0(-1);
4274
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4275
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4276
        gen_op_set_T0(-1);
4277
    else if (u == 0) {
4278
        switch (rt) {
4279
        case 2:
4280
            switch (sel) {
4281
            case 1:
4282
                gen_op_mftc0_tcstatus();
4283
                break;
4284
            case 2:
4285
                gen_op_mftc0_tcbind();
4286
                break;
4287
            case 3:
4288
                gen_op_mftc0_tcrestart();
4289
                break;
4290
            case 4:
4291
                gen_op_mftc0_tchalt();
4292
                break;
4293
            case 5:
4294
                gen_op_mftc0_tccontext();
4295
                break;
4296
            case 6:
4297
                gen_op_mftc0_tcschedule();
4298
                break;
4299
            case 7:
4300
                gen_op_mftc0_tcschefback();
4301
                break;
4302
            default:
4303
                gen_mfc0(env, ctx, rt, sel);
4304
                break;
4305
            }
4306
            break;
4307
        case 10:
4308
            switch (sel) {
4309
            case 0:
4310
                gen_op_mftc0_entryhi();
4311
                break;
4312
            default:
4313
                gen_mfc0(env, ctx, rt, sel);
4314
                break;
4315
            }
4316
        case 12:
4317
            switch (sel) {
4318
            case 0:
4319
                gen_op_mftc0_status();
4320
                break;
4321
            default:
4322
                gen_mfc0(env, ctx, rt, sel);
4323
                break;
4324
            }
4325
        case 23:
4326
            switch (sel) {
4327
            case 0:
4328
                gen_op_mftc0_debug();
4329
                break;
4330
            default:
4331
                gen_mfc0(env, ctx, rt, sel);
4332
                break;
4333
            }
4334
            break;
4335
        default:
4336
            gen_mfc0(env, ctx, rt, sel);
4337
        }
4338
    } else switch (sel) {
4339
    /* GPR registers. */
4340
    case 0:
4341
        gen_op_mftgpr(rt);
4342
        break;
4343
    /* Auxiliary CPU registers */
4344
    case 1:
4345
        switch (rt) {
4346
        case 0:
4347
            gen_op_mftlo(0);
4348
            break;
4349
        case 1:
4350
            gen_op_mfthi(0);
4351
            break;
4352
        case 2:
4353
            gen_op_mftacx(0);
4354
            break;
4355
        case 4:
4356
            gen_op_mftlo(1);
4357
            break;
4358
        case 5:
4359
            gen_op_mfthi(1);
4360
            break;
4361
        case 6:
4362
            gen_op_mftacx(1);
4363
            break;
4364
        case 8:
4365
            gen_op_mftlo(2);
4366
            break;
4367
        case 9:
4368
            gen_op_mfthi(2);
4369
            break;
4370
        case 10:
4371
            gen_op_mftacx(2);
4372
            break;
4373
        case 12:
4374
            gen_op_mftlo(3);
4375
            break;
4376
        case 13:
4377
            gen_op_mfthi(3);
4378
            break;
4379
        case 14:
4380
            gen_op_mftacx(3);
4381
            break;
4382
        case 16:
4383
            gen_op_mftdsp();
4384
            break;
4385
        default:
4386
            goto die;
4387
        }
4388
        break;
4389
    /* Floating point (COP1). */
4390
    case 2:
4391
        /* XXX: For now we support only a single FPU context. */
4392
        if (h == 0) {
4393
            GEN_LOAD_FREG_FTN(WT0, rt);
4394
            gen_op_mfc1();
4395
        } else {
4396
            GEN_LOAD_FREG_FTN(WTH0, rt);
4397
            gen_op_mfhc1();
4398
        }
4399
        break;
4400
    case 3:
4401
        /* XXX: For now we support only a single FPU context. */
4402
        gen_op_cfc1(rt);
4403
        break;
4404
    /* COP2: Not implemented. */
4405
    case 4:
4406
    case 5:
4407
        /* fall through */
4408
    default:
4409
        goto die;
4410
    }
4411
#if defined MIPS_DEBUG_DISAS
4412
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4413
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4414
                rt, u, sel, h);
4415
    }
4416
#endif
4417
    return;
4418

    
4419
die:
4420
#if defined MIPS_DEBUG_DISAS
4421
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4422
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
4423
                rt, u, sel, h);
4424
    }
4425
#endif
4426
    generate_exception(ctx, EXCP_RI);
4427
}
4428

    
4429
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
4430
                     int u, int sel, int h)
4431
{
4432
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4433

    
4434
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4435
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4436
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4437
        /* NOP */ ;
4438
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4439
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4440
        /* NOP */ ;
4441
    else if (u == 0) {
4442
        switch (rd) {
4443
        case 2:
4444
            switch (sel) {
4445
            case 1:
4446
                gen_op_mttc0_tcstatus();
4447
                break;
4448
            case 2:
4449
                gen_op_mttc0_tcbind();
4450
                break;
4451
            case 3:
4452
                gen_op_mttc0_tcrestart();
4453
                break;
4454
            case 4:
4455
                gen_op_mttc0_tchalt();
4456
                break;
4457
            case 5:
4458
                gen_op_mttc0_tccontext();
4459
                break;
4460
            case 6:
4461
                gen_op_mttc0_tcschedule();
4462
                break;
4463
            case 7:
4464
                gen_op_mttc0_tcschefback();
4465
                break;
4466
            default:
4467
                gen_mtc0(env, ctx, rd, sel);
4468
                break;
4469
            }
4470
            break;
4471
        case 10:
4472
            switch (sel) {
4473
            case 0:
4474
                gen_op_mttc0_entryhi();
4475
                break;
4476
            default:
4477
                gen_mtc0(env, ctx, rd, sel);
4478
                break;
4479
            }
4480
        case 12:
4481
            switch (sel) {
4482
            case 0:
4483
                gen_op_mttc0_status();
4484
                break;
4485
            default:
4486
                gen_mtc0(env, ctx, rd, sel);
4487
                break;
4488
            }
4489
        case 23:
4490
            switch (sel) {
4491
            case 0:
4492
                gen_op_mttc0_debug();
4493
                break;
4494
            default:
4495
                gen_mtc0(env, ctx, rd, sel);
4496
                break;
4497
            }
4498
            break;
4499
        default:
4500
            gen_mtc0(env, ctx, rd, sel);
4501
        }
4502
    } else switch (sel) {
4503
    /* GPR registers. */
4504
    case 0:
4505
        gen_op_mttgpr(rd);
4506
        break;
4507
    /* Auxiliary CPU registers */
4508
    case 1:
4509
        switch (rd) {
4510
        case 0:
4511
            gen_op_mttlo(0);
4512
            break;
4513
        case 1:
4514
            gen_op_mtthi(0);
4515
            break;
4516
        case 2:
4517
            gen_op_mttacx(0);
4518
            break;
4519
        case 4:
4520
            gen_op_mttlo(1);
4521
            break;
4522
        case 5:
4523
            gen_op_mtthi(1);
4524
            break;
4525
        case 6:
4526
            gen_op_mttacx(1);
4527
            break;
4528
        case 8:
4529
            gen_op_mttlo(2);
4530
            break;
4531
        case 9:
4532
            gen_op_mtthi(2);
4533
            break;
4534
        case 10:
4535
            gen_op_mttacx(2);
4536
            break;
4537
        case 12:
4538
            gen_op_mttlo(3);
4539
            break;
4540
        case 13:
4541
            gen_op_mtthi(3);
4542
            break;
4543
        case 14:
4544
            gen_op_mttacx(3);
4545
            break;
4546
        case 16:
4547
            gen_op_mttdsp();
4548
            break;
4549
        default:
4550
            goto die;
4551
        }
4552
        break;
4553
    /* Floating point (COP1). */
4554
    case 2:
4555
        /* XXX: For now we support only a single FPU context. */
4556
        if (h == 0) {
4557
            gen_op_mtc1();
4558
            GEN_STORE_FTN_FREG(rd, WT0);
4559
        } else {
4560
            gen_op_mthc1();
4561
            GEN_STORE_FTN_FREG(rd, WTH0);
4562
        }
4563
        break;
4564
    case 3:
4565
        /* XXX: For now we support only a single FPU context. */
4566
        gen_op_ctc1(rd);
4567
        break;
4568
    /* COP2: Not implemented. */
4569
    case 4:
4570
    case 5:
4571
        /* fall through */
4572
    default:
4573
        goto die;
4574
    }
4575
#if defined MIPS_DEBUG_DISAS
4576
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4577
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4578
                rd, u, sel, h);
4579
    }
4580
#endif
4581
    return;
4582

    
4583
die:
4584
#if defined MIPS_DEBUG_DISAS
4585
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4586
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
4587
                rd, u, sel, h);
4588
    }
4589
#endif
4590
    generate_exception(ctx, EXCP_RI);
4591
}
4592

    
4593
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4594
{
4595
    const char *opn = "ldst";
4596

    
4597
    switch (opc) {
4598
    case OPC_MFC0:
4599
        if (rt == 0) {
4600
            /* Treat as NOP. */
4601
            return;
4602
        }
4603
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
4604
        gen_op_store_T0_gpr(rt);
4605
        opn = "mfc0";
4606
        break;
4607
    case OPC_MTC0:
4608
        GEN_LOAD_REG_TN(T0, rt);
4609
        save_cpu_state(ctx, 1);
4610
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
4611
        opn = "mtc0";
4612
        break;
4613
#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64)
4614
    case OPC_DMFC0:
4615
        check_insn(env, ctx, ISA_MIPS3);
4616
        if (rt == 0) {
4617
            /* Treat as NOP. */
4618
            return;
4619
        }
4620
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
4621
        gen_op_store_T0_gpr(rt);
4622
        opn = "dmfc0";
4623
        break;
4624
    case OPC_DMTC0:
4625
        check_insn(env, ctx, ISA_MIPS3);
4626
        GEN_LOAD_REG_TN(T0, rt);
4627
        save_cpu_state(ctx, 1);
4628
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
4629
        opn = "dmtc0";
4630
        break;
4631
#endif
4632
    case OPC_MFTR:
4633
        check_mips_mt(env, ctx);
4634
        if (rd == 0) {
4635
            /* Treat as NOP. */
4636
            return;
4637
        }
4638
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
4639
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4640
        gen_op_store_T0_gpr(rd);
4641
        opn = "mftr";
4642
        break;
4643
    case OPC_MTTR:
4644
        check_mips_mt(env, ctx);
4645
        GEN_LOAD_REG_TN(T0, rt);
4646
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
4647
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
4648
        opn = "mttr";
4649
        break;
4650
    case OPC_TLBWI:
4651
        opn = "tlbwi";
4652
        if (!env->tlb->do_tlbwi)
4653
            goto die;
4654
        gen_op_tlbwi();
4655
        break;
4656
    case OPC_TLBWR:
4657
        opn = "tlbwr";
4658
        if (!env->tlb->do_tlbwr)
4659
            goto die;
4660
        gen_op_tlbwr();
4661
        break;
4662
    case OPC_TLBP:
4663
        opn = "tlbp";
4664
        if (!env->tlb->do_tlbp)
4665
            goto die;
4666
        gen_op_tlbp();
4667
        break;
4668
    case OPC_TLBR:
4669
        opn = "tlbr";
4670
        if (!env->tlb->do_tlbr)
4671
            goto die;
4672
        gen_op_tlbr();
4673
        break;
4674
    case OPC_ERET:
4675
        opn = "eret";
4676
        check_insn(env, ctx, ISA_MIPS2);
4677
        save_cpu_state(ctx, 1);
4678
        gen_op_eret();
4679
        ctx->bstate = BS_EXCP;
4680
        break;
4681
    case OPC_DERET:
4682
        opn = "deret";
4683
        check_insn(env, ctx, ISA_MIPS32);
4684
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4685
            MIPS_INVAL(opn);
4686
            generate_exception(ctx, EXCP_RI);
4687
        } else {
4688
            save_cpu_state(ctx, 1);
4689
            gen_op_deret();
4690
            ctx->bstate = BS_EXCP;
4691
        }
4692
        break;
4693
    case OPC_WAIT:
4694
        opn = "wait";
4695
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4696
        /* If we get an exception, we want to restart at next instruction */
4697
        ctx->pc += 4;
4698
        save_cpu_state(ctx, 1);
4699
        ctx->pc -= 4;
4700
        gen_op_wait();
4701