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