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
34 #include "qemu-common.h"
36 //#define MIPS_DEBUG_DISAS
37 //#define MIPS_DEBUG_SIGN_EXTENSIONS
38 //#define MIPS_SINGLE_STEP
40 /* MIPS major opcodes */
41 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
44 /* indirect opcode tables */
45 OPC_SPECIAL = (0x00 << 26),
46 OPC_REGIMM = (0x01 << 26),
47 OPC_CP0 = (0x10 << 26),
48 OPC_CP1 = (0x11 << 26),
49 OPC_CP2 = (0x12 << 26),
50 OPC_CP3 = (0x13 << 26),
51 OPC_SPECIAL2 = (0x1C << 26),
52 OPC_SPECIAL3 = (0x1F << 26),
53 /* arithmetic with immediate */
54 OPC_ADDI = (0x08 << 26),
55 OPC_ADDIU = (0x09 << 26),
56 OPC_SLTI = (0x0A << 26),
57 OPC_SLTIU = (0x0B << 26),
58 OPC_ANDI = (0x0C << 26),
59 OPC_ORI = (0x0D << 26),
60 OPC_XORI = (0x0E << 26),
61 OPC_LUI = (0x0F << 26),
62 OPC_DADDI = (0x18 << 26),
63 OPC_DADDIU = (0x19 << 26),
64 /* Jump and branches */
66 OPC_JAL = (0x03 << 26),
67 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
68 OPC_BEQL = (0x14 << 26),
69 OPC_BNE = (0x05 << 26),
70 OPC_BNEL = (0x15 << 26),
71 OPC_BLEZ = (0x06 << 26),
72 OPC_BLEZL = (0x16 << 26),
73 OPC_BGTZ = (0x07 << 26),
74 OPC_BGTZL = (0x17 << 26),
75 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
77 OPC_LDL = (0x1A << 26),
78 OPC_LDR = (0x1B << 26),
79 OPC_LB = (0x20 << 26),
80 OPC_LH = (0x21 << 26),
81 OPC_LWL = (0x22 << 26),
82 OPC_LW = (0x23 << 26),
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_SC = (0x38 << 26),
98 OPC_SCD = (0x3C << 26),
99 OPC_SD = (0x3F << 26),
100 /* Floating point load/store */
101 OPC_LWC1 = (0x31 << 26),
102 OPC_LWC2 = (0x32 << 26),
103 OPC_LDC1 = (0x35 << 26),
104 OPC_LDC2 = (0x36 << 26),
105 OPC_SWC1 = (0x39 << 26),
106 OPC_SWC2 = (0x3A << 26),
107 OPC_SDC1 = (0x3D << 26),
108 OPC_SDC2 = (0x3E << 26),
109 /* MDMX ASE specific */
110 OPC_MDMX = (0x1E << 26),
111 /* Cache and prefetch */
112 OPC_CACHE = (0x2F << 26),
113 OPC_PREF = (0x33 << 26),
114 /* Reserved major opcode */
115 OPC_MAJOR3B_RESERVED = (0x3B << 26),
118 /* MIPS special opcodes */
119 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
123 OPC_SLL = 0x00 | OPC_SPECIAL,
124 /* NOP is SLL r0, r0, 0 */
125 /* SSNOP is SLL r0, r0, 1 */
126 /* EHB is SLL r0, r0, 3 */
127 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
128 OPC_SRA = 0x03 | OPC_SPECIAL,
129 OPC_SLLV = 0x04 | OPC_SPECIAL,
130 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
131 OPC_SRAV = 0x07 | OPC_SPECIAL,
132 OPC_DSLLV = 0x14 | OPC_SPECIAL,
133 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
134 OPC_DSRAV = 0x17 | OPC_SPECIAL,
135 OPC_DSLL = 0x38 | OPC_SPECIAL,
136 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
137 OPC_DSRA = 0x3B | OPC_SPECIAL,
138 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
139 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
140 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
141 /* Multiplication / division */
142 OPC_MULT = 0x18 | OPC_SPECIAL,
143 OPC_MULTU = 0x19 | OPC_SPECIAL,
144 OPC_DIV = 0x1A | OPC_SPECIAL,
145 OPC_DIVU = 0x1B | OPC_SPECIAL,
146 OPC_DMULT = 0x1C | OPC_SPECIAL,
147 OPC_DMULTU = 0x1D | OPC_SPECIAL,
148 OPC_DDIV = 0x1E | OPC_SPECIAL,
149 OPC_DDIVU = 0x1F | OPC_SPECIAL,
150 /* 2 registers arithmetic / logic */
151 OPC_ADD = 0x20 | OPC_SPECIAL,
152 OPC_ADDU = 0x21 | OPC_SPECIAL,
153 OPC_SUB = 0x22 | OPC_SPECIAL,
154 OPC_SUBU = 0x23 | OPC_SPECIAL,
155 OPC_AND = 0x24 | OPC_SPECIAL,
156 OPC_OR = 0x25 | OPC_SPECIAL,
157 OPC_XOR = 0x26 | OPC_SPECIAL,
158 OPC_NOR = 0x27 | OPC_SPECIAL,
159 OPC_SLT = 0x2A | OPC_SPECIAL,
160 OPC_SLTU = 0x2B | OPC_SPECIAL,
161 OPC_DADD = 0x2C | OPC_SPECIAL,
162 OPC_DADDU = 0x2D | OPC_SPECIAL,
163 OPC_DSUB = 0x2E | OPC_SPECIAL,
164 OPC_DSUBU = 0x2F | OPC_SPECIAL,
166 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
167 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
169 OPC_TGE = 0x30 | OPC_SPECIAL,
170 OPC_TGEU = 0x31 | OPC_SPECIAL,
171 OPC_TLT = 0x32 | OPC_SPECIAL,
172 OPC_TLTU = 0x33 | OPC_SPECIAL,
173 OPC_TEQ = 0x34 | OPC_SPECIAL,
174 OPC_TNE = 0x36 | OPC_SPECIAL,
175 /* HI / LO registers load & stores */
176 OPC_MFHI = 0x10 | OPC_SPECIAL,
177 OPC_MTHI = 0x11 | OPC_SPECIAL,
178 OPC_MFLO = 0x12 | OPC_SPECIAL,
179 OPC_MTLO = 0x13 | OPC_SPECIAL,
180 /* Conditional moves */
181 OPC_MOVZ = 0x0A | OPC_SPECIAL,
182 OPC_MOVN = 0x0B | OPC_SPECIAL,
184 OPC_MOVCI = 0x01 | OPC_SPECIAL,
187 OPC_PMON = 0x05 | OPC_SPECIAL, /* inofficial */
188 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
189 OPC_BREAK = 0x0D | OPC_SPECIAL,
190 OPC_SPIM = 0x0E | OPC_SPECIAL, /* inofficial */
191 OPC_SYNC = 0x0F | OPC_SPECIAL,
193 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
194 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
195 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
196 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
197 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
198 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
199 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
202 /* Multiplication variants of the vr54xx. */
203 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
206 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
207 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
208 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
209 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
210 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
211 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
212 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
213 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
214 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
215 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
216 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
217 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
218 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
219 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
222 /* REGIMM (rt field) opcodes */
223 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
226 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
227 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
228 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
229 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
230 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
231 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
232 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
233 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
234 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
235 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
236 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
237 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
238 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
239 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
240 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
243 /* Special2 opcodes */
244 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
247 /* Multiply & xxx operations */
248 OPC_MADD = 0x00 | OPC_SPECIAL2,
249 OPC_MADDU = 0x01 | OPC_SPECIAL2,
250 OPC_MUL = 0x02 | OPC_SPECIAL2,
251 OPC_MSUB = 0x04 | OPC_SPECIAL2,
252 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
254 OPC_CLZ = 0x20 | OPC_SPECIAL2,
255 OPC_CLO = 0x21 | OPC_SPECIAL2,
256 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
257 OPC_DCLO = 0x25 | OPC_SPECIAL2,
259 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
262 /* Special3 opcodes */
263 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
266 OPC_EXT = 0x00 | OPC_SPECIAL3,
267 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
268 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
269 OPC_DEXT = 0x03 | OPC_SPECIAL3,
270 OPC_INS = 0x04 | OPC_SPECIAL3,
271 OPC_DINSM = 0x05 | OPC_SPECIAL3,
272 OPC_DINSU = 0x06 | OPC_SPECIAL3,
273 OPC_DINS = 0x07 | OPC_SPECIAL3,
274 OPC_FORK = 0x08 | OPC_SPECIAL3,
275 OPC_YIELD = 0x09 | OPC_SPECIAL3,
276 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
277 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
278 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
282 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
285 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
286 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
287 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
291 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
294 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
295 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
298 /* Coprocessor 0 (rs field) */
299 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
302 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
303 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
304 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
305 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
306 OPC_MFTR = (0x08 << 21) | OPC_CP0,
307 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
308 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
309 OPC_MTTR = (0x0C << 21) | OPC_CP0,
310 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
311 OPC_C0 = (0x10 << 21) | OPC_CP0,
312 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
313 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
317 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
320 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
321 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
322 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
323 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
324 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
325 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
328 /* Coprocessor 0 (with rs == C0) */
329 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
332 OPC_TLBR = 0x01 | OPC_C0,
333 OPC_TLBWI = 0x02 | OPC_C0,
334 OPC_TLBWR = 0x06 | OPC_C0,
335 OPC_TLBP = 0x08 | OPC_C0,
336 OPC_RFE = 0x10 | OPC_C0,
337 OPC_ERET = 0x18 | OPC_C0,
338 OPC_DERET = 0x1F | OPC_C0,
339 OPC_WAIT = 0x20 | OPC_C0,
342 /* Coprocessor 1 (rs field) */
343 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
346 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
347 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
348 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
349 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
350 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
351 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
352 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
353 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
354 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
355 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
356 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
357 OPC_S_FMT = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
358 OPC_D_FMT = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
359 OPC_E_FMT = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
360 OPC_Q_FMT = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
361 OPC_W_FMT = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
362 OPC_L_FMT = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
363 OPC_PS_FMT = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
366 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
367 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
370 OPC_BC1F = (0x00 << 16) | OPC_BC1,
371 OPC_BC1T = (0x01 << 16) | OPC_BC1,
372 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
373 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
377 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
378 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
382 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
383 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
386 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
389 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
390 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
391 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
392 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
393 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
394 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
395 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
396 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
397 OPC_BC2 = (0x08 << 21) | OPC_CP2,
400 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
403 OPC_LWXC1 = 0x00 | OPC_CP3,
404 OPC_LDXC1 = 0x01 | OPC_CP3,
405 OPC_LUXC1 = 0x05 | OPC_CP3,
406 OPC_SWXC1 = 0x08 | OPC_CP3,
407 OPC_SDXC1 = 0x09 | OPC_CP3,
408 OPC_SUXC1 = 0x0D | OPC_CP3,
409 OPC_PREFX = 0x0F | OPC_CP3,
410 OPC_ALNV_PS = 0x1E | OPC_CP3,
411 OPC_MADD_S = 0x20 | OPC_CP3,
412 OPC_MADD_D = 0x21 | OPC_CP3,
413 OPC_MADD_PS = 0x26 | OPC_CP3,
414 OPC_MSUB_S = 0x28 | OPC_CP3,
415 OPC_MSUB_D = 0x29 | OPC_CP3,
416 OPC_MSUB_PS = 0x2E | OPC_CP3,
417 OPC_NMADD_S = 0x30 | OPC_CP3,
418 OPC_NMADD_D = 0x31 | OPC_CP3,
419 OPC_NMADD_PS= 0x36 | OPC_CP3,
420 OPC_NMSUB_S = 0x38 | OPC_CP3,
421 OPC_NMSUB_D = 0x39 | OPC_CP3,
422 OPC_NMSUB_PS= 0x3E | OPC_CP3,
425 /* global register indices */
426 static TCGv cpu_env, current_tc_gprs, current_tc_hi, current_fpu, cpu_T[2];
428 /* FPU TNs, global for now. */
429 static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3];
431 static inline void tcg_gen_helper_0_1i(void *func, TCGv arg)
433 TCGv t = tcg_const_i32(arg);
435 tcg_gen_helper_0_1(func, t);
439 static inline void tcg_gen_helper_0_2ii(void *func, TCGv arg1, TCGv arg2)
441 TCGv t1 = tcg_const_i32(arg1);
442 TCGv t2 = tcg_const_i32(arg2);
444 tcg_gen_helper_0_2(func, t1, t2);
449 typedef struct DisasContext {
450 struct TranslationBlock *tb;
451 target_ulong pc, saved_pc;
454 /* Routine used to access memory */
456 uint32_t hflags, saved_hflags;
458 target_ulong btarget;
462 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
463 * exception condition
465 BS_STOP = 1, /* We want to stop translation for any reason */
466 BS_BRANCH = 2, /* We reached a branch condition */
467 BS_EXCP = 3, /* We reached an exception condition */
470 static const char *regnames[] =
471 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
472 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
473 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
474 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
476 static const char *fregnames[] =
477 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
478 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
479 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
480 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
482 #ifdef MIPS_DEBUG_DISAS
483 #define MIPS_DEBUG(fmt, args...) \
485 if (loglevel & CPU_LOG_TB_IN_ASM) { \
486 fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n", \
487 ctx->pc, ctx->opcode , ##args); \
491 #define MIPS_DEBUG(fmt, args...) do { } while(0)
494 #define MIPS_INVAL(op) \
496 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
497 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
500 /* General purpose registers moves. */
501 static inline void gen_load_gpr (TCGv t, int reg)
504 tcg_gen_movi_tl(t, 0);
506 tcg_gen_ld_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
509 static inline void gen_store_gpr (TCGv t, int reg)
512 tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
515 /* Moves to/from HI and LO registers. */
516 static inline void gen_load_LO (TCGv t, int reg)
518 tcg_gen_ld_tl(t, current_tc_hi,
519 offsetof(CPUState, LO)
520 - offsetof(CPUState, HI)
521 + sizeof(target_ulong) * reg);
524 static inline void gen_store_LO (TCGv t, int reg)
526 tcg_gen_st_tl(t, current_tc_hi,
527 offsetof(CPUState, LO)
528 - offsetof(CPUState, HI)
529 + sizeof(target_ulong) * reg);
532 static inline void gen_load_HI (TCGv t, int reg)
534 tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
537 static inline void gen_store_HI (TCGv t, int reg)
539 tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
542 /* Moves to/from shadow registers. */
543 static inline void gen_load_srsgpr (TCGv t, int reg)
546 tcg_gen_movi_tl(t, 0);
548 TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
550 tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
551 tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
552 tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
553 tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
554 tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
556 tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg);
557 tcg_temp_free(r_tmp);
561 static inline void gen_store_srsgpr (TCGv t, int reg)
564 TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
566 tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
567 tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
568 tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
569 tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
570 tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
572 tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg);
573 tcg_temp_free(r_tmp);
577 /* Floating point register moves. */
578 static inline void gen_load_fpr32 (TCGv t, int reg)
580 tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
583 static inline void gen_store_fpr32 (TCGv t, int reg)
585 tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
588 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
590 if (ctx->hflags & MIPS_HFLAG_F64) {
591 tcg_gen_ld_i64(t, current_fpu, 8 * reg);
593 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
594 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
596 tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
597 tcg_gen_extu_i32_i64(t, r_tmp1);
598 tcg_gen_shli_i64(t, t, 32);
599 tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
600 tcg_gen_extu_i32_i64(r_tmp2, r_tmp1);
601 tcg_gen_or_i64(t, t, r_tmp2);
602 tcg_temp_free(r_tmp1);
603 tcg_temp_free(r_tmp2);
607 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg)
609 if (ctx->hflags & MIPS_HFLAG_F64) {
610 tcg_gen_st_i64(t, current_fpu, 8 * reg);
612 TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
614 tcg_gen_trunc_i64_i32(r_tmp, t);
615 tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
616 tcg_gen_shri_i64(t, t, 32);
617 tcg_gen_trunc_i64_i32(r_tmp, t);
618 tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
619 tcg_temp_free(r_tmp);
623 static inline void gen_load_fpr32h (TCGv t, int reg)
625 tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
628 static inline void gen_store_fpr32h (TCGv t, int reg)
630 tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
633 #define FOP_CONDS(type, fmt) \
634 static GenOpFunc1 * fcmp ## type ## _ ## fmt ## _table[16] = { \
635 do_cmp ## type ## _ ## fmt ## _f, \
636 do_cmp ## type ## _ ## fmt ## _un, \
637 do_cmp ## type ## _ ## fmt ## _eq, \
638 do_cmp ## type ## _ ## fmt ## _ueq, \
639 do_cmp ## type ## _ ## fmt ## _olt, \
640 do_cmp ## type ## _ ## fmt ## _ult, \
641 do_cmp ## type ## _ ## fmt ## _ole, \
642 do_cmp ## type ## _ ## fmt ## _ule, \
643 do_cmp ## type ## _ ## fmt ## _sf, \
644 do_cmp ## type ## _ ## fmt ## _ngle, \
645 do_cmp ## type ## _ ## fmt ## _seq, \
646 do_cmp ## type ## _ ## fmt ## _ngl, \
647 do_cmp ## type ## _ ## fmt ## _lt, \
648 do_cmp ## type ## _ ## fmt ## _nge, \
649 do_cmp ## type ## _ ## fmt ## _le, \
650 do_cmp ## type ## _ ## fmt ## _ngt, \
652 static inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \
654 tcg_gen_helper_0_1i(fcmp ## type ## _ ## fmt ## _table[n], cc); \
666 #define OP_COND(name, cond) \
667 void glue(gen_op_, name) (void) \
669 int l1 = gen_new_label(); \
670 int l2 = gen_new_label(); \
672 tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1); \
673 tcg_gen_movi_tl(cpu_T[0], 0); \
676 tcg_gen_movi_tl(cpu_T[0], 1); \
679 OP_COND(eq, TCG_COND_EQ);
680 OP_COND(ne, TCG_COND_NE);
681 OP_COND(ge, TCG_COND_GE);
682 OP_COND(geu, TCG_COND_GEU);
683 OP_COND(lt, TCG_COND_LT);
684 OP_COND(ltu, TCG_COND_LTU);
687 #define OP_CONDI(name, cond) \
688 void glue(gen_op_, name) (target_ulong val) \
690 int l1 = gen_new_label(); \
691 int l2 = gen_new_label(); \
693 tcg_gen_brcondi_tl(cond, cpu_T[0], val, l1); \
694 tcg_gen_movi_tl(cpu_T[0], 0); \
697 tcg_gen_movi_tl(cpu_T[0], 1); \
700 OP_CONDI(lti, TCG_COND_LT);
701 OP_CONDI(ltiu, TCG_COND_LTU);
704 #define OP_CONDZ(name, cond) \
705 void glue(gen_op_, name) (void) \
707 int l1 = gen_new_label(); \
708 int l2 = gen_new_label(); \
710 tcg_gen_brcondi_tl(cond, cpu_T[0], 0, l1); \
711 tcg_gen_movi_tl(cpu_T[0], 0); \
714 tcg_gen_movi_tl(cpu_T[0], 1); \
717 OP_CONDZ(gez, TCG_COND_GE);
718 OP_CONDZ(gtz, TCG_COND_GT);
719 OP_CONDZ(lez, TCG_COND_LE);
720 OP_CONDZ(ltz, TCG_COND_LT);
723 static inline void gen_save_pc(target_ulong pc)
725 TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
726 TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32);
727 TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR);
728 TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
730 tcg_gen_movi_tl(r_tmp, pc);
731 tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
732 tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
733 tcg_gen_ext_i32_ptr(r_tc_off_ptr, r_tc_off);
734 tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_ptr);
735 tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
736 tcg_temp_free(r_tc_off);
737 tcg_temp_free(r_tc_off_ptr);
738 tcg_temp_free(r_ptr);
739 tcg_temp_free(r_tmp);
742 static inline void gen_breg_pc(void)
744 TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
745 TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32);
746 TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR);
747 TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
749 tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
750 tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
751 tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
752 tcg_gen_ext_i32_ptr(r_tc_off_ptr, r_tc_off);
753 tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_ptr);
754 tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
755 tcg_temp_free(r_tc_off);
756 tcg_temp_free(r_tc_off_ptr);
757 tcg_temp_free(r_ptr);
758 tcg_temp_free(r_tmp);
761 static inline void gen_save_btarget(target_ulong btarget)
763 TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
765 tcg_gen_movi_tl(r_tmp, btarget);
766 tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
767 tcg_temp_free(r_tmp);
770 static always_inline void gen_save_breg_target(int reg)
772 TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
774 gen_load_gpr(r_tmp, reg);
775 tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
776 tcg_temp_free(r_tmp);
779 static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
781 #if defined MIPS_DEBUG_DISAS
782 if (loglevel & CPU_LOG_TB_IN_ASM) {
783 fprintf(logfile, "hflags %08x saved %08x\n",
784 ctx->hflags, ctx->saved_hflags);
787 if (do_save_pc && ctx->pc != ctx->saved_pc) {
788 gen_save_pc(ctx->pc);
789 ctx->saved_pc = ctx->pc;
791 if (ctx->hflags != ctx->saved_hflags) {
792 TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
794 tcg_gen_movi_i32(r_tmp, ctx->hflags);
795 tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
796 tcg_temp_free(r_tmp);
797 ctx->saved_hflags = ctx->hflags;
798 switch (ctx->hflags & MIPS_HFLAG_BMASK) {
804 gen_save_btarget(ctx->btarget);
810 static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
812 ctx->saved_hflags = ctx->hflags;
813 switch (ctx->hflags & MIPS_HFLAG_BMASK) {
819 ctx->btarget = env->btarget;
824 static always_inline void
825 generate_exception_err (DisasContext *ctx, int excp, int err)
827 save_cpu_state(ctx, 1);
828 tcg_gen_helper_0_2ii(do_raise_exception_err, excp, err);
829 tcg_gen_helper_0_0(do_interrupt_restart);
833 static always_inline void
834 generate_exception (DisasContext *ctx, int excp)
836 save_cpu_state(ctx, 1);
837 tcg_gen_helper_0_1i(do_raise_exception, excp);
838 tcg_gen_helper_0_0(do_interrupt_restart);
842 /* Addresses computation */
843 static inline void gen_op_addr_add (void)
845 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
847 #if defined(TARGET_MIPS64)
848 /* For compatibility with 32-bit code, data reference in user mode
849 with Status_UX = 0 should be casted to 32-bit and sign extended.
850 See the MIPS64 PRA manual, section 4.10. */
852 int l1 = gen_new_label();
853 TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
855 tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
856 tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
857 tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
858 tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
859 tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
860 tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
861 tcg_temp_free(r_tmp);
862 tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
868 static always_inline void check_cp0_enabled(DisasContext *ctx)
870 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
871 generate_exception_err(ctx, EXCP_CpU, 1);
874 static always_inline void check_cp1_enabled(DisasContext *ctx)
876 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
877 generate_exception_err(ctx, EXCP_CpU, 1);
880 /* Verify that the processor is running with COP1X instructions enabled.
881 This is associated with the nabla symbol in the MIPS32 and MIPS64
884 static always_inline void check_cop1x(DisasContext *ctx)
886 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
887 generate_exception(ctx, EXCP_RI);
890 /* Verify that the processor is running with 64-bit floating-point
891 operations enabled. */
893 static always_inline void check_cp1_64bitmode(DisasContext *ctx)
895 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
896 generate_exception(ctx, EXCP_RI);
900 * Verify if floating point register is valid; an operation is not defined
901 * if bit 0 of any register specification is set and the FR bit in the
902 * Status register equals zero, since the register numbers specify an
903 * even-odd pair of adjacent coprocessor general registers. When the FR bit
904 * in the Status register equals one, both even and odd register numbers
905 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
907 * Multiple 64 bit wide registers can be checked by calling
908 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
910 void check_cp1_registers(DisasContext *ctx, int regs)
912 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
913 generate_exception(ctx, EXCP_RI);
916 /* This code generates a "reserved instruction" exception if the
917 CPU does not support the instruction set corresponding to flags. */
918 static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
920 if (unlikely(!(env->insn_flags & flags)))
921 generate_exception(ctx, EXCP_RI);
924 /* This code generates a "reserved instruction" exception if 64-bit
925 instructions are not enabled. */
926 static always_inline void check_mips_64(DisasContext *ctx)
928 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
929 generate_exception(ctx, EXCP_RI);
932 /* load/store instructions. */
933 #if defined(CONFIG_USER_ONLY)
934 #define op_ldst(name) gen_op_##name##_raw()
935 #define OP_LD_TABLE(width)
936 #define OP_ST_TABLE(width)
938 #define op_ldst(name) (*gen_op_##name[ctx->mem_idx])()
939 #define OP_LD_TABLE(width) \
940 static GenOpFunc *gen_op_l##width[] = { \
941 &gen_op_l##width##_kernel, \
942 &gen_op_l##width##_super, \
943 &gen_op_l##width##_user, \
945 #define OP_ST_TABLE(width) \
946 static GenOpFunc *gen_op_s##width[] = { \
947 &gen_op_s##width##_kernel, \
948 &gen_op_s##width##_super, \
949 &gen_op_s##width##_user, \
953 #if defined(TARGET_MIPS64)
964 #define OP_LD(insn,fname) \
965 void inline op_ldst_##insn(DisasContext *ctx) \
967 tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx); \
974 #if defined(TARGET_MIPS64)
980 #define OP_ST(insn,fname) \
981 void inline op_ldst_##insn(DisasContext *ctx) \
983 tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx); \
988 #if defined(TARGET_MIPS64)
993 #define OP_LD_ATOMIC(insn,fname) \
994 void inline op_ldst_##insn(DisasContext *ctx) \
996 tcg_gen_mov_tl(cpu_T[1], cpu_T[0]); \
997 tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx); \
998 tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr)); \
1000 OP_LD_ATOMIC(ll,ld32s);
1001 #if defined(TARGET_MIPS64)
1002 OP_LD_ATOMIC(lld,ld64);
1006 #define OP_ST_ATOMIC(insn,fname,almask) \
1007 void inline op_ldst_##insn(DisasContext *ctx) \
1009 TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL); \
1010 int l1 = gen_new_label(); \
1011 int l2 = gen_new_label(); \
1012 int l3 = gen_new_label(); \
1014 tcg_gen_andi_tl(r_tmp, cpu_T[0], almask); \
1015 tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1); \
1016 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1017 generate_exception(ctx, EXCP_AdES); \
1018 gen_set_label(l1); \
1019 tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr)); \
1020 tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2); \
1021 tcg_temp_free(r_tmp); \
1022 tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx); \
1023 tcg_gen_movi_tl(cpu_T[0], 1); \
1025 gen_set_label(l2); \
1026 tcg_gen_movi_tl(cpu_T[0], 0); \
1027 gen_set_label(l3); \
1029 OP_ST_ATOMIC(sc,st32,0x3);
1030 #if defined(TARGET_MIPS64)
1031 OP_ST_ATOMIC(scd,st64,0x7);
1035 /* Load and store */
1036 static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1037 int base, int16_t offset)
1039 const char *opn = "ldst";
1042 tcg_gen_movi_tl(cpu_T[0], offset);
1043 } else if (offset == 0) {
1044 gen_load_gpr(cpu_T[0], base);
1046 gen_load_gpr(cpu_T[0], base);
1047 tcg_gen_movi_tl(cpu_T[1], offset);
1050 /* Don't do NOP if destination is zero: we must perform the actual
1053 #if defined(TARGET_MIPS64)
1056 gen_store_gpr(cpu_T[0], rt);
1061 gen_store_gpr(cpu_T[0], rt);
1066 gen_store_gpr(cpu_T[0], rt);
1070 gen_load_gpr(cpu_T[1], rt);
1075 save_cpu_state(ctx, 1);
1076 gen_load_gpr(cpu_T[1], rt);
1078 gen_store_gpr(cpu_T[0], rt);
1082 gen_load_gpr(cpu_T[1], rt);
1084 gen_store_gpr(cpu_T[1], rt);
1088 gen_load_gpr(cpu_T[1], rt);
1093 gen_load_gpr(cpu_T[1], rt);
1095 gen_store_gpr(cpu_T[1], rt);
1099 gen_load_gpr(cpu_T[1], rt);
1106 gen_store_gpr(cpu_T[0], rt);
1110 gen_load_gpr(cpu_T[1], rt);
1116 gen_store_gpr(cpu_T[0], rt);
1120 gen_load_gpr(cpu_T[1], rt);
1126 gen_store_gpr(cpu_T[0], rt);
1131 gen_store_gpr(cpu_T[0], rt);
1135 gen_load_gpr(cpu_T[1], rt);
1141 gen_store_gpr(cpu_T[0], rt);
1145 gen_load_gpr(cpu_T[1], rt);
1147 gen_store_gpr(cpu_T[1], rt);
1151 gen_load_gpr(cpu_T[1], rt);
1156 gen_load_gpr(cpu_T[1], rt);
1158 gen_store_gpr(cpu_T[1], rt);
1162 gen_load_gpr(cpu_T[1], rt);
1168 gen_store_gpr(cpu_T[0], rt);
1172 save_cpu_state(ctx, 1);
1173 gen_load_gpr(cpu_T[1], rt);
1175 gen_store_gpr(cpu_T[0], rt);
1180 generate_exception(ctx, EXCP_RI);
1183 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1186 /* Load and store */
1187 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1188 int base, int16_t offset)
1190 const char *opn = "flt_ldst";
1193 tcg_gen_movi_tl(cpu_T[0], offset);
1194 } else if (offset == 0) {
1195 gen_load_gpr(cpu_T[0], base);
1197 gen_load_gpr(cpu_T[0], base);
1198 tcg_gen_movi_tl(cpu_T[1], offset);
1201 /* Don't do NOP if destination is zero: we must perform the actual
1205 tcg_gen_qemu_ld32s(fpu32_T[0], cpu_T[0], ctx->mem_idx);
1206 gen_store_fpr32(fpu32_T[0], ft);
1210 gen_load_fpr32(fpu32_T[0], ft);
1211 tcg_gen_qemu_st32(fpu32_T[0], cpu_T[0], ctx->mem_idx);
1215 tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
1216 gen_store_fpr64(ctx, fpu64_T[0], ft);
1220 gen_load_fpr64(ctx, fpu64_T[0], ft);
1221 tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
1226 generate_exception(ctx, EXCP_RI);
1229 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1232 /* Arithmetic with immediate operand */
1233 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1234 int rt, int rs, int16_t imm)
1237 const char *opn = "imm arith";
1239 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1240 /* If no destination, treat it as a NOP.
1241 For addi, we must generate the overflow exception when needed. */
1245 uimm = (uint16_t)imm;
1249 #if defined(TARGET_MIPS64)
1255 uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1256 tcg_gen_movi_tl(cpu_T[1], uimm);
1261 gen_load_gpr(cpu_T[0], rs);
1264 tcg_gen_movi_tl(cpu_T[0], imm << 16);
1269 #if defined(TARGET_MIPS64)
1278 gen_load_gpr(cpu_T[0], rs);
1284 TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1285 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1286 int l1 = gen_new_label();
1288 save_cpu_state(ctx, 1);
1289 tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1290 tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1292 tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1293 tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1294 tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1295 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1296 tcg_temp_free(r_tmp2);
1297 tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1298 tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1299 tcg_temp_free(r_tmp1);
1300 /* operands of same sign, result different sign */
1301 generate_exception(ctx, EXCP_OVERFLOW);
1304 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1309 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1310 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1311 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1314 #if defined(TARGET_MIPS64)
1317 TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1318 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1319 int l1 = gen_new_label();
1321 save_cpu_state(ctx, 1);
1322 tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1323 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1325 tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1326 tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1327 tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1328 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1329 tcg_temp_free(r_tmp2);
1330 tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1331 tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1332 tcg_temp_free(r_tmp1);
1333 /* operands of same sign, result different sign */
1334 generate_exception(ctx, EXCP_OVERFLOW);
1340 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1353 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm);
1357 tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm);
1361 tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm);
1368 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1369 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1370 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1374 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1375 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1376 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1380 switch ((ctx->opcode >> 21) & 0x1f) {
1382 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1383 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1384 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1388 /* rotr is decoded as srl on non-R2 CPUs */
1389 if (env->insn_flags & ISA_MIPS32R2) {
1391 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1392 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1394 tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1395 tcg_gen_movi_i32(r_tmp2, 0x20);
1396 tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1397 tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1398 tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1399 tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1400 tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1);
1401 tcg_temp_free(r_tmp1);
1402 tcg_temp_free(r_tmp2);
1406 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1407 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1408 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1413 MIPS_INVAL("invalid srl flag");
1414 generate_exception(ctx, EXCP_RI);
1418 #if defined(TARGET_MIPS64)
1420 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1424 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1428 switch ((ctx->opcode >> 21) & 0x1f) {
1430 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1434 /* drotr is decoded as dsrl on non-R2 CPUs */
1435 if (env->insn_flags & ISA_MIPS32R2) {
1437 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1439 tcg_gen_movi_tl(r_tmp1, 0x40);
1440 tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1441 tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1442 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1443 tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1444 tcg_temp_free(r_tmp1);
1448 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1453 MIPS_INVAL("invalid dsrl flag");
1454 generate_exception(ctx, EXCP_RI);
1459 tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32);
1463 tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32);
1467 switch ((ctx->opcode >> 21) & 0x1f) {
1469 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1473 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1474 if (env->insn_flags & ISA_MIPS32R2) {
1475 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1476 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1478 tcg_gen_movi_tl(r_tmp1, 0x40);
1479 tcg_gen_movi_tl(r_tmp2, 32);
1480 tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1481 tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1482 tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1483 tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2);
1484 tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1485 tcg_temp_free(r_tmp1);
1486 tcg_temp_free(r_tmp2);
1489 tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1494 MIPS_INVAL("invalid dsrl32 flag");
1495 generate_exception(ctx, EXCP_RI);
1502 generate_exception(ctx, EXCP_RI);
1505 gen_store_gpr(cpu_T[0], rt);
1506 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1510 static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1511 int rd, int rs, int rt)
1513 const char *opn = "arith";
1515 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1516 && opc != OPC_DADD && opc != OPC_DSUB) {
1517 /* If no destination, treat it as a NOP.
1518 For add & sub, we must generate the overflow exception when needed. */
1522 gen_load_gpr(cpu_T[0], rs);
1523 /* Specialcase the conventional move operation. */
1524 if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1525 || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1526 gen_store_gpr(cpu_T[0], rd);
1529 gen_load_gpr(cpu_T[1], rt);
1533 TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1534 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1535 int l1 = gen_new_label();
1537 save_cpu_state(ctx, 1);
1538 tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1539 tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1540 tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1542 tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1543 tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1544 tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1545 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1546 tcg_temp_free(r_tmp2);
1547 tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1548 tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1549 tcg_temp_free(r_tmp1);
1550 /* operands of same sign, result different sign */
1551 generate_exception(ctx, EXCP_OVERFLOW);
1554 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1559 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1560 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1561 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1562 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1567 TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1568 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1569 int l1 = gen_new_label();
1571 save_cpu_state(ctx, 1);
1572 tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1573 tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1574 tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1576 tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1577 tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1578 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1579 tcg_temp_free(r_tmp2);
1580 tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1581 tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1582 tcg_temp_free(r_tmp1);
1583 /* operands of different sign, first operand and result different sign */
1584 generate_exception(ctx, EXCP_OVERFLOW);
1587 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1592 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1593 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1594 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1595 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1598 #if defined(TARGET_MIPS64)
1601 TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1602 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1603 int l1 = gen_new_label();
1605 save_cpu_state(ctx, 1);
1606 tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1607 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1609 tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1610 tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1611 tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1612 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1613 tcg_temp_free(r_tmp2);
1614 tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1615 tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1616 tcg_temp_free(r_tmp1);
1617 /* operands of same sign, result different sign */
1618 generate_exception(ctx, EXCP_OVERFLOW);
1624 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1629 TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1630 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1631 int l1 = gen_new_label();
1633 save_cpu_state(ctx, 1);
1634 tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1635 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1637 tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1638 tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1639 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1640 tcg_temp_free(r_tmp2);
1641 tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1642 tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1643 tcg_temp_free(r_tmp1);
1644 /* operands of different sign, first operand and result different sign */
1645 generate_exception(ctx, EXCP_OVERFLOW);
1651 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1664 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1668 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1669 tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1673 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1677 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1681 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1682 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1683 tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1684 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1689 int l1 = gen_new_label();
1691 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1692 gen_store_gpr(cpu_T[0], rd);
1699 int l1 = gen_new_label();
1701 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], 0, l1);
1702 gen_store_gpr(cpu_T[0], rd);
1708 tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1709 tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1710 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1711 tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1712 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1716 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1717 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1718 tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1719 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1723 switch ((ctx->opcode >> 6) & 0x1f) {
1725 tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1726 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1727 tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1728 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1732 /* rotrv is decoded as srlv on non-R2 CPUs */
1733 if (env->insn_flags & ISA_MIPS32R2) {
1734 int l1 = gen_new_label();
1735 int l2 = gen_new_label();
1737 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1738 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1740 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1741 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1742 TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1744 tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1745 tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1746 tcg_gen_movi_i32(r_tmp3, 0x20);
1747 tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1748 tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1749 tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1750 tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1751 tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1);
1752 tcg_temp_free(r_tmp1);
1753 tcg_temp_free(r_tmp2);
1754 tcg_temp_free(r_tmp3);
1758 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1762 tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1763 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1764 tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1765 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1770 MIPS_INVAL("invalid srlv flag");
1771 generate_exception(ctx, EXCP_RI);
1775 #if defined(TARGET_MIPS64)
1777 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1778 tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1782 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1783 tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1787 switch ((ctx->opcode >> 6) & 0x1f) {
1789 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1790 tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1794 /* drotrv is decoded as dsrlv on non-R2 CPUs */
1795 if (env->insn_flags & ISA_MIPS32R2) {
1796 int l1 = gen_new_label();
1797 int l2 = gen_new_label();
1799 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1800 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1802 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1804 tcg_gen_movi_tl(r_tmp1, 0x40);
1805 tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]);
1806 tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1);
1807 tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1808 tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1809 tcg_temp_free(r_tmp1);
1813 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1817 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1818 tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1823 MIPS_INVAL("invalid dsrlv flag");
1824 generate_exception(ctx, EXCP_RI);
1831 generate_exception(ctx, EXCP_RI);
1834 gen_store_gpr(cpu_T[0], rd);
1836 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1839 /* Arithmetic on HI/LO registers */
1840 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1842 const char *opn = "hilo";
1844 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1851 gen_load_HI(cpu_T[0], 0);
1852 gen_store_gpr(cpu_T[0], reg);
1856 gen_load_LO(cpu_T[0], 0);
1857 gen_store_gpr(cpu_T[0], reg);
1861 gen_load_gpr(cpu_T[0], reg);
1862 gen_store_HI(cpu_T[0], 0);
1866 gen_load_gpr(cpu_T[0], reg);
1867 gen_store_LO(cpu_T[0], 0);
1872 generate_exception(ctx, EXCP_RI);
1875 MIPS_DEBUG("%s %s", opn, regnames[reg]);
1878 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1881 const char *opn = "mul/div";
1883 gen_load_gpr(cpu_T[0], rs);
1884 gen_load_gpr(cpu_T[1], rt);
1888 int l1 = gen_new_label();
1890 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1891 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1892 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1894 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1895 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1896 TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1898 tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]);
1899 tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]);
1900 tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1901 tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1902 tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp3);
1903 tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp2);
1904 tcg_temp_free(r_tmp1);
1905 tcg_temp_free(r_tmp2);
1906 tcg_temp_free(r_tmp3);
1907 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1908 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1909 gen_store_LO(cpu_T[0], 0);
1910 gen_store_HI(cpu_T[1], 0);
1918 int l1 = gen_new_label();
1920 tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1921 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1923 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1924 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1925 TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1927 tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1928 tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1929 tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1930 tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1931 tcg_gen_ext_i32_tl(cpu_T[0], r_tmp3);
1932 tcg_gen_ext_i32_tl(cpu_T[1], r_tmp1);
1933 tcg_temp_free(r_tmp1);
1934 tcg_temp_free(r_tmp2);
1935 tcg_temp_free(r_tmp3);
1936 gen_store_LO(cpu_T[0], 0);
1937 gen_store_HI(cpu_T[1], 0);
1951 #if defined(TARGET_MIPS64)
1954 int l1 = gen_new_label();
1956 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1958 int l2 = gen_new_label();
1960 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], -1LL << 63, l2);
1961 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1LL, l2);
1963 tcg_gen_movi_tl(cpu_T[1], 0);
1964 gen_store_LO(cpu_T[0], 0);
1965 gen_store_HI(cpu_T[1], 0);
1970 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1971 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1973 tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1974 tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1975 gen_store_LO(r_tmp1, 0);
1976 gen_store_HI(r_tmp2, 0);
1977 tcg_temp_free(r_tmp1);
1978 tcg_temp_free(r_tmp2);
1987 int l1 = gen_new_label();
1989 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1991 TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1992 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1994 tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1995 tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1996 tcg_temp_free(r_tmp1);
1997 tcg_temp_free(r_tmp2);
1998 gen_store_LO(r_tmp1, 0);
1999 gen_store_HI(r_tmp2, 0);
2032 generate_exception(ctx, EXCP_RI);
2035 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2038 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2039 int rd, int rs, int rt)
2041 const char *opn = "mul vr54xx";
2043 gen_load_gpr(cpu_T[0], rs);
2044 gen_load_gpr(cpu_T[1], rt);
2047 case OPC_VR54XX_MULS:
2051 case OPC_VR54XX_MULSU:
2055 case OPC_VR54XX_MACC:
2059 case OPC_VR54XX_MACCU:
2063 case OPC_VR54XX_MSAC:
2067 case OPC_VR54XX_MSACU:
2071 case OPC_VR54XX_MULHI:
2075 case OPC_VR54XX_MULHIU:
2079 case OPC_VR54XX_MULSHI:
2083 case OPC_VR54XX_MULSHIU:
2087 case OPC_VR54XX_MACCHI:
2091 case OPC_VR54XX_MACCHIU:
2095 case OPC_VR54XX_MSACHI:
2099 case OPC_VR54XX_MSACHIU:
2104 MIPS_INVAL("mul vr54xx");
2105 generate_exception(ctx, EXCP_RI);
2108 gen_store_gpr(cpu_T[0], rd);
2109 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2112 static void gen_cl (DisasContext *ctx, uint32_t opc,
2115 const char *opn = "CLx";
2121 gen_load_gpr(cpu_T[0], rs);
2124 tcg_gen_helper_0_0(do_clo);
2128 tcg_gen_helper_0_0(do_clz);
2131 #if defined(TARGET_MIPS64)
2133 tcg_gen_helper_0_0(do_dclo);
2137 tcg_gen_helper_0_0(do_dclz);
2143 generate_exception(ctx, EXCP_RI);
2146 gen_store_gpr(cpu_T[0], rd);
2147 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2151 static void gen_trap (DisasContext *ctx, uint32_t opc,
2152 int rs, int rt, int16_t imm)
2157 /* Load needed operands */
2165 /* Compare two registers */
2167 gen_load_gpr(cpu_T[0], rs);
2168 gen_load_gpr(cpu_T[1], rt);
2178 /* Compare register to immediate */
2179 if (rs != 0 || imm != 0) {
2180 gen_load_gpr(cpu_T[0], rs);
2181 tcg_gen_movi_tl(cpu_T[1], (int32_t)imm);
2188 case OPC_TEQ: /* rs == rs */
2189 case OPC_TEQI: /* r0 == 0 */
2190 case OPC_TGE: /* rs >= rs */
2191 case OPC_TGEI: /* r0 >= 0 */
2192 case OPC_TGEU: /* rs >= rs unsigned */
2193 case OPC_TGEIU: /* r0 >= 0 unsigned */
2195 tcg_gen_movi_tl(cpu_T[0], 1);
2197 case OPC_TLT: /* rs < rs */
2198 case OPC_TLTI: /* r0 < 0 */
2199 case OPC_TLTU: /* rs < rs unsigned */
2200 case OPC_TLTIU: /* r0 < 0 unsigned */
2201 case OPC_TNE: /* rs != rs */
2202 case OPC_TNEI: /* r0 != 0 */
2203 /* Never trap: treat as NOP. */
2207 generate_exception(ctx, EXCP_RI);
2238 generate_exception(ctx, EXCP_RI);
2242 save_cpu_state(ctx, 1);
2244 int l1 = gen_new_label();
2246 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
2247 tcg_gen_helper_0_1i(do_raise_exception, EXCP_TRAP);
2250 ctx->bstate = BS_STOP;
2253 static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2255 TranslationBlock *tb;
2257 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2260 tcg_gen_exit_tb((long)tb + n);
2267 /* Branches (before delay slot) */
2268 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2269 int rs, int rt, int32_t offset)
2271 target_ulong btarget = -1;
2275 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2276 #ifdef MIPS_DEBUG_DISAS
2277 if (loglevel & CPU_LOG_TB_IN_ASM) {
2279 "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2283 generate_exception(ctx, EXCP_RI);
2287 /* Load needed operands */
2293 /* Compare two registers */
2295 gen_load_gpr(cpu_T[0], rs);
2296 gen_load_gpr(cpu_T[1], rt);
2299 btarget = ctx->pc + 4 + offset;
2313 /* Compare to zero */
2315 gen_load_gpr(cpu_T[0], rs);
2318 btarget = ctx->pc + 4 + offset;
2322 /* Jump to immediate */
2323 btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2327 /* Jump to register */
2328 if (offset != 0 && offset != 16) {
2329 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2330 others are reserved. */
2331 MIPS_INVAL("jump hint");
2332 generate_exception(ctx, EXCP_RI);
2335 gen_save_breg_target(rs);
2338 MIPS_INVAL("branch/jump");
2339 generate_exception(ctx, EXCP_RI);
2343 /* No condition to be computed */
2345 case OPC_BEQ: /* rx == rx */
2346 case OPC_BEQL: /* rx == rx likely */
2347 case OPC_BGEZ: /* 0 >= 0 */
2348 case OPC_BGEZL: /* 0 >= 0 likely */
2349 case OPC_BLEZ: /* 0 <= 0 */
2350 case OPC_BLEZL: /* 0 <= 0 likely */
2352 ctx->hflags |= MIPS_HFLAG_B;
2353 MIPS_DEBUG("balways");
2355 case OPC_BGEZAL: /* 0 >= 0 */
2356 case OPC_BGEZALL: /* 0 >= 0 likely */
2357 /* Always take and link */
2359 ctx->hflags |= MIPS_HFLAG_B;
2360 MIPS_DEBUG("balways and link");
2362 case OPC_BNE: /* rx != rx */
2363 case OPC_BGTZ: /* 0 > 0 */
2364 case OPC_BLTZ: /* 0 < 0 */
2366 MIPS_DEBUG("bnever (NOP)");
2368 case OPC_BLTZAL: /* 0 < 0 */
2369 tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2370 gen_store_gpr(cpu_T[0], 31);
2371 MIPS_DEBUG("bnever and link");
2373 case OPC_BLTZALL: /* 0 < 0 likely */
2374 tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2375 gen_store_gpr(cpu_T[0], 31);
2376 /* Skip the instruction in the delay slot */
2377 MIPS_DEBUG("bnever, link and skip");
2380 case OPC_BNEL: /* rx != rx likely */
2381 case OPC_BGTZL: /* 0 > 0 likely */
2382 case OPC_BLTZL: /* 0 < 0 likely */
2383 /* Skip the instruction in the delay slot */
2384 MIPS_DEBUG("bnever and skip");
2388 ctx->hflags |= MIPS_HFLAG_B;
2389 MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
2393 ctx->hflags |= MIPS_HFLAG_B;
2394 MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
2397 ctx->hflags |= MIPS_HFLAG_BR;
2398 MIPS_DEBUG("jr %s", regnames[rs]);
2402 ctx->hflags |= MIPS_HFLAG_BR;
2403 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2406 MIPS_INVAL("branch/jump");
2407 generate_exception(ctx, EXCP_RI);
2414 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2415 regnames[rs], regnames[rt], btarget);
2419 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2420 regnames[rs], regnames[rt], btarget);
2424 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2425 regnames[rs], regnames[rt], btarget);
2429 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2430 regnames[rs], regnames[rt], btarget);
2434 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2438 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2442 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2448 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2452 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2456 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2460 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2464 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2468 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2472 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2477 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2479 ctx->hflags |= MIPS_HFLAG_BC;
2480 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2485 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2487 ctx->hflags |= MIPS_HFLAG_BL;
2488 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2491 MIPS_INVAL("conditional branch/jump");
2492 generate_exception(ctx, EXCP_RI);
2496 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2497 blink, ctx->hflags, btarget);
2499 ctx->btarget = btarget;
2501 tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2502 gen_store_gpr(cpu_T[0], blink);
2506 /* special3 bitfield operations */
2507 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2508 int rs, int lsb, int msb)
2510 gen_load_gpr(cpu_T[1], rs);
2515 tcg_gen_helper_0_2ii(do_ext, lsb, msb + 1);
2517 #if defined(TARGET_MIPS64)
2521 tcg_gen_helper_0_2ii(do_dext, lsb, msb + 1 + 32);
2526 tcg_gen_helper_0_2ii(do_dext, lsb + 32, msb + 1);
2531 tcg_gen_helper_0_2ii(do_dext, lsb, msb + 1);
2537 gen_load_gpr(cpu_T[0], rt);
2538 tcg_gen_helper_0_2ii(do_ins, lsb, msb - lsb + 1);
2540 #if defined(TARGET_MIPS64)
2544 gen_load_gpr(cpu_T[0], rt);
2545 tcg_gen_helper_0_2ii(do_dins, lsb, msb - lsb + 1 + 32);
2550 gen_load_gpr(cpu_T[0], rt);
2551 tcg_gen_helper_0_2ii(do_dins, lsb + 32, msb - lsb + 1);
2556 gen_load_gpr(cpu_T[0], rt);
2557 tcg_gen_helper_0_2ii(do_dins, lsb, msb - lsb + 1);
2562 MIPS_INVAL("bitops");
2563 generate_exception(ctx, EXCP_RI);
2566 gen_store_gpr(cpu_T[0], rt);
2569 /* CP0 (MMU and control) */
2570 #ifndef CONFIG_USER_ONLY
2571 static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2573 TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2575 tcg_gen_ld_i32(r_tmp, cpu_env, off);
2576 tcg_gen_ext_i32_tl(t, r_tmp);
2577 tcg_temp_free(r_tmp);
2580 static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2582 tcg_gen_ld_tl(t, cpu_env, off);
2583 tcg_gen_ext32s_tl(t, t);
2586 static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2588 TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2590 tcg_gen_trunc_tl_i32(r_tmp, t);
2591 tcg_gen_st_i32(r_tmp, cpu_env, off);
2592 tcg_temp_free(r_tmp);
2595 static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2597 tcg_gen_ext32s_tl(t, t);
2598 tcg_gen_st_tl(t, cpu_env, off);
2601 static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2603 const char *rn = "invalid";
2606 check_insn(env, ctx, ISA_MIPS32);
2612 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index));
2616 check_insn(env, ctx, ASE_MT);
2617 tcg_gen_helper_0_0(do_mfc0_mvpcontrol);
2621 check_insn(env, ctx, ASE_MT);
2622 tcg_gen_helper_0_0(do_mfc0_mvpconf0);
2626 check_insn(env, ctx, ASE_MT);
2627 tcg_gen_helper_0_0(do_mfc0_mvpconf1);
2637 tcg_gen_helper_0_0(do_mfc0_random);
2641 check_insn(env, ctx, ASE_MT);
2642 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl));
2646 check_insn(env, ctx, ASE_MT);
2647 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0));
2651 check_insn(env, ctx, ASE_MT);
2652 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1));
2656 check_insn(env, ctx, ASE_MT);
2657 gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_YQMask));
2661 check_insn(env, ctx, ASE_MT);
2662 gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPESchedule));
2666 check_insn(env, ctx, ASE_MT);
2667 gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPEScheFBack));
2668 rn = "VPEScheFBack";
2671 check_insn(env, ctx, ASE_MT);
2672 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt));
2682 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
2683 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2687 check_insn(env, ctx, ASE_MT);
2688 tcg_gen_helper_0_0(do_mfc0_tcstatus);
2692 check_insn(env, ctx, ASE_MT);
2693 tcg_gen_helper_0_0(do_mfc0_tcbind);
2697 check_insn(env, ctx, ASE_MT);
2698 tcg_gen_helper_0_0(do_mfc0_tcrestart);
2702 check_insn(env, ctx, ASE_MT);
2703 tcg_gen_helper_0_0(do_mfc0_tchalt);
2707 check_insn(env, ctx, ASE_MT);
2708 tcg_gen_helper_0_0(do_mfc0_tccontext);
2712 check_insn(env, ctx, ASE_MT);
2713 tcg_gen_helper_0_0(do_mfc0_tcschedule);
2717 check_insn(env, ctx, ASE_MT);
2718 tcg_gen_helper_0_0(do_mfc0_tcschefback);
2728 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
2729 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2739 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
2740 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2744 // tcg_gen_helper_0_0(do_mfc0_contextconfig); /* SmartMIPS ASE */
2745 rn = "ContextConfig";
2754 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask));
2758 check_insn(env, ctx, ISA_MIPS32R2);
2759 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain));
2769 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired));
2773 check_insn(env, ctx, ISA_MIPS32R2);
2774 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0));
2778 check_insn(env, ctx, ISA_MIPS32R2);
2779 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1));
2783 check_insn(env, ctx, ISA_MIPS32R2);
2784 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2));
2788 check_insn(env, ctx, ISA_MIPS32R2);
2789 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3));
2793 check_insn(env, ctx, ISA_MIPS32R2);
2794 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4));
2804 check_insn(env, ctx, ISA_MIPS32R2);
2805 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna));
2815 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
2816 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2826 tcg_gen_helper_0_0(do_mfc0_count);
2829 /* 6,7 are implementation dependent */
2837 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
2838 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2848 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare));
2851 /* 6,7 are implementation dependent */
2859 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status));
2863 check_insn(env, ctx, ISA_MIPS32R2);
2864 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl));
2868 check_insn(env, ctx, ISA_MIPS32R2);
2869 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl));
2873 check_insn(env, ctx, ISA_MIPS32R2);
2874 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
2884 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause));
2894 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
2895 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2905 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid));
2909 check_insn(env, ctx, ISA_MIPS32R2);
2910 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase));
2920 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0));
2924 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1));
2928 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2));
2932 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3));
2935 /* 4,5 are reserved */
2936 /* 6,7 are implementation dependent */
2938 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6));
2942 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7));
2952 tcg_gen_helper_0_0(do_mfc0_lladdr);
2962 tcg_gen_helper_0_1i(do_mfc0_watchlo, sel);
2972 tcg_gen_helper_0_1i(do_mfc0_watchhi, sel);
2982 #if defined(TARGET_MIPS64)
2983 check_insn(env, ctx, ISA_MIPS3);
2984 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
2985 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2994 /* Officially reserved, but sel 0 is used for R1x000 framemask */
2997 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask));
3006 rn = "'Diagnostic"; /* implementation dependent */
3011 tcg_gen_helper_0_0(do_mfc0_debug); /* EJTAG support */
3015 // tcg_gen_helper_0_0(do_mfc0_tracecontrol); /* PDtrace support */
3016 rn = "TraceControl";
3019 // tcg_gen_helper_0_0(do_mfc0_tracecontrol2); /* PDtrace support */
3020 rn = "TraceControl2";
3023 // tcg_gen_helper_0_0(do_mfc0_usertracedata); /* PDtrace support */
3024 rn = "UserTraceData";
3027 // tcg_gen_helper_0_0(do_mfc0_debug); /* PDtrace support */
3038 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
3039 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3049 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0));
3050 rn = "Performance0";
3053 // tcg_gen_helper_0_0(do_mfc0_performance1);
3054 rn = "Performance1";
3057 // tcg_gen_helper_0_0(do_mfc0_performance2);
3058 rn = "Performance2";
3061 // tcg_gen_helper_0_0(do_mfc0_performance3);
3062 rn = "Performance3";
3065 // tcg_gen_helper_0_0(do_mfc0_performance4);
3066 rn = "Performance4";
3069 // tcg_gen_helper_0_0(do_mfc0_performance5);
3070 rn = "Performance5";
3073 // tcg_gen_helper_0_0(do_mfc0_performance6);
3074 rn = "Performance6";
3077 // tcg_gen_helper_0_0(do_mfc0_performance7);
3078 rn = "Performance7";
3103 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo));
3110 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo));
3123 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi));
3130 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi));
3140 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3141 tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3152 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
3162 #if defined MIPS_DEBUG_DISAS
3163 if (loglevel & CPU_LOG_TB_IN_ASM) {
3164 fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3171 #if defined MIPS_DEBUG_DISAS
3172 if (loglevel & CPU_LOG_TB_IN_ASM) {
3173 fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3177 generate_exception(ctx, EXCP_RI);
3180 static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3182 const char *rn = "invalid";
3185 check_insn(env, ctx, ISA_MIPS32);
3191 tcg_gen_helper_0_0(do_mtc0_index);
3195 check_insn(env, ctx, ASE_MT);
3196 tcg_gen_helper_0_0(do_mtc0_mvpcontrol);
3200 check_insn(env, ctx, ASE_MT);
3205 check_insn(env, ctx, ASE_MT);
3220 check_insn(env, ctx, ASE_MT);
3221 tcg_gen_helper_0_0(do_mtc0_vpecontrol);
3225 check_insn(env, ctx, ASE_MT);
3226 tcg_gen_helper_0_0(do_mtc0_vpeconf0);
3230 check_insn(env, ctx, ASE_MT);
3231 tcg_gen_helper_0_0(do_mtc0_vpeconf1);
3235 check_insn(env, ctx, ASE_MT);
3236 tcg_gen_helper_0_0(do_mtc0_yqmask);
3240 check_insn(env, ctx, ASE_MT);
3241 gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_VPESchedule));
3245 check_insn(env, ctx, ASE_MT);
3246 gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_VPEScheFBack));
3247 rn = "VPEScheFBack";
3250 check_insn(env, ctx, ASE_MT);
3251 tcg_gen_helper_0_0(do_mtc0_vpeopt);
3261 tcg_gen_helper_0_0(do_mtc0_entrylo0);
3265 check_insn(env, ctx, ASE_MT);
3266 tcg_gen_helper_0_0(do_mtc0_tcstatus);
3270 check_insn(env, ctx, ASE_MT);
3271 tcg_gen_helper_0_0(do_mtc0_tcbind);
3275 check_insn(env, ctx, ASE_MT);
3276 tcg_gen_helper_0_0(do_mtc0_tcrestart);
3280 check_insn(env, ctx, ASE_MT);
3281 tcg_gen_helper_0_0(do_mtc0_tchalt);
3285 check_insn(env, ctx, ASE_MT);
3286 tcg_gen_helper_0_0(do_mtc0_tccontext);
3290 check_insn(env, ctx, ASE_MT);
3291 tcg_gen_helper_0_0(do_mtc0_tcschedule);
3295 check_insn(env, ctx, ASE_MT);
3296 tcg_gen_helper_0_0(do_mtc0_tcschefback);
3306 tcg_gen_helper_0_0(do_mtc0_entrylo1);
3316 tcg_gen_helper_0_0(do_mtc0_context);
3320 // tcg_gen_helper_0_0(do_mtc0_contextconfig); /* SmartMIPS ASE */
3321 rn = "ContextConfig";
3330 tcg_gen_helper_0_0(do_mtc0_pagemask);
3334 check_insn(env, ctx, ISA_MIPS32R2);
3335 tcg_gen_helper_0_0(do_mtc0_pagegrain);
3345 tcg_gen_helper_0_0(do_mtc0_wired);
3349 check_insn(env, ctx, ISA_MIPS32R2);
3350 tcg_gen_helper_0_0(do_mtc0_srsconf0);
3354 check_insn(env, ctx, ISA_MIPS32R2);
3355 tcg_gen_helper_0_0(do_mtc0_srsconf1);
3359 check_insn(env, ctx, ISA_MIPS32R2);
3360 tcg_gen_helper_0_0(do_mtc0_srsconf2);
3364 check_insn(env, ctx, ISA_MIPS32R2);
3365 tcg_gen_helper_0_0(do_mtc0_srsconf3);
3369 check_insn(env, ctx, ISA_MIPS32R2);
3370 tcg_gen_helper_0_0(do_mtc0_srsconf4);
3380 check_insn(env, ctx, ISA_MIPS32R2);
3381 tcg_gen_helper_0_0(do_mtc0_hwrena);
3395 tcg_gen_helper_0_0(do_mtc0_count);
3398 /* 6,7 are implementation dependent */
3402 /* Stop translation as we may have switched the execution mode */
3403 ctx->bstate = BS_STOP;
3408 tcg_gen_helper_0_0(do_mtc0_entryhi);
3418 tcg_gen_helper_0_0(do_mtc0_compare);
3421 /* 6,7 are implementation dependent */
3425 /* Stop translation as we may have switched the execution mode */
3426 ctx->bstate = BS_STOP;
3431 tcg_gen_helper_0_0(do_mtc0_status);
3432 /* BS_STOP isn't good enough here, hflags may have changed. */
3433 gen_save_pc(ctx->pc + 4);
3434 ctx->bstate = BS_EXCP;
3438 check_insn(env, ctx, ISA_MIPS32R2);
3439 tcg_gen_helper_0_0(do_mtc0_intctl);
3440 /* Stop translation as we may have switched the execution mode */
3441 ctx->bstate = BS_STOP;
3445 check_insn(env, ctx, ISA_MIPS32R2);
3446 tcg_gen_helper_0_0(do_mtc0_srsctl);
3447 /* Stop translation as we may have switched the execution mode */
3448 ctx->bstate = BS_STOP;
3452 check_insn(env, ctx, ISA_MIPS32R2);
3453 gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
3454 /* Stop translation as we may have switched the execution mode */
3455 ctx->bstate = BS_STOP;
3465 tcg_gen_helper_0_0(do_mtc0_cause);
3471 /* Stop translation as we may have switched the execution mode */
3472 ctx->bstate = BS_STOP;
3477 gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_EPC));
3491 check_insn(env, ctx, ISA_MIPS32R2);
3492 tcg_gen_helper_0_0(do_mtc0_ebase);
3502 tcg_gen_helper_0_0(do_mtc0_config0);
3504 /* Stop translation as we may have switched the execution mode */
3505 ctx->bstate = BS_STOP;
3508 /* ignored, read only */
3512 tcg_gen_helper_0_0(do_mtc0_config2);
3514 /* Stop translation as we may have switched the execution mode */
3515 ctx->bstate = BS_STOP;
3518 /* ignored, read only */
3521 /* 4,5 are reserved */
3522 /* 6,7 are implementation dependent */
3532 rn = "Invalid config selector";
3549 tcg_gen_helper_0_1i(do_mtc0_watchlo, sel);
3559 tcg_gen_helper_0_1i(do_mtc0_watchhi, sel);
3569 #if defined(TARGET_MIPS64)
3570 check_insn(env, ctx, ISA_MIPS3);
3571 tcg_gen_helper_0_0(do_mtc0_xcontext);
3580 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3583 tcg_gen_helper_0_0(do_mtc0_framemask);
3592 rn = "Diagnostic"; /* implementation dependent */
3597 tcg_gen_helper_0_0(do_mtc0_debug); /* EJTAG support */
3598 /* BS_STOP isn't good enough here, hflags may have changed. */
3599 gen_save_pc(ctx->pc + 4);
3600 ctx->bstate = BS_EXCP;
3604 // tcg_gen_helper_0_0(do_mtc0_tracecontrol); /* PDtrace support */
3605 rn = "TraceControl";
3606 /* Stop translation as we may have switched the execution mode */
3607 ctx->bstate = BS_STOP;
3610 // tcg_gen_helper_0_0(do_mtc0_tracecontrol2); /* PDtrace support */
3611 rn = "TraceControl2";
3612 /* Stop translation as we may have switched the execution mode */
3613 ctx->bstate = BS_STOP;
3616 /* Stop translation as we may have switched the execution mode */
3617 ctx->bstate = BS_STOP;
3618 // tcg_gen_helper_0_0(do_mtc0_usertracedata); /* PDtrace support */
3619 rn = "UserTraceData";
3620 /* Stop translation as we may have switched the execution mode */
3621 ctx->bstate = BS_STOP;
3624 // tcg_gen_helper_0_0(do_mtc0_debug); /* PDtrace support */
3625 /* Stop translation as we may have switched the execution mode */
3626 ctx->bstate = BS_STOP;
3637 gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_DEPC));
3647 tcg_gen_helper_0_0(do_mtc0_performance0);
3648 rn = "Performance0";
3651 // tcg_gen_helper_0_0(do_mtc0_performance1);
3652 rn = "Performance1";
3655 // tcg_gen_helper_0_0(do_mtc0_performance2);
3656 rn = "Performance2";
3659 // tcg_gen_helper_0_0(do_mtc0_performance3);
3660 rn = "Performance3";
3663 // tcg_gen_helper_0_0(do_mtc0_performance4);
3664 rn = "Performance4";
3667 // tcg_gen_helper_0_0(do_mtc0_performance5);
3668 rn = "Performance5";
3671 // tcg_gen_helper_0_0(do_mtc0_performance6);
3672 rn = "Performance6";
3675 // tcg_gen_helper_0_0(do_mtc0_performance7);
3676 rn = "Performance7";
3702 tcg_gen_helper_0_0(do_mtc0_taglo);
3709 tcg_gen_helper_0_0(do_mtc0_datalo);
3722 tcg_gen_helper_0_0(do_mtc0_taghi);
3729 tcg_gen_helper_0_0(do_mtc0_datahi);
3740 gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_ErrorEPC));
3751 gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
3757 /* Stop translation as we may have switched the execution mode */
3758 ctx->bstate = BS_STOP;
3763 #if defined MIPS_DEBUG_DISAS
3764 if (loglevel & CPU_LOG_TB_IN_ASM) {
3765 fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3772 #if defined MIPS_DEBUG_DISAS
3773 if (loglevel & CPU_LOG_TB_IN_ASM) {
3774 fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3778 generate_exception(ctx, EXCP_RI);
3781 #if defined(TARGET_MIPS64)
3782 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3784 const char *rn = "invalid";
3787 check_insn(env, ctx, ISA_MIPS64);
3793 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index));
3797 check_insn(env, ctx, ASE_MT);
3798 tcg_gen_helper_0_0(do_mfc0_mvpcontrol);
3802 check_insn(env, ctx, ASE_MT);
3803 tcg_gen_helper_0_0(do_mfc0_mvpconf0);
3807 check_insn(env, ctx, ASE_MT);
3808 tcg_gen_helper_0_0(do_mfc0_mvpconf1);
3818 tcg_gen_helper_0_0(do_mfc0_random);
3822 check_insn(env, ctx, ASE_MT);
3823 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl));
3827 check_insn(env, ctx, ASE_MT);
3828 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0));
3832 check_insn(env, ctx, ASE_MT);
3833 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1));
3837 check_insn(env, ctx, ASE_MT);
3838 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask));
3842 check_insn(env, ctx, ASE_MT);
3843 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
3847 check_insn(env, ctx, ASE_MT);
3848 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3849 rn = "VPEScheFBack";
3852 check_insn(env, ctx, ASE_MT);
3853 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt));
3863 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
3867 check_insn(env, ctx, ASE_MT);
3868 tcg_gen_helper_0_0(do_mfc0_tcstatus);
3872 check_insn(env, ctx, ASE_MT);
3873 tcg_gen_helper_0_0(do_mfc0_tcbind);
3877 check_insn(env, ctx, ASE_MT);
3878 tcg_gen_helper_0_0(do_dmfc0_tcrestart);
3882 check_insn(env, ctx, ASE_MT);
3883 tcg_gen_helper_0_0(do_dmfc0_tchalt);
3887 check_insn(env, ctx, ASE_MT);
3888 tcg_gen_helper_0_0(do_dmfc0_tccontext);
3892 check_insn(env, ctx, ASE_MT);
3893 tcg_gen_helper_0_0(do_dmfc0_tcschedule);
3897 check_insn(env, ctx, ASE_MT);
3898 tcg_gen_helper_0_0(do_dmfc0_tcschefback);
3908 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
3918 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
3922 // tcg_gen_helper_0_0(do_dmfc0_contextconfig); /* SmartMIPS ASE */
3923 rn = "ContextConfig";
3932 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask));
3936 check_insn(env, ctx, ISA_MIPS32R2);
3937 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain));
3947 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired));
3951 check_insn(env, ctx, ISA_MIPS32R2);
3952 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0));
3956 check_insn(env, ctx, ISA_MIPS32R2);
3957 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1));
3961 check_insn(env, ctx, ISA_MIPS32R2);
3962 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2));
3966 check_insn(env, ctx, ISA_MIPS32R2);
3967 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3));
3971 check_insn(env, ctx, ISA_MIPS32R2);
3972 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4));
3982 check_insn(env, ctx, ISA_MIPS32R2);
3983 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna));
3993 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
4003 tcg_gen_helper_0_0(do_mfc0_count);
4006 /* 6,7 are implementation dependent */
4014 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
4024 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare));
4027 /* 6,7 are implementation dependent */
4035 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status));
4039 check_insn(env, ctx, ISA_MIPS32R2);
4040 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl));
4044 check_insn(env, ctx, ISA_MIPS32R2);
4045 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl));
4049 check_insn(env, ctx, ISA_MIPS32R2);
4050 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
4060 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause));
4070 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4080 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid));
4084 check_insn(env, ctx, ISA_MIPS32R2);
4085 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase));
4095 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0));
4099 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1));
4103 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2));
4107 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3));
4110 /* 6,7 are implementation dependent */
4112 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6));
4116 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7));
4126 tcg_gen_helper_0_0(do_dmfc0_lladdr);
4136 tcg_gen_helper_0_1i(do_dmfc0_watchlo, sel);
4146 tcg_gen_helper_0_1i(do_mfc0_watchhi, sel);
4156 check_insn(env, ctx, ISA_MIPS3);
4157 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
4165 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4168 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask));
4177 rn = "'Diagnostic"; /* implementation dependent */
4182 tcg_gen_helper_0_0(do_mfc0_debug); /* EJTAG support */
4186 // tcg_gen_helper_0_0(do_dmfc0_tracecontrol); /* PDtrace support */
4187 rn = "TraceControl";
4190 // tcg_gen_helper_0_0(do_dmfc0_tracecontrol2); /* PDtrace support */
4191 rn = "TraceControl2";
4194 // tcg_gen_helper_0_0(do_dmfc0_usertracedata); /* PDtrace support */
4195 rn = "UserTraceData";
4198 // tcg_gen_helper_0_0(do_dmfc0_debug); /* PDtrace support */
4209 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4219 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0));
4220 rn = "Performance0";
4223 // tcg_gen_helper_0_0(do_dmfc0_performance1);
4224 rn = "Performance1";
4227 // tcg_gen_helper_0_0(do_dmfc0_performance2);
4228 rn = "Performance2";
4231 // tcg_gen_helper_0_0(do_dmfc0_performance3);
4232 rn = "Performance3";
4235 // tcg_gen_helper_0_0(do_dmfc0_performance4);
4236 rn = "Performance4";
4239 // tcg_gen_helper_0_0(do_dmfc0_performance5);
4240 rn = "Performance5";
4243 // tcg_gen_helper_0_0(do_dmfc0_performance6);
4244 rn = "Performance6";
4247 // tcg_gen_helper_0_0(do_dmfc0_performance7);
4248 rn = "Performance7";
4273 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo));
4280 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo));
4293 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi));
4300 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi));
4310 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4321 gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
4331 #if defined MIPS_DEBUG_DISAS
4332 if (loglevel & CPU_LOG_TB_IN_ASM) {
4333 fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4340 #if defined MIPS_DEBUG_DISAS
4341 if (loglevel & CPU_LOG_TB_IN_ASM) {
4342 fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4346 generate_exception(ctx, EXCP_RI);
4349 static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4351 const char *rn = "invalid";
4354 check_insn(env, ctx, ISA_MIPS64);
4360 tcg_gen_helper_0_0(do_mtc0_index);
4364 check_insn(env, ctx, ASE_MT);
4365 tcg_gen_helper_0_0(do_mtc0_mvpcontrol);
4369 check_insn(env, ctx, ASE_MT);
4374 check_insn(env, ctx, ASE_MT);
4389 check_insn(env, ctx, ASE_MT);
4390 tcg_gen_helper_0_0(do_mtc0_vpecontrol);
4394 check_insn(env, ctx, ASE_MT);
4395 tcg_gen_helper_0_0(do_mtc0_vpeconf0);
4399 check_insn(env, ctx, ASE_MT);
4400 tcg_gen_helper_0_0(do_mtc0_vpeconf1);
4404 check_insn(env, ctx, ASE_MT);
4405 tcg_gen_helper_0_0(do_mtc0_yqmask);
4409 check_insn(env, ctx, ASE_MT);
4410 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
4414 check_insn(env, ctx, ASE_MT);
4415 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4416 rn = "VPEScheFBack";
4419 check_insn(env, ctx, ASE_MT);
4420 tcg_gen_helper_0_0(do_mtc0_vpeopt);
4430 tcg_gen_helper_0_0(do_mtc0_entrylo0);
4434 check_insn(env, ctx, ASE_MT);
4435 tcg_gen_helper_0_0(do_mtc0_tcstatus);
4439 check_insn(env, ctx, ASE_MT);
4440 tcg_gen_helper_0_0(do_mtc0_tcbind);
4444 check_insn(env, ctx, ASE_MT);
4445 tcg_gen_helper_0_0(do_mtc0_tcrestart);
4449 check_insn(env, ctx, ASE_MT);
4450 tcg_gen_helper_0_0(do_mtc0_tchalt);
4454 check_insn(env, ctx, ASE_MT);
4455 tcg_gen_helper_0_0(do_mtc0_tccontext);
4459 check_insn(env, ctx, ASE_MT);
4460 tcg_gen_helper_0_0(do_mtc0_tcschedule);
4464 check_insn(env, ctx, ASE_MT);
4465 tcg_gen_helper_0_0(do_mtc0_tcschefback);
4475 tcg_gen_helper_0_0(do_mtc0_entrylo1);
4485 tcg_gen_helper_0_0(do_mtc0_context);
4489 // tcg_gen_helper_0_0(do_mtc0_contextconfig); /* SmartMIPS ASE */
4490 rn = "ContextConfig";
4499 tcg_gen_helper_0_0(do_mtc0_pagemask);
4503 check_insn(env, ctx, ISA_MIPS32R2);
4504 tcg_gen_helper_0_0(do_mtc0_pagegrain);
4514 tcg_gen_helper_0_0(do_mtc0_wired);
4518 check_insn(env, ctx, ISA_MIPS32R2);
4519 tcg_gen_helper_0_0(do_mtc0_srsconf0);
4523 check_insn(env, ctx, ISA_MIPS32R2);
4524 tcg_gen_helper_0_0(do_mtc0_srsconf1);
4528 check_insn(env, ctx, ISA_MIPS32R2);
4529 tcg_gen_helper_0_0(do_mtc0_srsconf2);
4533 check_insn(env, ctx, ISA_MIPS32R2);
4534 tcg_gen_helper_0_0(do_mtc0_srsconf3);
4538 check_insn(env, ctx, ISA_MIPS32R2);
4539 tcg_gen_helper_0_0(do_mtc0_srsconf4);
4549 check_insn(env, ctx, ISA_MIPS32R2);
4550 tcg_gen_helper_0_0(do_mtc0_hwrena);
4564 tcg_gen_helper_0_0(do_mtc0_count);
4567 /* 6,7 are implementation dependent */
4571 /* Stop translation as we may have switched the execution mode */
4572 ctx->bstate = BS_STOP;
4577 tcg_gen_helper_0_0(do_mtc0_entryhi);
4587 tcg_gen_helper_0_0(do_mtc0_compare);
4590 /* 6,7 are implementation dependent */
4594 /* Stop translation as we may have switched the execution mode */
4595 ctx->bstate = BS_STOP;
4600 tcg_gen_helper_0_0(do_mtc0_status);
4601 /* BS_STOP isn't good enough here, hflags may have changed. */
4602 gen_save_pc(ctx->pc + 4);
4603 ctx->bstate = BS_EXCP;
4607 check_insn(env, ctx, ISA_MIPS32R2);
4608 tcg_gen_helper_0_0(do_mtc0_intctl);
4609 /* Stop translation as we may have switched the execution mode */
4610 ctx->bstate = BS_STOP;
4614 check_insn(env, ctx, ISA_MIPS32R2);
4615 tcg_gen_helper_0_0(do_mtc0_srsctl);
4616 /* Stop translation as we may have switched the execution mode */
4617 ctx->bstate = BS_STOP;
4621 check_insn(env, ctx, ISA_MIPS32R2);
4622 gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
4623 /* Stop translation as we may have switched the execution mode */
4624 ctx->bstate = BS_STOP;
4634 tcg_gen_helper_0_0(do_mtc0_cause);
4640 /* Stop translation as we may have switched the execution mode */
4641 ctx->bstate = BS_STOP;
4646 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4660 check_insn(env, ctx, ISA_MIPS32R2);
4661 tcg_gen_helper_0_0(do_mtc0_ebase);
4671 tcg_gen_helper_0_0(do_mtc0_config0);
4673 /* Stop translation as we may have switched the execution mode */
4674 ctx->bstate = BS_STOP;
4681 tcg_gen_helper_0_0(do_mtc0_config2);
4683 /* Stop translation as we may have switched the execution mode */
4684 ctx->bstate = BS_STOP;
4690 /* 6,7 are implementation dependent */
4692 rn = "Invalid config selector";
4709 tcg_gen_helper_0_1i(do_mtc0_watchlo, sel);
4719 tcg_gen_helper_0_1i(do_mtc0_watchhi, sel);
4729 check_insn(env, ctx, ISA_MIPS3);
4730 tcg_gen_helper_0_0(do_mtc0_xcontext);
4738 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4741 tcg_gen_helper_0_0(do_mtc0_framemask);
4750 rn = "Diagnostic"; /* implementation dependent */
4755 tcg_gen_helper_0_0(do_mtc0_debug); /* EJTAG support */
4756 /* BS_STOP isn't good enough here, hflags may have changed. */
4757 gen_save_pc(ctx->pc + 4);
4758 ctx->bstate = BS_EXCP;
4762 // tcg_gen_helper_0_0(do_mtc0_tracecontrol); /* PDtrace support */
4763 /* Stop translation as we may have switched the execution mode */
4764 ctx->bstate = BS_STOP;
4765 rn = "TraceControl";
4768 // tcg_gen_helper_0_0(do_mtc0_tracecontrol2); /* PDtrace support */
4769 /* Stop translation as we may have switched the execution mode */
4770 ctx->bstate = BS_STOP;
4771 rn = "TraceControl2";
4774 // tcg_gen_helper_0_0(do_mtc0_usertracedata); /* PDtrace support */
4775 /* Stop translation as we may have switched the execution mode */
4776 ctx->bstate = BS_STOP;
4777 rn = "UserTraceData";
4780 // tcg_gen_helper_0_0(do_mtc0_debug); /* PDtrace support */
4781 /* Stop translation as we may have switched the execution mode */
4782 ctx->bstate = BS_STOP;
4793 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4803 tcg_gen_helper_0_0(do_mtc0_performance0);
4804 rn = "Performance0";
4807 // tcg_gen_helper_0_0(do_mtc0_performance1);
4808 rn = "Performance1";
4811 // tcg_gen_helper_0_0(do_mtc0_performance2);
4812 rn = "Performance2";
4815 // tcg_gen_helper_0_0(do_mtc0_performance3);
4816 rn = "Performance3";
4819 // tcg_gen_helper_0_0(do_mtc0_performance4);
4820 rn = "Performance4";
4823 // tcg_gen_helper_0_0(do_mtc0_performance5);
4824 rn = "Performance5";
4827 // tcg_gen_helper_0_0(do_mtc0_performance6);
4828 rn = "Performance6";
4831 // tcg_gen_helper_0_0(do_mtc0_performance7);
4832 rn = "Performance7";
4858 tcg_gen_helper_0_0(do_mtc0_taglo);
4865 tcg_gen_helper_0_0(do_mtc0_datalo);
4878 tcg_gen_helper_0_0(do_mtc0_taghi);
4885 tcg_gen_helper_0_0(do_mtc0_datahi);
4896 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4907 gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
4913 /* Stop translation as we may have switched the execution mode */
4914 ctx->bstate = BS_STOP;
4919 #if defined MIPS_DEBUG_DISAS
4920 if (loglevel & CPU_LOG_TB_IN_ASM) {
4921 fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4928 #if defined MIPS_DEBUG_DISAS
4929 if (loglevel & CPU_LOG_TB_IN_ASM) {
4930 fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4934 generate_exception(ctx, EXCP_RI);
4936 #endif /* TARGET_MIPS64 */
4938 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4939 int u, int sel, int h)
4941 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4943 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4944 ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4945 (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4946 tcg_gen_movi_tl(cpu_T[0], -1);
4947 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4948 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4949 tcg_gen_movi_tl(cpu_T[0], -1);
4955 tcg_gen_helper_0_0(do_mftc0_tcstatus);
4958 tcg_gen_helper_0_0(do_mftc0_tcbind);
4961 tcg_gen_helper_0_0(do_mftc0_tcrestart);
4964 tcg_gen_helper_0_0(do_mftc0_tchalt);
4967 tcg_gen_helper_0_0(do_mftc0_tccontext);
4970 tcg_gen_helper_0_0(do_mftc0_tcschedule);
4973 tcg_gen_helper_0_0(do_mftc0_tcschefback);
4976 gen_mfc0(env, ctx, rt, sel);
4983 tcg_gen_helper_0_0(do_mftc0_entryhi);
4986 gen_mfc0(env, ctx, rt, sel);
4992 tcg_gen_helper_0_0(do_mftc0_status);
4995 gen_mfc0(env, ctx, rt, sel);
5001 tcg_gen_helper_0_0(do_mftc0_debug);
5004 gen_mfc0(env, ctx, rt, sel);
5009 gen_mfc0(env, ctx, rt, sel);
5011 } else switch (sel) {
5012 /* GPR registers. */
5014 tcg_gen_helper_0_1i(do_mftgpr, rt);
5016 /* Auxiliary CPU registers */
5020 tcg_gen_helper_0_1i(do_mftlo, 0);
5023 tcg_gen_helper_0_1i(do_mfthi, 0);
5026 tcg_gen_helper_0_1i(do_mftacx, 0);
5029 tcg_gen_helper_0_1i(do_mftlo, 1);
5032 tcg_gen_helper_0_1i(do_mfthi, 1);
5035 tcg_gen_helper_0_1i(do_mftacx, 1);
5038 tcg_gen_helper_0_1i(do_mftlo, 2);
5041 tcg_gen_helper_0_1i(do_mfthi, 2);
5044 tcg_gen_helper_0_1i(do_mftacx, 2);
5047 tcg_gen_helper_0_1i(do_mftlo, 3);
5050 tcg_gen_helper_0_1i(do_mfthi, 3);
5053 tcg_gen_helper_0_1i(do_mftacx, 3);
5056 tcg_gen_helper_0_0(do_mftdsp);
5062 /* Floating point (COP1). */
5064 /* XXX: For now we support only a single FPU context. */
5066 gen_load_fpr32(fpu32_T[0], rt);
5067 tcg_gen_ext_i32_tl(cpu_T[0], fpu32_T[0]);
5069 gen_load_fpr32h(fpu32h_T[0], rt);
5070 tcg_gen_ext_i32_tl(cpu_T[0], fpu32h_T[0]);
5074 /* XXX: For now we support only a single FPU context. */
5075 tcg_gen_helper_0_1i(do_cfc1, rt);
5077 /* COP2: Not implemented. */
5084 #if defined MIPS_DEBUG_DISAS
5085 if (loglevel & CPU_LOG_TB_IN_ASM) {
5086 fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5093 #if defined MIPS_DEBUG_DISAS
5094 if (loglevel & CPU_LOG_TB_IN_ASM) {
5095 fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5099 generate_exception(ctx, EXCP_RI);
5102 static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5103 int u, int sel, int h)
5105 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5107 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5108 ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
5109 (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
5111 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5112 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5119 tcg_gen_helper_0_0(do_mttc0_tcstatus);
5122 tcg_gen_helper_0_0(do_mttc0_tcbind);
5125 tcg_gen_helper_0_0(do_mttc0_tcrestart);
5128 tcg_gen_helper_0_0(do_mttc0_tchalt);
5131 tcg_gen_helper_0_0(do_mttc0_tccontext);
5134 tcg_gen_helper_0_0(do_mttc0_tcschedule);
5137 tcg_gen_helper_0_0(do_mttc0_tcschefback);
5140 gen_mtc0(env, ctx, rd, sel);
5147 tcg_gen_helper_0_0(do_mttc0_entryhi);
5150 gen_mtc0(env, ctx, rd, sel);
5156 tcg_gen_helper_0_0(do_mttc0_status);
5159 gen_mtc0(env, ctx, rd, sel);
5165 tcg_gen_helper_0_0(do_mttc0_debug);
5168 gen_mtc0(env, ctx, rd, sel);
5173 gen_mtc0(env, ctx, rd, sel);
5175 } else switch (sel) {
5176 /* GPR registers. */
5178 tcg_gen_helper_0_1i(do_mttgpr, rd);
5180 /* Auxiliary CPU registers */
5184 tcg_gen_helper_0_1i(do_mttlo, 0);
5187 tcg_gen_helper_0_1i(do_mtthi, 0);
5190 tcg_gen_helper_0_1i(do_mttacx, 0);
5193 tcg_gen_helper_0_1i(do_mttlo, 1);
5196 tcg_gen_helper_0_1i(do_mtthi, 1);
5199 tcg_gen_helper_0_1i(do_mttacx, 1);
5202 tcg_gen_helper_0_1i(do_mttlo, 2);
5205 tcg_gen_helper_0_1i(do_mtthi, 2);
5208 tcg_gen_helper_0_1i(do_mttacx, 2);
5211 tcg_gen_helper_0_1i(do_mttlo, 3);
5214 tcg_gen_helper_0_1i(do_mtthi, 3);
5217 tcg_gen_helper_0_1i(do_mttacx, 3);
5220 tcg_gen_helper_0_0(do_mttdsp);
5226 /* Floating point (COP1). */
5228 /* XXX: For now we support only a single FPU context. */
5230 tcg_gen_trunc_tl_i32(fpu32_T[0], cpu_T[0]);
5231 gen_store_fpr32(fpu32_T[0], rd);
5233 tcg_gen_trunc_tl_i32(fpu32h_T[0], cpu_T[0]);
5234 gen_store_fpr32h(fpu32h_T[0], rd);
5238 /* XXX: For now we support only a single FPU context. */
5239 tcg_gen_helper_0_1i(do_ctc1, rd);
5241 /* COP2: Not implemented. */
5248 #if defined MIPS_DEBUG_DISAS
5249 if (loglevel & CPU_LOG_TB_IN_ASM) {
5250 fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5257 #if defined MIPS_DEBUG_DISAS
5258 if (loglevel & CPU_LOG_TB_IN_ASM) {
5259 fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5263 generate_exception(ctx, EXCP_RI);
5266 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5268 const char *opn = "ldst";
5276 gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
5277 gen_store_gpr(cpu_T[0], rt);
5281 gen_load_gpr(cpu_T[0], rt);
5282 save_cpu_state(ctx, 1);
5283 gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
5286 #if defined(TARGET_MIPS64)
5288 check_insn(env, ctx, ISA_MIPS3);
5293 gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
5294 gen_store_gpr(cpu_T[0], rt);
5298 check_insn(env, ctx, ISA_MIPS3);
5299 gen_load_gpr(cpu_T[0], rt);
5300 save_cpu_state(ctx, 1);
5301 gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
5306 check_insn(env, ctx, ASE_MT);
5311 gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
5312 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5313 gen_store_gpr(cpu_T[0], rd);
5317 check_insn(env, ctx, ASE_MT);
5318 gen_load_gpr(cpu_T[0], rt);
5319 gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
5320 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5325 if (!env->tlb->do_tlbwi)
5327 tcg_gen_helper_0_0(env->tlb->do_tlbwi);
5331 if (!env->tlb->do_tlbwr)
5333 tcg_gen_helper_0_0(env->tlb->do_tlbwr);
5337 if (!env->tlb->do_tlbp)
5339 tcg_gen_helper_0_0(env->tlb->do_tlbp);
5343 if (!env->tlb->do_tlbr)
5345 tcg_gen_helper_0_0(env->tlb->do_tlbr);
5349 check_insn(env, ctx, ISA_MIPS2);
5350 save_cpu_state(ctx, 1);
5351 tcg_gen_helper_0_0(do_eret);
5352 ctx->bstate = BS_EXCP;
5356 check_insn(env, ctx, ISA_MIPS32);
5357 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5359 generate_exception(ctx, EXCP_RI);
5361 save_cpu_state(ctx, 1);
5362 tcg_gen_helper_0_0(do_deret);
5363 ctx->bstate = BS_EXCP;
5368 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5369 /* If we get an exception, we want to restart at next instruction */
5371 save_cpu_state(ctx, 1);
5373 tcg_gen_helper_0_0(do_wait);
5374 ctx->bstate = BS_EXCP;
5379 generate_exception(ctx, EXCP_RI);
5382 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5384 #endif /* !CONFIG_USER_ONLY */
5386 /* CP1 Branches (before delay slot) */
5387 static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5388 int32_t cc, int32_t offset)
5390 target_ulong btarget;
5391 const char *opn = "cp1 cond branch";
5394 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5396 btarget = ctx->pc + 4 + offset;
5415 ctx->hflags |= MIPS_HFLAG_BL;
5416 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5419 gen_op_bc1any2f(cc);
5423 gen_op_bc1any2t(cc);
5427 gen_op_bc1any4f(cc);
5431 gen_op_bc1any4t(cc);
5434 ctx->hflags |= MIPS_HFLAG_BC;
5435 tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5439 generate_exception (ctx, EXCP_RI);
5442 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5443 ctx->hflags, btarget);
5444 ctx->btarget = btarget;
5447 /* Coprocessor 1 (FPU) */
5449 #define FOP(func, fmt) (((fmt) << 21) | (func))
5451 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5453 const char *opn = "cp1 move";
5457 gen_load_fpr32(fpu32_T[0], fs);
5458 tcg_gen_ext_i32_tl(cpu_T[0], fpu32_T[0]);
5459 gen_store_gpr(cpu_T[0], rt);
5463 gen_load_gpr(cpu_T[0], rt);
5464 tcg_gen_trunc_tl_i32(fpu32_T[0], cpu_T[0]);
5465 gen_store_fpr32(fpu32_T[0], fs);
5469 tcg_gen_helper_0_1i(do_cfc1, fs);
5470 gen_store_gpr(cpu_T[0], rt);
5474 gen_load_gpr(cpu_T[0], rt);
5475 tcg_gen_helper_0_1i(do_ctc1, fs);
5479 gen_load_fpr64(ctx, fpu64_T[0], fs);
5480 tcg_gen_mov_tl(cpu_T[0], fpu64_T[0]);
5481 gen_store_gpr(cpu_T[0], rt);
5485 gen_load_gpr(cpu_T[0], rt);
5486 tcg_gen_mov_tl(fpu64_T[0], cpu_T[0]);
5487 gen_store_fpr64(ctx, fpu64_T[0], fs);
5491 gen_load_fpr32h(fpu32h_T[0], fs);
5492 tcg_gen_ext_i32_tl(cpu_T[0], fpu32h_T[0]);
5493 gen_store_gpr(cpu_T[0], rt);
5497 gen_load_gpr(cpu_T[0], rt);
5498 tcg_gen_trunc_tl_i32(fpu32h_T[0], cpu_T[0]);
5499 gen_store_fpr32h(fpu32h_T[0], fs);
5504 generate_exception (ctx, EXCP_RI);
5507 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5510 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5512 int l1 = gen_new_label();
5517 ccbit = 1 << (24 + cc);
5525 gen_load_gpr(cpu_T[0], rd);
5526 gen_load_gpr(cpu_T[1], rs);
5528 TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5529 TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
5531 tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5532 tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5533 tcg_temp_free(r_ptr);
5534 tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5535 tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5536 tcg_temp_free(r_tmp);
5538 tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
5541 gen_store_gpr(cpu_T[0], rd);
5544 #define GEN_MOVCF(fmt) \
5545 static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5550 ccbit = 1 << (24 + cc); \
5554 glue(gen_op_float_movf_, fmt)(ccbit); \
5556 glue(gen_op_float_movt_, fmt)(ccbit); \
5562 static void gen_farith (DisasContext *ctx, uint32_t op1,
5563 int ft, int fs, int fd, int cc)
5565 const char *opn = "farith";
5566 const char *condnames[] = {
5584 const char *condnames_abs[] = {
5602 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5603 uint32_t func = ctx->opcode & 0x3f;
5605 switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5607 gen_load_fpr32(fpu32_T[0], fs);
5608 gen_load_fpr32(fpu32_T[1], ft);
5609 tcg_gen_helper_0_0(do_float_add_s);
5610 gen_store_fpr32(fpu32_T[2], fd);
5615 gen_load_fpr32(fpu32_T[0], fs);
5616 gen_load_fpr32(fpu32_T[1], ft);
5617 tcg_gen_helper_0_0(do_float_sub_s);
5618 gen_store_fpr32(fpu32_T[2], fd);
5623 gen_load_fpr32(fpu32_T[0], fs);
5624 gen_load_fpr32(fpu32_T[1], ft);
5625 tcg_gen_helper_0_0(do_float_mul_s);
5626 gen_store_fpr32(fpu32_T[2], fd);
5631 gen_load_fpr32(fpu32_T[0], fs);
5632 gen_load_fpr32(fpu32_T[1], ft);
5633 tcg_gen_helper_0_0(do_float_div_s);
5634 gen_store_fpr32(fpu32_T[2], fd);
5639 gen_load_fpr32(fpu32_T[0], fs);
5640 gen_op_float_sqrt_s();
5641 gen_store_fpr32(fpu32_T[2], fd);
5645 gen_load_fpr32(fpu32_T[0], fs);
5646 gen_op_float_abs_s();
5647 gen_store_fpr32(fpu32_T[2], fd);
5651 gen_load_fpr32(fpu32_T[0], fs);
5652 gen_store_fpr32(fpu32_T[0], fd);
5656 gen_load_fpr32(fpu32_T[0], fs);
5657 gen_op_float_chs_s();
5658 gen_store_fpr32(fpu32_T[2], fd);
5662 check_cp1_64bitmode(ctx);
5663 gen_load_fpr32(fpu32_T[0], fs);
5664 tcg_gen_helper_0_0(do_float_roundl_s);
5665 gen_store_fpr64(ctx, fpu64_T[2], fd);
5669 check_cp1_64bitmode(ctx);
5670 gen_load_fpr32(fpu32_T[0], fs);
5671 tcg_gen_helper_0_0(do_float_truncl_s);
5672 gen_store_fpr64(ctx, fpu64_T[2], fd);
5676 check_cp1_64bitmode(ctx);
5677 gen_load_fpr32(fpu32_T[0], fs);
5678 tcg_gen_helper_0_0(do_float_ceill_s);
5679 gen_store_fpr64(ctx, fpu64_T[2], fd);
5683 check_cp1_64bitmode(ctx);
5684 gen_load_fpr32(fpu32_T[0], fs);
5685 tcg_gen_helper_0_0(do_float_floorl_s);
5686 gen_store_fpr64(ctx, fpu64_T[2], fd);
5690 gen_load_fpr32(fpu32_T[0], fs);
5691 tcg_gen_helper_0_0(do_float_roundw_s);
5692 gen_store_fpr32(fpu32_T[2], fd);
5696 gen_load_fpr32(fpu32_T[0], fs);
5697 tcg_gen_helper_0_0(do_float_truncw_s);
5698 gen_store_fpr32(fpu32_T[2], fd);
5702 gen_load_fpr32(fpu32_T[0], fs);
5703 tcg_gen_helper_0_0(do_float_ceilw_s);
5704 gen_store_fpr32(fpu32_T[2], fd);
5708 gen_load_fpr32(fpu32_T[0], fs);
5709 tcg_gen_helper_0_0(do_float_floorw_s);
5710 gen_store_fpr32(fpu32_T[2], fd);
5714 gen_load_gpr(cpu_T[0], ft);
5715 gen_load_fpr32(fpu32_T[0], fs);
5716 gen_load_fpr32(fpu32_T[2], fd);
5717 gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5718 gen_store_fpr32(fpu32_T[2], fd);
5722 gen_load_gpr(cpu_T[0], ft);
5723 gen_load_fpr32(fpu32_T[0], fs);
5724 gen_load_fpr32(fpu32_T[2], fd);
5725 gen_op_float_movz_s();
5726 gen_store_fpr32(fpu32_T[2], fd);
5730 gen_load_gpr(cpu_T[0], ft);
5731 gen_load_fpr32(fpu32_T[0], fs);
5732 gen_load_fpr32(fpu32_T[2], fd);
5733 gen_op_float_movn_s();
5734 gen_store_fpr32(fpu32_T[2], fd);
5739 gen_load_fpr32(fpu32_T[0], fs);
5740 tcg_gen_helper_0_0(do_float_recip_s);
5741 gen_store_fpr32(fpu32_T[2], fd);
5746 gen_load_fpr32(fpu32_T[0], fs);
5747 tcg_gen_helper_0_0(do_float_rsqrt_s);
5748 gen_store_fpr32(fpu32_T[2], fd);
5752 check_cp1_64bitmode(ctx);
5753 gen_load_fpr32(fpu32_T[0], fs);
5754 gen_load_fpr32(fpu32_T[2], fd);
5755 tcg_gen_helper_0_0(do_float_recip2_s);
5756 gen_store_fpr32(fpu32_T[2], fd);
5760 check_cp1_64bitmode(ctx);
5761 gen_load_fpr32(fpu32_T[0], fs);
5762 tcg_gen_helper_0_0(do_float_recip1_s);
5763 gen_store_fpr32(fpu32_T[2], fd);
5767 check_cp1_64bitmode(ctx);
5768 gen_load_fpr32(fpu32_T[0], fs);
5769 tcg_gen_helper_0_0(do_float_rsqrt1_s);
5770 gen_store_fpr32(fpu32_T[2], fd);
5774 check_cp1_64bitmode(ctx);
5775 gen_load_fpr32(fpu32_T[0], fs);
5776 gen_load_fpr32(fpu32_T[2], ft);
5777 tcg_gen_helper_0_0(do_float_rsqrt2_s);
5778 gen_store_fpr32(fpu32_T[2], fd);
5782 check_cp1_registers(ctx, fd);
5783 gen_load_fpr32(fpu32_T[0], fs);
5784 tcg_gen_helper_0_0(do_float_cvtd_s);
5785 gen_store_fpr64(ctx, fpu64_T[2], fd);
5789 gen_load_fpr32(fpu32_T[0], fs);
5790 tcg_gen_helper_0_0(do_float_cvtw_s);
5791 gen_store_fpr32(fpu32_T[2], fd);
5795 check_cp1_64bitmode(ctx);
5796 gen_load_fpr32(fpu32_T[0], fs);
5797 tcg_gen_helper_0_0(do_float_cvtl_s);
5798 gen_store_fpr64(ctx, fpu64_T[2], fd);
5802 check_cp1_64bitmode(ctx);
5803 gen_load_fpr32(fpu32_T[0], fs);
5804 gen_load_fpr32(fpu32_T[1], ft);
5805 tcg_gen_extu_i32_i64(fpu64_T[0], fpu32_T[0]);
5806 tcg_gen_extu_i32_i64(fpu64_T[1], fpu32_T[1]);
5807 tcg_gen_shli_i64(fpu64_T[1], fpu64_T[1], 32);
5808 tcg_gen_or_i64(fpu64_T[2], fpu64_T[0], fpu64_T[1]);
5809 gen_store_fpr64(ctx, fpu64_T[2], fd);
5828 gen_load_fpr32(fpu32_T[0], fs);
5829 gen_load_fpr32(fpu32_T[1], ft);
5830 if (ctx->opcode & (1 << 6)) {
5832 gen_cmpabs_s(func-48, cc);
5833 opn = condnames_abs[func-48];
5835 gen_cmp_s(func-48, cc);
5836 opn = condnames[func-48];
5840 check_cp1_registers(ctx, fs | ft | fd);
5841 gen_load_fpr64(ctx, fpu64_T[0], fs);
5842 gen_load_fpr64(ctx, fpu64_T[1], ft);
5843 tcg_gen_helper_0_0(do_float_add_d);
5844 gen_store_fpr64(ctx, fpu64_T[2], fd);
5849 check_cp1_registers(ctx, fs | ft | fd);
5850 gen_load_fpr64(ctx, fpu64_T[0], fs);
5851 gen_load_fpr64(ctx, fpu64_T[1], ft);
5852 tcg_gen_helper_0_0(do_float_sub_d);
5853 gen_store_fpr64(ctx, fpu64_T[2], fd);
5858 check_cp1_registers(ctx, fs | ft | fd);
5859 gen_load_fpr64(ctx, fpu64_T[0], fs);
5860 gen_load_fpr64(ctx, fpu64_T[1], ft);
5861 tcg_gen_helper_0_0(do_float_mul_d);
5862 gen_store_fpr64(ctx, fpu64_T[2], fd);
5867 check_cp1_registers(ctx, fs | ft | fd);
5868 gen_load_fpr64(ctx, fpu64_T[0], fs);
5869 gen_load_fpr64(ctx, fpu64_T[1], ft);
5870 tcg_gen_helper_0_0(do_float_div_d);
5871 gen_store_fpr64(ctx, fpu64_T[2], fd);
5876 check_cp1_registers(ctx, fs | fd);
5877 gen_load_fpr64(ctx, fpu64_T[0], fs);
5878 gen_op_float_sqrt_d();
5879 gen_store_fpr64(ctx, fpu64_T[2], fd);
5883 check_cp1_registers(ctx, fs | fd);
5884 gen_load_fpr64(ctx, fpu64_T[0], fs);
5885 gen_op_float_abs_d();
5886 gen_store_fpr64(ctx, fpu64_T[2], fd);
5890 check_cp1_registers(ctx, fs | fd);
5891 gen_load_fpr64(ctx, fpu64_T[0], fs);
5892 gen_store_fpr64(ctx, fpu64_T[0], fd);
5896 check_cp1_registers(ctx, fs | fd);
5897 gen_load_fpr64(ctx, fpu64_T[0], fs);
5898 gen_op_float_chs_d();
5899 gen_store_fpr64(ctx, fpu64_T[2], fd);
5903 check_cp1_64bitmode(ctx);
5904 gen_load_fpr64(ctx, fpu64_T[0], fs);
5905 tcg_gen_helper_0_0(do_float_roundl_d);
5906 gen_store_fpr64(ctx, fpu64_T[2], fd);
5910 check_cp1_64bitmode(ctx);
5911 gen_load_fpr64(ctx, fpu64_T[0], fs);
5912 tcg_gen_helper_0_0(do_float_truncl_d);
5913 gen_store_fpr64(ctx, fpu64_T[2], fd);
5917 check_cp1_64bitmode(ctx);
5918 gen_load_fpr64(ctx, fpu64_T[0], fs);
5919 tcg_gen_helper_0_0(do_float_ceill_d);
5920 gen_store_fpr64(ctx, fpu64_T[2], fd);
5924 check_cp1_64bitmode(ctx);
5925 gen_load_fpr64(ctx, fpu64_T[0], fs);
5926 tcg_gen_helper_0_0(do_float_floorl_d);
5927 gen_store_fpr64(ctx, fpu64_T[2], fd);
5931 check_cp1_registers(ctx, fs);
5932 gen_load_fpr64(ctx, fpu64_T[0], fs);
5933 tcg_gen_helper_0_0(do_float_roundw_d);
5934 gen_store_fpr32(fpu32_T[2], fd);
5938 check_cp1_registers(ctx, fs);
5939 gen_load_fpr64(ctx, fpu64_T[0], fs);
5940 tcg_gen_helper_0_0(do_float_truncw_d);
5941 gen_store_fpr32(fpu32_T[2], fd);
5945 check_cp1_registers(ctx, fs);
5946 gen_load_fpr64(ctx, fpu64_T[0], fs);
5947 tcg_gen_helper_0_0(do_float_ceilw_d);
5948 gen_store_fpr32(fpu32_T[2], fd);
5952 check_cp1_registers(ctx, fs);
5953 gen_load_fpr64(ctx, fpu64_T[0], fs);
5954 tcg_gen_helper_0_0(do_float_floorw_d);
5955 gen_store_fpr32(fpu32_T[2], fd);
5959 gen_load_gpr(cpu_T[0], ft);
5960 gen_load_fpr64(ctx, fpu64_T[0], fs);
5961 gen_load_fpr64(ctx, fpu64_T[2], fd);
5962 gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5963 gen_store_fpr64(ctx, fpu64_T[2], fd);
5967 gen_load_gpr(cpu_T[0], ft);
5968 gen_load_fpr64(ctx, fpu64_T[0], fs);
5969 gen_load_fpr64(ctx, fpu64_T[2], fd);
5970 gen_op_float_movz_d();
5971 gen_store_fpr64(ctx, fpu64_T[2], fd);
5975 gen_load_gpr(cpu_T[0], ft);
5976 gen_load_fpr64(ctx, fpu64_T[0], fs);
5977 gen_load_fpr64(ctx, fpu64_T[2], fd);
5978 gen_op_float_movn_d();
5979 gen_store_fpr64(ctx, fpu64_T[2], fd);
5983 check_cp1_64bitmode(ctx);
5984 gen_load_fpr64(ctx, fpu64_T[0], fs);
5985 tcg_gen_helper_0_0(do_float_recip_d);
5986 gen_store_fpr64(ctx, fpu64_T[2], fd);
5990 check_cp1_64bitmode(ctx);
5991 gen_load_fpr64(ctx, fpu64_T[0], fs);
5992 tcg_gen_helper_0_0(do_float_rsqrt_d);
5993 gen_store_fpr64(ctx, fpu64_T[2], fd);
5997 check_cp1_64bitmode(ctx);
5998 gen_load_fpr64(ctx, fpu64_T[0], fs);
5999 gen_load_fpr64(ctx, fpu64_T[2], ft);
6000 tcg_gen_helper_0_0(do_float_recip2_d);
6001 gen_store_fpr64(ctx, fpu64_T[2], fd);
6005 check_cp1_64bitmode(ctx);
6006 gen_load_fpr64(ctx, fpu64_T[0], fs);
6007 tcg_gen_helper_0_0(do_float_recip1_d);
6008 gen_store_fpr64(ctx, fpu64_T[2], fd);
6012 check_cp1_64bitmode(ctx);
6013 gen_load_fpr64(ctx, fpu64_T[0], fs);
6014 tcg_gen_helper_0_0(do_float_rsqrt1_d);
6015 gen_store_fpr64(ctx, fpu64_T[2], fd);
6019 check_cp1_64bitmode(ctx);
6020 gen_load_fpr64(ctx, fpu64_T[0], fs);
6021 gen_load_fpr64(ctx, fpu64_T[2], ft);
6022 tcg_gen_helper_0_0(do_float_rsqrt2_d);
6023 gen_store_fpr64(ctx, fpu64_T[2], fd);
6042 gen_load_fpr64(ctx, fpu64_T[0], fs);
6043 gen_load_fpr64(ctx, fpu64_T[1], ft);
6044 if (ctx->opcode & (1 << 6)) {
6046 check_cp1_registers(ctx, fs | ft);
6047 gen_cmpabs_d(func-48, cc);
6048 opn = condnames_abs[func-48];
6050 check_cp1_registers(ctx, fs | ft);
6051 gen_cmp_d(func-48, cc);
6052 opn = condnames[func-48];
6056 check_cp1_registers(ctx, fs);
6057 gen_load_fpr64(ctx, fpu64_T[0], fs);
6058 tcg_gen_helper_0_0(do_float_cvts_d);
6059 gen_store_fpr32(fpu32_T[2], fd);
6063 check_cp1_registers(ctx, fs);
6064 gen_load_fpr64(ctx, fpu64_T[0], fs);
6065 tcg_gen_helper_0_0(do_float_cvtw_d);
6066 gen_store_fpr32(fpu32_T[2], fd);
6070 check_cp1_64bitmode(ctx);
6071 gen_load_fpr64(ctx, fpu64_T[0], fs);
6072 tcg_gen_helper_0_0(do_float_cvtl_d);
6073 gen_store_fpr64(ctx, fpu64_T[2], fd);
6077 gen_load_fpr32(fpu32_T[0], fs);
6078 tcg_gen_helper_0_0(do_float_cvts_w);
6079 gen_store_fpr32(fpu32_T[2], fd);
6083 check_cp1_registers(ctx, fd);
6084 gen_load_fpr32(fpu32_T[0], fs);
6085 tcg_gen_helper_0_0(do_float_cvtd_w);
6086 gen_store_fpr64(ctx, fpu64_T[2], fd);
6090 check_cp1_64bitmode(ctx);
6091 gen_load_fpr64(ctx, fpu64_T[0], fs);
6092 tcg_gen_helper_0_0(do_float_cvts_l);
6093 gen_store_fpr32(fpu32_T[2], fd);
6097 check_cp1_64bitmode(ctx);
6098 gen_load_fpr64(ctx, fpu64_T[0], fs);
6099 tcg_gen_helper_0_0(do_float_cvtd_l);
6100 gen_store_fpr64(ctx, fpu64_T[2], fd);
6104 check_cp1_64bitmode(ctx);
6105 gen_load_fpr32(fpu32_T[0], fs);
6106 gen_load_fpr32h(fpu32h_T[0], fs);
6107 tcg_gen_helper_0_0(do_float_cvtps_pw);
6108 gen_store_fpr32(fpu32_T[2], fd);
6109 gen_store_fpr32h(fpu32h_T[2], fd);
6113 check_cp1_64bitmode(ctx);
6114 gen_load_fpr32(fpu32_T[0], fs);
6115 gen_load_fpr32h(fpu32h_T[0], fs);
6116 gen_load_fpr32(fpu32_T[1], ft);
6117 gen_load_fpr32h(fpu32h_T[1], ft);
6118 tcg_gen_helper_0_0(do_float_add_ps);
6119 gen_store_fpr32(fpu32_T[2], fd);
6120 gen_store_fpr32h(fpu32h_T[2], fd);
6124 check_cp1_64bitmode(ctx);
6125 gen_load_fpr32(fpu32_T[0], fs);
6126 gen_load_fpr32h(fpu32h_T[0], fs);
6127 gen_load_fpr32(fpu32_T[1], ft);
6128 gen_load_fpr32h(fpu32h_T[1], ft);
6129 tcg_gen_helper_0_0(do_float_sub_ps);
6130 gen_store_fpr32(fpu32_T[2], fd);
6131 gen_store_fpr32h(fpu32h_T[2], fd);
6135 check_cp1_64bitmode(ctx);
6136 gen_load_fpr32(fpu32_T[0], fs);
6137 gen_load_fpr32h(fpu32h_T[0], fs);
6138 gen_load_fpr32(fpu32_T[1], ft);
6139 gen_load_fpr32h(fpu32h_T[1], ft);
6140 tcg_gen_helper_0_0(do_float_mul_ps);
6141 gen_store_fpr32(fpu32_T[2], fd);
6142 gen_store_fpr32h(fpu32h_T[2], fd);
6146 check_cp1_64bitmode(ctx);
6147 gen_load_fpr32(fpu32_T[0], fs);
6148 gen_load_fpr32h(fpu32h_T[0], fs);
6149 gen_op_float_abs_ps();
6150 gen_store_fpr32(fpu32_T[2], fd);
6151 gen_store_fpr32h(fpu32h_T[2], fd);
6155 check_cp1_64bitmode(ctx);
6156 gen_load_fpr32(fpu32_T[0], fs);
6157 gen_load_fpr32h(fpu32h_T[0], fs);
6158 gen_store_fpr32(fpu32_T[0], fd);
6159 gen_store_fpr32h(fpu32h_T[0], fd);
6163 check_cp1_64bitmode(ctx);
6164 gen_load_fpr32(fpu32_T[0], fs);
6165 gen_load_fpr32h(fpu32h_T[0], fs);
6166 gen_op_float_chs_ps();
6167 gen_store_fpr32(fpu32_T[2], fd);
6168 gen_store_fpr32h(fpu32h_T[2], fd);
6172 check_cp1_64bitmode(ctx);
6173 gen_load_gpr(cpu_T[0], ft);
6174 gen_load_fpr32(fpu32_T[0], fs);
6175 gen_load_fpr32h(fpu32h_T[0], fs);
6176 gen_load_fpr32(fpu32_T[2], fd);
6177 gen_load_fpr32h(fpu32h_T[2], fd);
6179 gen_op_float_movt_ps ((ft >> 2) & 0x7);
6181 gen_op_float_movf_ps ((ft >> 2) & 0x7);
6182 gen_store_fpr32(fpu32_T[2], fd);
6183 gen_store_fpr32h(fpu32h_T[2], fd);
6187 check_cp1_64bitmode(ctx);
6188 gen_load_gpr(cpu_T[0], ft);
6189 gen_load_fpr32(fpu32_T[0], fs);
6190 gen_load_fpr32h(fpu32h_T[0], fs);
6191 gen_load_fpr32(fpu32_T[2], fd);
6192 gen_load_fpr32h(fpu32h_T[2], fd);
6193 gen_op_float_movz_ps();
6194 gen_store_fpr32(fpu32_T[2], fd);
6195 gen_store_fpr32h(fpu32h_T[2], fd);
6199 check_cp1_64bitmode(ctx);
6200 gen_load_gpr(cpu_T[0], ft);
6201 gen_load_fpr32(fpu32_T[0], fs);
6202 gen_load_fpr32h(fpu32h_T[0], fs);
6203 gen_load_fpr32(fpu32_T[2], fd);
6204 gen_load_fpr32h(fpu32h_T[2], fd);
6205 gen_op_float_movn_ps();
6206 gen_store_fpr32(fpu32_T[2], fd);
6207 gen_store_fpr32h(fpu32h_T[2], fd);
6211 check_cp1_64bitmode(ctx);
6212 gen_load_fpr32(fpu32_T[0], ft);
6213 gen_load_fpr32h(fpu32h_T[0], ft);
6214 gen_load_fpr32(fpu32_T[1], fs);
6215 gen_load_fpr32h(fpu32h_T[1], fs);
6216 tcg_gen_helper_0_0(do_float_addr_ps);
6217 gen_store_fpr32(fpu32_T[2], fd);
6218 gen_store_fpr32h(fpu32h_T[2], fd);
6222 check_cp1_64bitmode(ctx);
6223 gen_load_fpr32(fpu32_T[0], ft);
6224 gen_load_fpr32h(fpu32h_T[0], ft);
6225 gen_load_fpr32(fpu32_T[1], fs);
6226 gen_load_fpr32h(fpu32h_T[1], fs);
6227 tcg_gen_helper_0_0(do_float_mulr_ps);
6228 gen_store_fpr32(fpu32_T[2], fd);
6229 gen_store_fpr32h(fpu32h_T[2], fd);
6233 check_cp1_64bitmode(ctx);
6234 gen_load_fpr32(fpu32_T[0], fs);
6235 gen_load_fpr32h(fpu32h_T[0], fs);
6236 gen_load_fpr32(fpu32_T[2], fd);
6237 gen_load_fpr32h(fpu32h_T[2], fd);
6238 tcg_gen_helper_0_0(do_float_recip2_ps);
6239 gen_store_fpr32(fpu32_T[2], fd);
6240 gen_store_fpr32h(fpu32h_T[2], fd);
6244 check_cp1_64bitmode(ctx);
6245 gen_load_fpr32(fpu32_T[0], fs);
6246 gen_load_fpr32h(fpu32h_T[0], fs);
6247 tcg_gen_helper_0_0(do_float_recip1_ps);
6248 gen_store_fpr32(fpu32_T[2], fd);
6249 gen_store_fpr32h(fpu32h_T[2], fd);
6253 check_cp1_64bitmode(ctx);
6254 gen_load_fpr32(fpu32_T[0], fs);
6255 gen_load_fpr32h(fpu32h_T[0], fs);
6256 tcg_gen_helper_0_0(do_float_rsqrt1_ps);
6257 gen_store_fpr32(fpu32_T[2], fd);
6258 gen_store_fpr32h(fpu32h_T[2], fd);
6262 check_cp1_64bitmode(ctx);
6263 gen_load_fpr32(fpu32_T[0], fs);
6264 gen_load_fpr32h(fpu32h_T[0], fs);
6265 gen_load_fpr32(fpu32_T[2], ft);
6266 gen_load_fpr32h(fpu32h_T[2], ft);
6267 tcg_gen_helper_0_0(do_float_rsqrt2_ps);
6268 gen_store_fpr32(fpu32_T[2], fd);
6269 gen_store_fpr32h(fpu32h_T[2], fd);
6273 check_cp1_64bitmode(ctx);
6274 gen_load_fpr32h(fpu32h_T[0], fs);
6275 tcg_gen_helper_0_0(do_float_cvts_pu);
6276 gen_store_fpr32(fpu32_T[2], fd);
6280 check_cp1_64bitmode(ctx);
6281 gen_load_fpr32(fpu32_T[0], fs);
6282 gen_load_fpr32h(fpu32h_T[0], fs);
6283 tcg_gen_helper_0_0(do_float_cvtpw_ps);
6284 gen_store_fpr32(fpu32_T[2], fd);
6285 gen_store_fpr32h(fpu32h_T[2], fd);
6289 check_cp1_64bitmode(ctx);
6290 gen_load_fpr32(fpu32_T[0], fs);
6291 tcg_gen_helper_0_0(do_float_cvts_pl);
6292 gen_store_fpr32(fpu32_T[2], fd);
6296 check_cp1_64bitmode(ctx);
6297 gen_load_fpr32(fpu32_T[0], fs);
6298 gen_load_fpr32(fpu32_T[1], ft);
6299 gen_op_float_pll_ps();
6300 gen_store_fpr64(ctx, fpu64_T[2], fd);
6304 check_cp1_64bitmode(ctx);
6305 gen_load_fpr32(fpu32_T[0], fs);
6306 gen_load_fpr32h(fpu32h_T[1], ft);
6307 gen_op_float_plu_ps();
6308 gen_store_fpr64(ctx, fpu64_T[2], fd);
6312 check_cp1_64bitmode(ctx);
6313 gen_load_fpr32h(fpu32h_T[0], fs);
6314 gen_load_fpr32(fpu32_T[1], ft);
6315 gen_op_float_pul_ps();
6316 gen_store_fpr64(ctx, fpu64_T[2], fd);
6320 check_cp1_64bitmode(ctx);
6321 gen_load_fpr32h(fpu32h_T[0], fs);
6322 gen_load_fpr32h(fpu32h_T[1], ft);
6323 gen_op_float_puu_ps();
6324 gen_store_fpr64(ctx, fpu64_T[2], fd);
6343 check_cp1_64bitmode(ctx);
6344 gen_load_fpr32(fpu32_T[0], fs);
6345 gen_load_fpr32h(fpu32h_T[0], fs);
6346 gen_load_fpr32(fpu32_T[1], ft);
6347 gen_load_fpr32h(fpu32h_T[1], ft);
6348 if (ctx->opcode & (1 << 6)) {
6349 gen_cmpabs_ps(func-48, cc);
6350 opn = condnames_abs[func-48];
6352 gen_cmp_ps(func-48, cc);
6353 opn = condnames[func-48];
6358 generate_exception (ctx, EXCP_RI);
6363 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
6366 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
6369 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
6374 /* Coprocessor 3 (FPU) */
6375 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6376 int fd, int fs, int base, int index)
6378 const char *opn = "extended float load/store";
6382 gen_load_gpr(cpu_T[0], index);
6383 } else if (index == 0) {
6384 gen_load_gpr(cpu_T[0], base);
6386 gen_load_gpr(cpu_T[0], base);
6387 gen_load_gpr(cpu_T[1], index);
6390 /* Don't do NOP if destination is zero: we must perform the actual
6395 tcg_gen_qemu_ld32s(fpu32_T[0], cpu_T[0], ctx->mem_idx);
6396 gen_store_fpr32(fpu32_T[0], fd);
6401 check_cp1_registers(ctx, fd);
6402 tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
6403 gen_store_fpr64(ctx, fpu64_T[0], fd);
6407 check_cp1_64bitmode(ctx);
6408 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0x7);
6409 tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
6410 gen_store_fpr64(ctx, fpu64_T[0], fd);
6415 gen_load_fpr32(fpu32_T[0], fs);
6416 tcg_gen_qemu_st32(fpu32_T[0], cpu_T[0], ctx->mem_idx);
6422 check_cp1_registers(ctx, fs);
6423 gen_load_fpr64(ctx, fpu64_T[0], fs);
6424 tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
6429 check_cp1_64bitmode(ctx);
6430 gen_load_fpr64(ctx, fpu64_T[0], fs);
6431 tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0x7);
6432 tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
6438 generate_exception(ctx, EXCP_RI);
6441 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6442 regnames[index], regnames[base]);
6445 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6446 int fd, int fr, int fs, int ft)
6448 const char *opn = "flt3_arith";
6452 check_cp1_64bitmode(ctx);
6453 gen_load_gpr(cpu_T[0], fr);
6454 gen_load_fpr64(ctx, fpu64_T[0], fs);
6455 gen_load_fpr64(ctx, fpu64_T[1], ft);
6456 gen_op_float_alnv_ps();
6457 gen_store_fpr64(ctx, fpu64_T[2], fd);
6462 gen_load_fpr32(fpu32_T[0], fs);
6463 gen_load_fpr32(fpu32_T[1], ft);
6464 gen_load_fpr32(fpu32_T[2], fr);
6465 gen_op_float_muladd_s();
6466 gen_store_fpr32(fpu32_T[2], fd);
6471 check_cp1_registers(ctx, fd | fs | ft | fr);
6472 gen_load_fpr64(ctx, fpu64_T[0], fs);
6473 gen_load_fpr64(ctx, fpu64_T[1], ft);
6474 gen_load_fpr64(ctx, fpu64_T[2], fr);
6475 gen_op_float_muladd_d();
6476 gen_store_fpr64(ctx, fpu64_T[2], fd);
6480 check_cp1_64bitmode(ctx);
6481 gen_load_fpr32(fpu32_T[0], fs);
6482 gen_load_fpr32h(fpu32h_T[0], fs);
6483 gen_load_fpr32(fpu32_T[1], ft);
6484 gen_load_fpr32h(fpu32h_T[1], ft);
6485 gen_load_fpr32(fpu32_T[2], fr);
6486 gen_load_fpr32h(fpu32h_T[2], fr);
6487 gen_op_float_muladd_ps();
6488 gen_store_fpr32(fpu32_T[2], fd);
6489 gen_store_fpr32h(fpu32h_T[2], fd);
6494 gen_load_fpr32(fpu32_T[0], fs);
6495 gen_load_fpr32(fpu32_T[1], ft);
6496 gen_load_fpr32(fpu32_T[2], fr);
6497 gen_op_float_mulsub_s();
6498 gen_store_fpr32(fpu32_T[2], fd);
6503 check_cp1_registers(ctx, fd | fs | ft | fr);
6504 gen_load_fpr64(ctx, fpu64_T[0], fs);
6505 gen_load_fpr64(ctx, fpu64_T[1], ft);
6506 gen_load_fpr64(ctx, fpu64_T[2], fr);
6507 gen_op_float_mulsub_d();
6508 gen_store_fpr64(ctx, fpu64_T[2], fd);
6512 check_cp1_64bitmode(ctx);
6513 gen_load_fpr32(fpu32_T[0], fs);
6514 gen_load_fpr32h(fpu32h_T[0], fs);
6515 gen_load_fpr32(fpu32_T[1], ft);
6516 gen_load_fpr32h(fpu32h_T[1], ft);
6517 gen_load_fpr32(fpu32_T[2], fr);
6518 gen_load_fpr32h(fpu32h_T[2], fr);
6519 gen_op_float_mulsub_ps();
6520 gen_store_fpr32(fpu32_T[2], fd);
6521 gen_store_fpr32h(fpu32h_T[2], fd);
6526 gen_load_fpr32(fpu32_T[0], fs);
6527 gen_load_fpr32(fpu32_T[1], ft);
6528 gen_load_fpr32(fpu32_T[2], fr);
6529 gen_op_float_nmuladd_s();
6530 gen_store_fpr32(fpu32_T[2], fd);
6535 check_cp1_registers(ctx, fd | fs | ft | fr);
6536 gen_load_fpr64(ctx, fpu64_T[0], fs);
6537 gen_load_fpr64(ctx, fpu64_T[1], ft);
6538 gen_load_fpr64(ctx, fpu64_T[2], fr);
6539 gen_op_float_nmuladd_d();
6540 gen_store_fpr64(ctx, fpu64_T[2], fd);
6544 check_cp1_64bitmode(ctx);
6545 gen_load_fpr32(fpu32_T[0], fs);
6546 gen_load_fpr32h(fpu32h_T[0], fs);
6547 gen_load_fpr32(fpu32_T[1], ft);
6548 gen_load_fpr32h(fpu32h_T[1], ft);
6549 gen_load_fpr32(fpu32_T[2], fr);
6550 gen_load_fpr32h(fpu32h_T[2], fr);
6551 gen_op_float_nmuladd_ps();
6552 gen_store_fpr32(fpu32_T[2], fd);
6553 gen_store_fpr32h(fpu32h_T[2], fd);
6558 gen_load_fpr32(fpu32_T[0], fs);
6559 gen_load_fpr32(fpu32_T[1], ft);
6560 gen_load_fpr32(fpu32_T[2], fr);
6561 gen_op_float_nmulsub_s();
6562 gen_store_fpr32(fpu32_T[2], fd);
6567 check_cp1_registers(ctx, fd | fs | ft | fr);
6568 gen_load_fpr64(ctx, fpu64_T[0], fs);
6569 gen_load_fpr64(ctx, fpu64_T[1], ft);
6570 gen_load_fpr64(ctx, fpu64_T[2], fr);
6571 gen_op_float_nmulsub_d();
6572 gen_store_fpr64(ctx, fpu64_T[2], fd);
6576 check_cp1_64bitmode(ctx);
6577 gen_load_fpr32(fpu32_T[0], fs);
6578 gen_load_fpr32h(fpu32h_T[0], fs);
6579 gen_load_fpr32(fpu32_T[1], ft);
6580 gen_load_fpr32h(fpu32h_T[1], ft);
6581 gen_load_fpr32(fpu32_T[2], fr);
6582 gen_load_fpr32h(fpu32h_T[2], fr);
6583 gen_op_float_nmulsub_ps();
6584 gen_store_fpr32(fpu32_T[2], fd);
6585 gen_store_fpr32h(fpu32h_T[2], fd);
6590 generate_exception (ctx, EXCP_RI);
6593 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6594 fregnames[fs], fregnames[ft]);
6597 /* ISA extensions (ASEs) */
6598 /* MIPS16 extension to MIPS32 */
6599 /* SmartMIPS extension to MIPS32 */
6601 #if defined(TARGET_MIPS64)
6603 /* MDMX extension to MIPS64 */
6607 static void decode_opc (CPUState *env, DisasContext *ctx)
6611 uint32_t op, op1, op2;
6614 /* make sure instructions are on a word boundary */
6615 if (ctx->pc & 0x3) {
6616 env->CP0_BadVAddr = ctx->pc;
6617 generate_exception(ctx, EXCP_AdEL);
6621 /* Handle blikely not taken case */
6622 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6623 TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);
6624 int l1 = gen_new_label();
6626 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6627 tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
6628 tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
6629 tcg_temp_free(r_tmp);
6631 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
6633 tcg_gen_movi_i32(r_tmp2, ctx->hflags & ~MIPS_HFLAG_BMASK);
6634 tcg_gen_st_i32(r_tmp2, cpu_env, offsetof(CPUState, hflags));
6635 tcg_temp_free(r_tmp2);
6637 gen_goto_tb(ctx, 1, ctx->pc + 4);
6640 op = MASK_OP_MAJOR(ctx->opcode);
6641 rs = (ctx->opcode >> 21) & 0x1f;
6642 rt = (ctx->opcode >> 16) & 0x1f;
6643 rd = (ctx->opcode >> 11) & 0x1f;
6644 sa = (ctx->opcode >> 6) & 0x1f;
6645 imm = (int16_t)ctx->opcode;
6648 op1 = MASK_SPECIAL(ctx->opcode);
6650 case OPC_SLL: /* Arithmetic with immediate */
6651 case OPC_SRL ... OPC_SRA:
6652 gen_arith_imm(env, ctx, op1, rd, rt, sa);
6654 case OPC_MOVZ ... OPC_MOVN:
6655 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6656 case OPC_SLLV: /* Arithmetic */
6657 case OPC_SRLV ... OPC_SRAV:
6658 case OPC_ADD ... OPC_NOR:
6659 case OPC_SLT ... OPC_SLTU:
6660 gen_arith(env, ctx, op1, rd, rs, rt);
6662 case OPC_MULT ... OPC_DIVU:
6664 check_insn(env, ctx, INSN_VR54XX);
6665 op1 = MASK_MUL_VR54XX(ctx->opcode);
6666 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6668 gen_muldiv(ctx, op1, rs, rt);
6670 case OPC_JR ... OPC_JALR:
6671 gen_compute_branch(ctx, op1, rs, rd, sa);
6673 case OPC_TGE ... OPC_TEQ: /* Traps */
6675 gen_trap(ctx, op1, rs, rt, -1);
6677 case OPC_MFHI: /* Move from HI/LO */
6679 gen_HILO(ctx, op1, rd);
6682 case OPC_MTLO: /* Move to HI/LO */
6683 gen_HILO(ctx, op1, rs);
6685 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
6686 #ifdef MIPS_STRICT_STANDARD
6687 MIPS_INVAL("PMON / selsl");
6688 generate_exception(ctx, EXCP_RI);
6690 tcg_gen_helper_0_1i(do_pmon, sa);
6694 generate_exception(ctx, EXCP_SYSCALL);
6697 generate_exception(ctx, EXCP_BREAK);
6700 #ifdef MIPS_STRICT_STANDARD
6702 generate_exception(ctx, EXCP_RI);
6704 /* Implemented as RI exception for now. */
6705 MIPS_INVAL("spim (unofficial)");
6706 generate_exception(ctx, EXCP_RI);
6714 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6715 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6716 save_cpu_state(ctx, 1);
6717 check_cp1_enabled(ctx);
6718 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6719 (ctx->opcode >> 16) & 1);
6721 generate_exception_err(ctx, EXCP_CpU, 1);
6725 #if defined(TARGET_MIPS64)
6726 /* MIPS64 specific opcodes */
6728 case OPC_DSRL ... OPC_DSRA:
6730 case OPC_DSRL32 ... OPC_DSRA32:
6731 check_insn(env, ctx, ISA_MIPS3);
6733 gen_arith_imm(env, ctx, op1, rd, rt, sa);
6736 case OPC_DSRLV ... OPC_DSRAV:
6737 case OPC_DADD ... OPC_DSUBU:
6738 check_insn(env, ctx, ISA_MIPS3);
6740 gen_arith(env, ctx, op1, rd, rs, rt);
6742 case OPC_DMULT ... OPC_DDIVU:
6743 check_insn(env, ctx, ISA_MIPS3);
6745 gen_muldiv(ctx, op1, rs, rt);
6748 default: /* Invalid */
6749 MIPS_INVAL("special");
6750 generate_exception(ctx, EXCP_RI);
6755 op1 = MASK_SPECIAL2(ctx->opcode);
6757 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6758 case OPC_MSUB ... OPC_MSUBU:
6759 check_insn(env, ctx, ISA_MIPS32);
6760 gen_muldiv(ctx, op1, rs, rt);
6763 gen_arith(env, ctx, op1, rd, rs, rt);
6765 case OPC_CLZ ... OPC_CLO:
6766 check_insn(env, ctx, ISA_MIPS32);
6767 gen_cl(ctx, op1, rd, rs);
6770 /* XXX: not clear which exception should be raised
6771 * when in debug mode...
6773 check_insn(env, ctx, ISA_MIPS32);
6774 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6775 generate_exception(ctx, EXCP_DBp);
6777 generate_exception(ctx, EXCP_DBp);
6781 #if defined(TARGET_MIPS64)
6782 case OPC_DCLZ ... OPC_DCLO:
6783 check_insn(env, ctx, ISA_MIPS64);
6785 gen_cl(ctx, op1, rd, rs);
6788 default: /* Invalid */
6789 MIPS_INVAL("special2");
6790 generate_exception(ctx, EXCP_RI);
6795 op1 = MASK_SPECIAL3(ctx->opcode);
6799 check_insn(env, ctx, ISA_MIPS32R2);
6800 gen_bitops(ctx, op1, rt, rs, sa, rd);
6803 check_insn(env, ctx, ISA_MIPS32R2);
6804 op2 = MASK_BSHFL(ctx->opcode);
6807 gen_load_gpr(cpu_T[1], rt);
6808 tcg_gen_helper_0_0(do_wsbh);
6811 gen_load_gpr(cpu_T[1], rt);
6812 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]);
6815 gen_load_gpr(cpu_T[1], rt);
6816 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]);
6818 default: /* Invalid */
6819 MIPS_INVAL("bshfl");
6820 generate_exception(ctx, EXCP_RI);
6823 gen_store_gpr(cpu_T[0], rd);
6826 check_insn(env, ctx, ISA_MIPS32R2);
6829 save_cpu_state(ctx, 1);
6830 tcg_gen_helper_0_0(do_rdhwr_cpunum);
6833 save_cpu_state(ctx, 1);
6834 tcg_gen_helper_0_0(do_rdhwr_synci_step);
6837 save_cpu_state(ctx, 1);
6838 tcg_gen_helper_0_0(do_rdhwr_cc);
6841 save_cpu_state(ctx, 1);
6842 tcg_gen_helper_0_0(do_rdhwr_ccres);
6845 #if defined (CONFIG_USER_ONLY)
6846 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, tls_value));
6849 /* XXX: Some CPUs implement this in hardware. Not supported yet. */
6851 default: /* Invalid */
6852 MIPS_INVAL("rdhwr");
6853 generate_exception(ctx, EXCP_RI);
6856 gen_store_gpr(cpu_T[0], rt);
6859 check_insn(env, ctx, ASE_MT);
6860 gen_load_gpr(cpu_T[0], rt);
6861 gen_load_gpr(cpu_T[1], rs);
6862 tcg_gen_helper_0_0(do_fork);
6865 check_insn(env, ctx, ASE_MT);
6866 gen_load_gpr(cpu_T[0], rs);
6867 tcg_gen_helper_0_0(do_yield);
6868 gen_store_gpr(cpu_T[0], rd);
6870 #if defined(TARGET_MIPS64)
6871 case OPC_DEXTM ... OPC_DEXT:
6872 case OPC_DINSM ... OPC_DINS:
6873 check_insn(env, ctx, ISA_MIPS64R2);
6875 gen_bitops(ctx, op1, rt, rs, sa, rd);
6878 check_insn(env, ctx, ISA_MIPS64R2);
6880 op2 = MASK_DBSHFL(ctx->opcode);
6883 gen_load_gpr(cpu_T[1], rt);
6884 tcg_gen_helper_0_0(do_dsbh);
6887 gen_load_gpr(cpu_T[1], rt);
6888 tcg_gen_helper_0_0(do_dshd);
6890 default: /* Invalid */
6891 MIPS_INVAL("dbshfl");
6892 generate_exception(ctx, EXCP_RI);
6895 gen_store_gpr(cpu_T[0], rd);
6898 default: /* Invalid */
6899 MIPS_INVAL("special3");
6900 generate_exception(ctx, EXCP_RI);
6905 op1 = MASK_REGIMM(ctx->opcode);
6907 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6908 case OPC_BLTZAL ... OPC_BGEZALL:
6909 gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6911 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6913 gen_trap(ctx, op1, rs, -1, imm);
6916 check_insn(env, ctx, ISA_MIPS32R2);
6919 default: /* Invalid */
6920 MIPS_INVAL("regimm");
6921 generate_exception(ctx, EXCP_RI);
6926 check_cp0_enabled(ctx);
6927 op1 = MASK_CP0(ctx->opcode);
6933 #if defined(TARGET_MIPS64)
6937 #ifndef CONFIG_USER_ONLY
6938 gen_cp0(env, ctx, op1, rt, rd);
6941 case OPC_C0_FIRST ... OPC_C0_LAST:
6942 #ifndef CONFIG_USER_ONLY
6943 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6947 op2 = MASK_MFMC0(ctx->opcode);
6950 check_insn(env, ctx, ASE_MT);
6951 tcg_gen_helper_0_0(do_dmt);
6954 check_insn(env, ctx, ASE_MT);
6955 tcg_gen_helper_0_0(do_emt);
6958 check_insn(env, ctx, ASE_MT);
6959 tcg_gen_helper_0_0(do_dvpe);
6962 check_insn(env, ctx, ASE_MT);
6963 tcg_gen_helper_0_0(do_evpe);
6966 check_insn(env, ctx, ISA_MIPS32R2);
6967 save_cpu_state(ctx, 1);
6968 tcg_gen_helper_0_0(do_di);
6969 /* Stop translation as we may have switched the execution mode */
6970 ctx->bstate = BS_STOP;
6973 check_insn(env, ctx, ISA_MIPS32R2);
6974 save_cpu_state(ctx, 1);
6975 tcg_gen_helper_0_0(do_ei);
6976 /* Stop translation as we may have switched the execution mode */
6977 ctx->bstate = BS_STOP;
6979 default: /* Invalid */
6980 MIPS_INVAL("mfmc0");
6981 generate_exception(ctx, EXCP_RI);
6984 gen_store_gpr(cpu_T[0], rt);
6987 check_insn(env, ctx, ISA_MIPS32R2);
6988 gen_load_srsgpr(cpu_T[0], rt);
6989 gen_store_gpr(cpu_T[0], rd);
6992 check_insn(env, ctx, ISA_MIPS32R2);
6993 gen_load_gpr(cpu_T[0], rt);
6994 gen_store_srsgpr(cpu_T[0], rd);
6998 generate_exception(ctx, EXCP_RI);
7002 case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7003 gen_arith_imm(env, ctx, op, rt, rs, imm);
7005 case OPC_J ... OPC_JAL: /* Jump */
7006 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7007 gen_compute_branch(ctx, op, rs, rt, offset);
7009 case OPC_BEQ ... OPC_BGTZ: /* Branch */
7010 case OPC_BEQL ... OPC_BGTZL:
7011 gen_compute_branch(ctx, op, rs, rt, imm << 2);
7013 case OPC_LB ... OPC_LWR: /* Load and stores */
7014 case OPC_SB ... OPC_SW:
7018 gen_ldst(ctx, op, rt, rs, imm);
7021 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7025 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7029 /* Floating point (COP1). */
7034 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7035 save_cpu_state(ctx, 1);
7036 check_cp1_enabled(ctx);
7037 gen_flt_ldst(ctx, op, rt, rs, imm);
7039 generate_exception_err(ctx, EXCP_CpU, 1);
7044 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7045 save_cpu_state(ctx, 1);
7046 check_cp1_enabled(ctx);
7047 op1 = MASK_CP1(ctx->opcode);
7051 check_insn(env, ctx, ISA_MIPS32R2);
7056 gen_cp1(ctx, op1, rt, rd);
7058 #if defined(TARGET_MIPS64)
7061 check_insn(env, ctx, ISA_MIPS3);
7062 gen_cp1(ctx, op1, rt, rd);
7068 check_insn(env, ctx, ASE_MIPS3D);
7071 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7072 (rt >> 2) & 0x7, imm << 2);
7079 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7084 generate_exception (ctx, EXCP_RI);
7088 generate_exception_err(ctx, EXCP_CpU, 1);
7098 /* COP2: Not implemented. */
7099 generate_exception_err(ctx, EXCP_CpU, 2);
7103 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7104 save_cpu_state(ctx, 1);
7105 check_cp1_enabled(ctx);
7106 op1 = MASK_CP3(ctx->opcode);
7114 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7132 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7136 generate_exception (ctx, EXCP_RI);
7140 generate_exception_err(ctx, EXCP_CpU, 1);
7144 #if defined(TARGET_MIPS64)
7145 /* MIPS64 opcodes */
7147 case OPC_LDL ... OPC_LDR:
7148 case OPC_SDL ... OPC_SDR:
7153 check_insn(env, ctx, ISA_MIPS3);
7155 gen_ldst(ctx, op, rt, rs, imm);
7157 case OPC_DADDI ... OPC_DADDIU:
7158 check_insn(env, ctx, ISA_MIPS3);
7160 gen_arith_imm(env, ctx, op, rt, rs, imm);
7164 check_insn(env, ctx, ASE_MIPS16);
7165 /* MIPS16: Not implemented. */
7167 check_insn(env, ctx, ASE_MDMX);
7168 /* MDMX: Not implemented. */
7169 default: /* Invalid */
7170 MIPS_INVAL("major opcode");
7171 generate_exception(ctx, EXCP_RI);
7174 if (ctx->hflags & MIPS_HFLAG_BMASK) {
7175 int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7176 /* Branches completion */
7177 ctx->hflags &= ~MIPS_HFLAG_BMASK;
7178 ctx->bstate = BS_BRANCH;
7179 save_cpu_state(ctx, 0);
7182 /* unconditional branch */
7183 MIPS_DEBUG("unconditional branch");
7184 gen_goto_tb(ctx, 0, ctx->btarget);
7187 /* blikely taken case */
7188 MIPS_DEBUG("blikely branch taken");
7189 gen_goto_tb(ctx, 0, ctx->btarget);
7192 /* Conditional branch */
7193 MIPS_DEBUG("conditional branch");
7195 TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);
7196 int l1 = gen_new_label();
7198 tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7199 tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
7200 tcg_temp_free(r_tmp);
7201 gen_goto_tb(ctx, 1, ctx->pc + 4);
7203 gen_goto_tb(ctx, 0, ctx->btarget);
7207 /* unconditional branch to register */
7208 MIPS_DEBUG("branch to register");
7213 MIPS_DEBUG("unknown branch");
7219 static always_inline int
7220 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7224 target_ulong pc_start;
7225 uint16_t *gen_opc_end;
7228 if (search_pc && loglevel)
7229 fprintf (logfile, "search pc %d\n", search_pc);
7232 /* Leave some spare opc slots for branch handling. */
7233 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
7237 ctx.bstate = BS_NONE;
7238 /* Restore delay slot state from the tb context. */
7239 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7240 restore_cpu_state(env, &ctx);
7241 #if defined(CONFIG_USER_ONLY)
7242 ctx.mem_idx = MIPS_HFLAG_UM;
7244 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7247 if (loglevel & CPU_LOG_TB_CPU) {
7248 fprintf(logfile, "------------------------------------------------\n");
7249 /* FIXME: This may print out stale hflags from env... */
7250 cpu_dump_state(env, logfile, fprintf, 0);
7253 #ifdef MIPS_DEBUG_DISAS
7254 if (loglevel & CPU_LOG_TB_IN_ASM)
7255 fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7256 tb, ctx.mem_idx, ctx.hflags);
7258 while (ctx.bstate == BS_NONE) {
7259 if (env->nb_breakpoints > 0) {
7260 for(j = 0; j < env->nb_breakpoints; j++) {
7261 if (env->breakpoints[j] == ctx.pc) {
7262 save_cpu_state(&ctx, 1);
7263 ctx.bstate = BS_BRANCH;
7264 tcg_gen_helper_0_1i(do_raise_exception, EXCP_DEBUG);
7265 /* Include the breakpoint location or the tb won't
7266 * be flushed when it must be. */
7268 goto done_generating;
7274 j = gen_opc_ptr - gen_opc_buf;
7278 gen_opc_instr_start[lj++] = 0;
7280 gen_opc_pc[lj] = ctx.pc;
7281 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7282 gen_opc_instr_start[lj] = 1;
7284 ctx.opcode = ldl_code(ctx.pc);
7285 decode_opc(env, &ctx);
7288 if (env->singlestep_enabled)
7291 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7294 if (gen_opc_ptr >= gen_opc_end)
7297 if (gen_opc_ptr >= gen_opc_end)
7300 #if defined (MIPS_SINGLE_STEP)
7304 if (env->singlestep_enabled) {
7305 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7306 tcg_gen_helper_0_1i(do_raise_exception, EXCP_DEBUG);
7308 switch (ctx.bstate) {
7310 tcg_gen_helper_0_0(do_interrupt_restart);
7311 gen_goto_tb(&ctx, 0, ctx.pc);
7314 save_cpu_state(&ctx, 0);
7315 gen_goto_tb(&ctx, 0, ctx.pc);
7318 tcg_gen_helper_0_0(do_interrupt_restart);
7327 *gen_opc_ptr = INDEX_op_end;
7329 j = gen_opc_ptr - gen_opc_buf;
7332 gen_opc_instr_start[lj++] = 0;
7334 tb->size = ctx.pc - pc_start;
7337 #if defined MIPS_DEBUG_DISAS
7338 if (loglevel & CPU_LOG_TB_IN_ASM)
7339 fprintf(logfile, "\n");
7341 if (loglevel & CPU_LOG_TB_IN_ASM) {
7342 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7343 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7344 fprintf(logfile, "\n");
7346 if (loglevel & CPU_LOG_TB_CPU) {
7347 fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7354 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7356 return gen_intermediate_code_internal(env, tb, 0);
7359 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7361 return gen_intermediate_code_internal(env, tb, 1);
7364 void fpu_dump_state(CPUState *env, FILE *f,
7365 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7369 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7371 #define printfpr(fp) \
7374 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n", \
7375 (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd, \
7376 (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
7379 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
7380 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
7381 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n", \
7382 tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd, \
7383 tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]); \
7388 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n",
7389 env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
7390 get_float_exception_flags(&env->fpu->fp_status));
7391 fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
7392 fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
7393 fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
7394 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
7395 fpu_fprintf(f, "%3s: ", fregnames[i]);
7396 printfpr(&env->fpu->fpr[i]);
7402 void dump_fpu (CPUState *env)
7406 "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
7407 " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
7409 env->PC[env->current_tc], env->HI[env->current_tc][0],
7410 env->LO[env->current_tc][0], env->hflags, env->btarget,
7412 fpu_dump_state(env, logfile, fprintf, 0);
7416 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7417 /* Debug help: The architecture requires 32bit code to maintain proper
7418 sign-extened values on 64bit machines. */
7420 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7422 void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7423 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7428 if (!SIGN_EXT_P(env->PC[env->current_tc]))
7429 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7430 if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7431 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7432 if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7433 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7434 if (!SIGN_EXT_P(env->btarget))
7435 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7437 for (i = 0; i < 32; i++) {
7438 if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7439 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7442 if (!SIGN_EXT_P(env->CP0_EPC))
7443 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7444 if (!SIGN_EXT_P(env->CP0_LLAddr))
7445 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7449 void cpu_dump_state (CPUState *env, FILE *f,
7450 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7455 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",
7456 env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7457 for (i = 0; i < 32; i++) {
7459 cpu_fprintf(f, "GPR%02d:", i);
7460 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7462 cpu_fprintf(f, "\n");
7465 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
7466 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7467 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7468 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7469 if (env->hflags & MIPS_HFLAG_FPU)
7470 fpu_dump_state(env, f, cpu_fprintf, flags);
7471 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7472 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7476 static void mips_tcg_init(void)
7480 /* Initialize various static tables. */
7484 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7485 current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7487 offsetof(CPUState, current_tc_gprs),
7489 current_tc_hi = tcg_global_mem_new(TCG_TYPE_PTR,
7491 offsetof(CPUState, current_tc_hi),
7493 current_fpu = tcg_global_mem_new(TCG_TYPE_PTR,
7495 offsetof(CPUState, fpu),
7497 #if TARGET_LONG_BITS > HOST_LONG_BITS
7498 cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7499 TCG_AREG0, offsetof(CPUState, t0), "T0");
7500 cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7501 TCG_AREG0, offsetof(CPUState, t1), "T1");
7503 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7504 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7507 /* register helpers */
7509 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
7512 fpu32_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[FP_ENDIAN_IDX]), "WT0");
7513 fpu32_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[FP_ENDIAN_IDX]), "WT1");
7514 fpu32_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[FP_ENDIAN_IDX]), "WT2");
7515 fpu64_T[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft0.d), "DT0");
7516 fpu64_T[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft1.d), "DT1");
7517 fpu64_T[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft2.d), "DT2");
7518 fpu32h_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[!FP_ENDIAN_IDX]), "WTH0");
7519 fpu32h_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[!FP_ENDIAN_IDX]), "WTH1");
7520 fpu32h_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[!FP_ENDIAN_IDX]), "WTH2");
7525 #include "translate_init.c"
7527 CPUMIPSState *cpu_mips_init (const char *cpu_model)
7530 const mips_def_t *def;
7532 def = cpu_mips_find_by_name(cpu_model);
7535 env = qemu_mallocz(sizeof(CPUMIPSState));
7538 env->cpu_model = def;
7541 env->cpu_model_str = cpu_model;
7547 void cpu_reset (CPUMIPSState *env)
7549 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7554 #if !defined(CONFIG_USER_ONLY)
7555 if (env->hflags & MIPS_HFLAG_BMASK) {
7556 /* If the exception was raised from a delay slot,
7557 * come back to the jump. */
7558 env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7560 env->CP0_ErrorEPC = env->PC[env->current_tc];
7562 env->PC[env->current_tc] = (int32_t)0xBFC00000;
7564 /* SMP not implemented */
7565 env->CP0_EBase = 0x80000000;
7566 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7567 /* vectored interrupts not implemented, timer on int 7,
7568 no performance counters. */
7569 env->CP0_IntCtl = 0xe0000000;
7573 for (i = 0; i < 7; i++) {
7574 env->CP0_WatchLo[i] = 0;
7575 env->CP0_WatchHi[i] = 0x80000000;
7577 env->CP0_WatchLo[7] = 0;
7578 env->CP0_WatchHi[7] = 0;
7580 /* Count register increments in debug mode, EJTAG version 1 */
7581 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7583 env->exception_index = EXCP_NONE;
7584 #if defined(CONFIG_USER_ONLY)
7585 env->hflags = MIPS_HFLAG_UM;
7586 env->user_mode_only = 1;
7588 env->hflags = MIPS_HFLAG_CP0;
7590 cpu_mips_register(env, env->cpu_model);
7593 void gen_pc_load(CPUState *env, TranslationBlock *tb,
7594 unsigned long searched_pc, int pc_pos, void *puc)
7596 env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7597 env->hflags &= ~MIPS_HFLAG_BMASK;
7598 env->hflags |= gen_opc_hflags[pc_pos];