]> Git Repo - qemu.git/blob - target-mips/translate.c
Fix lui sign extension.
[qemu.git] / target-mips / translate.c
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,
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_BSHFL    = 0x20 | OPC_SPECIAL3,
270     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
271     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
272 };
273
274 /* BSHFL opcodes */
275 #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
276
277 enum {
278     OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
279     OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
280     OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
281 };
282
283 /* DBSHFL opcodes */
284 #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
285
286 enum {
287     OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
288     OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
289 };
290
291 /* Coprocessor 0 (rs field) */
292 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
293
294 enum {
295     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
296     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
297     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
298     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
299     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
300     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
301     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
302     OPC_C0       = (0x10 << 21) | OPC_CP0,
303     OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
304     OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
305 };
306
307 /* MFMC0 opcodes */
308 #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
309
310 enum {
311     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
312     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
313 };
314
315 /* Coprocessor 0 (with rs == C0) */
316 #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
317
318 enum {
319     OPC_TLBR     = 0x01 | OPC_C0,
320     OPC_TLBWI    = 0x02 | OPC_C0,
321     OPC_TLBWR    = 0x06 | OPC_C0,
322     OPC_TLBP     = 0x08 | OPC_C0,
323     OPC_RFE      = 0x10 | OPC_C0,
324     OPC_ERET     = 0x18 | OPC_C0,
325     OPC_DERET    = 0x1F | OPC_C0,
326     OPC_WAIT     = 0x20 | OPC_C0,
327 };
328
329 /* Coprocessor 1 (rs field) */
330 #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
331
332 enum {
333     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
334     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
335     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
336     OPC_MFHCI    = (0x03 << 21) | OPC_CP1,
337     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
338     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
339     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
340     OPC_MTHCI    = (0x07 << 21) | OPC_CP1,
341     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
342     OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
343     OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
344     OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
345     OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
346     OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
347     OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
348 };
349
350 enum {
351     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
352     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
353     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
354     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
355 };
356
357 #define MASK_CP1_BCOND(op)      MASK_CP1(op) | (op & (0x3 << 16))
358 #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
359
360 #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
361
362 enum {
363     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
364     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
365     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
366     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
367     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
368     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
369     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
370     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
371     OPC_BC2     = (0x08 << 21) | OPC_CP2,
372 };
373
374 #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
375
376 enum {
377     OPC_LWXC1   = 0x00 | OPC_CP3,
378     OPC_LDXC1   = 0x01 | OPC_CP3,
379     OPC_LUXC1   = 0x05 | OPC_CP3,
380     OPC_SWXC1   = 0x08 | OPC_CP3,
381     OPC_SDXC1   = 0x09 | OPC_CP3,
382     OPC_SUXC1   = 0x0D | OPC_CP3,
383     OPC_PREFX   = 0x0F | OPC_CP3,
384     OPC_ALNV_PS = 0x1E | OPC_CP3,
385     OPC_MADD_S  = 0x20 | OPC_CP3,
386     OPC_MADD_D  = 0x21 | OPC_CP3,
387     OPC_MADD_PS = 0x26 | OPC_CP3,
388     OPC_MSUB_S  = 0x28 | OPC_CP3,
389     OPC_MSUB_D  = 0x29 | OPC_CP3,
390     OPC_MSUB_PS = 0x2E | OPC_CP3,
391     OPC_NMADD_S = 0x30 | OPC_CP3,
392     OPC_NMADD_D = 0x32 | OPC_CP3,
393     OPC_NMADD_PS= 0x36 | OPC_CP3,
394     OPC_NMSUB_S = 0x38 | OPC_CP3,
395     OPC_NMSUB_D = 0x39 | OPC_CP3,
396     OPC_NMSUB_PS= 0x3E | OPC_CP3,
397 };
398
399
400 const unsigned char *regnames[] =
401     { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
402       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
403       "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
404       "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
405
406 /* Warning: no function for r0 register (hard wired to zero) */
407 #define GEN32(func, NAME) \
408 static GenOpFunc *NAME ## _table [32] = {                                     \
409 NULL,       NAME ## 1, NAME ## 2, NAME ## 3,                                  \
410 NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,                                  \
411 NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,                                \
412 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
413 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
414 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
415 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
416 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
417 };                                                                            \
418 static inline void func(int n)                                                \
419 {                                                                             \
420     NAME ## _table[n]();                                                      \
421 }
422
423 /* General purpose registers moves */
424 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
425 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
426 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
427
428 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
429 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
430
431 static const char *fregnames[] =
432     { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
433       "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
434       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
435       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
436
437 # define SFGEN32(func, NAME) \
438 static GenOpFunc *NAME ## _table [32] = {                                     \
439 NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,                                \
440 NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,                                \
441 NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,                               \
442 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
443 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
444 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
445 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
446 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
447 };                                                                            \
448 static inline void func(int n)                                                \
449 {                                                                             \
450     NAME ## _table[n]();                                                      \
451 }
452
453 # define DFGEN32(func, NAME) \
454 static GenOpFunc *NAME ## _table [32] = {                                     \
455 NAME ## 0,  0, NAME ## 2,  0,                                                 \
456 NAME ## 4,  0, NAME ## 6,  0,                                                 \
457 NAME ## 8,  0, NAME ## 10, 0,                                                 \
458 NAME ## 12, 0, NAME ## 14, 0,                                                 \
459 NAME ## 16, 0, NAME ## 18, 0,                                                 \
460 NAME ## 20, 0, NAME ## 22, 0,                                                 \
461 NAME ## 24, 0, NAME ## 26, 0,                                                 \
462 NAME ## 28, 0, NAME ## 30, 0,                                                 \
463 };                                                                            \
464 static inline void func(int n)                                                \
465 {                                                                             \
466     NAME ## _table[n]();                                                      \
467 }
468
469 SFGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
470 SFGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
471
472 SFGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
473 SFGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
474
475 SFGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
476 SFGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
477
478 DFGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
479 DFGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
480
481 DFGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
482 DFGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
483
484 DFGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
485 DFGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
486
487 #define FOP_CONDS(fmt) \
488 static GenOpFunc * cond_ ## fmt ## _table[16] = {                       \
489     gen_op_cmp_ ## fmt ## _f,                                           \
490     gen_op_cmp_ ## fmt ## _un,                                          \
491     gen_op_cmp_ ## fmt ## _eq,                                          \
492     gen_op_cmp_ ## fmt ## _ueq,                                         \
493     gen_op_cmp_ ## fmt ## _olt,                                         \
494     gen_op_cmp_ ## fmt ## _ult,                                         \
495     gen_op_cmp_ ## fmt ## _ole,                                         \
496     gen_op_cmp_ ## fmt ## _ule,                                         \
497     gen_op_cmp_ ## fmt ## _sf,                                          \
498     gen_op_cmp_ ## fmt ## _ngle,                                        \
499     gen_op_cmp_ ## fmt ## _seq,                                         \
500     gen_op_cmp_ ## fmt ## _ngl,                                         \
501     gen_op_cmp_ ## fmt ## _lt,                                          \
502     gen_op_cmp_ ## fmt ## _nge,                                         \
503     gen_op_cmp_ ## fmt ## _le,                                          \
504     gen_op_cmp_ ## fmt ## _ngt,                                         \
505 };                                                                      \
506 static inline void gen_cmp_ ## fmt(int n)                               \
507 {                                                                       \
508     cond_ ## fmt ## _table[n]();                                        \
509 }
510
511 FOP_CONDS(d)
512 FOP_CONDS(s)
513
514 typedef struct DisasContext {
515     struct TranslationBlock *tb;
516     target_ulong pc, saved_pc;
517     uint32_t opcode;
518     /* Routine used to access memory */
519     int mem_idx;
520     uint32_t hflags, saved_hflags;
521     uint32_t CP0_Status;
522     int bstate;
523     target_ulong btarget;
524 } DisasContext;
525
526 enum {
527     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
528                       * exception condition
529                       */
530     BS_STOP     = 1, /* We want to stop translation for any reason */
531     BS_BRANCH   = 2, /* We reached a branch condition     */
532     BS_EXCP     = 3, /* We reached an exception condition */
533 };
534
535 #if defined MIPS_DEBUG_DISAS
536 #define MIPS_DEBUG(fmt, args...)                                              \
537 do {                                                                          \
538     if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
539         fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
540                 ctx->pc, ctx->opcode , ##args);                               \
541     }                                                                         \
542 } while (0)
543 #else
544 #define MIPS_DEBUG(fmt, args...) do { } while(0)
545 #endif
546
547 #define MIPS_INVAL(op)                                                        \
548 do {                                                                          \
549     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
550                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
551 } while (0)
552
553 #define GEN_LOAD_REG_TN(Tn, Rn)                                               \
554 do {                                                                          \
555     if (Rn == 0) {                                                            \
556         glue(gen_op_reset_, Tn)();                                            \
557     } else {                                                                  \
558         glue(gen_op_load_gpr_, Tn)(Rn);                                       \
559     }                                                                         \
560 } while (0)
561
562 #define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
563 do {                                                                          \
564     if (Imm == 0) {                                                           \
565         glue(gen_op_reset_, Tn)();                                            \
566     } else {                                                                  \
567         glue(gen_op_set_, Tn)(Imm);                                           \
568     }                                                                         \
569 } while (0)
570
571 #define GEN_STORE_TN_REG(Rn, Tn)                                              \
572 do {                                                                          \
573     if (Rn != 0) {                                                            \
574         glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
575     }                                                                         \
576 } while (0)
577
578 #define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
579 do {                                                                          \
580     glue(gen_op_load_fpr_, FTn)(Fn);                                          \
581 } while (0)
582
583 #define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
584 do {                                                                          \
585     glue(gen_op_store_fpr_, FTn)(Fn);                                         \
586 } while (0)
587
588 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
589 {
590 #if defined MIPS_DEBUG_DISAS
591     if (loglevel & CPU_LOG_TB_IN_ASM) {
592             fprintf(logfile, "hflags %08x saved %08x\n",
593                     ctx->hflags, ctx->saved_hflags);
594     }
595 #endif
596     if (do_save_pc && ctx->pc != ctx->saved_pc) {
597         gen_op_save_pc(ctx->pc);
598         ctx->saved_pc = ctx->pc;
599     }
600     if (ctx->hflags != ctx->saved_hflags) {
601         gen_op_save_state(ctx->hflags);
602         ctx->saved_hflags = ctx->hflags;
603         if (ctx->hflags & MIPS_HFLAG_BR) {
604             gen_op_save_breg_target();
605         } else if (ctx->hflags & MIPS_HFLAG_B) {
606             gen_op_save_btarget(ctx->btarget);
607         } else if (ctx->hflags & MIPS_HFLAG_BMASK) {
608             gen_op_save_bcond();
609             gen_op_save_btarget(ctx->btarget);
610         }
611     }
612 }
613
614 static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
615 {
616 #if defined MIPS_DEBUG_DISAS
617     if (loglevel & CPU_LOG_TB_IN_ASM)
618             fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
619 #endif
620     save_cpu_state(ctx, 1);
621     if (err == 0)
622         gen_op_raise_exception(excp);
623     else
624         gen_op_raise_exception_err(excp, err);
625     ctx->bstate = BS_EXCP;
626 }
627
628 static inline void generate_exception (DisasContext *ctx, int excp)
629 {
630     generate_exception_err (ctx, excp, 0);
631 }
632
633 #if defined(CONFIG_USER_ONLY)
634 #define op_ldst(name)        gen_op_##name##_raw()
635 #define OP_LD_TABLE(width)
636 #define OP_ST_TABLE(width)
637 #else
638 #define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
639 #define OP_LD_TABLE(width)                                                    \
640 static GenOpFunc *gen_op_l##width[] = {                                       \
641     &gen_op_l##width##_user,                                                  \
642     &gen_op_l##width##_kernel,                                                \
643 }
644 #define OP_ST_TABLE(width)                                                    \
645 static GenOpFunc *gen_op_s##width[] = {                                       \
646     &gen_op_s##width##_user,                                                  \
647     &gen_op_s##width##_kernel,                                                \
648 }
649 #endif
650
651 #ifdef TARGET_MIPS64
652 OP_LD_TABLE(d);
653 OP_LD_TABLE(dl);
654 OP_LD_TABLE(dr);
655 OP_ST_TABLE(d);
656 OP_ST_TABLE(dl);
657 OP_ST_TABLE(dr);
658 OP_LD_TABLE(ld);
659 OP_ST_TABLE(cd);
660 #endif
661 OP_LD_TABLE(w);
662 OP_LD_TABLE(wu);
663 OP_LD_TABLE(wl);
664 OP_LD_TABLE(wr);
665 OP_ST_TABLE(w);
666 OP_ST_TABLE(wl);
667 OP_ST_TABLE(wr);
668 OP_LD_TABLE(h);
669 OP_LD_TABLE(hu);
670 OP_ST_TABLE(h);
671 OP_LD_TABLE(b);
672 OP_LD_TABLE(bu);
673 OP_ST_TABLE(b);
674 OP_LD_TABLE(l);
675 OP_ST_TABLE(c);
676 OP_LD_TABLE(wc1);
677 OP_ST_TABLE(wc1);
678 OP_LD_TABLE(dc1);
679 OP_ST_TABLE(dc1);
680
681 /* Load and store */
682 static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
683                       int base, int16_t offset)
684 {
685     const char *opn = "unk";
686
687     if (base == 0) {
688         GEN_LOAD_IMM_TN(T0, offset);
689     } else if (offset == 0) {
690         gen_op_load_gpr_T0(base);
691     } else {
692         gen_op_load_gpr_T0(base);
693         gen_op_set_T1(offset);
694         gen_op_add();
695     }
696     /* Don't do NOP if destination is zero: we must perform the actual
697      * memory access
698      */
699     switch (opc) {
700 #ifdef TARGET_MIPS64
701     case OPC_LD:
702         op_ldst(ld);
703         GEN_STORE_TN_REG(rt, T0);
704         opn = "ld";
705         break;
706     case OPC_LLD:
707         op_ldst(lld);
708         GEN_STORE_TN_REG(rt, T0);
709         opn = "lld";
710         break;
711     case OPC_SD:
712         GEN_LOAD_REG_TN(T1, rt);
713         op_ldst(sd);
714         opn = "sd";
715         break;
716     case OPC_SCD:
717         save_cpu_state(ctx, 1);
718         GEN_LOAD_REG_TN(T1, rt);
719         op_ldst(scd);
720         opn = "scd";
721         break;
722     case OPC_LDL:
723         op_ldst(ldl);
724         GEN_STORE_TN_REG(rt, T0);
725         opn = "ldl";
726         break;
727     case OPC_SDL:
728         GEN_LOAD_REG_TN(T1, rt);
729         op_ldst(sdl);
730         opn = "sdl";
731         break;
732     case OPC_LDR:
733         op_ldst(ldr);
734         GEN_STORE_TN_REG(rt, T0);
735         opn = "ldr";
736         break;
737     case OPC_SDR:
738         GEN_LOAD_REG_TN(T1, rt);
739         op_ldst(sdr);
740         opn = "sdr";
741         break;
742 #endif
743     case OPC_LW:
744         op_ldst(lw);
745         GEN_STORE_TN_REG(rt, T0);
746         opn = "lw";
747         break;
748     case OPC_LWU:
749         op_ldst(lwu);
750         GEN_STORE_TN_REG(rt, T0);
751         opn = "lwu";
752         break;
753     case OPC_SW:
754         GEN_LOAD_REG_TN(T1, rt);
755         op_ldst(sw);
756         opn = "sw";
757         break;
758     case OPC_LH:
759         op_ldst(lh);
760         GEN_STORE_TN_REG(rt, T0);
761         opn = "lh";
762         break;
763     case OPC_SH:
764         GEN_LOAD_REG_TN(T1, rt);
765         op_ldst(sh);
766         opn = "sh";
767         break;
768     case OPC_LHU:
769         op_ldst(lhu);
770         GEN_STORE_TN_REG(rt, T0);
771         opn = "lhu";
772         break;
773     case OPC_LB:
774         op_ldst(lb);
775         GEN_STORE_TN_REG(rt, T0);
776         opn = "lb";
777         break;
778     case OPC_SB:
779         GEN_LOAD_REG_TN(T1, rt);
780         op_ldst(sb);
781         opn = "sb";
782         break;
783     case OPC_LBU:
784         op_ldst(lbu);
785         GEN_STORE_TN_REG(rt, T0);
786         opn = "lbu";
787         break;
788     case OPC_LWL:
789         GEN_LOAD_REG_TN(T1, rt);
790         op_ldst(lwl);
791         GEN_STORE_TN_REG(rt, T0);
792         opn = "lwl";
793         break;
794     case OPC_SWL:
795         GEN_LOAD_REG_TN(T1, rt);
796         op_ldst(swl);
797         opn = "swr";
798         break;
799     case OPC_LWR:
800         GEN_LOAD_REG_TN(T1, rt);
801         op_ldst(lwr);
802         GEN_STORE_TN_REG(rt, T0);
803         opn = "lwr";
804         break;
805     case OPC_SWR:
806         GEN_LOAD_REG_TN(T1, rt);
807         op_ldst(swr);
808         opn = "swr";
809         break;
810     case OPC_LL:
811         op_ldst(ll);
812         GEN_STORE_TN_REG(rt, T0);
813         opn = "ll";
814         break;
815     case OPC_SC:
816         save_cpu_state(ctx, 1);
817         GEN_LOAD_REG_TN(T1, rt);
818         op_ldst(sc);
819         GEN_STORE_TN_REG(rt, T0);
820         opn = "sc";
821         break;
822     default:
823         MIPS_INVAL("load/store");
824         generate_exception(ctx, EXCP_RI);
825         return;
826     }
827     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
828 }
829
830 /* Load and store */
831 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
832                       int base, int16_t offset)
833 {
834     const char *opn = "unk";
835
836     if (base == 0) {
837         GEN_LOAD_IMM_TN(T0, offset);
838     } else if (offset == 0) {
839         gen_op_load_gpr_T0(base);
840     } else {
841         gen_op_load_gpr_T0(base);
842         gen_op_set_T1(offset);
843         gen_op_add();
844     }
845     /* Don't do NOP if destination is zero: we must perform the actual
846      * memory access
847      */
848     switch (opc) {
849     case OPC_LWC1:
850         op_ldst(lwc1);
851         GEN_STORE_FTN_FREG(ft, WT0);
852         opn = "lwc1";
853         break;
854     case OPC_SWC1:
855         GEN_LOAD_FREG_FTN(WT0, ft);
856         op_ldst(swc1);
857         opn = "swc1";
858         break;
859     case OPC_LDC1:
860         op_ldst(ldc1);
861         GEN_STORE_FTN_FREG(ft, DT0);
862         opn = "ldc1";
863         break;
864     case OPC_SDC1:
865         GEN_LOAD_FREG_FTN(DT0, ft);
866         op_ldst(sdc1);
867         opn = "sdc1";
868         break;
869     default:
870         MIPS_INVAL("float load/store");
871         generate_exception(ctx, EXCP_RI);
872         return;
873     }
874     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
875 }
876
877 /* Arithmetic with immediate operand */
878 static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
879                            int rs, int16_t imm)
880 {
881     uint32_t uimm;
882     const char *opn = "unk";
883
884     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
885         /* if no destination, treat it as a NOP 
886          * For addi, we must generate the overflow exception when needed.
887          */
888         MIPS_DEBUG("NOP");
889         return;
890     }
891     uimm = (uint16_t)imm;
892     switch (opc) {
893     case OPC_ADDI:
894     case OPC_ADDIU:
895 #ifdef TARGET_MIPS64
896     case OPC_DADDI:
897     case OPC_DADDIU:
898 #endif
899     case OPC_SLTI:
900     case OPC_SLTIU:
901         uimm = (int32_t)imm; /* Sign extend to 32 bits */
902         /* Fall through. */
903     case OPC_ANDI:
904     case OPC_ORI:
905     case OPC_XORI:
906         GEN_LOAD_REG_TN(T0, rs);
907         GEN_LOAD_IMM_TN(T1, uimm);
908         break;
909     case OPC_LUI:
910         uimm =  (int32_t)(imm << 16);
911         GEN_LOAD_IMM_TN(T0, uimm);
912         break;
913     case OPC_SLL:
914     case OPC_SRA:
915     case OPC_SRL:
916 #ifdef TARGET_MIPS64
917     case OPC_DSLL:
918     case OPC_DSRA:
919     case OPC_DSRL:
920     case OPC_DSLL32:
921     case OPC_DSRA32:
922     case OPC_DSRL32:
923 #endif
924         uimm &= 0x1f;
925         GEN_LOAD_REG_TN(T0, rs);
926         GEN_LOAD_IMM_TN(T1, uimm);
927         break;
928     }
929     switch (opc) {
930     case OPC_ADDI:
931         save_cpu_state(ctx, 1);
932         gen_op_addo();
933         opn = "addi";
934         break;
935     case OPC_ADDIU:
936         gen_op_add();
937         opn = "addiu";
938         break;
939 #ifdef TARGET_MIPS64
940     case OPC_DADDI:
941         save_cpu_state(ctx, 1);
942         gen_op_daddo();
943         opn = "daddi";
944         break;
945     case OPC_DADDIU:
946         gen_op_dadd();
947         opn = "daddiu";
948         break;
949 #endif
950     case OPC_SLTI:
951         gen_op_lt();
952         opn = "slti";
953         break;
954     case OPC_SLTIU:
955         gen_op_ltu();
956         opn = "sltiu";
957         break;
958     case OPC_ANDI:
959         gen_op_and();
960         opn = "andi";
961         break;
962     case OPC_ORI:
963         gen_op_or();
964         opn = "ori";
965         break;
966     case OPC_XORI:
967         gen_op_xor();
968         opn = "xori";
969         break;
970     case OPC_LUI:
971         opn = "lui";
972         break;
973     case OPC_SLL:
974         gen_op_sll();
975         opn = "sll";
976         break;
977     case OPC_SRA:
978         gen_op_sra();
979         opn = "sra";
980         break;
981     case OPC_SRL:
982         switch ((ctx->opcode >> 21) & 0x1f) {
983         case 0:
984             gen_op_srl();
985             opn = "srl";
986             break;
987         case 1:
988             gen_op_rotr();
989             opn = "rotr";
990             break;
991         default:
992             MIPS_INVAL("invalid srl flag");
993             generate_exception(ctx, EXCP_RI);
994             break;
995         }
996         break;
997 #ifdef TARGET_MIPS64
998     case OPC_DSLL:
999         gen_op_dsll();
1000         opn = "dsll";
1001         break;
1002     case OPC_DSRA:
1003         gen_op_dsra();
1004         opn = "dsra";
1005         break;
1006     case OPC_DSRL:
1007         switch ((ctx->opcode >> 21) & 0x1f) {
1008         case 0:
1009             gen_op_dsrl();
1010             opn = "dsrl";
1011             break;
1012         case 1:
1013             gen_op_drotr();
1014             opn = "drotr";
1015             break;
1016         default:
1017             MIPS_INVAL("invalid dsrl flag");
1018             generate_exception(ctx, EXCP_RI);
1019             break;
1020         }
1021         break;
1022     case OPC_DSLL32:
1023         gen_op_dsll32();
1024         opn = "dsll32";
1025         break;
1026     case OPC_DSRA32:
1027         gen_op_dsra32();
1028         opn = "dsra32";
1029         break;
1030     case OPC_DSRL32:
1031         switch ((ctx->opcode >> 21) & 0x1f) {
1032         case 0:
1033             gen_op_dsrl32();
1034             opn = "dsrl32";
1035             break;
1036         case 1:
1037             gen_op_drotr32();
1038             opn = "drotr32";
1039             break;
1040         default:
1041             MIPS_INVAL("invalid dsrl32 flag");
1042             generate_exception(ctx, EXCP_RI);
1043             break;
1044         }
1045         break;
1046 #endif
1047     default:
1048         MIPS_INVAL("imm arith");
1049         generate_exception(ctx, EXCP_RI);
1050         return;
1051     }
1052     GEN_STORE_TN_REG(rt, T0);
1053     MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
1054 }
1055
1056 /* Arithmetic */
1057 static void gen_arith (DisasContext *ctx, uint32_t opc,
1058                        int rd, int rs, int rt)
1059 {
1060     const char *opn = "unk";
1061
1062     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1063        && opc != OPC_DADD && opc != OPC_DSUB) {
1064         /* if no destination, treat it as a NOP 
1065          * For add & sub, we must generate the overflow exception when needed.
1066          */
1067         MIPS_DEBUG("NOP");
1068         return;
1069     }
1070     GEN_LOAD_REG_TN(T0, rs);
1071     GEN_LOAD_REG_TN(T1, rt);
1072     switch (opc) {
1073     case OPC_ADD:
1074         save_cpu_state(ctx, 1);
1075         gen_op_addo();
1076         opn = "add";
1077         break;
1078     case OPC_ADDU:
1079         gen_op_add();
1080         opn = "addu";
1081         break;
1082     case OPC_SUB:
1083         save_cpu_state(ctx, 1);
1084         gen_op_subo();
1085         opn = "sub";
1086         break;
1087     case OPC_SUBU:
1088         gen_op_sub();
1089         opn = "subu";
1090         break;
1091 #ifdef TARGET_MIPS64
1092     case OPC_DADD:
1093         save_cpu_state(ctx, 1);
1094         gen_op_daddo();
1095         opn = "dadd";
1096         break;
1097     case OPC_DADDU:
1098         gen_op_dadd();
1099         opn = "daddu";
1100         break;
1101     case OPC_DSUB:
1102         save_cpu_state(ctx, 1);
1103         gen_op_dsubo();
1104         opn = "dsub";
1105         break;
1106     case OPC_DSUBU:
1107         gen_op_dsub();
1108         opn = "dsubu";
1109         break;
1110 #endif
1111     case OPC_SLT:
1112         gen_op_lt();
1113         opn = "slt";
1114         break;
1115     case OPC_SLTU:
1116         gen_op_ltu();
1117         opn = "sltu";
1118         break;
1119     case OPC_AND:
1120         gen_op_and();
1121         opn = "and";
1122         break;
1123     case OPC_NOR:
1124         gen_op_nor();
1125         opn = "nor";
1126         break;
1127     case OPC_OR:
1128         gen_op_or();
1129         opn = "or";
1130         break;
1131     case OPC_XOR:
1132         gen_op_xor();
1133         opn = "xor";
1134         break;
1135     case OPC_MUL:
1136         gen_op_mul();
1137         opn = "mul";
1138         break;
1139     case OPC_MOVN:
1140         gen_op_movn(rd);
1141         opn = "movn";
1142         goto print;
1143     case OPC_MOVZ:
1144         gen_op_movz(rd);
1145         opn = "movz";
1146         goto print;
1147     case OPC_SLLV:
1148         gen_op_sllv();
1149         opn = "sllv";
1150         break;
1151     case OPC_SRAV:
1152         gen_op_srav();
1153         opn = "srav";
1154         break;
1155     case OPC_SRLV:
1156         switch ((ctx->opcode >> 6) & 0x1f) {
1157         case 0:
1158             gen_op_srlv();
1159             opn = "srlv";
1160             break;
1161         case 1:
1162             gen_op_rotrv();
1163             opn = "rotrv";
1164             break;
1165         default:
1166             MIPS_INVAL("invalid srlv flag");
1167             generate_exception(ctx, EXCP_RI);
1168             break;
1169         }
1170         break;
1171 #ifdef TARGET_MIPS64
1172     case OPC_DSLLV:
1173         gen_op_dsllv();
1174         opn = "dsllv";
1175         break;
1176     case OPC_DSRAV:
1177         gen_op_dsrav();
1178         opn = "dsrav";
1179         break;
1180     case OPC_DSRLV:
1181         switch ((ctx->opcode >> 6) & 0x1f) {
1182         case 0:
1183             gen_op_dsrlv();
1184             opn = "dsrlv";
1185             break;
1186         case 1:
1187             gen_op_drotrv();
1188             opn = "drotrv";
1189             break;
1190         default:
1191             MIPS_INVAL("invalid dsrlv flag");
1192             generate_exception(ctx, EXCP_RI);
1193             break;
1194         }
1195         break;
1196 #endif
1197     default:
1198         MIPS_INVAL("arith");
1199         generate_exception(ctx, EXCP_RI);
1200         return;
1201     }
1202     GEN_STORE_TN_REG(rd, T0);
1203  print:
1204     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1205 }
1206
1207 /* Arithmetic on HI/LO registers */
1208 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1209 {
1210     const char *opn = "unk";
1211
1212     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1213         /* Treat as a NOP */
1214         MIPS_DEBUG("NOP");
1215         return;
1216     }
1217     switch (opc) {
1218     case OPC_MFHI:
1219         gen_op_load_HI();
1220         GEN_STORE_TN_REG(reg, T0);
1221         opn = "mfhi";
1222         break;
1223     case OPC_MFLO:
1224         gen_op_load_LO();
1225         GEN_STORE_TN_REG(reg, T0);
1226         opn = "mflo";
1227         break;
1228     case OPC_MTHI:
1229         GEN_LOAD_REG_TN(T0, reg);
1230         gen_op_store_HI();
1231         opn = "mthi";
1232         break;
1233     case OPC_MTLO:
1234         GEN_LOAD_REG_TN(T0, reg);
1235         gen_op_store_LO();
1236         opn = "mtlo";
1237         break;
1238     default:
1239         MIPS_INVAL("HILO");
1240         generate_exception(ctx, EXCP_RI);
1241         return;
1242     }
1243     MIPS_DEBUG("%s %s", opn, regnames[reg]);
1244 }
1245
1246 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1247                         int rs, int rt)
1248 {
1249     const char *opn = "unk";
1250
1251     GEN_LOAD_REG_TN(T0, rs);
1252     GEN_LOAD_REG_TN(T1, rt);
1253     switch (opc) {
1254     case OPC_DIV:
1255         gen_op_div();
1256         opn = "div";
1257         break;
1258     case OPC_DIVU:
1259         gen_op_divu();
1260         opn = "divu";
1261         break;
1262     case OPC_MULT:
1263         gen_op_mult();
1264         opn = "mult";
1265         break;
1266     case OPC_MULTU:
1267         gen_op_multu();
1268         opn = "multu";
1269         break;
1270 #ifdef TARGET_MIPS64
1271     case OPC_DDIV:
1272         gen_op_ddiv();
1273         opn = "ddiv";
1274         break;
1275     case OPC_DDIVU:
1276         gen_op_ddivu();
1277         opn = "ddivu";
1278         break;
1279     case OPC_DMULT:
1280         gen_op_dmult();
1281         opn = "dmult";
1282         break;
1283     case OPC_DMULTU:
1284         gen_op_dmultu();
1285         opn = "dmultu";
1286         break;
1287 #endif
1288     case OPC_MADD:
1289         gen_op_madd();
1290         opn = "madd";
1291         break;
1292     case OPC_MADDU:
1293         gen_op_maddu();
1294         opn = "maddu";
1295         break;
1296     case OPC_MSUB:
1297         gen_op_msub();
1298         opn = "msub";
1299         break;
1300     case OPC_MSUBU:
1301         gen_op_msubu();
1302         opn = "msubu";
1303         break;
1304     default:
1305         MIPS_INVAL("mul/div");
1306         generate_exception(ctx, EXCP_RI);
1307         return;
1308     }
1309     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1310 }
1311
1312 static void gen_cl (DisasContext *ctx, uint32_t opc,
1313                     int rd, int rs)
1314 {
1315     const char *opn = "unk";
1316     if (rd == 0) {
1317         /* Treat as a NOP */
1318         MIPS_DEBUG("NOP");
1319         return;
1320     }
1321     GEN_LOAD_REG_TN(T0, rs);
1322     switch (opc) {
1323     case OPC_CLO:
1324         gen_op_clo();
1325         opn = "clo";
1326         break;
1327     case OPC_CLZ:
1328         gen_op_clz();
1329         opn = "clz";
1330         break;
1331 #ifdef TARGET_MIPS64
1332     case OPC_DCLO:
1333         gen_op_dclo();
1334         opn = "dclo";
1335         break;
1336     case OPC_DCLZ:
1337         gen_op_dclz();
1338         opn = "dclz";
1339         break;
1340 #endif
1341     default:
1342         MIPS_INVAL("CLx");
1343         generate_exception(ctx, EXCP_RI);
1344         return;
1345     }
1346     gen_op_store_T0_gpr(rd);
1347     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1348 }
1349
1350 /* Traps */
1351 static void gen_trap (DisasContext *ctx, uint32_t opc,
1352                       int rs, int rt, int16_t imm)
1353 {
1354     int cond;
1355
1356     cond = 0;
1357     /* Load needed operands */
1358     switch (opc) {
1359     case OPC_TEQ:
1360     case OPC_TGE:
1361     case OPC_TGEU:
1362     case OPC_TLT:
1363     case OPC_TLTU:
1364     case OPC_TNE:
1365         /* Compare two registers */
1366         if (rs != rt) {
1367             GEN_LOAD_REG_TN(T0, rs);
1368             GEN_LOAD_REG_TN(T1, rt);
1369             cond = 1;
1370         }
1371         break;
1372     case OPC_TEQI:
1373     case OPC_TGEI:
1374     case OPC_TGEIU:
1375     case OPC_TLTI:
1376     case OPC_TLTIU:
1377     case OPC_TNEI:
1378         /* Compare register to immediate */
1379         if (rs != 0 || imm != 0) {
1380             GEN_LOAD_REG_TN(T0, rs);
1381             GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1382             cond = 1;
1383         }
1384         break;
1385     }
1386     if (cond == 0) {
1387         switch (opc) {
1388         case OPC_TEQ:   /* rs == rs */
1389         case OPC_TEQI:  /* r0 == 0  */
1390         case OPC_TGE:   /* rs >= rs */
1391         case OPC_TGEI:  /* r0 >= 0  */
1392         case OPC_TGEU:  /* rs >= rs unsigned */
1393         case OPC_TGEIU: /* r0 >= 0  unsigned */
1394             /* Always trap */
1395             gen_op_set_T0(1);
1396             break;
1397         case OPC_TLT:   /* rs < rs           */
1398         case OPC_TLTI:  /* r0 < 0            */
1399         case OPC_TLTU:  /* rs < rs unsigned  */
1400         case OPC_TLTIU: /* r0 < 0  unsigned  */
1401         case OPC_TNE:   /* rs != rs          */
1402         case OPC_TNEI:  /* r0 != 0           */
1403             /* Never trap: treat as NOP */
1404             return;
1405         default:
1406             MIPS_INVAL("TRAP");
1407             generate_exception(ctx, EXCP_RI);
1408             return;
1409         }
1410     } else {
1411         switch (opc) {
1412         case OPC_TEQ:
1413         case OPC_TEQI:
1414             gen_op_eq();
1415             break;
1416         case OPC_TGE:
1417         case OPC_TGEI:
1418             gen_op_ge();
1419             break;
1420         case OPC_TGEU:
1421         case OPC_TGEIU:
1422             gen_op_geu();
1423             break;
1424         case OPC_TLT:
1425         case OPC_TLTI:
1426             gen_op_lt();
1427             break;
1428         case OPC_TLTU:
1429         case OPC_TLTIU:
1430             gen_op_ltu();
1431             break;
1432         case OPC_TNE:
1433         case OPC_TNEI:
1434             gen_op_ne();
1435             break;
1436         default:
1437             MIPS_INVAL("TRAP");
1438             generate_exception(ctx, EXCP_RI);
1439             return;
1440         }
1441     }
1442     save_cpu_state(ctx, 1);
1443     gen_op_trap();
1444     ctx->bstate = BS_STOP;
1445 }
1446
1447 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1448 {
1449     TranslationBlock *tb;
1450     tb = ctx->tb;
1451     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1452         if (n == 0)
1453             gen_op_goto_tb0(TBPARAM(tb));
1454         else
1455             gen_op_goto_tb1(TBPARAM(tb));
1456         gen_op_save_pc(dest);
1457         gen_op_set_T0((long)tb + n);
1458     } else {
1459         gen_op_save_pc(dest);
1460         gen_op_reset_T0();
1461     }
1462     gen_op_exit_tb();
1463 }
1464
1465 /* Branches (before delay slot) */
1466 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1467                                 int rs, int rt, int32_t offset)
1468 {
1469     target_ulong btarget = -1;
1470     int blink = 0;
1471     int bcond = 0;
1472
1473     if (ctx->hflags & MIPS_HFLAG_BMASK) {
1474         if (loglevel & CPU_LOG_TB_IN_ASM) {
1475             fprintf(logfile,
1476                     "undefined branch in delay slot at PC " TARGET_FMT_lx "\n",
1477                     ctx->pc);
1478         }
1479         MIPS_INVAL("branch/jump in bdelay slot");
1480         generate_exception(ctx, EXCP_RI);
1481         return;
1482     }
1483
1484     /* Load needed operands */
1485     switch (opc) {
1486     case OPC_BEQ:
1487     case OPC_BEQL:
1488     case OPC_BNE:
1489     case OPC_BNEL:
1490         /* Compare two registers */
1491         if (rs != rt) {
1492             GEN_LOAD_REG_TN(T0, rs);
1493             GEN_LOAD_REG_TN(T1, rt);
1494             bcond = 1;
1495         }
1496         btarget = ctx->pc + 4 + offset;
1497         break;
1498     case OPC_BGEZ:
1499     case OPC_BGEZAL:
1500     case OPC_BGEZALL:
1501     case OPC_BGEZL:
1502     case OPC_BGTZ:
1503     case OPC_BGTZL:
1504     case OPC_BLEZ:
1505     case OPC_BLEZL:
1506     case OPC_BLTZ:
1507     case OPC_BLTZAL:
1508     case OPC_BLTZALL:
1509     case OPC_BLTZL:
1510         /* Compare to zero */
1511         if (rs != 0) {
1512             gen_op_load_gpr_T0(rs);
1513             bcond = 1;
1514         }
1515         btarget = ctx->pc + 4 + offset;
1516         break;
1517     case OPC_J:
1518     case OPC_JAL:
1519         /* Jump to immediate */
1520         btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset;
1521         break;
1522     case OPC_JR:
1523     case OPC_JALR:
1524         /* Jump to register */
1525         if (offset != 0 && offset != 16) {
1526             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1527                others are reserved. */
1528             generate_exception(ctx, EXCP_RI);
1529             return;
1530         }
1531         GEN_LOAD_REG_TN(T2, rs);
1532         break;
1533     default:
1534         MIPS_INVAL("branch/jump");
1535         generate_exception(ctx, EXCP_RI);
1536         return;
1537     }
1538     if (bcond == 0) {
1539         /* No condition to be computed */
1540         switch (opc) {
1541         case OPC_BEQ:     /* rx == rx        */
1542         case OPC_BEQL:    /* rx == rx likely */
1543         case OPC_BGEZ:    /* 0 >= 0          */
1544         case OPC_BGEZL:   /* 0 >= 0 likely   */
1545         case OPC_BLEZ:    /* 0 <= 0          */
1546         case OPC_BLEZL:   /* 0 <= 0 likely   */
1547             /* Always take */
1548             ctx->hflags |= MIPS_HFLAG_B;
1549             MIPS_DEBUG("balways");
1550             break;
1551         case OPC_BGEZAL:  /* 0 >= 0          */
1552         case OPC_BGEZALL: /* 0 >= 0 likely   */
1553             /* Always take and link */
1554             blink = 31;
1555             ctx->hflags |= MIPS_HFLAG_B;
1556             MIPS_DEBUG("balways and link");
1557             break;
1558         case OPC_BNE:     /* rx != rx        */
1559         case OPC_BGTZ:    /* 0 > 0           */
1560         case OPC_BLTZ:    /* 0 < 0           */
1561             /* Treated as NOP */
1562             MIPS_DEBUG("bnever (NOP)");
1563             return;
1564         case OPC_BLTZAL:  /* 0 < 0           */
1565             gen_op_set_T0(ctx->pc + 8);
1566             gen_op_store_T0_gpr(31);
1567             MIPS_DEBUG("bnever and link");
1568             return;
1569         case OPC_BLTZALL: /* 0 < 0 likely */
1570             gen_op_set_T0(ctx->pc + 8);
1571             gen_op_store_T0_gpr(31);
1572             /* Skip the instruction in the delay slot */
1573             MIPS_DEBUG("bnever, link and skip");
1574             ctx->pc += 4;
1575             return;
1576         case OPC_BNEL:    /* rx != rx likely */
1577         case OPC_BGTZL:   /* 0 > 0 likely */
1578         case OPC_BLTZL:   /* 0 < 0 likely */
1579             /* Skip the instruction in the delay slot */
1580             MIPS_DEBUG("bnever and skip");
1581             ctx->pc += 4;
1582             return;
1583         case OPC_J:
1584             ctx->hflags |= MIPS_HFLAG_B;
1585             MIPS_DEBUG("j %08x", btarget);
1586             break;
1587         case OPC_JAL:
1588             blink = 31;
1589             ctx->hflags |= MIPS_HFLAG_B;
1590             MIPS_DEBUG("jal %08x", btarget);
1591             break;
1592         case OPC_JR:
1593             ctx->hflags |= MIPS_HFLAG_BR;
1594             MIPS_DEBUG("jr %s", regnames[rs]);
1595             break;
1596         case OPC_JALR:
1597             blink = rt;
1598             ctx->hflags |= MIPS_HFLAG_BR;
1599             MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1600             break;
1601         default:
1602             MIPS_INVAL("branch/jump");
1603             generate_exception(ctx, EXCP_RI);
1604             return;
1605         }
1606     } else {
1607         switch (opc) {
1608         case OPC_BEQ:
1609             gen_op_eq();
1610             MIPS_DEBUG("beq %s, %s, %08x",
1611                        regnames[rs], regnames[rt], btarget);
1612             goto not_likely;
1613         case OPC_BEQL:
1614             gen_op_eq();
1615             MIPS_DEBUG("beql %s, %s, %08x",
1616                        regnames[rs], regnames[rt], btarget);
1617             goto likely;
1618         case OPC_BNE:
1619             gen_op_ne();
1620             MIPS_DEBUG("bne %s, %s, %08x",
1621                        regnames[rs], regnames[rt], btarget);
1622             goto not_likely;
1623         case OPC_BNEL:
1624             gen_op_ne();
1625             MIPS_DEBUG("bnel %s, %s, %08x",
1626                        regnames[rs], regnames[rt], btarget);
1627             goto likely;
1628         case OPC_BGEZ:
1629             gen_op_gez();
1630             MIPS_DEBUG("bgez %s, %08x", regnames[rs], btarget);
1631             goto not_likely;
1632         case OPC_BGEZL:
1633             gen_op_gez();
1634             MIPS_DEBUG("bgezl %s, %08x", regnames[rs], btarget);
1635             goto likely;
1636         case OPC_BGEZAL:
1637             gen_op_gez();
1638             MIPS_DEBUG("bgezal %s, %08x", regnames[rs], btarget);
1639             blink = 31;
1640             goto not_likely;
1641         case OPC_BGEZALL:
1642             gen_op_gez();
1643             blink = 31;
1644             MIPS_DEBUG("bgezall %s, %08x", regnames[rs], btarget);
1645             goto likely;
1646         case OPC_BGTZ:
1647             gen_op_gtz();
1648             MIPS_DEBUG("bgtz %s, %08x", regnames[rs], btarget);
1649             goto not_likely;
1650         case OPC_BGTZL:
1651             gen_op_gtz();
1652             MIPS_DEBUG("bgtzl %s, %08x", regnames[rs], btarget);
1653             goto likely;
1654         case OPC_BLEZ:
1655             gen_op_lez();
1656             MIPS_DEBUG("blez %s, %08x", regnames[rs], btarget);
1657             goto not_likely;
1658         case OPC_BLEZL:
1659             gen_op_lez();
1660             MIPS_DEBUG("blezl %s, %08x", regnames[rs], btarget);
1661             goto likely;
1662         case OPC_BLTZ:
1663             gen_op_ltz();
1664             MIPS_DEBUG("bltz %s, %08x", regnames[rs], btarget);
1665             goto not_likely;
1666         case OPC_BLTZL:
1667             gen_op_ltz();
1668             MIPS_DEBUG("bltzl %s, %08x", regnames[rs], btarget);
1669             goto likely;
1670         case OPC_BLTZAL:
1671             gen_op_ltz();
1672             blink = 31;
1673             MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);
1674         not_likely:
1675             ctx->hflags |= MIPS_HFLAG_BC;
1676             break;
1677         case OPC_BLTZALL:
1678             gen_op_ltz();
1679             blink = 31;
1680             MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);
1681         likely:
1682             ctx->hflags |= MIPS_HFLAG_BL;
1683             break;
1684         default:
1685             MIPS_INVAL("conditional branch/jump");
1686             generate_exception(ctx, EXCP_RI);
1687             return;
1688         }
1689         gen_op_set_bcond();
1690     }
1691     MIPS_DEBUG("enter ds: link %d cond %02x target %08x",
1692                blink, ctx->hflags, btarget);
1693     ctx->btarget = btarget;
1694     if (blink > 0) {
1695         gen_op_set_T0(ctx->pc + 8);
1696         gen_op_store_T0_gpr(blink);
1697     }
1698 }
1699
1700 /* special3 bitfield operations */
1701 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1702                        int rs, int lsb, int msb)
1703 {
1704     GEN_LOAD_REG_TN(T1, rs);
1705     switch (opc) {
1706     case OPC_EXT:
1707         if (lsb + msb > 31)
1708             goto fail;
1709         gen_op_ext(lsb, msb + 1);
1710         break;
1711     case OPC_DEXTM:
1712         if (lsb + msb > 63)
1713             goto fail;
1714         gen_op_ext(lsb, msb + 1 + 32);
1715         break;
1716     case OPC_DEXTU:
1717         if (lsb + msb > 63)
1718             goto fail;
1719         gen_op_ext(lsb + 32, msb + 1);
1720         break;
1721     case OPC_DEXT:
1722         gen_op_ext(lsb, msb + 1);
1723         break;
1724     case OPC_INS:
1725         if (lsb > msb)
1726             goto fail;
1727         GEN_LOAD_REG_TN(T0, rt);
1728         gen_op_ins(lsb, msb - lsb + 1);
1729         break;
1730     case OPC_DINSM:
1731         if (lsb > msb)
1732             goto fail;
1733         GEN_LOAD_REG_TN(T0, rt);
1734         gen_op_ins(lsb, msb - lsb + 1 + 32);
1735         break;
1736     case OPC_DINSU:
1737         if (lsb > msb)
1738             goto fail;
1739         GEN_LOAD_REG_TN(T0, rt);
1740         gen_op_ins(lsb + 32, msb - lsb + 1);
1741         break;
1742     case OPC_DINS:
1743         if (lsb > msb)
1744             goto fail;
1745         GEN_LOAD_REG_TN(T0, rt);
1746         gen_op_ins(lsb, msb - lsb + 1);
1747         break;
1748     default:
1749 fail:
1750         MIPS_INVAL("bitops");
1751         generate_exception(ctx, EXCP_RI);
1752         return;
1753     }
1754     GEN_STORE_TN_REG(rt, T0);
1755 }
1756
1757 /* CP0 (MMU and control) */
1758 static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1759 {
1760     const char *rn = "invalid";
1761
1762     switch (reg) {
1763     case 0:
1764         switch (sel) {
1765         case 0:
1766             gen_op_mfc0_index();
1767             rn = "Index";
1768             break;
1769         case 1:
1770 //            gen_op_mfc0_mvpcontrol(); /* MT ASE */
1771             rn = "MVPControl";
1772 //            break;
1773         case 2:
1774 //            gen_op_mfc0_mvpconf0(); /* MT ASE */
1775             rn = "MVPConf0";
1776 //            break;
1777         case 3:
1778 //            gen_op_mfc0_mvpconf1(); /* MT ASE */
1779             rn = "MVPConf1";
1780 //            break;
1781         default:
1782             goto die;
1783         }
1784         break;
1785     case 1:
1786         switch (sel) {
1787         case 0:
1788             gen_op_mfc0_random();
1789             rn = "Random";
1790             break;
1791         case 1:
1792 //            gen_op_mfc0_vpecontrol(); /* MT ASE */
1793             rn = "VPEControl";
1794 //            break;
1795         case 2:
1796 //            gen_op_mfc0_vpeconf0(); /* MT ASE */
1797             rn = "VPEConf0";
1798 //            break;
1799         case 3:
1800 //            gen_op_mfc0_vpeconf1(); /* MT ASE */
1801             rn = "VPEConf1";
1802 //            break;
1803         case 4:
1804 //            gen_op_mfc0_YQMask(); /* MT ASE */
1805             rn = "YQMask";
1806 //            break;
1807         case 5:
1808 //            gen_op_mfc0_vpeschedule(); /* MT ASE */
1809             rn = "VPESchedule";
1810 //            break;
1811         case 6:
1812 //            gen_op_mfc0_vpeschefback(); /* MT ASE */
1813             rn = "VPEScheFBack";
1814 //            break;
1815         case 7:
1816 //            gen_op_mfc0_vpeopt(); /* MT ASE */
1817             rn = "VPEOpt";
1818 //            break;
1819         default:
1820             goto die;
1821         }
1822         break;
1823     case 2:
1824         switch (sel) {
1825         case 0:
1826             gen_op_mfc0_entrylo0();
1827             rn = "EntryLo0";
1828             break;
1829         case 1:
1830 //            gen_op_mfc0_tcstatus(); /* MT ASE */
1831             rn = "TCStatus";
1832 //            break;
1833         case 2:
1834 //            gen_op_mfc0_tcbind(); /* MT ASE */
1835             rn = "TCBind";
1836 //            break;
1837         case 3:
1838 //            gen_op_mfc0_tcrestart(); /* MT ASE */
1839             rn = "TCRestart";
1840 //            break;
1841         case 4:
1842 //            gen_op_mfc0_tchalt(); /* MT ASE */
1843             rn = "TCHalt";
1844 //            break;
1845         case 5:
1846 //            gen_op_mfc0_tccontext(); /* MT ASE */
1847             rn = "TCContext";
1848 //            break;
1849         case 6:
1850 //            gen_op_mfc0_tcschedule(); /* MT ASE */
1851             rn = "TCSchedule";
1852 //            break;
1853         case 7:
1854 //            gen_op_mfc0_tcschefback(); /* MT ASE */
1855             rn = "TCScheFBack";
1856 //            break;
1857         default:
1858             goto die;
1859         }
1860         break;
1861     case 3:
1862         switch (sel) {
1863         case 0:
1864             gen_op_mfc0_entrylo1();
1865             rn = "EntryLo1";
1866             break;
1867         default:
1868             goto die;
1869         }
1870         break;
1871     case 4:
1872         switch (sel) {
1873         case 0:
1874             gen_op_mfc0_context();
1875             rn = "Context";
1876             break;
1877         case 1:
1878 //            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
1879             rn = "ContextConfig";
1880 //            break;
1881         default:
1882             goto die;
1883         }
1884         break;
1885     case 5:
1886         switch (sel) {
1887         case 0:
1888             gen_op_mfc0_pagemask();
1889             rn = "PageMask";
1890             break;
1891         case 1:
1892             gen_op_mfc0_pagegrain();
1893             rn = "PageGrain";
1894             break;
1895         default:
1896             goto die;
1897         }
1898         break;
1899     case 6:
1900         switch (sel) {
1901         case 0:
1902             gen_op_mfc0_wired();
1903             rn = "Wired";
1904             break;
1905         case 1:
1906 //            gen_op_mfc0_srsconf0(); /* shadow registers */
1907             rn = "SRSConf0";
1908 //            break;
1909         case 2:
1910 //            gen_op_mfc0_srsconf1(); /* shadow registers */
1911             rn = "SRSConf1";
1912 //            break;
1913         case 3:
1914 //            gen_op_mfc0_srsconf2(); /* shadow registers */
1915             rn = "SRSConf2";
1916 //            break;
1917         case 4:
1918 //            gen_op_mfc0_srsconf3(); /* shadow registers */
1919             rn = "SRSConf3";
1920 //            break;
1921         case 5:
1922 //            gen_op_mfc0_srsconf4(); /* shadow registers */
1923             rn = "SRSConf4";
1924 //            break;
1925         default:
1926             goto die;
1927         }
1928         break;
1929     case 7:
1930         switch (sel) {
1931         case 0:
1932             gen_op_mfc0_hwrena();
1933             rn = "HWREna";
1934             break;
1935         default:
1936             goto die;
1937         }
1938         break;
1939     case 8:
1940         switch (sel) {
1941         case 0:
1942             gen_op_mfc0_badvaddr();
1943             rn = "BadVaddr";
1944             break;
1945         default:
1946             goto die;
1947        }
1948         break;
1949     case 9:
1950         switch (sel) {
1951         case 0:
1952             gen_op_mfc0_count();
1953             rn = "Count";
1954             break;
1955         /* 6,7 are implementation dependent */
1956         default:
1957             goto die;
1958         }
1959         break;
1960     case 10:
1961         switch (sel) {
1962         case 0:
1963             gen_op_mfc0_entryhi();
1964             rn = "EntryHi";
1965             break;
1966         default:
1967             goto die;
1968         }
1969         break;
1970     case 11:
1971         switch (sel) {
1972         case 0:
1973             gen_op_mfc0_compare();
1974             rn = "Compare";
1975             break;
1976         /* 6,7 are implementation dependent */
1977         default:
1978             goto die;
1979         }
1980         break;
1981     case 12:
1982         switch (sel) {
1983         case 0:
1984             gen_op_mfc0_status();
1985             rn = "Status";
1986             break;
1987         case 1:
1988             gen_op_mfc0_intctl();
1989             rn = "IntCtl";
1990             break;
1991         case 2:
1992             gen_op_mfc0_srsctl();
1993             rn = "SRSCtl";
1994             break;
1995         case 3:
1996 //            gen_op_mfc0_srsmap(); /* shadow registers */
1997             rn = "SRSMap";
1998 //            break;
1999         default:
2000             goto die;
2001        }
2002         break;
2003     case 13:
2004         switch (sel) {
2005         case 0:
2006             gen_op_mfc0_cause();
2007             rn = "Cause";
2008             break;
2009         default:
2010             goto die;
2011        }
2012         break;
2013     case 14:
2014         switch (sel) {
2015         case 0:
2016             gen_op_mfc0_epc();
2017             rn = "EPC";
2018             break;
2019         default:
2020             goto die;
2021         }
2022         break;
2023     case 15:
2024         switch (sel) {
2025         case 0:
2026             gen_op_mfc0_prid();
2027             rn = "PRid";
2028             break;
2029         case 1:
2030             gen_op_mfc0_ebase();
2031             rn = "EBase";
2032             break;
2033         default:
2034             goto die;
2035        }
2036         break;
2037     case 16:
2038         switch (sel) {
2039         case 0:
2040             gen_op_mfc0_config0();
2041             rn = "Config";
2042             break;
2043         case 1:
2044             gen_op_mfc0_config1();
2045             rn = "Config1";
2046             break;
2047         case 2:
2048             gen_op_mfc0_config2();
2049             rn = "Config2";
2050             break;
2051         case 3:
2052             gen_op_mfc0_config3();
2053             rn = "Config3";
2054             break;
2055         /* 4,5 are reserved */
2056         /* 6,7 are implementation dependent */
2057         case 6:
2058             gen_op_mfc0_config6();
2059             rn = "Config6";
2060             break;
2061         case 7:
2062             gen_op_mfc0_config7();
2063             rn = "Config7";
2064             break;
2065         default:
2066             goto die;
2067         }
2068         break;
2069     case 17:
2070         switch (sel) {
2071         case 0:
2072             gen_op_mfc0_lladdr();
2073             rn = "LLAddr";
2074             break;
2075         default:
2076             goto die;
2077         }
2078         break;
2079     case 18:
2080         switch (sel) {
2081         case 0:
2082             gen_op_mfc0_watchlo0();
2083             rn = "WatchLo";
2084             break;
2085         case 1:
2086 //            gen_op_mfc0_watchlo1();
2087             rn = "WatchLo1";
2088 //            break;
2089         case 2:
2090 //            gen_op_mfc0_watchlo2();
2091             rn = "WatchLo2";
2092 //            break;
2093         case 3:
2094 //            gen_op_mfc0_watchlo3();
2095             rn = "WatchLo3";
2096 //            break;
2097         case 4:
2098 //            gen_op_mfc0_watchlo4();
2099             rn = "WatchLo4";
2100 //            break;
2101         case 5:
2102 //            gen_op_mfc0_watchlo5();
2103             rn = "WatchLo5";
2104 //            break;
2105         case 6:
2106 //            gen_op_mfc0_watchlo6();
2107             rn = "WatchLo6";
2108 //            break;
2109         case 7:
2110 //            gen_op_mfc0_watchlo7();
2111             rn = "WatchLo7";
2112 //            break;
2113         default:
2114             goto die;
2115         }
2116         break;
2117     case 19:
2118         switch (sel) {
2119         case 0:
2120             gen_op_mfc0_watchhi0();
2121             rn = "WatchHi";
2122             break;
2123         case 1:
2124 //            gen_op_mfc0_watchhi1();
2125             rn = "WatchHi1";
2126 //            break;
2127         case 2:
2128 //            gen_op_mfc0_watchhi2();
2129             rn = "WatchHi2";
2130 //            break;
2131         case 3:
2132 //            gen_op_mfc0_watchhi3();
2133             rn = "WatchHi3";
2134 //            break;
2135         case 4:
2136 //            gen_op_mfc0_watchhi4();
2137             rn = "WatchHi4";
2138 //            break;
2139         case 5:
2140 //            gen_op_mfc0_watchhi5();
2141             rn = "WatchHi5";
2142 //            break;
2143         case 6:
2144 //            gen_op_mfc0_watchhi6();
2145             rn = "WatchHi6";
2146 //            break;
2147         case 7:
2148 //            gen_op_mfc0_watchhi7();
2149             rn = "WatchHi7";
2150 //            break;
2151         default:
2152             goto die;
2153         }
2154         break;
2155     case 20:
2156         switch (sel) {
2157         case 0:
2158             /* 64 bit MMU only */
2159             gen_op_mfc0_xcontext();
2160             rn = "XContext";
2161             break;
2162         default:
2163             goto die;
2164         }
2165         break;
2166     case 21:
2167        /* Officially reserved, but sel 0 is used for R1x000 framemask */
2168         switch (sel) {
2169         case 0:
2170             gen_op_mfc0_framemask();
2171             rn = "Framemask";
2172             break;
2173         default:
2174             goto die;
2175         }
2176         break;
2177     case 22:
2178         /* ignored */
2179         rn = "'Diagnostic"; /* implementation dependent */
2180         break;
2181     case 23:
2182         switch (sel) {
2183         case 0:
2184             gen_op_mfc0_debug(); /* EJTAG support */
2185             rn = "Debug";
2186             break;
2187         case 1:
2188 //            gen_op_mfc0_tracecontrol(); /* PDtrace support */
2189             rn = "TraceControl";
2190 //            break;
2191         case 2:
2192 //            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2193             rn = "TraceControl2";
2194 //            break;
2195         case 3:
2196 //            gen_op_mfc0_usertracedata(); /* PDtrace support */
2197             rn = "UserTraceData";
2198 //            break;
2199         case 4:
2200 //            gen_op_mfc0_debug(); /* PDtrace support */
2201             rn = "TraceBPC";
2202 //            break;
2203         default:
2204             goto die;
2205         }
2206         break;
2207     case 24:
2208         switch (sel) {
2209         case 0:
2210             gen_op_mfc0_depc(); /* EJTAG support */
2211             rn = "DEPC";
2212             break;
2213         default:
2214             goto die;
2215         }
2216         break;
2217     case 25:
2218         switch (sel) {
2219         case 0:
2220             gen_op_mfc0_performance0();
2221             rn = "Performance0";
2222             break;
2223         case 1:
2224 //            gen_op_mfc0_performance1();
2225             rn = "Performance1";
2226 //            break;
2227         case 2:
2228 //            gen_op_mfc0_performance2();
2229             rn = "Performance2";
2230 //            break;
2231         case 3:
2232 //            gen_op_mfc0_performance3();
2233             rn = "Performance3";
2234 //            break;
2235         case 4:
2236 //            gen_op_mfc0_performance4();
2237             rn = "Performance4";
2238 //            break;
2239         case 5:
2240 //            gen_op_mfc0_performance5();
2241             rn = "Performance5";
2242 //            break;
2243         case 6:
2244 //            gen_op_mfc0_performance6();
2245             rn = "Performance6";
2246 //            break;
2247         case 7:
2248 //            gen_op_mfc0_performance7();
2249             rn = "Performance7";
2250 //            break;
2251         default:
2252             goto die;
2253         }
2254         break;
2255     case 26:
2256        rn = "ECC";
2257        break;
2258     case 27:
2259         switch (sel) {
2260         /* ignored */
2261         case 0 ... 3:
2262             rn = "CacheErr";
2263             break;
2264         default:
2265             goto die;
2266         }
2267         break;
2268     case 28:
2269         switch (sel) {
2270         case 0:
2271         case 2:
2272         case 4:
2273         case 6:
2274             gen_op_mfc0_taglo();
2275             rn = "TagLo";
2276             break;
2277         case 1:
2278         case 3:
2279         case 5:
2280         case 7:
2281             gen_op_mfc0_datalo();
2282             rn = "DataLo";
2283             break;
2284         default:
2285             goto die;
2286         }
2287         break;
2288     case 29:
2289         switch (sel) {
2290         case 0:
2291         case 2:
2292         case 4:
2293         case 6:
2294             gen_op_mfc0_taghi();
2295             rn = "TagHi";
2296             break;
2297         case 1:
2298         case 3:
2299         case 5:
2300         case 7:
2301             gen_op_mfc0_datahi();
2302             rn = "DataHi";
2303             break;
2304         default:
2305             goto die;
2306         }
2307         break;
2308     case 30:
2309         switch (sel) {
2310         case 0:
2311             gen_op_mfc0_errorepc();
2312             rn = "ErrorEPC";
2313             break;
2314         default:
2315             goto die;
2316         }
2317         break;
2318     case 31:
2319         switch (sel) {
2320         case 0:
2321             gen_op_mfc0_desave(); /* EJTAG support */
2322             rn = "DESAVE";
2323             break;
2324         default:
2325             goto die;
2326         }
2327         break;
2328     default:
2329        goto die;
2330     }
2331 #if defined MIPS_DEBUG_DISAS
2332     if (loglevel & CPU_LOG_TB_IN_ASM) {
2333         fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2334                 rn, reg, sel);
2335     }
2336 #endif
2337     return;
2338
2339 die:
2340 #if defined MIPS_DEBUG_DISAS
2341     if (loglevel & CPU_LOG_TB_IN_ASM) {
2342         fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2343                 rn, reg, sel);
2344     }
2345 #endif
2346     generate_exception(ctx, EXCP_RI);
2347 }
2348
2349 static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2350 {
2351     const char *rn = "invalid";
2352
2353     switch (reg) {
2354     case 0:
2355         switch (sel) {
2356         case 0:
2357            gen_op_mtc0_index();
2358             rn = "Index";
2359             break;
2360         case 1:
2361 //            gen_op_mtc0_mvpcontrol(); /* MT ASE */
2362             rn = "MVPControl";
2363 //            break;
2364         case 2:
2365 //            gen_op_mtc0_mvpconf0(); /* MT ASE */
2366             rn = "MVPConf0";
2367 //            break;
2368         case 3:
2369 //            gen_op_mtc0_mvpconf1(); /* MT ASE */
2370             rn = "MVPConf1";
2371 //            break;
2372         default:
2373             goto die;
2374         }
2375         break;
2376     case 1:
2377         switch (sel) {
2378         case 0:
2379             /* ignored */
2380             rn = "Random";
2381             break;
2382         case 1:
2383 //            gen_op_mtc0_vpecontrol(); /* MT ASE */
2384             rn = "VPEControl";
2385 //            break;
2386         case 2:
2387 //            gen_op_mtc0_vpeconf0(); /* MT ASE */
2388             rn = "VPEConf0";
2389 //            break;
2390         case 3:
2391 //            gen_op_mtc0_vpeconf1(); /* MT ASE */
2392             rn = "VPEConf1";
2393 //            break;
2394         case 4:
2395 //            gen_op_mtc0_YQMask(); /* MT ASE */
2396             rn = "YQMask";
2397 //            break;
2398         case 5:
2399 //            gen_op_mtc0_vpeschedule(); /* MT ASE */
2400             rn = "VPESchedule";
2401 //            break;
2402         case 6:
2403 //            gen_op_mtc0_vpeschefback(); /* MT ASE */
2404             rn = "VPEScheFBack";
2405 //            break;
2406         case 7:
2407 //            gen_op_mtc0_vpeopt(); /* MT ASE */
2408             rn = "VPEOpt";
2409 //            break;
2410         default:
2411             goto die;
2412         }
2413         break;
2414     case 2:
2415         switch (sel) {
2416         case 0:
2417             gen_op_mtc0_entrylo0();
2418             rn = "EntryLo0";
2419             break;
2420         case 1:
2421 //            gen_op_mtc0_tcstatus(); /* MT ASE */
2422             rn = "TCStatus";
2423 //            break;
2424         case 2:
2425 //            gen_op_mtc0_tcbind(); /* MT ASE */
2426             rn = "TCBind";
2427 //            break;
2428         case 3:
2429 //            gen_op_mtc0_tcrestart(); /* MT ASE */
2430             rn = "TCRestart";
2431 //            break;
2432         case 4:
2433 //            gen_op_mtc0_tchalt(); /* MT ASE */
2434             rn = "TCHalt";
2435 //            break;
2436         case 5:
2437 //            gen_op_mtc0_tccontext(); /* MT ASE */
2438             rn = "TCContext";
2439 //            break;
2440         case 6:
2441 //            gen_op_mtc0_tcschedule(); /* MT ASE */
2442             rn = "TCSchedule";
2443 //            break;
2444         case 7:
2445 //            gen_op_mtc0_tcschefback(); /* MT ASE */
2446             rn = "TCScheFBack";
2447 //            break;
2448         default:
2449             goto die;
2450         }
2451         break;
2452     case 3:
2453         switch (sel) {
2454         case 0:
2455             gen_op_mtc0_entrylo1();
2456             rn = "EntryLo1";
2457             break;
2458         default:
2459             goto die;
2460         }
2461         break;
2462     case 4:
2463         switch (sel) {
2464         case 0:
2465             gen_op_mtc0_context();
2466             rn = "Context";
2467             break;
2468         case 1:
2469 //            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2470             rn = "ContextConfig";
2471 //            break;
2472         default:
2473             goto die;
2474         }
2475         break;
2476     case 5:
2477         switch (sel) {
2478         case 0:
2479             gen_op_mtc0_pagemask();
2480             rn = "PageMask";
2481             break;
2482         case 1:
2483             gen_op_mtc0_pagegrain();
2484             rn = "PageGrain";
2485             break;
2486         default:
2487             goto die;
2488         }
2489         break;
2490     case 6:
2491         switch (sel) {
2492         case 0:
2493             gen_op_mtc0_wired();
2494             rn = "Wired";
2495             break;
2496         case 1:
2497 //            gen_op_mtc0_srsconf0(); /* shadow registers */
2498             rn = "SRSConf0";
2499 //            break;
2500         case 2:
2501 //            gen_op_mtc0_srsconf1(); /* shadow registers */
2502             rn = "SRSConf1";
2503 //            break;
2504         case 3:
2505 //            gen_op_mtc0_srsconf2(); /* shadow registers */
2506             rn = "SRSConf2";
2507 //            break;
2508         case 4:
2509 //            gen_op_mtc0_srsconf3(); /* shadow registers */
2510             rn = "SRSConf3";
2511 //            break;
2512         case 5:
2513 //            gen_op_mtc0_srsconf4(); /* shadow registers */
2514             rn = "SRSConf4";
2515 //            break;
2516         default:
2517             goto die;
2518         }
2519         break;
2520     case 7:
2521         switch (sel) {
2522         case 0:
2523             gen_op_mtc0_hwrena();
2524             rn = "HWREna";
2525             break;
2526         default:
2527             goto die;
2528         }
2529         break;
2530     case 8:
2531         /* ignored */
2532         rn = "BadVaddr";
2533         break;
2534     case 9:
2535         switch (sel) {
2536         case 0:
2537             gen_op_mtc0_count();
2538             rn = "Count";
2539             break;
2540         /* 6,7 are implementation dependent */
2541         default:
2542             goto die;
2543         }
2544         /* Stop translation as we may have switched the execution mode */
2545         ctx->bstate = BS_STOP;
2546         break;
2547     case 10:
2548         switch (sel) {
2549         case 0:
2550             gen_op_mtc0_entryhi();
2551             rn = "EntryHi";
2552             break;
2553         default:
2554             goto die;
2555         }
2556         break;
2557     case 11:
2558         switch (sel) {
2559         case 0:
2560             gen_op_mtc0_compare();
2561             rn = "Compare";
2562             break;
2563         /* 6,7 are implementation dependent */
2564         default:
2565             goto die;
2566         }
2567         /* Stop translation as we may have switched the execution mode */
2568         ctx->bstate = BS_STOP;
2569         break;
2570     case 12:
2571         switch (sel) {
2572         case 0:
2573             gen_op_mtc0_status();
2574             rn = "Status";
2575             break;
2576         case 1:
2577             gen_op_mtc0_intctl();
2578             rn = "IntCtl";
2579             break;
2580         case 2:
2581             gen_op_mtc0_srsctl();
2582             rn = "SRSCtl";
2583             break;
2584         case 3:
2585 //            gen_op_mtc0_srsmap(); /* shadow registers */
2586             rn = "SRSMap";
2587 //            break;
2588         default:
2589             goto die;
2590         }
2591         /* Stop translation as we may have switched the execution mode */
2592         ctx->bstate = BS_STOP;
2593         break;
2594     case 13:
2595         switch (sel) {
2596         case 0:
2597             gen_op_mtc0_cause();
2598             rn = "Cause";
2599             break;
2600         default:
2601             goto die;
2602         }
2603         /* Stop translation as we may have switched the execution mode */
2604         ctx->bstate = BS_STOP;
2605         break;
2606     case 14:
2607         switch (sel) {
2608         case 0:
2609             gen_op_mtc0_epc();
2610             rn = "EPC";
2611             break;
2612         default:
2613             goto die;
2614         }
2615         break;
2616     case 15:
2617         switch (sel) {
2618         case 0:
2619             /* ignored */
2620             rn = "PRid";
2621             break;
2622         case 1:
2623             gen_op_mtc0_ebase();
2624             rn = "EBase";
2625             break;
2626         default:
2627             goto die;
2628         }
2629         break;
2630     case 16:
2631         switch (sel) {
2632         case 0:
2633             gen_op_mtc0_config0();
2634             rn = "Config";
2635             /* Stop translation as we may have switched the execution mode */
2636             ctx->bstate = BS_STOP;
2637             break;
2638         case 1:
2639             /* ignored, read only */
2640             rn = "Config1";
2641             break;
2642         case 2:
2643             gen_op_mtc0_config2();
2644             rn = "Config2";
2645             /* Stop translation as we may have switched the execution mode */
2646             ctx->bstate = BS_STOP;
2647             break;
2648         case 3:
2649             /* ignored, read only */
2650             rn = "Config3";
2651             break;
2652         /* 4,5 are reserved */
2653         /* 6,7 are implementation dependent */
2654         case 6:
2655             /* ignored */
2656             rn = "Config6";
2657             break;
2658         case 7:
2659             /* ignored */
2660             rn = "Config7";
2661             break;
2662         default:
2663             rn = "Invalid config selector";
2664             goto die;
2665         }
2666         break;
2667     case 17:
2668         switch (sel) {
2669         case 0:
2670             /* ignored */
2671             rn = "LLAddr";
2672             break;
2673         default:
2674             goto die;
2675         }
2676         break;
2677     case 18:
2678         switch (sel) {
2679         case 0:
2680             gen_op_mtc0_watchlo0();
2681             rn = "WatchLo";
2682             break;
2683         case 1:
2684 //            gen_op_mtc0_watchlo1();
2685             rn = "WatchLo1";
2686 //            break;
2687         case 2:
2688 //            gen_op_mtc0_watchlo2();
2689             rn = "WatchLo2";
2690 //            break;
2691         case 3:
2692 //            gen_op_mtc0_watchlo3();
2693             rn = "WatchLo3";
2694 //            break;
2695         case 4:
2696 //            gen_op_mtc0_watchlo4();
2697             rn = "WatchLo4";
2698 //            break;
2699         case 5:
2700 //            gen_op_mtc0_watchlo5();
2701             rn = "WatchLo5";
2702 //            break;
2703         case 6:
2704 //            gen_op_mtc0_watchlo6();
2705             rn = "WatchLo6";
2706 //            break;
2707         case 7:
2708 //            gen_op_mtc0_watchlo7();
2709             rn = "WatchLo7";
2710 //            break;
2711         default:
2712             goto die;
2713         }
2714         break;
2715     case 19:
2716         switch (sel) {
2717         case 0:
2718             gen_op_mtc0_watchhi0();
2719             rn = "WatchHi";
2720             break;
2721         case 1:
2722 //            gen_op_mtc0_watchhi1();
2723             rn = "WatchHi1";
2724 //            break;
2725         case 2:
2726 //            gen_op_mtc0_watchhi2();
2727             rn = "WatchHi2";
2728 //            break;
2729         case 3:
2730 //            gen_op_mtc0_watchhi3();
2731             rn = "WatchHi3";
2732 //            break;
2733         case 4:
2734 //            gen_op_mtc0_watchhi4();
2735             rn = "WatchHi4";
2736 //            break;
2737         case 5:
2738 //            gen_op_mtc0_watchhi5();
2739             rn = "WatchHi5";
2740 //            break;
2741         case 6:
2742 //            gen_op_mtc0_watchhi6();
2743             rn = "WatchHi6";
2744 //            break;
2745         case 7:
2746 //            gen_op_mtc0_watchhi7();
2747             rn = "WatchHi7";
2748 //            break;
2749         default:
2750             goto die;
2751         }
2752         break;
2753     case 20:
2754         switch (sel) {
2755         case 0:
2756             /* 64 bit MMU only */
2757             /* Nothing writable in lower 32 bits */
2758             rn = "XContext";
2759             break;
2760         default:
2761             goto die;
2762         }
2763         break;
2764     case 21:
2765        /* Officially reserved, but sel 0 is used for R1x000 framemask */
2766         switch (sel) {
2767         case 0:
2768             gen_op_mtc0_framemask();
2769             rn = "Framemask";
2770             break;
2771         default:
2772             goto die;
2773         }
2774         break;
2775     case 22:
2776         /* ignored */
2777         rn = "Diagnostic"; /* implementation dependent */
2778         break;
2779     case 23:
2780         switch (sel) {
2781         case 0:
2782             gen_op_mtc0_debug(); /* EJTAG support */
2783             rn = "Debug";
2784             break;
2785         case 1:
2786 //            gen_op_mtc0_tracecontrol(); /* PDtrace support */
2787             rn = "TraceControl";
2788 //            break;
2789         case 2:
2790 //            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2791             rn = "TraceControl2";
2792 //            break;
2793         case 3:
2794 //            gen_op_mtc0_usertracedata(); /* PDtrace support */
2795             rn = "UserTraceData";
2796 //            break;
2797         case 4:
2798 //            gen_op_mtc0_debug(); /* PDtrace support */
2799             rn = "TraceBPC";
2800 //            break;
2801         default:
2802             goto die;
2803         }
2804         /* Stop translation as we may have switched the execution mode */
2805         ctx->bstate = BS_STOP;
2806         break;
2807     case 24:
2808         switch (sel) {
2809         case 0:
2810             gen_op_mtc0_depc(); /* EJTAG support */
2811             rn = "DEPC";
2812             break;
2813         default:
2814             goto die;
2815         }
2816         break;
2817     case 25:
2818         switch (sel) {
2819         case 0:
2820             gen_op_mtc0_performance0();
2821             rn = "Performance0";
2822             break;
2823         case 1:
2824 //            gen_op_mtc0_performance1();
2825             rn = "Performance1";
2826 //            break;
2827         case 2:
2828 //            gen_op_mtc0_performance2();
2829             rn = "Performance2";
2830 //            break;
2831         case 3:
2832 //            gen_op_mtc0_performance3();
2833             rn = "Performance3";
2834 //            break;
2835         case 4:
2836 //            gen_op_mtc0_performance4();
2837             rn = "Performance4";
2838 //            break;
2839         case 5:
2840 //            gen_op_mtc0_performance5();
2841             rn = "Performance5";
2842 //            break;
2843         case 6:
2844 //            gen_op_mtc0_performance6();
2845             rn = "Performance6";
2846 //            break;
2847         case 7:
2848 //            gen_op_mtc0_performance7();
2849             rn = "Performance7";
2850 //            break;
2851         default:
2852             goto die;
2853         }
2854        break;
2855     case 26:
2856         /* ignored */
2857         rn = "ECC";
2858         break;
2859     case 27:
2860         switch (sel) {
2861         case 0 ... 3:
2862             /* ignored */
2863             rn = "CacheErr";
2864             break;
2865         default:
2866             goto die;
2867         }
2868        break;
2869     case 28:
2870         switch (sel) {
2871         case 0:
2872         case 2:
2873         case 4:
2874         case 6:
2875             gen_op_mtc0_taglo();
2876             rn = "TagLo";
2877             break;
2878         case 1:
2879         case 3:
2880         case 5:
2881         case 7:
2882             gen_op_mtc0_datalo();
2883             rn = "DataLo";
2884             break;
2885         default:
2886             goto die;
2887         }
2888         break;
2889     case 29:
2890         switch (sel) {
2891         case 0:
2892         case 2:
2893         case 4:
2894         case 6:
2895             gen_op_mtc0_taghi();
2896             rn = "TagHi";
2897             break;
2898         case 1:
2899         case 3:
2900         case 5:
2901         case 7:
2902             gen_op_mtc0_datahi();
2903             rn = "DataHi";
2904             break;
2905         default:
2906             rn = "invalid sel";
2907             goto die;
2908         }
2909        break;
2910     case 30:
2911         switch (sel) {
2912         case 0:
2913             gen_op_mtc0_errorepc();
2914             rn = "ErrorEPC";
2915             break;
2916         default:
2917             goto die;
2918         }
2919         break;
2920     case 31:
2921         switch (sel) {
2922         case 0:
2923             gen_op_mtc0_desave(); /* EJTAG support */
2924             rn = "DESAVE";
2925             break;
2926         default:
2927             goto die;
2928         }
2929         /* Stop translation as we may have switched the execution mode */
2930         ctx->bstate = BS_STOP;
2931         break;
2932     default:
2933        goto die;
2934     }
2935 #if defined MIPS_DEBUG_DISAS
2936     if (loglevel & CPU_LOG_TB_IN_ASM) {
2937         fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2938                 rn, reg, sel);
2939     }
2940 #endif
2941     return;
2942
2943 die:
2944 #if defined MIPS_DEBUG_DISAS
2945     if (loglevel & CPU_LOG_TB_IN_ASM) {
2946         fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2947                 rn, reg, sel);
2948     }
2949 #endif
2950     generate_exception(ctx, EXCP_RI);
2951 }
2952
2953 #ifdef TARGET_MIPS64
2954 static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2955 {
2956     const char *rn = "invalid";
2957
2958     switch (reg) {
2959     case 0:
2960         switch (sel) {
2961         case 0:
2962             gen_op_mfc0_index();
2963             rn = "Index";
2964             break;
2965         case 1:
2966 //            gen_op_dmfc0_mvpcontrol(); /* MT ASE */
2967             rn = "MVPControl";
2968 //            break;
2969         case 2:
2970 //            gen_op_dmfc0_mvpconf0(); /* MT ASE */
2971             rn = "MVPConf0";
2972 //            break;
2973         case 3:
2974 //            gen_op_dmfc0_mvpconf1(); /* MT ASE */
2975             rn = "MVPConf1";
2976 //            break;
2977         default:
2978             goto die;
2979         }
2980         break;
2981     case 1:
2982         switch (sel) {
2983         case 0:
2984             gen_op_mfc0_random();
2985             rn = "Random";
2986             break;
2987         case 1:
2988 //            gen_op_dmfc0_vpecontrol(); /* MT ASE */
2989             rn = "VPEControl";
2990 //            break;
2991         case 2:
2992 //            gen_op_dmfc0_vpeconf0(); /* MT ASE */
2993             rn = "VPEConf0";
2994 //            break;
2995         case 3:
2996 //            gen_op_dmfc0_vpeconf1(); /* MT ASE */
2997             rn = "VPEConf1";
2998 //            break;
2999         case 4:
3000 //            gen_op_dmfc0_YQMask(); /* MT ASE */
3001             rn = "YQMask";
3002 //            break;
3003         case 5:
3004 //            gen_op_dmfc0_vpeschedule(); /* MT ASE */
3005             rn = "VPESchedule";
3006 //            break;
3007         case 6:
3008 //            gen_op_dmfc0_vpeschefback(); /* MT ASE */
3009             rn = "VPEScheFBack";
3010 //            break;
3011         case 7:
3012 //            gen_op_dmfc0_vpeopt(); /* MT ASE */
3013             rn = "VPEOpt";
3014 //            break;
3015         default:
3016             goto die;
3017         }
3018         break;
3019     case 2:
3020         switch (sel) {
3021         case 0:
3022             gen_op_dmfc0_entrylo0();
3023             rn = "EntryLo0";
3024             break;
3025         case 1:
3026 //            gen_op_dmfc0_tcstatus(); /* MT ASE */
3027             rn = "TCStatus";
3028 //            break;
3029         case 2:
3030 //            gen_op_dmfc0_tcbind(); /* MT ASE */
3031             rn = "TCBind";
3032 //            break;
3033         case 3:
3034 //            gen_op_dmfc0_tcrestart(); /* MT ASE */
3035             rn = "TCRestart";
3036 //            break;
3037         case 4:
3038 //            gen_op_dmfc0_tchalt(); /* MT ASE */
3039             rn = "TCHalt";
3040 //            break;
3041         case 5:
3042 //            gen_op_dmfc0_tccontext(); /* MT ASE */
3043             rn = "TCContext";
3044 //            break;
3045         case 6:
3046 //            gen_op_dmfc0_tcschedule(); /* MT ASE */
3047             rn = "TCSchedule";
3048 //            break;
3049         case 7:
3050 //            gen_op_dmfc0_tcschefback(); /* MT ASE */
3051             rn = "TCScheFBack";
3052 //            break;
3053         default:
3054             goto die;
3055         }
3056         break;
3057     case 3:
3058         switch (sel) {
3059         case 0:
3060             gen_op_dmfc0_entrylo1();
3061             rn = "EntryLo1";
3062             break;
3063         default:
3064             goto die;
3065         }
3066         break;
3067     case 4:
3068         switch (sel) {
3069         case 0:
3070             gen_op_dmfc0_context();
3071             rn = "Context";
3072             break;
3073         case 1:
3074 //            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3075             rn = "ContextConfig";
3076 //            break;
3077         default:
3078             goto die;
3079         }
3080         break;
3081     case 5:
3082         switch (sel) {
3083         case 0:
3084             gen_op_mfc0_pagemask();
3085             rn = "PageMask";
3086             break;
3087         case 1:
3088             gen_op_mfc0_pagegrain();
3089             rn = "PageGrain";
3090             break;
3091         default:
3092             goto die;
3093         }
3094         break;
3095     case 6:
3096         switch (sel) {
3097         case 0:
3098             gen_op_mfc0_wired();
3099             rn = "Wired";
3100             break;
3101         case 1:
3102 //            gen_op_dmfc0_srsconf0(); /* shadow registers */
3103             rn = "SRSConf0";
3104 //            break;
3105         case 2:
3106 //            gen_op_dmfc0_srsconf1(); /* shadow registers */
3107             rn = "SRSConf1";
3108 //            break;
3109         case 3:
3110 //            gen_op_dmfc0_srsconf2(); /* shadow registers */
3111             rn = "SRSConf2";
3112 //            break;
3113         case 4:
3114 //            gen_op_dmfc0_srsconf3(); /* shadow registers */
3115             rn = "SRSConf3";
3116 //            break;
3117         case 5:
3118 //            gen_op_dmfc0_srsconf4(); /* shadow registers */
3119             rn = "SRSConf4";
3120 //            break;
3121         default:
3122             goto die;
3123         }
3124         break;
3125     case 7:
3126         switch (sel) {
3127         case 0:
3128             gen_op_mfc0_hwrena();
3129             rn = "HWREna";
3130             break;
3131         default:
3132             goto die;
3133         }
3134         break;
3135     case 8:
3136         switch (sel) {
3137         case 0:
3138             gen_op_dmfc0_badvaddr();
3139             rn = "BadVaddr";
3140             break;
3141         default:
3142             goto die;
3143         }
3144         break;
3145     case 9:
3146         switch (sel) {
3147         case 0:
3148             gen_op_mfc0_count();
3149             rn = "Count";
3150             break;
3151         /* 6,7 are implementation dependent */
3152         default:
3153             goto die;
3154         }
3155         break;
3156     case 10:
3157         switch (sel) {
3158         case 0:
3159             gen_op_dmfc0_entryhi();
3160             rn = "EntryHi";
3161             break;
3162         default:
3163             goto die;
3164         }
3165         break;
3166     case 11:
3167         switch (sel) {
3168         case 0:
3169             gen_op_mfc0_compare();
3170             rn = "Compare";
3171             break;
3172         /* 6,7 are implementation dependent */
3173         default:
3174             goto die;
3175         }
3176         break;
3177     case 12:
3178         switch (sel) {
3179         case 0:
3180             gen_op_mfc0_status();
3181             rn = "Status";
3182             break;
3183         case 1:
3184             gen_op_mfc0_intctl();
3185             rn = "IntCtl";
3186             break;
3187         case 2:
3188             gen_op_mfc0_srsctl();
3189             rn = "SRSCtl";
3190             break;
3191         case 3:
3192             gen_op_mfc0_srsmap(); /* shadow registers */
3193             rn = "SRSMap";
3194             break;
3195         default:
3196             goto die;
3197         }
3198         break;
3199     case 13:
3200         switch (sel) {
3201         case 0:
3202             gen_op_mfc0_cause();
3203             rn = "Cause";
3204             break;
3205         default:
3206             goto die;
3207         }
3208         break;
3209     case 14:
3210         switch (sel) {
3211         case 0:
3212             gen_op_dmfc0_epc();
3213             rn = "EPC";
3214             break;
3215         default:
3216             goto die;
3217         }
3218         break;
3219     case 15:
3220         switch (sel) {
3221         case 0:
3222             gen_op_mfc0_prid();
3223             rn = "PRid";
3224             break;
3225         case 1:
3226             gen_op_mfc0_ebase();
3227             rn = "EBase";
3228             break;
3229         default:
3230             goto die;
3231         }
3232         break;
3233     case 16:
3234         switch (sel) {
3235         case 0:
3236             gen_op_mfc0_config0();
3237             rn = "Config";
3238             break;
3239         case 1:
3240             gen_op_mfc0_config1();
3241             rn = "Config1";
3242             break;
3243         case 2:
3244             gen_op_mfc0_config2();
3245             rn = "Config2";
3246             break;
3247         case 3:
3248             gen_op_mfc0_config3();
3249             rn = "Config3";
3250             break;
3251        /* 6,7 are implementation dependent */
3252         default:
3253             goto die;
3254         }
3255         break;
3256     case 17:
3257         switch (sel) {
3258         case 0:
3259             gen_op_dmfc0_lladdr();
3260             rn = "LLAddr";
3261             break;
3262         default:
3263             goto die;
3264         }
3265         break;
3266     case 18:
3267         switch (sel) {
3268         case 0:
3269             gen_op_dmfc0_watchlo0();
3270             rn = "WatchLo";
3271             break;
3272         case 1:
3273 //            gen_op_dmfc0_watchlo1();
3274             rn = "WatchLo1";
3275 //            break;
3276         case 2:
3277 //            gen_op_dmfc0_watchlo2();
3278             rn = "WatchLo2";
3279 //            break;
3280         case 3:
3281 //            gen_op_dmfc0_watchlo3();
3282             rn = "WatchLo3";
3283 //            break;
3284         case 4:
3285 //            gen_op_dmfc0_watchlo4();
3286             rn = "WatchLo4";
3287 //            break;
3288         case 5:
3289 //            gen_op_dmfc0_watchlo5();
3290             rn = "WatchLo5";
3291 //            break;
3292         case 6:
3293 //            gen_op_dmfc0_watchlo6();
3294             rn = "WatchLo6";
3295 //            break;
3296         case 7:
3297 //            gen_op_dmfc0_watchlo7();
3298             rn = "WatchLo7";
3299 //            break;
3300         default:
3301             goto die;
3302         }
3303         break;
3304     case 19:
3305         switch (sel) {
3306         case 0:
3307             gen_op_mfc0_watchhi0();
3308             rn = "WatchHi";
3309             break;
3310         case 1:
3311 //            gen_op_mfc0_watchhi1();
3312             rn = "WatchHi1";
3313 //            break;
3314         case 2:
3315 //            gen_op_mfc0_watchhi2();
3316             rn = "WatchHi2";
3317 //            break;
3318         case 3:
3319 //            gen_op_mfc0_watchhi3();
3320             rn = "WatchHi3";
3321 //            break;
3322         case 4:
3323 //            gen_op_mfc0_watchhi4();
3324             rn = "WatchHi4";
3325 //            break;
3326         case 5:
3327 //            gen_op_mfc0_watchhi5();
3328             rn = "WatchHi5";
3329 //            break;
3330         case 6:
3331 //            gen_op_mfc0_watchhi6();
3332             rn = "WatchHi6";
3333 //            break;
3334         case 7:
3335 //            gen_op_mfc0_watchhi7();
3336             rn = "WatchHi7";
3337 //            break;
3338         default:
3339             goto die;
3340         }
3341         break;
3342     case 20:
3343         switch (sel) {
3344         case 0:
3345             /* 64 bit MMU only */
3346             gen_op_dmfc0_xcontext();
3347             rn = "XContext";
3348             break;
3349         default:
3350             goto die;
3351         }
3352         break;
3353     case 21:
3354        /* Officially reserved, but sel 0 is used for R1x000 framemask */
3355         switch (sel) {
3356         case 0:
3357             gen_op_mfc0_framemask();
3358             rn = "Framemask";
3359             break;
3360         default:
3361             goto die;
3362         }
3363         break;
3364     case 22:
3365         /* ignored */
3366         rn = "'Diagnostic"; /* implementation dependent */
3367         break;
3368     case 23:
3369         switch (sel) {
3370         case 0:
3371             gen_op_mfc0_debug(); /* EJTAG support */
3372             rn = "Debug";
3373             break;
3374         case 1:
3375 //            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3376             rn = "TraceControl";
3377 //            break;
3378         case 2:
3379 //            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3380             rn = "TraceControl2";
3381 //            break;
3382         case 3:
3383 //            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3384             rn = "UserTraceData";
3385 //            break;
3386         case 4:
3387 //            gen_op_dmfc0_debug(); /* PDtrace support */
3388             rn = "TraceBPC";
3389 //            break;
3390         default:
3391             goto die;
3392         }
3393         break;
3394     case 24:
3395         switch (sel) {
3396         case 0:
3397             gen_op_dmfc0_depc(); /* EJTAG support */
3398             rn = "DEPC";
3399             break;
3400         default:
3401             goto die;
3402         }
3403         break;
3404     case 25:
3405         switch (sel) {
3406         case 0:
3407             gen_op_mfc0_performance0();
3408             rn = "Performance0";
3409             break;
3410         case 1:
3411 //            gen_op_dmfc0_performance1();
3412             rn = "Performance1";
3413 //            break;
3414         case 2:
3415 //            gen_op_dmfc0_performance2();
3416             rn = "Performance2";
3417 //            break;
3418         case 3:
3419 //            gen_op_dmfc0_performance3();
3420             rn = "Performance3";
3421 //            break;
3422         case 4:
3423 //            gen_op_dmfc0_performance4();
3424             rn = "Performance4";
3425 //            break;
3426         case 5:
3427 //            gen_op_dmfc0_performance5();
3428             rn = "Performance5";
3429 //            break;
3430         case 6:
3431 //            gen_op_dmfc0_performance6();
3432             rn = "Performance6";
3433 //            break;
3434         case 7:
3435 //            gen_op_dmfc0_performance7();
3436             rn = "Performance7";
3437 //            break;
3438         default:
3439             goto die;
3440         }
3441         break;
3442     case 26:
3443        rn = "ECC";
3444        break;
3445     case 27:
3446         switch (sel) {
3447         /* ignored */
3448         case 0 ... 3:
3449             rn = "CacheErr";
3450             break;
3451         default:
3452             goto die;
3453         }
3454         break;
3455     case 28:
3456         switch (sel) {
3457         case 0:
3458         case 2:
3459         case 4:
3460         case 6:
3461             gen_op_mfc0_taglo();
3462             rn = "TagLo";
3463             break;
3464         case 1:
3465         case 3:
3466         case 5:
3467         case 7:
3468             gen_op_mfc0_datalo();
3469             rn = "DataLo";
3470             break;
3471         default:
3472             goto die;
3473         }
3474         break;
3475     case 29:
3476         switch (sel) {
3477         case 0:
3478         case 2:
3479         case 4:
3480         case 6:
3481             gen_op_mfc0_taghi();
3482             rn = "TagHi";
3483             break;
3484         case 1:
3485         case 3:
3486         case 5:
3487         case 7:
3488             gen_op_mfc0_datahi();
3489             rn = "DataHi";
3490             break;
3491         default:
3492             goto die;
3493         }
3494         break;
3495     case 30:
3496         switch (sel) {
3497         case 0:
3498             gen_op_dmfc0_errorepc();
3499             rn = "ErrorEPC";
3500             break;
3501         default:
3502             goto die;
3503         }
3504         break;
3505     case 31:
3506         switch (sel) {
3507         case 0:
3508             gen_op_mfc0_desave(); /* EJTAG support */
3509             rn = "DESAVE";
3510             break;
3511         default:
3512             goto die;
3513         }
3514         break;
3515     default:
3516         goto die;
3517     }
3518 #if defined MIPS_DEBUG_DISAS
3519     if (loglevel & CPU_LOG_TB_IN_ASM) {
3520         fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3521                 rn, reg, sel);
3522     }
3523 #endif
3524     return;
3525
3526 die:
3527 #if defined MIPS_DEBUG_DISAS
3528     if (loglevel & CPU_LOG_TB_IN_ASM) {
3529         fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3530                 rn, reg, sel);
3531     }
3532 #endif
3533     generate_exception(ctx, EXCP_RI);
3534 }
3535
3536 static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3537 {
3538     const char *rn = "invalid";
3539
3540     switch (reg) {
3541     case 0:
3542         switch (sel) {
3543         case 0:
3544             gen_op_mtc0_index();
3545             rn = "Index";
3546             break;
3547         case 1:
3548 //            gen_op_dmtc0_mvpcontrol(); /* MT ASE */
3549             rn = "MVPControl";
3550 //            break;
3551         case 2:
3552 //            gen_op_dmtc0_mvpconf0(); /* MT ASE */
3553             rn = "MVPConf0";
3554 //            break;
3555         case 3:
3556 //            gen_op_dmtc0_mvpconf1(); /* MT ASE */
3557             rn = "MVPConf1";
3558 //            break;
3559         default:
3560             goto die;
3561         }
3562         break;
3563     case 1:
3564         switch (sel) {
3565         case 0:
3566             /* ignored */
3567             rn = "Random";
3568             break;
3569         case 1:
3570 //            gen_op_dmtc0_vpecontrol(); /* MT ASE */
3571             rn = "VPEControl";
3572 //            break;
3573         case 2:
3574 //            gen_op_dmtc0_vpeconf0(); /* MT ASE */
3575             rn = "VPEConf0";
3576 //            break;
3577         case 3:
3578 //            gen_op_dmtc0_vpeconf1(); /* MT ASE */
3579             rn = "VPEConf1";
3580 //            break;
3581         case 4:
3582 //            gen_op_dmtc0_YQMask(); /* MT ASE */
3583             rn = "YQMask";
3584 //            break;
3585         case 5:
3586 //            gen_op_dmtc0_vpeschedule(); /* MT ASE */
3587             rn = "VPESchedule";
3588 //            break;
3589         case 6:
3590 //            gen_op_dmtc0_vpeschefback(); /* MT ASE */
3591             rn = "VPEScheFBack";
3592 //            break;
3593         case 7:
3594 //            gen_op_dmtc0_vpeopt(); /* MT ASE */
3595             rn = "VPEOpt";
3596 //            break;
3597         default:
3598             goto die;
3599         }
3600         break;
3601     case 2:
3602         switch (sel) {
3603         case 0:
3604             gen_op_dmtc0_entrylo0();
3605             rn = "EntryLo0";
3606             break;
3607         case 1:
3608 //            gen_op_dmtc0_tcstatus(); /* MT ASE */
3609             rn = "TCStatus";
3610 //            break;
3611         case 2:
3612 //            gen_op_dmtc0_tcbind(); /* MT ASE */
3613             rn = "TCBind";
3614 //            break;
3615         case 3:
3616 //            gen_op_dmtc0_tcrestart(); /* MT ASE */
3617             rn = "TCRestart";
3618 //            break;
3619         case 4:
3620 //            gen_op_dmtc0_tchalt(); /* MT ASE */
3621             rn = "TCHalt";
3622 //            break;
3623         case 5:
3624 //            gen_op_dmtc0_tccontext(); /* MT ASE */
3625             rn = "TCContext";
3626 //            break;
3627         case 6:
3628 //            gen_op_dmtc0_tcschedule(); /* MT ASE */
3629             rn = "TCSchedule";
3630 //            break;
3631         case 7:
3632 //            gen_op_dmtc0_tcschefback(); /* MT ASE */
3633             rn = "TCScheFBack";
3634 //            break;
3635         default:
3636             goto die;
3637         }
3638         break;
3639     case 3:
3640         switch (sel) {
3641         case 0:
3642             gen_op_dmtc0_entrylo1();
3643             rn = "EntryLo1";
3644             break;
3645         default:
3646             goto die;
3647         }
3648         break;
3649     case 4:
3650         switch (sel) {
3651         case 0:
3652             gen_op_dmtc0_context();
3653             rn = "Context";
3654             break;
3655         case 1:
3656 //           gen_op_dmtc0_contextconfig(); /* SmartMIPS ASE */
3657             rn = "ContextConfig";
3658 //           break;
3659         default:
3660             goto die;
3661         }
3662         break;
3663     case 5:
3664         switch (sel) {
3665         case 0:
3666             gen_op_mtc0_pagemask();
3667             rn = "PageMask";
3668             break;
3669         case 1:
3670             gen_op_mtc0_pagegrain();
3671             rn = "PageGrain";
3672             break;
3673         default:
3674             goto die;
3675         }
3676         break;
3677     case 6:
3678         switch (sel) {
3679         case 0:
3680             gen_op_mtc0_wired();
3681             rn = "Wired";
3682             break;
3683         case 1:
3684 //            gen_op_dmtc0_srsconf0(); /* shadow registers */
3685             rn = "SRSConf0";
3686 //            break;
3687         case 2:
3688 //            gen_op_dmtc0_srsconf1(); /* shadow registers */
3689             rn = "SRSConf1";
3690 //            break;
3691         case 3:
3692 //            gen_op_dmtc0_srsconf2(); /* shadow registers */
3693             rn = "SRSConf2";
3694 //            break;
3695         case 4:
3696 //            gen_op_dmtc0_srsconf3(); /* shadow registers */
3697             rn = "SRSConf3";
3698 //            break;
3699         case 5:
3700 //            gen_op_dmtc0_srsconf4(); /* shadow registers */
3701             rn = "SRSConf4";
3702 //            break;
3703         default:
3704             goto die;
3705         }
3706         break;
3707     case 7:
3708         switch (sel) {
3709         case 0:
3710             gen_op_mtc0_hwrena();
3711             rn = "HWREna";
3712             break;
3713         default:
3714             goto die;
3715         }
3716         break;
3717     case 8:
3718         /* ignored */
3719         rn = "BadVaddr";
3720         break;
3721     case 9:
3722         switch (sel) {
3723         case 0:
3724             gen_op_mtc0_count();
3725             rn = "Count";
3726             break;
3727         /* 6,7 are implementation dependent */
3728         default:
3729             goto die;
3730         }
3731         /* Stop translation as we may have switched the execution mode */
3732         ctx->bstate = BS_STOP;
3733         break;
3734     case 10:
3735         switch (sel) {
3736         case 0:
3737             gen_op_mtc0_entryhi();
3738             rn = "EntryHi";
3739             break;
3740         default:
3741             goto die;
3742         }
3743         break;
3744     case 11:
3745         switch (sel) {
3746         case 0:
3747             gen_op_mtc0_compare();
3748             rn = "Compare";
3749             break;
3750         /* 6,7 are implementation dependent */
3751         default:
3752             goto die;
3753         }
3754         /* Stop translation as we may have switched the execution mode */
3755         ctx->bstate = BS_STOP;
3756         break;
3757     case 12:
3758         switch (sel) {
3759         case 0:
3760             gen_op_mtc0_status();
3761             rn = "Status";
3762             break;
3763         case 1:
3764             gen_op_mtc0_intctl();
3765             rn = "IntCtl";
3766             break;
3767         case 2:
3768             gen_op_mtc0_srsctl();
3769             rn = "SRSCtl";
3770             break;
3771         case 3:
3772             gen_op_mtc0_srsmap(); /* shadow registers */
3773             rn = "SRSMap";
3774             break;
3775         default:
3776             goto die;
3777         }
3778         /* Stop translation as we may have switched the execution mode */
3779         ctx->bstate = BS_STOP;
3780         break;
3781     case 13:
3782         switch (sel) {
3783         case 0:
3784             gen_op_mtc0_cause();
3785             rn = "Cause";
3786             break;
3787         default:
3788             goto die;
3789         }
3790         /* Stop translation as we may have switched the execution mode */
3791         ctx->bstate = BS_STOP;
3792         break;
3793     case 14:
3794         switch (sel) {
3795         case 0:
3796             gen_op_dmtc0_epc();
3797             rn = "EPC";
3798             break;
3799         default:
3800             goto die;
3801         }
3802         break;
3803     case 15:
3804         switch (sel) {
3805         case 0:
3806             /* ignored */
3807             rn = "PRid";
3808             break;
3809         case 1:
3810             gen_op_mtc0_ebase();
3811             rn = "EBase";
3812             break;
3813         default:
3814             goto die;
3815         }
3816         break;
3817     case 16:
3818         switch (sel) {
3819         case 0:
3820             gen_op_mtc0_config0();
3821             rn = "Config";
3822             /* Stop translation as we may have switched the execution mode */
3823             ctx->bstate = BS_STOP;
3824             break;
3825         case 1:
3826             /* ignored */
3827             rn = "Config1";
3828             break;
3829         case 2:
3830             gen_op_mtc0_config2();
3831             rn = "Config2";
3832             /* Stop translation as we may have switched the execution mode */
3833             ctx->bstate = BS_STOP;
3834             break;
3835         case 3:
3836             /* ignored */
3837             rn = "Config3";
3838             break;
3839         /* 6,7 are implementation dependent */
3840         default:
3841             rn = "Invalid config selector";
3842             goto die;
3843         }
3844         break;
3845     case 17:
3846         switch (sel) {
3847         case 0:
3848             /* ignored */
3849             rn = "LLAddr";
3850             break;
3851         default:
3852             goto die;
3853         }
3854         break;
3855     case 18:
3856         switch (sel) {
3857         case 0:
3858             gen_op_dmtc0_watchlo0();
3859             rn = "WatchLo";
3860             break;
3861         case 1:
3862 //            gen_op_dmtc0_watchlo1();
3863             rn = "WatchLo1";
3864 //            break;
3865         case 2:
3866 //            gen_op_dmtc0_watchlo2();
3867             rn = "WatchLo2";
3868 //            break;
3869         case 3:
3870 //            gen_op_dmtc0_watchlo3();
3871             rn = "WatchLo3";
3872 //            break;
3873         case 4:
3874 //            gen_op_dmtc0_watchlo4();
3875             rn = "WatchLo4";
3876 //            break;
3877         case 5:
3878 //            gen_op_dmtc0_watchlo5();
3879             rn = "WatchLo5";
3880 //            break;
3881         case 6:
3882 //            gen_op_dmtc0_watchlo6();
3883             rn = "WatchLo6";
3884 //            break;
3885         case 7:
3886 //            gen_op_dmtc0_watchlo7();
3887             rn = "WatchLo7";
3888 //            break;
3889         default:
3890             goto die;
3891         }
3892         break;
3893     case 19:
3894         switch (sel) {
3895         case 0:
3896             gen_op_mtc0_watchhi0();
3897             rn = "WatchHi";
3898             break;
3899         case 1:
3900 //            gen_op_dmtc0_watchhi1();
3901             rn = "WatchHi1";
3902 //            break;
3903         case 2:
3904 //            gen_op_dmtc0_watchhi2();
3905             rn = "WatchHi2";
3906 //            break;
3907         case 3:
3908 //            gen_op_dmtc0_watchhi3();
3909             rn = "WatchHi3";
3910 //            break;
3911         case 4:
3912 //            gen_op_dmtc0_watchhi4();
3913             rn = "WatchHi4";
3914 //            break;
3915         case 5:
3916 //            gen_op_dmtc0_watchhi5();
3917             rn = "WatchHi5";
3918 //            break;
3919         case 6:
3920 //            gen_op_dmtc0_watchhi6();
3921             rn = "WatchHi6";
3922 //            break;
3923         case 7:
3924 //            gen_op_dmtc0_watchhi7();
3925             rn = "WatchHi7";
3926 //            break;
3927         default:
3928             goto die;
3929         }
3930         break;
3931     case 20:
3932         switch (sel) {
3933         case 0:
3934             /* 64 bit MMU only */
3935             gen_op_dmtc0_xcontext();
3936             rn = "XContext";
3937             break;
3938         default:
3939             goto die;
3940         }
3941         break;
3942     case 21:
3943        /* Officially reserved, but sel 0 is used for R1x000 framemask */
3944         switch (sel) {
3945         case 0:
3946             gen_op_mtc0_framemask();
3947             rn = "Framemask";
3948             break;
3949         default:
3950             goto die;
3951         }
3952         break;
3953     case 22:
3954         /* ignored */
3955         rn = "Diagnostic"; /* implementation dependent */
3956         break;
3957     case 23:
3958         switch (sel) {
3959         case 0:
3960             gen_op_mtc0_debug(); /* EJTAG support */
3961             rn = "Debug";
3962             break;
3963         case 1:
3964 //            gen_op_dmtc0_tracecontrol(); /* PDtrace support */
3965             rn = "TraceControl";
3966 //            break;
3967         case 2:
3968 //            gen_op_dmtc0_tracecontrol2(); /* PDtrace support */
3969             rn = "TraceControl2";
3970 //            break;
3971         case 3:
3972 //            gen_op_dmtc0_usertracedata(); /* PDtrace support */
3973             rn = "UserTraceData";
3974 //            break;
3975         case 4:
3976 //            gen_op_dmtc0_debug(); /* PDtrace support */
3977             rn = "TraceBPC";
3978 //            break;
3979         default:
3980             goto die;
3981         }
3982         /* Stop translation as we may have switched the execution mode */
3983         ctx->bstate = BS_STOP;
3984         break;
3985     case 24:
3986         switch (sel) {
3987         case 0:
3988             gen_op_dmtc0_depc(); /* EJTAG support */
3989             rn = "DEPC";
3990             break;
3991         default:
3992             goto die;
3993         }
3994         break;
3995     case 25:
3996         switch (sel) {
3997         case 0:
3998             gen_op_mtc0_performance0();
3999             rn = "Performance0";
4000             break;
4001         case 1:
4002 //            gen_op_dmtc0_performance1();
4003             rn = "Performance1";
4004 //            break;
4005         case 2:
4006 //            gen_op_dmtc0_performance2();
4007             rn = "Performance2";
4008 //            break;
4009         case 3:
4010 //            gen_op_dmtc0_performance3();
4011             rn = "Performance3";
4012 //            break;
4013         case 4:
4014 //            gen_op_dmtc0_performance4();
4015             rn = "Performance4";
4016 //            break;
4017         case 5:
4018 //            gen_op_dmtc0_performance5();
4019             rn = "Performance5";
4020 //            break;
4021         case 6:
4022 //            gen_op_dmtc0_performance6();
4023             rn = "Performance6";
4024 //            break;
4025         case 7:
4026 //            gen_op_dmtc0_performance7();
4027             rn = "Performance7";
4028 //            break;
4029         default:
4030             goto die;
4031         }
4032         break;
4033     case 26:
4034         /* ignored */
4035         rn = "ECC";
4036         break;
4037     case 27:
4038         switch (sel) {
4039         case 0 ... 3:
4040             /* ignored */
4041             rn = "CacheErr";
4042             break;
4043         default:
4044             goto die;
4045         }
4046         break;
4047     case 28:
4048         switch (sel) {
4049         case 0:
4050         case 2:
4051         case 4:
4052         case 6:
4053             gen_op_mtc0_taglo();
4054             rn = "TagLo";
4055             break;
4056         case 1:
4057         case 3:
4058         case 5:
4059         case 7:
4060             gen_op_mtc0_datalo();
4061             rn = "DataLo";
4062             break;
4063         default:
4064             goto die;
4065         }
4066         break;
4067     case 29:
4068         switch (sel) {
4069         case 0:
4070         case 2:
4071         case 4:
4072         case 6:
4073             gen_op_mtc0_taghi();
4074             rn = "TagHi";
4075             break;
4076         case 1:
4077         case 3:
4078         case 5:
4079         case 7:
4080             gen_op_mtc0_datahi();
4081             rn = "DataHi";
4082             break;
4083         default:
4084             rn = "invalid sel";
4085             goto die;
4086         }
4087         break;
4088     case 30:
4089         switch (sel) {
4090         case 0:
4091             gen_op_dmtc0_errorepc();
4092             rn = "ErrorEPC";
4093             break;
4094         default:
4095             goto die;
4096         }
4097         break;
4098     case 31:
4099         switch (sel) {
4100         case 0:
4101             gen_op_mtc0_desave(); /* EJTAG support */
4102             rn = "DESAVE";
4103             break;
4104         default:
4105             goto die;
4106         }
4107         /* Stop translation as we may have switched the execution mode */
4108         ctx->bstate = BS_STOP;
4109         break;
4110     default:
4111         goto die;
4112     }
4113 #if defined MIPS_DEBUG_DISAS
4114     if (loglevel & CPU_LOG_TB_IN_ASM) {
4115         fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4116                 rn, reg, sel);
4117     }
4118 #endif
4119     return;
4120
4121 die:
4122 #if defined MIPS_DEBUG_DISAS
4123     if (loglevel & CPU_LOG_TB_IN_ASM) {
4124         fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4125                 rn, reg, sel);
4126     }
4127 #endif
4128     generate_exception(ctx, EXCP_RI);
4129 }
4130 #endif /* TARGET_MIPS64 */
4131
4132 static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
4133 {
4134     const char *opn = "unk";
4135
4136     switch (opc) {
4137     case OPC_MFC0:
4138         if (rt == 0) {
4139             /* Treat as NOP */
4140             return;
4141         }
4142         gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4143         gen_op_store_T0_gpr(rt);
4144         opn = "mfc0";
4145         break;
4146     case OPC_MTC0:
4147         GEN_LOAD_REG_TN(T0, rt);
4148         gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4149         opn = "mtc0";
4150         break;
4151 #ifdef TARGET_MIPS64
4152     case OPC_DMFC0:
4153         if (rt == 0) {
4154             /* Treat as NOP */
4155             return;
4156         }
4157         gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4158         gen_op_store_T0_gpr(rt);
4159         opn = "dmfc0";
4160         break;
4161     case OPC_DMTC0:
4162         GEN_LOAD_REG_TN(T0, rt);
4163         gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4164         opn = "dmtc0";
4165         break;
4166 #endif
4167 #if defined(MIPS_USES_R4K_TLB)
4168     case OPC_TLBWI:
4169         gen_op_tlbwi();
4170         opn = "tlbwi";
4171         break;
4172     case OPC_TLBWR:
4173         gen_op_tlbwr();
4174         opn = "tlbwr";
4175         break;
4176     case OPC_TLBP:
4177         gen_op_tlbp();
4178         opn = "tlbp";
4179         break;
4180     case OPC_TLBR:
4181         gen_op_tlbr();
4182         opn = "tlbr";
4183         break;
4184 #endif
4185     case OPC_ERET:
4186         opn = "eret";
4187         save_cpu_state(ctx, 0);
4188         gen_op_eret();
4189         ctx->bstate = BS_EXCP;
4190         break;
4191     case OPC_DERET:
4192         opn = "deret";
4193         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4194             generate_exception(ctx, EXCP_RI);
4195         } else {
4196             save_cpu_state(ctx, 0);
4197             gen_op_deret();
4198             ctx->bstate = BS_EXCP;
4199         }
4200         break;
4201     case OPC_WAIT:
4202         opn = "wait";
4203         /* If we get an exception, we want to restart at next instruction */
4204         ctx->pc += 4;
4205         save_cpu_state(ctx, 1);
4206         ctx->pc -= 4;
4207         gen_op_wait();
4208         ctx->bstate = BS_EXCP;
4209         break;
4210     default:
4211         if (loglevel & CPU_LOG_TB_IN_ASM) {
4212             fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
4213                     ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4214                     ((ctx->opcode >> 16) & 0x1F));
4215         }
4216         generate_exception(ctx, EXCP_RI);
4217         return;
4218     }
4219     MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4220 }
4221
4222 /* CP1 Branches (before delay slot) */
4223 static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4224                                  int32_t offset)
4225 {
4226     target_ulong btarget;
4227
4228     btarget = ctx->pc + 4 + offset;
4229
4230     switch (op) {
4231     case OPC_BC1F:
4232         gen_op_bc1f();
4233         MIPS_DEBUG("bc1f " TARGET_FMT_lx, btarget);
4234         goto not_likely;
4235     case OPC_BC1FL:
4236         gen_op_bc1f();
4237         MIPS_DEBUG("bc1fl " TARGET_FMT_lx, btarget);
4238         goto likely;
4239     case OPC_BC1T:
4240         gen_op_bc1t();
4241         MIPS_DEBUG("bc1t " TARGET_FMT_lx, btarget);
4242     not_likely:
4243         ctx->hflags |= MIPS_HFLAG_BC;
4244         break;
4245     case OPC_BC1TL:
4246         gen_op_bc1t();
4247         MIPS_DEBUG("bc1tl " TARGET_FMT_lx, btarget);
4248     likely:
4249         ctx->hflags |= MIPS_HFLAG_BL;
4250         break;
4251     default:    
4252         MIPS_INVAL("cp1 branch/jump");
4253         generate_exception (ctx, EXCP_RI);
4254         return;
4255     }
4256     gen_op_set_bcond();
4257
4258     MIPS_DEBUG("enter ds: cond %02x target " TARGET_FMT_lx,
4259                ctx->hflags, btarget);
4260     ctx->btarget = btarget;
4261
4262     return;
4263 }
4264
4265 /* Coprocessor 1 (FPU) */
4266 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4267 {
4268     const char *opn = "unk";
4269
4270     switch (opc) {
4271     case OPC_MFC1:
4272         GEN_LOAD_FREG_FTN(WT0, fs);
4273         gen_op_mfc1();
4274         GEN_STORE_TN_REG(rt, T0);
4275         opn = "mfc1";
4276         break;
4277     case OPC_MTC1:
4278         GEN_LOAD_REG_TN(T0, rt);
4279         gen_op_mtc1();
4280         GEN_STORE_FTN_FREG(fs, WT0);
4281         opn = "mtc1";
4282         break;
4283     case OPC_CFC1:
4284         if (fs != 0 && fs != 31) {
4285             MIPS_INVAL("cfc1 freg");
4286             generate_exception (ctx, EXCP_RI);
4287             return;
4288         }
4289         GEN_LOAD_IMM_TN(T1, fs);
4290         gen_op_cfc1();
4291         GEN_STORE_TN_REG(rt, T0);
4292         opn = "cfc1";
4293         break;
4294     case OPC_CTC1:
4295          if (fs != 0 && fs != 31) {
4296             MIPS_INVAL("ctc1 freg");
4297             generate_exception (ctx, EXCP_RI);
4298             return;
4299         }
4300         GEN_LOAD_IMM_TN(T1, fs);
4301         GEN_LOAD_REG_TN(T0, rt);
4302         gen_op_ctc1();
4303         opn = "ctc1";
4304         break;
4305     case OPC_DMFC1:
4306     case OPC_DMTC1:
4307         /* Not implemented, fallthrough. */
4308     default:
4309         if (loglevel & CPU_LOG_TB_IN_ASM) {
4310             fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
4311                     ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4312                     ((ctx->opcode >> 16) & 0x1F));
4313         }
4314         generate_exception (ctx, EXCP_RI);
4315         return;
4316     }
4317     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4318 }
4319
4320 /* verify if floating point register is valid; an operation is not defined
4321  * if bit 0 of any register specification is set and the FR bit in the
4322  * Status register equals zero, since the register numbers specify an
4323  * even-odd pair of adjacent coprocessor general registers. When the FR bit
4324  * in the Status register equals one, both even and odd register numbers
4325  * are valid. This limitation exists only for 64 bit wide (d,l) registers.
4326  * 
4327  * Multiple 64 bit wide registers can be checked by calling
4328  * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
4329  */
4330 #define CHECK_FR(ctx, freg) do { \
4331         if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \
4332             generate_exception (ctx, EXCP_RI); \
4333             return; \
4334         } \
4335     } while(0)
4336
4337 #define FOP(func, fmt) (((fmt) << 21) | (func))
4338
4339 static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
4340 {
4341     const char *opn = "unk";
4342     const char *condnames[] = {
4343             "c.f",
4344             "c.un",
4345             "c.eq",
4346             "c.ueq",
4347             "c.olt",
4348             "c.ult",
4349             "c.ole",
4350             "c.ule",
4351             "c.sf",
4352             "c.ngle",
4353             "c.seq",
4354             "c.ngl",
4355             "c.lt",
4356             "c.nge",
4357             "c.le",
4358             "c.ngt",
4359     };
4360     int binary = 0;
4361     uint32_t func = ctx->opcode & 0x3f;
4362
4363     switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4364     case FOP(0, 17):
4365         CHECK_FR(ctx, fs | ft | fd);
4366         GEN_LOAD_FREG_FTN(DT0, fs);
4367         GEN_LOAD_FREG_FTN(DT1, ft);
4368         gen_op_float_add_d();
4369         GEN_STORE_FTN_FREG(fd, DT2);
4370         opn = "add.d";
4371         binary = 1;
4372         break;
4373     case FOP(1, 17):
4374         CHECK_FR(ctx, fs | ft | fd);
4375         GEN_LOAD_FREG_FTN(DT0, fs);
4376         GEN_LOAD_FREG_FTN(DT1, ft);
4377         gen_op_float_sub_d();
4378         GEN_STORE_FTN_FREG(fd, DT2);
4379         opn = "sub.d";
4380         binary = 1;
4381         break;
4382     case FOP(2, 17):
4383         CHECK_FR(ctx, fs | ft | fd);
4384         GEN_LOAD_FREG_FTN(DT0, fs);
4385         GEN_LOAD_FREG_FTN(DT1, ft);
4386         gen_op_float_mul_d();
4387         GEN_STORE_FTN_FREG(fd, DT2);
4388         opn = "mul.d";
4389         binary = 1;
4390         break;
4391     case FOP(3, 17):
4392         CHECK_FR(ctx, fs | ft | fd);
4393         GEN_LOAD_FREG_FTN(DT0, fs);
4394         GEN_LOAD_FREG_FTN(DT1, ft);
4395         gen_op_float_div_d();
4396         GEN_STORE_FTN_FREG(fd, DT2);
4397         opn = "div.d";
4398         binary = 1;
4399         break;
4400     case FOP(4, 17):
4401         CHECK_FR(ctx, fs | fd);
4402         GEN_LOAD_FREG_FTN(DT0, fs);
4403         gen_op_float_sqrt_d();
4404         GEN_STORE_FTN_FREG(fd, DT2);
4405         opn = "sqrt.d";
4406         break;
4407     case FOP(5, 17):
4408         CHECK_FR(ctx, fs | fd);
4409         GEN_LOAD_FREG_FTN(DT0, fs);
4410         gen_op_float_abs_d();
4411         GEN_STORE_FTN_FREG(fd, DT2);
4412         opn = "abs.d";
4413         break;
4414     case FOP(6, 17):
4415         CHECK_FR(ctx, fs | fd);
4416         GEN_LOAD_FREG_FTN(DT0, fs);
4417         gen_op_float_mov_d();
4418         GEN_STORE_FTN_FREG(fd, DT2);
4419         opn = "mov.d";
4420         break;
4421     case FOP(7, 17):
4422         CHECK_FR(ctx, fs | fd);
4423         GEN_LOAD_FREG_FTN(DT0, fs);
4424         gen_op_float_chs_d();
4425         GEN_STORE_FTN_FREG(fd, DT2);
4426         opn = "neg.d";
4427         break;
4428     /*  8 - round.l */
4429     /*  9 - trunc.l */
4430     /* 10 - ceil.l  */
4431     /* 11 - floor.l */
4432     case FOP(12, 17):
4433         CHECK_FR(ctx, fs);
4434         GEN_LOAD_FREG_FTN(DT0, fs);
4435         gen_op_float_roundw_d();
4436         GEN_STORE_FTN_FREG(fd, WT2);
4437         opn = "round.w.d";
4438         break;
4439     case FOP(13, 17):
4440         CHECK_FR(ctx, fs);
4441         GEN_LOAD_FREG_FTN(DT0, fs);
4442         gen_op_float_truncw_d();
4443         GEN_STORE_FTN_FREG(fd, WT2);
4444         opn = "trunc.w.d";
4445         break;
4446     case FOP(14, 17):
4447         CHECK_FR(ctx, fs);
4448         GEN_LOAD_FREG_FTN(DT0, fs);
4449         gen_op_float_ceilw_d();
4450         GEN_STORE_FTN_FREG(fd, WT2);
4451         opn = "ceil.w.d";
4452         break;
4453     case FOP(15, 17):
4454         CHECK_FR(ctx, fs);
4455         GEN_LOAD_FREG_FTN(DT0, fs);
4456         gen_op_float_floorw_d();
4457         GEN_STORE_FTN_FREG(fd, WT2);
4458         opn = "floor.w.d";
4459         break;
4460     case FOP(33, 16):
4461         CHECK_FR(ctx, fd);
4462         GEN_LOAD_FREG_FTN(WT0, fs);
4463         gen_op_float_cvtd_s();
4464         GEN_STORE_FTN_FREG(fd, DT2);
4465         opn = "cvt.d.s";
4466         break;
4467     case FOP(33, 20):
4468         CHECK_FR(ctx, fd);
4469         GEN_LOAD_FREG_FTN(WT0, fs);
4470         gen_op_float_cvtd_w();
4471         GEN_STORE_FTN_FREG(fd, DT2);
4472         opn = "cvt.d.w";
4473         break;
4474     case FOP(48, 17):
4475     case FOP(49, 17):
4476     case FOP(50, 17):
4477     case FOP(51, 17):
4478     case FOP(52, 17):
4479     case FOP(53, 17):
4480     case FOP(54, 17):
4481     case FOP(55, 17):
4482     case FOP(56, 17):
4483     case FOP(57, 17):
4484     case FOP(58, 17):
4485     case FOP(59, 17):
4486     case FOP(60, 17):
4487     case FOP(61, 17):
4488     case FOP(62, 17):
4489     case FOP(63, 17):
4490         CHECK_FR(ctx, fs | ft);
4491         GEN_LOAD_FREG_FTN(DT0, fs);
4492         GEN_LOAD_FREG_FTN(DT1, ft);
4493         gen_cmp_d(func-48);
4494         opn = condnames[func-48];
4495         break;
4496     case FOP(0, 16):
4497         GEN_LOAD_FREG_FTN(WT0, fs);
4498         GEN_LOAD_FREG_FTN(WT1, ft);
4499         gen_op_float_add_s();
4500         GEN_STORE_FTN_FREG(fd, WT2);
4501         opn = "add.s";
4502         binary = 1;
4503         break;
4504     case FOP(1, 16):
4505         GEN_LOAD_FREG_FTN(WT0, fs);
4506         GEN_LOAD_FREG_FTN(WT1, ft);
4507         gen_op_float_sub_s();
4508         GEN_STORE_FTN_FREG(fd, WT2);
4509         opn = "sub.s";
4510         binary = 1;
4511         break;
4512     case FOP(2, 16):
4513         GEN_LOAD_FREG_FTN(WT0, fs);
4514         GEN_LOAD_FREG_FTN(WT1, ft);
4515         gen_op_float_mul_s();
4516         GEN_STORE_FTN_FREG(fd, WT2);
4517         opn = "mul.s";
4518         binary = 1;
4519         break;
4520     case FOP(3, 16):
4521         GEN_LOAD_FREG_FTN(WT0, fs);
4522         GEN_LOAD_FREG_FTN(WT1, ft);
4523         gen_op_float_div_s();
4524         GEN_STORE_FTN_FREG(fd, WT2);
4525         opn = "div.s";
4526         binary = 1;
4527         break;
4528     case FOP(4, 16):
4529         GEN_LOAD_FREG_FTN(WT0, fs);
4530         gen_op_float_sqrt_s();
4531         GEN_STORE_FTN_FREG(fd, WT2);
4532         opn = "sqrt.s";
4533         break;
4534     case FOP(5, 16):
4535         GEN_LOAD_FREG_FTN(WT0, fs);
4536         gen_op_float_abs_s();
4537         GEN_STORE_FTN_FREG(fd, WT2);
4538         opn = "abs.s";
4539         break;
4540     case FOP(6, 16):
4541         GEN_LOAD_FREG_FTN(WT0, fs);
4542         gen_op_float_mov_s();
4543         GEN_STORE_FTN_FREG(fd, WT2);
4544         opn = "mov.s";
4545         break;
4546     case FOP(7, 16):
4547         GEN_LOAD_FREG_FTN(WT0, fs);
4548         gen_op_float_chs_s();
4549         GEN_STORE_FTN_FREG(fd, WT2);
4550         opn = "neg.s";
4551         break;
4552     case FOP(12, 16):
4553         GEN_LOAD_FREG_FTN(WT0, fs);
4554         gen_op_float_roundw_s();
4555         GEN_STORE_FTN_FREG(fd, WT2);
4556         opn = "round.w.s";
4557         break;
4558     case FOP(13, 16):
4559         GEN_LOAD_FREG_FTN(WT0, fs);
4560         gen_op_float_truncw_s();
4561         GEN_STORE_FTN_FREG(fd, WT2);
4562         opn = "trunc.w.s";
4563         break;
4564     case FOP(32, 17):
4565         CHECK_FR(ctx, fs);
4566         GEN_LOAD_FREG_FTN(DT0, fs);
4567         gen_op_float_cvts_d();
4568         GEN_STORE_FTN_FREG(fd, WT2);
4569         opn = "cvt.s.d";
4570         break;
4571     case FOP(32, 20):
4572         GEN_LOAD_FREG_FTN(WT0, fs);
4573         gen_op_float_cvts_w();
4574         GEN_STORE_FTN_FREG(fd, WT2);
4575         opn = "cvt.s.w";
4576         break;
4577     case FOP(36, 16):
4578         GEN_LOAD_FREG_FTN(WT0, fs);
4579         gen_op_float_cvtw_s();
4580         GEN_STORE_FTN_FREG(fd, WT2);
4581         opn = "cvt.w.s";
4582         break;
4583     case FOP(36, 17):
4584         CHECK_FR(ctx, fs);
4585         GEN_LOAD_FREG_FTN(DT0, fs);
4586         gen_op_float_cvtw_d();
4587         GEN_STORE_FTN_FREG(fd, WT2);
4588         opn = "cvt.w.d";
4589         break;
4590     case FOP(48, 16):
4591     case FOP(49, 16):
4592     case FOP(50, 16):
4593     case FOP(51, 16):
4594     case FOP(52, 16):
4595     case FOP(53, 16):
4596     case FOP(54, 16):
4597     case FOP(55, 16):
4598     case FOP(56, 16):
4599     case FOP(57, 16):
4600     case FOP(58, 16):
4601     case FOP(59, 16):
4602     case FOP(60, 16):
4603     case FOP(61, 16):
4604     case FOP(62, 16):
4605     case FOP(63, 16):
4606         GEN_LOAD_FREG_FTN(WT0, fs);
4607         GEN_LOAD_FREG_FTN(WT1, ft);
4608         gen_cmp_s(func-48);
4609         opn = condnames[func-48];
4610         break;
4611     default:    
4612         if (loglevel & CPU_LOG_TB_IN_ASM) {
4613             fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
4614                     ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
4615                     ((ctx->opcode >> 16) & 0x1F));
4616         }
4617         generate_exception (ctx, EXCP_RI);
4618         return;
4619     }
4620     if (binary)
4621         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
4622     else
4623         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
4624 }
4625
4626 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4627 {
4628     uint32_t ccbit;
4629
4630     if (cc)
4631         ccbit = 1 << (24 + cc);
4632     else
4633         ccbit = 1 << 23;
4634     if (!tf)
4635         gen_op_movf(ccbit, rd, rs);
4636     else
4637        gen_op_movt(ccbit, rd, rs);
4638 }
4639
4640 /* ISA extensions (ASEs) */
4641 /* MIPS16 extension to MIPS32 */
4642 /* SmartMIPS extension to MIPS32 */
4643
4644 #ifdef TARGET_MIPS64
4645 /* Coprocessor 3 (FPU) */
4646
4647 /* MDMX extension to MIPS64 */
4648 /* MIPS-3D extension to MIPS64 */
4649
4650 #endif
4651
4652 static void gen_blikely(DisasContext *ctx)
4653 {
4654     int l1;
4655     l1 = gen_new_label();
4656     gen_op_jnz_T2(l1);
4657     gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
4658     gen_goto_tb(ctx, 1, ctx->pc + 4);
4659     gen_set_label(l1);
4660 }
4661
4662 static void decode_opc (CPUState *env, DisasContext *ctx)
4663 {
4664     int32_t offset;
4665     int rs, rt, rd, sa;
4666     uint32_t op, op1, op2;
4667     int16_t imm;
4668
4669     /* make sure instructions are on a word boundary */
4670     if (ctx->pc & 0x3) {
4671         env->CP0_BadVAddr = ctx->pc;
4672         generate_exception(ctx, EXCP_AdEL);
4673         return;
4674     }
4675
4676     if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
4677         /* Handle blikely not taken case */
4678         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
4679         gen_blikely(ctx);
4680     }
4681     op = MASK_OP_MAJOR(ctx->opcode);
4682     rs = (ctx->opcode >> 21) & 0x1f;
4683     rt = (ctx->opcode >> 16) & 0x1f;
4684     rd = (ctx->opcode >> 11) & 0x1f;
4685     sa = (ctx->opcode >> 6) & 0x1f;
4686     imm = (int16_t)ctx->opcode;
4687     switch (op) {
4688     case OPC_SPECIAL:
4689         op1 = MASK_SPECIAL(ctx->opcode);
4690         switch (op1) {
4691         case OPC_SLL:          /* Arithmetic with immediate */
4692         case OPC_SRL ... OPC_SRA:
4693             gen_arith_imm(ctx, op1, rd, rt, sa);
4694             break;
4695         case OPC_SLLV:         /* Arithmetic */
4696         case OPC_SRLV ... OPC_SRAV:
4697         case OPC_MOVZ ... OPC_MOVN:
4698         case OPC_ADD ... OPC_NOR:
4699         case OPC_SLT ... OPC_SLTU:
4700             gen_arith(ctx, op1, rd, rs, rt);
4701             break;
4702         case OPC_MULT ... OPC_DIVU:
4703             gen_muldiv(ctx, op1, rs, rt);
4704             break;
4705         case OPC_JR ... OPC_JALR:
4706             gen_compute_branch(ctx, op1, rs, rd, sa);
4707             return;
4708         case OPC_TGE ... OPC_TEQ: /* Traps */
4709         case OPC_TNE:
4710             gen_trap(ctx, op1, rs, rt, -1);
4711             break;
4712         case OPC_MFHI:          /* Move from HI/LO */
4713         case OPC_MFLO:
4714             gen_HILO(ctx, op1, rd);
4715             break;
4716         case OPC_MTHI:
4717         case OPC_MTLO:          /* Move to HI/LO */
4718             gen_HILO(ctx, op1, rs);
4719             break;
4720         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
4721 #ifdef MIPS_STRICT_STANDARD
4722             MIPS_INVAL("PMON / selsl");
4723             generate_exception(ctx, EXCP_RI);
4724 #else
4725             gen_op_pmon(sa);
4726 #endif
4727             break;
4728         case OPC_SYSCALL:
4729             generate_exception(ctx, EXCP_SYSCALL);
4730             break;
4731         case OPC_BREAK:
4732             generate_exception(ctx, EXCP_BREAK);
4733             break;
4734         case OPC_SPIM:
4735 #ifdef MIPS_STRICT_STANDARD
4736             MIPS_INVAL("SPIM");
4737             generate_exception(ctx, EXCP_RI);
4738 #else
4739            /* Implemented as RI exception for now. */
4740             MIPS_INVAL("spim (unofficial)");
4741             generate_exception(ctx, EXCP_RI);
4742 #endif
4743             break;
4744         case OPC_SYNC:
4745             /* Treat as a noop. */
4746             break;
4747
4748         case OPC_MOVCI:
4749             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
4750                 save_cpu_state(ctx, 1);
4751                 gen_op_cp1_enabled();
4752                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
4753                           (ctx->opcode >> 16) & 1);
4754             } else {
4755                 generate_exception_err(ctx, EXCP_CpU, 1);
4756             }
4757             break;
4758
4759 #ifdef TARGET_MIPS64
4760        /* MIPS64 specific opcodes */
4761         case OPC_DSLL:
4762         case OPC_DSRL ... OPC_DSRA:
4763         case OPC_DSLL32:
4764         case OPC_DSRL32 ... OPC_DSRA32:
4765             gen_arith_imm(ctx, op1, rd, rt, sa);
4766             break;
4767         case OPC_DSLLV:
4768         case OPC_DSRLV ... OPC_DSRAV:
4769         case OPC_DADD ... OPC_DSUBU:
4770             gen_arith(ctx, op1, rd, rs, rt);
4771             break;
4772         case OPC_DMULT ... OPC_DDIVU:
4773             gen_muldiv(ctx, op1, rs, rt);
4774             break;
4775 #endif
4776         default:            /* Invalid */
4777             MIPS_INVAL("special");
4778             generate_exception(ctx, EXCP_RI);
4779             break;
4780         }
4781         break;
4782     case OPC_SPECIAL2:
4783         op1 = MASK_SPECIAL2(ctx->opcode);
4784         switch (op1) {
4785         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
4786         case OPC_MSUB ... OPC_MSUBU:
4787             gen_muldiv(ctx, op1, rs, rt);
4788             break;
4789         case OPC_MUL:
4790             gen_arith(ctx, op1, rd, rs, rt);
4791             break;
4792         case OPC_CLZ ... OPC_CLO:
4793             gen_cl(ctx, op1, rd, rs);
4794             break;
4795         case OPC_SDBBP:
4796             /* XXX: not clear which exception should be raised
4797              *      when in debug mode...
4798              */
4799             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4800                 generate_exception(ctx, EXCP_DBp);
4801             } else {
4802                 generate_exception(ctx, EXCP_DBp);
4803             }
4804             /* Treat as a noop */
4805             break;
4806 #ifdef TARGET_MIPS64
4807         case OPC_DCLZ ... OPC_DCLO:
4808             gen_cl(ctx, op1, rd, rs);
4809             break;
4810 #endif
4811         default:            /* Invalid */
4812             MIPS_INVAL("special2");
4813             generate_exception(ctx, EXCP_RI);
4814             break;
4815         }
4816         break;
4817     case OPC_SPECIAL3:
4818          op1 = MASK_SPECIAL3(ctx->opcode);
4819          switch (op1) {
4820          case OPC_EXT:
4821          case OPC_INS:
4822              gen_bitops(ctx, op1, rt, rs, sa, rd);
4823              break;
4824          case OPC_BSHFL:
4825              op2 = MASK_BSHFL(ctx->opcode);
4826              switch (op2) {
4827              case OPC_WSBH:
4828                  GEN_LOAD_REG_TN(T1, rt);
4829                  gen_op_wsbh();
4830                  break;
4831              case OPC_SEB:
4832                  GEN_LOAD_REG_TN(T1, rt);
4833                  gen_op_seb();
4834                  break;
4835              case OPC_SEH:
4836                  GEN_LOAD_REG_TN(T1, rt);
4837                  gen_op_seh();
4838                  break;
4839              default:            /* Invalid */
4840                  MIPS_INVAL("bshfl");
4841                  generate_exception(ctx, EXCP_RI);
4842                  break;
4843             }
4844             GEN_STORE_TN_REG(rd, T0);
4845             break;
4846         case OPC_RDHWR:
4847             switch (rd) {
4848             case 0:
4849                 save_cpu_state(ctx, 1);
4850                 gen_op_rdhwr_cpunum();
4851                 break;
4852             case 1:
4853                 save_cpu_state(ctx, 1);
4854                 gen_op_rdhwr_synci_step();
4855                 break;
4856             case 2:
4857                 save_cpu_state(ctx, 1);
4858                 gen_op_rdhwr_cc();
4859                 break;
4860             case 3:
4861                 save_cpu_state(ctx, 1);
4862                 gen_op_rdhwr_ccres();
4863                 break;
4864             case 29:
4865 #if defined (CONFIG_USER_ONLY)
4866                 gen_op_tls_value ();
4867                 break;
4868 #endif
4869             default:            /* Invalid */
4870                 MIPS_INVAL("rdhwr");
4871                 generate_exception(ctx, EXCP_RI);
4872                 break;
4873             }
4874             GEN_STORE_TN_REG(rt, T0);
4875             break;
4876 #ifdef TARGET_MIPS64
4877         case OPC_DEXTM ... OPC_DEXT:
4878         case OPC_DINSM ... OPC_DINS:
4879             gen_bitops(ctx, op1, rt, rs, sa, rd);
4880             break;
4881         case OPC_DBSHFL:
4882             op2 = MASK_DBSHFL(ctx->opcode);
4883             switch (op2) {
4884             case OPC_DSBH:
4885                 GEN_LOAD_REG_TN(T1, rt);
4886                 gen_op_dsbh();
4887                 break;
4888             case OPC_DSHD:
4889                 GEN_LOAD_REG_TN(T1, rt);
4890                 gen_op_dshd();
4891                 break;
4892             default:            /* Invalid */
4893                 MIPS_INVAL("dbshfl");
4894                 generate_exception(ctx, EXCP_RI);
4895                 break;
4896             }
4897             GEN_STORE_TN_REG(rd, T0);
4898 #endif
4899         default:            /* Invalid */
4900             MIPS_INVAL("special3");
4901             generate_exception(ctx, EXCP_RI);
4902             break;
4903         }
4904         break;
4905     case OPC_REGIMM:
4906         op1 = MASK_REGIMM(ctx->opcode);
4907         switch (op1) {
4908         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
4909         case OPC_BLTZAL ... OPC_BGEZALL:
4910             gen_compute_branch(ctx, op1, rs, -1, imm << 2);
4911             return;
4912         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
4913         case OPC_TNEI:
4914             gen_trap(ctx, op1, rs, -1, imm);
4915             break;
4916         case OPC_SYNCI:
4917             /* treat as noop */
4918             break;
4919         default:            /* Invalid */
4920             MIPS_INVAL("REGIMM");
4921             generate_exception(ctx, EXCP_RI);
4922             break;
4923         }
4924         break;
4925     case OPC_CP0:
4926         save_cpu_state(ctx, 1);
4927         gen_op_cp0_enabled();
4928         op1 = MASK_CP0(ctx->opcode);
4929         switch (op1) {
4930         case OPC_MFC0:
4931         case OPC_MTC0:
4932 #ifdef TARGET_MIPS64
4933         case OPC_DMFC0:
4934         case OPC_DMTC0:
4935 #endif
4936             gen_cp0(ctx, op1, rt, rd);
4937             break;
4938         case OPC_C0_FIRST ... OPC_C0_LAST:
4939             gen_cp0(ctx, MASK_C0(ctx->opcode), rt, rd);
4940             break;
4941         case OPC_MFMC0:
4942             op2 = MASK_MFMC0(ctx->opcode);
4943             switch (op2) {
4944             case OPC_DI:
4945                 gen_op_di();
4946                 /* Stop translation as we may have switched the execution mode */
4947                 ctx->bstate = BS_STOP;
4948                 break;
4949             case OPC_EI:
4950                 gen_op_ei();
4951                 /* Stop translation as we may have switched the execution mode */
4952                 ctx->bstate = BS_STOP;
4953                 break;
4954             default:            /* Invalid */
4955                 MIPS_INVAL("MFMC0");
4956                 generate_exception(ctx, EXCP_RI);
4957                 break;
4958             }
4959             GEN_STORE_TN_REG(rt, T0);
4960             break;
4961         case OPC_RDPGPR:
4962         case OPC_WRPGPR:
4963             if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
4964                 /* Shadow registers not implemented. */
4965                 GEN_LOAD_REG_TN(T0, rt);
4966                 GEN_STORE_TN_REG(rd, T0);
4967             } else
4968                 generate_exception(ctx, EXCP_RI);
4969             break;
4970         default:
4971             generate_exception(ctx, EXCP_RI);
4972             break;
4973         }
4974         break;
4975     case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
4976          gen_arith_imm(ctx, op, rt, rs, imm);
4977          break;
4978     case OPC_J ... OPC_JAL: /* Jump */
4979          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
4980          gen_compute_branch(ctx, op, rs, rt, offset);
4981          return;
4982     case OPC_BEQ ... OPC_BGTZ: /* Branch */
4983     case OPC_BEQL ... OPC_BGTZL:
4984          gen_compute_branch(ctx, op, rs, rt, imm << 2);
4985          return;
4986     case OPC_LB ... OPC_LWR: /* Load and stores */
4987     case OPC_SB ... OPC_SW:
4988     case OPC_SWR:
4989     case OPC_LL:
4990     case OPC_SC:
4991          gen_ldst(ctx, op, rt, rs, imm);
4992          break;
4993     case OPC_CACHE:
4994          /* Treat as a noop */
4995          break;
4996     case OPC_PREF:
4997         /* Treat as a noop */
4998         break;
4999
5000     /* Floating point.  */
5001     case OPC_LWC1:
5002     case OPC_LDC1:
5003     case OPC_SWC1:
5004     case OPC_SDC1:
5005         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5006             save_cpu_state(ctx, 1);
5007             gen_op_cp1_enabled();
5008             gen_flt_ldst(ctx, op, rt, rs, imm);
5009         } else {
5010             generate_exception_err(ctx, EXCP_CpU, 1);
5011         }
5012         break;
5013
5014     case OPC_CP1:
5015         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5016             save_cpu_state(ctx, 1);
5017             gen_op_cp1_enabled();
5018             op1 = MASK_CP1(ctx->opcode);
5019             switch (op1) {
5020             case OPC_MFC1:
5021             case OPC_CFC1:
5022             case OPC_MTC1:
5023             case OPC_CTC1:
5024 #ifdef TARGET_MIPS64
5025             case OPC_DMFC1:
5026             case OPC_DMTC1:
5027 #endif
5028                 gen_cp1(ctx, op1, rt, rd);
5029                 break;
5030             case OPC_BC1:
5031                 gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
5032                 return;
5033             case OPC_S_FMT:
5034             case OPC_D_FMT:
5035             case OPC_W_FMT:
5036             case OPC_L_FMT:
5037                 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
5038                 break;
5039             default:
5040                 generate_exception (ctx, EXCP_RI);
5041                 break;
5042             }
5043         } else {
5044             generate_exception_err(ctx, EXCP_CpU, 1);
5045         }
5046         break;
5047
5048     /* COP2.  */
5049     case OPC_LWC2:
5050     case OPC_LDC2:
5051     case OPC_SWC2:
5052     case OPC_SDC2:
5053     case OPC_CP2:
5054         /* COP2: Not implemented. */
5055         generate_exception_err(ctx, EXCP_CpU, 2);
5056         break;
5057
5058     case OPC_CP3:
5059         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5060             save_cpu_state(ctx, 1);
5061             gen_op_cp1_enabled();
5062             op1 = MASK_CP3(ctx->opcode);
5063             switch (op1) {
5064             case OPC_PREFX:
5065                 /* treat as noop */
5066                 break;
5067             /* Not implemented */
5068             default:
5069                 generate_exception (ctx, EXCP_RI);
5070                 break;
5071             }
5072         } else {
5073             generate_exception_err(ctx, EXCP_CpU, 1);
5074         }
5075         break;
5076
5077 #ifdef TARGET_MIPS64
5078     /* MIPS64 opcodes */
5079     case OPC_LWU:
5080     case OPC_LDL ... OPC_LDR:
5081     case OPC_SDL ... OPC_SDR:
5082     case OPC_LLD:
5083     case OPC_LD:
5084     case OPC_SCD:
5085     case OPC_SD:
5086         gen_ldst(ctx, op, rt, rs, imm);
5087         break;
5088     case OPC_DADDI ... OPC_DADDIU:
5089         gen_arith_imm(ctx, op, rt, rs, imm);
5090         break;
5091 #endif
5092 #ifdef MIPS_HAS_MIPS16
5093     case OPC_JALX:
5094         /* MIPS16: Not implemented. */
5095 #endif
5096 #ifdef MIPS_HAS_MDMX
5097     case OPC_MDMX:
5098         /* MDMX: Not implemented. */
5099 #endif
5100     default:            /* Invalid */
5101         MIPS_INVAL("");
5102         generate_exception(ctx, EXCP_RI);
5103         break;
5104     }
5105     if (ctx->hflags & MIPS_HFLAG_BMASK) {
5106         int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5107         /* Branches completion */
5108         ctx->hflags &= ~MIPS_HFLAG_BMASK;
5109         ctx->bstate = BS_BRANCH;
5110         save_cpu_state(ctx, 0);
5111         switch (hflags & MIPS_HFLAG_BMASK) {
5112         case MIPS_HFLAG_B:
5113             /* unconditional branch */
5114             MIPS_DEBUG("unconditional branch");
5115             gen_goto_tb(ctx, 0, ctx->btarget);
5116             break;
5117         case MIPS_HFLAG_BL:
5118             /* blikely taken case */
5119             MIPS_DEBUG("blikely branch taken");
5120             gen_goto_tb(ctx, 0, ctx->btarget);
5121             break;
5122         case MIPS_HFLAG_BC:
5123             /* Conditional branch */
5124             MIPS_DEBUG("conditional branch");
5125             {
5126               int l1;
5127               l1 = gen_new_label();
5128               gen_op_jnz_T2(l1);
5129               gen_goto_tb(ctx, 1, ctx->pc + 4);
5130               gen_set_label(l1);
5131               gen_goto_tb(ctx, 0, ctx->btarget);
5132             }
5133             break;
5134         case MIPS_HFLAG_BR:
5135             /* unconditional branch to register */
5136             MIPS_DEBUG("branch to register");
5137             gen_op_breg();
5138             break;
5139         default:
5140             MIPS_DEBUG("unknown branch");
5141             break;
5142         }
5143     }
5144 }
5145
5146 static inline int
5147 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5148                                 int search_pc)
5149 {
5150     DisasContext ctx, *ctxp = &ctx;
5151     target_ulong pc_start;
5152     uint16_t *gen_opc_end;
5153     int j, lj = -1;
5154
5155     if (search_pc && loglevel)
5156         fprintf (logfile, "search pc %d\n", search_pc);
5157
5158     pc_start = tb->pc;
5159     gen_opc_ptr = gen_opc_buf;
5160     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5161     gen_opparam_ptr = gen_opparam_buf;
5162     nb_gen_labels = 0;
5163     ctx.pc = pc_start;
5164     ctx.saved_pc = -1;
5165     ctx.tb = tb;
5166     ctx.bstate = BS_NONE;
5167     /* Restore delay slot state from the tb context.  */
5168     ctx.hflags = tb->flags;
5169     ctx.saved_hflags = ctx.hflags;
5170     if (ctx.hflags & MIPS_HFLAG_BR) {
5171         gen_op_restore_breg_target();
5172     } else if (ctx.hflags & MIPS_HFLAG_B) {
5173         ctx.btarget = env->btarget;
5174     } else if (ctx.hflags & MIPS_HFLAG_BMASK) {
5175         /* If we are in the delay slot of a conditional branch,
5176          * restore the branch condition from env->bcond to T2
5177          */
5178         ctx.btarget = env->btarget;
5179         gen_op_restore_bcond();
5180     }
5181 #if defined(CONFIG_USER_ONLY)
5182     ctx.mem_idx = 0;
5183 #else
5184     ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5185 #endif
5186     ctx.CP0_Status = env->CP0_Status;
5187 #ifdef DEBUG_DISAS
5188     if (loglevel & CPU_LOG_TB_CPU) {
5189         fprintf(logfile, "------------------------------------------------\n");
5190         /* FIXME: This may print out stale hflags from env... */
5191         cpu_dump_state(env, logfile, fprintf, 0);
5192     }
5193 #endif
5194 #if defined MIPS_DEBUG_DISAS
5195     if (loglevel & CPU_LOG_TB_IN_ASM)
5196         fprintf(logfile, "\ntb %p super %d cond %04x\n",
5197                 tb, ctx.mem_idx, ctx.hflags);
5198 #endif
5199     while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5200         if (env->nb_breakpoints > 0) {
5201             for(j = 0; j < env->nb_breakpoints; j++) {
5202                 if (env->breakpoints[j] == ctx.pc) {
5203                     save_cpu_state(ctxp, 1);
5204                     ctx.bstate = BS_BRANCH;
5205                     gen_op_debug();
5206                     goto done_generating;
5207                 }
5208             }
5209         }
5210
5211         if (search_pc) {
5212             j = gen_opc_ptr - gen_opc_buf;
5213             if (lj < j) {
5214                 lj++;
5215                 while (lj < j)
5216                     gen_opc_instr_start[lj++] = 0;
5217             }
5218             gen_opc_pc[lj] = ctx.pc;
5219             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5220             gen_opc_instr_start[lj] = 1;
5221         }
5222         ctx.opcode = ldl_code(ctx.pc);
5223         decode_opc(env, &ctx);
5224         ctx.pc += 4;
5225
5226         if (env->singlestep_enabled)
5227             break;
5228
5229         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5230             break;
5231
5232 #if defined (MIPS_SINGLE_STEP)
5233         break;
5234 #endif
5235     }
5236     if (env->singlestep_enabled) {
5237         save_cpu_state(ctxp, ctx.bstate == BS_NONE);
5238         gen_op_debug();
5239     } else {
5240         switch (ctx.bstate) {
5241         case BS_EXCP:
5242             gen_op_interrupt_restart();
5243             gen_op_reset_T0();
5244             /* Generate the return instruction. */
5245             gen_op_exit_tb();
5246             break;
5247         case BS_STOP:
5248             gen_op_interrupt_restart();
5249             /* Fall through. */
5250         case BS_NONE:
5251             save_cpu_state(ctxp, 0);
5252             gen_goto_tb(&ctx, 0, ctx.pc);
5253             break;
5254         case BS_BRANCH:
5255         default:
5256             gen_op_reset_T0();
5257             /* Generate the return instruction. */
5258             gen_op_exit_tb();
5259             break;
5260         }
5261     }
5262 done_generating:
5263     *gen_opc_ptr = INDEX_op_end;
5264     if (search_pc) {
5265         j = gen_opc_ptr - gen_opc_buf;
5266         lj++;
5267         while (lj <= j)
5268             gen_opc_instr_start[lj++] = 0;
5269         tb->size = 0;
5270     } else {
5271         tb->size = ctx.pc - pc_start;
5272     }
5273 #ifdef DEBUG_DISAS
5274 #if defined MIPS_DEBUG_DISAS
5275     if (loglevel & CPU_LOG_TB_IN_ASM)
5276         fprintf(logfile, "\n");
5277 #endif
5278     if (loglevel & CPU_LOG_TB_IN_ASM) {
5279         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5280         target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5281         fprintf(logfile, "\n");
5282     }
5283     if (loglevel & CPU_LOG_TB_OP) {
5284         fprintf(logfile, "OP:\n");
5285         dump_ops(gen_opc_buf, gen_opparam_buf);
5286         fprintf(logfile, "\n");
5287     }
5288     if (loglevel & CPU_LOG_TB_CPU) {
5289         fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5290     }
5291 #endif
5292     
5293     return 0;
5294 }
5295
5296 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5297 {
5298     return gen_intermediate_code_internal(env, tb, 0);
5299 }
5300
5301 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5302 {
5303     return gen_intermediate_code_internal(env, tb, 1);
5304 }
5305
5306 void fpu_dump_state(CPUState *env, FILE *f, 
5307                     int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5308                     int flags)
5309 {
5310     int i;
5311
5312 #   define printfpr(fp) do { \
5313         fpu_fprintf(f, "w:%08x d:%08lx%08lx fd:%g fs:%g\n", \
5314                 (fp)->w[FP_ENDIAN_IDX], (fp)->w[0], (fp)->w[1], (fp)->fd, (fp)->fs[FP_ENDIAN_IDX]); \
5315     } while(0)
5316
5317     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d\n",
5318                 env->fcr0, env->fcr31,
5319                 (env->CP0_Status & (1 << CP0St_FR)) != 0);
5320     fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
5321     fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
5322     fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
5323     for(i = 0; i < 32; i += 2) {
5324         fpu_fprintf(f, "%s: ", fregnames[i]);
5325         printfpr(FPR(env, i));
5326     }
5327
5328 #undef printfpr
5329 }
5330
5331 void dump_fpu (CPUState *env)
5332 {
5333     if (loglevel) { 
5334        fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5335                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5336        fpu_dump_state(env, logfile, fprintf, 0);
5337     }
5338 }
5339
5340 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5341 /* Debug help: The architecture requires 32bit code to maintain proper
5342    sign-extened values on 64bit machines.  */
5343
5344 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
5345
5346 void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
5347                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5348                      int flags)
5349 {
5350     int i;
5351
5352     if (!SIGN_EXT_P(env->PC))
5353         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
5354     if (!SIGN_EXT_P(env->HI))
5355         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
5356     if (!SIGN_EXT_P(env->LO))
5357         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
5358     if (!SIGN_EXT_P(env->btarget))
5359         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
5360
5361     for (i = 0; i < 32; i++) {
5362         if (!SIGN_EXT_P(env->gpr[i]))
5363             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
5364     }
5365
5366     if (!SIGN_EXT_P(env->CP0_EPC))
5367         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5368     if (!SIGN_EXT_P(env->CP0_LLAddr))
5369         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
5370 }
5371 #endif
5372
5373 void cpu_dump_state (CPUState *env, FILE *f, 
5374                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5375                      int flags)
5376 {
5377     uint32_t c0_status;
5378     int i;
5379     
5380     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
5381                 env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
5382     for (i = 0; i < 32; i++) {
5383         if ((i & 3) == 0)
5384             cpu_fprintf(f, "GPR%02d:", i);
5385         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
5386         if ((i & 3) == 3)
5387             cpu_fprintf(f, "\n");
5388     }
5389
5390     c0_status = env->CP0_Status;
5391
5392     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
5393                 c0_status, env->CP0_Cause, env->CP0_EPC);
5394     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5395                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
5396     if (c0_status & (1 << CP0St_CU1))
5397         fpu_dump_state(env, f, cpu_fprintf, flags);
5398 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
5399     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
5400 #endif
5401 }
5402
5403 CPUMIPSState *cpu_mips_init (void)
5404 {
5405     CPUMIPSState *env;
5406
5407     env = qemu_mallocz(sizeof(CPUMIPSState));
5408     if (!env)
5409         return NULL;
5410     cpu_exec_init(env);
5411     cpu_reset(env);
5412     return env;
5413 }
5414
5415 void cpu_reset (CPUMIPSState *env)
5416 {
5417     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
5418
5419     tlb_flush(env, 1);
5420
5421     /* Minimal init */
5422 #if !defined(CONFIG_USER_ONLY)
5423     if (env->hflags & MIPS_HFLAG_BMASK) {
5424         /* If the exception was raised from a delay slot,
5425          * come back to the jump.  */
5426         env->CP0_ErrorEPC = env->PC - 4;
5427         env->hflags &= ~MIPS_HFLAG_BMASK;
5428     } else {
5429         env->CP0_ErrorEPC = env->PC;
5430     }
5431     env->hflags = 0;
5432     env->PC = (int32_t)0xBFC00000;
5433     env->CP0_Wired = 0;
5434     /* SMP not implemented */
5435     env->CP0_EBase = 0x80000000;
5436     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
5437     /* vectored interrupts not implemented, timer on int 7,
5438        no performance counters. */
5439     env->CP0_IntCtl = 0xe0000000;
5440     env->CP0_WatchLo = 0;
5441     env->CP0_WatchHi = 0;
5442     /* Count register increments in debug mode, EJTAG version 1 */
5443     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
5444 #endif
5445     env->exception_index = EXCP_NONE;
5446 #if defined(CONFIG_USER_ONLY)
5447     env->hflags |= MIPS_HFLAG_UM;
5448     env->user_mode_only = 1;
5449 #endif
5450 }
5451
5452 #include "translate_init.c"
This page took 0.344263 seconds and 4 git commands to generate.