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