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