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)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
31 //#define MIPS_DEBUG_DISAS
32 //#define MIPS_DEBUG_SIGN_EXTENSIONS
34 /* MIPS major opcodes */
35 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
38 /* indirect opcode tables */
39 OPC_SPECIAL = (0x00 << 26),
40 OPC_REGIMM = (0x01 << 26),
41 OPC_CP0 = (0x10 << 26),
42 OPC_CP1 = (0x11 << 26),
43 OPC_CP2 = (0x12 << 26),
44 OPC_CP3 = (0x13 << 26),
45 OPC_SPECIAL2 = (0x1C << 26),
46 OPC_SPECIAL3 = (0x1F << 26),
47 /* arithmetic with immediate */
48 OPC_ADDI = (0x08 << 26),
49 OPC_ADDIU = (0x09 << 26),
50 OPC_SLTI = (0x0A << 26),
51 OPC_SLTIU = (0x0B << 26),
52 /* logic with immediate */
53 OPC_ANDI = (0x0C << 26),
54 OPC_ORI = (0x0D << 26),
55 OPC_XORI = (0x0E << 26),
56 OPC_LUI = (0x0F << 26),
57 /* arithmetic with immediate */
58 OPC_DADDI = (0x18 << 26),
59 OPC_DADDIU = (0x19 << 26),
60 /* Jump and branches */
62 OPC_JAL = (0x03 << 26),
63 OPC_JALS = OPC_JAL | 0x5,
64 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
65 OPC_BEQL = (0x14 << 26),
66 OPC_BNE = (0x05 << 26),
67 OPC_BNEL = (0x15 << 26),
68 OPC_BLEZ = (0x06 << 26),
69 OPC_BLEZL = (0x16 << 26),
70 OPC_BGTZ = (0x07 << 26),
71 OPC_BGTZL = (0x17 << 26),
72 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
73 OPC_JALXS = OPC_JALX | 0x5,
75 OPC_LDL = (0x1A << 26),
76 OPC_LDR = (0x1B << 26),
77 OPC_LB = (0x20 << 26),
78 OPC_LH = (0x21 << 26),
79 OPC_LWL = (0x22 << 26),
80 OPC_LW = (0x23 << 26),
81 OPC_LWPC = OPC_LW | 0x5,
82 OPC_LBU = (0x24 << 26),
83 OPC_LHU = (0x25 << 26),
84 OPC_LWR = (0x26 << 26),
85 OPC_LWU = (0x27 << 26),
86 OPC_SB = (0x28 << 26),
87 OPC_SH = (0x29 << 26),
88 OPC_SWL = (0x2A << 26),
89 OPC_SW = (0x2B << 26),
90 OPC_SDL = (0x2C << 26),
91 OPC_SDR = (0x2D << 26),
92 OPC_SWR = (0x2E << 26),
93 OPC_LL = (0x30 << 26),
94 OPC_LLD = (0x34 << 26),
95 OPC_LD = (0x37 << 26),
96 OPC_LDPC = OPC_LD | 0x5,
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_ROTR = OPC_SRL | (1 << 21),
129 OPC_SRA = 0x03 | OPC_SPECIAL,
130 OPC_SLLV = 0x04 | OPC_SPECIAL,
131 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
132 OPC_ROTRV = OPC_SRLV | (1 << 6),
133 OPC_SRAV = 0x07 | OPC_SPECIAL,
134 OPC_DSLLV = 0x14 | OPC_SPECIAL,
135 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
136 OPC_DROTRV = OPC_DSRLV | (1 << 6),
137 OPC_DSRAV = 0x17 | OPC_SPECIAL,
138 OPC_DSLL = 0x38 | OPC_SPECIAL,
139 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
140 OPC_DROTR = OPC_DSRL | (1 << 21),
141 OPC_DSRA = 0x3B | OPC_SPECIAL,
142 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
143 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
144 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
145 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
146 /* Multiplication / division */
147 OPC_MULT = 0x18 | OPC_SPECIAL,
148 OPC_MULTU = 0x19 | OPC_SPECIAL,
149 OPC_DIV = 0x1A | OPC_SPECIAL,
150 OPC_DIVU = 0x1B | OPC_SPECIAL,
151 OPC_DMULT = 0x1C | OPC_SPECIAL,
152 OPC_DMULTU = 0x1D | OPC_SPECIAL,
153 OPC_DDIV = 0x1E | OPC_SPECIAL,
154 OPC_DDIVU = 0x1F | OPC_SPECIAL,
155 /* 2 registers arithmetic / logic */
156 OPC_ADD = 0x20 | OPC_SPECIAL,
157 OPC_ADDU = 0x21 | OPC_SPECIAL,
158 OPC_SUB = 0x22 | OPC_SPECIAL,
159 OPC_SUBU = 0x23 | OPC_SPECIAL,
160 OPC_AND = 0x24 | OPC_SPECIAL,
161 OPC_OR = 0x25 | OPC_SPECIAL,
162 OPC_XOR = 0x26 | OPC_SPECIAL,
163 OPC_NOR = 0x27 | OPC_SPECIAL,
164 OPC_SLT = 0x2A | OPC_SPECIAL,
165 OPC_SLTU = 0x2B | OPC_SPECIAL,
166 OPC_DADD = 0x2C | OPC_SPECIAL,
167 OPC_DADDU = 0x2D | OPC_SPECIAL,
168 OPC_DSUB = 0x2E | OPC_SPECIAL,
169 OPC_DSUBU = 0x2F | OPC_SPECIAL,
171 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
172 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
173 OPC_JALRC = OPC_JALR | (0x5 << 6),
174 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
176 OPC_TGE = 0x30 | OPC_SPECIAL,
177 OPC_TGEU = 0x31 | OPC_SPECIAL,
178 OPC_TLT = 0x32 | OPC_SPECIAL,
179 OPC_TLTU = 0x33 | OPC_SPECIAL,
180 OPC_TEQ = 0x34 | OPC_SPECIAL,
181 OPC_TNE = 0x36 | OPC_SPECIAL,
182 /* HI / LO registers load & stores */
183 OPC_MFHI = 0x10 | OPC_SPECIAL,
184 OPC_MTHI = 0x11 | OPC_SPECIAL,
185 OPC_MFLO = 0x12 | OPC_SPECIAL,
186 OPC_MTLO = 0x13 | OPC_SPECIAL,
187 /* Conditional moves */
188 OPC_MOVZ = 0x0A | OPC_SPECIAL,
189 OPC_MOVN = 0x0B | OPC_SPECIAL,
191 OPC_MOVCI = 0x01 | OPC_SPECIAL,
194 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
195 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
196 OPC_BREAK = 0x0D | OPC_SPECIAL,
197 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
198 OPC_SYNC = 0x0F | OPC_SPECIAL,
200 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
201 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
202 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
203 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
204 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
205 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
206 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
209 /* Multiplication variants of the vr54xx. */
210 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
213 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
214 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
215 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
216 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
217 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
218 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
219 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
220 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
221 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
222 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
223 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
224 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
225 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
226 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
229 /* REGIMM (rt field) opcodes */
230 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
233 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
234 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
235 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
236 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
237 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
238 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
239 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
240 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
241 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
242 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
243 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
244 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
245 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
246 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
247 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
248 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
249 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
252 /* Special2 opcodes */
253 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
256 /* Multiply & xxx operations */
257 OPC_MADD = 0x00 | OPC_SPECIAL2,
258 OPC_MADDU = 0x01 | OPC_SPECIAL2,
259 OPC_MUL = 0x02 | OPC_SPECIAL2,
260 OPC_MSUB = 0x04 | OPC_SPECIAL2,
261 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
263 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
264 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
265 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
266 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
267 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
268 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
269 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
270 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
271 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
272 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
273 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
274 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
276 OPC_CLZ = 0x20 | OPC_SPECIAL2,
277 OPC_CLO = 0x21 | OPC_SPECIAL2,
278 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
279 OPC_DCLO = 0x25 | OPC_SPECIAL2,
281 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
284 /* Special3 opcodes */
285 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
288 OPC_EXT = 0x00 | OPC_SPECIAL3,
289 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
290 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
291 OPC_DEXT = 0x03 | OPC_SPECIAL3,
292 OPC_INS = 0x04 | OPC_SPECIAL3,
293 OPC_DINSM = 0x05 | OPC_SPECIAL3,
294 OPC_DINSU = 0x06 | OPC_SPECIAL3,
295 OPC_DINS = 0x07 | OPC_SPECIAL3,
296 OPC_FORK = 0x08 | OPC_SPECIAL3,
297 OPC_YIELD = 0x09 | OPC_SPECIAL3,
298 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
299 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
300 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
303 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
304 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
305 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
306 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
307 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
308 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
309 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
310 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
311 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
312 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
313 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
314 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
318 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
321 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
322 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
323 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
327 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
330 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
331 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
334 /* Coprocessor 0 (rs field) */
335 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
338 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
339 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
340 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
341 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
342 OPC_MFTR = (0x08 << 21) | OPC_CP0,
343 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
344 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
345 OPC_MTTR = (0x0C << 21) | OPC_CP0,
346 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
347 OPC_C0 = (0x10 << 21) | OPC_CP0,
348 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
349 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
353 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
356 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
357 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
358 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
359 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
360 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
361 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
364 /* Coprocessor 0 (with rs == C0) */
365 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
368 OPC_TLBR = 0x01 | OPC_C0,
369 OPC_TLBWI = 0x02 | OPC_C0,
370 OPC_TLBWR = 0x06 | OPC_C0,
371 OPC_TLBP = 0x08 | OPC_C0,
372 OPC_RFE = 0x10 | OPC_C0,
373 OPC_ERET = 0x18 | OPC_C0,
374 OPC_DERET = 0x1F | OPC_C0,
375 OPC_WAIT = 0x20 | OPC_C0,
378 /* Coprocessor 1 (rs field) */
379 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
381 /* Values for the fmt field in FP instructions */
383 /* 0 - 15 are reserved */
384 FMT_S = 16, /* single fp */
385 FMT_D = 17, /* double fp */
386 FMT_E = 18, /* extended fp */
387 FMT_Q = 19, /* quad fp */
388 FMT_W = 20, /* 32-bit fixed */
389 FMT_L = 21, /* 64-bit fixed */
390 FMT_PS = 22, /* paired single fp */
391 /* 23 - 31 are reserved */
395 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
396 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
397 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
398 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
399 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
400 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
401 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
402 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
403 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
404 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
405 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
406 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
407 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
408 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
409 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
410 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
411 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
412 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
415 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
416 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
419 OPC_BC1F = (0x00 << 16) | OPC_BC1,
420 OPC_BC1T = (0x01 << 16) | OPC_BC1,
421 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
422 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
426 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
427 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
431 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
432 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
435 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
438 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
439 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
440 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
441 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
442 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
443 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
444 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
445 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
446 OPC_BC2 = (0x08 << 21) | OPC_CP2,
449 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
452 OPC_LWXC1 = 0x00 | OPC_CP3,
453 OPC_LDXC1 = 0x01 | OPC_CP3,
454 OPC_LUXC1 = 0x05 | OPC_CP3,
455 OPC_SWXC1 = 0x08 | OPC_CP3,
456 OPC_SDXC1 = 0x09 | OPC_CP3,
457 OPC_SUXC1 = 0x0D | OPC_CP3,
458 OPC_PREFX = 0x0F | OPC_CP3,
459 OPC_ALNV_PS = 0x1E | OPC_CP3,
460 OPC_MADD_S = 0x20 | OPC_CP3,
461 OPC_MADD_D = 0x21 | OPC_CP3,
462 OPC_MADD_PS = 0x26 | OPC_CP3,
463 OPC_MSUB_S = 0x28 | OPC_CP3,
464 OPC_MSUB_D = 0x29 | OPC_CP3,
465 OPC_MSUB_PS = 0x2E | OPC_CP3,
466 OPC_NMADD_S = 0x30 | OPC_CP3,
467 OPC_NMADD_D = 0x31 | OPC_CP3,
468 OPC_NMADD_PS= 0x36 | OPC_CP3,
469 OPC_NMSUB_S = 0x38 | OPC_CP3,
470 OPC_NMSUB_D = 0x39 | OPC_CP3,
471 OPC_NMSUB_PS= 0x3E | OPC_CP3,
474 /* global register indices */
475 static TCGv_ptr cpu_env;
476 static TCGv cpu_gpr[32], cpu_PC;
477 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
478 static TCGv cpu_dspctrl, btarget, bcond;
479 static TCGv_i32 hflags;
480 static TCGv_i32 fpu_fcr0, fpu_fcr31;
482 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
484 #include "gen-icount.h"
486 #define gen_helper_0i(name, arg) do { \
487 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
488 gen_helper_##name(helper_tmp); \
489 tcg_temp_free_i32(helper_tmp); \
492 #define gen_helper_1i(name, arg1, arg2) do { \
493 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
494 gen_helper_##name(arg1, helper_tmp); \
495 tcg_temp_free_i32(helper_tmp); \
498 #define gen_helper_2i(name, arg1, arg2, arg3) do { \
499 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
500 gen_helper_##name(arg1, arg2, helper_tmp); \
501 tcg_temp_free_i32(helper_tmp); \
504 #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do { \
505 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
506 gen_helper_##name(arg1, arg2, arg3, helper_tmp); \
507 tcg_temp_free_i32(helper_tmp); \
510 typedef struct DisasContext {
511 struct TranslationBlock *tb;
512 target_ulong pc, saved_pc;
514 int singlestep_enabled;
515 /* Routine used to access memory */
517 uint32_t hflags, saved_hflags;
519 target_ulong btarget;
523 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
524 * exception condition */
525 BS_STOP = 1, /* We want to stop translation for any reason */
526 BS_BRANCH = 2, /* We reached a branch condition */
527 BS_EXCP = 3, /* We reached an exception condition */
530 static const char *regnames[] =
531 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
532 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
533 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
534 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
536 static const char *regnames_HI[] =
537 { "HI0", "HI1", "HI2", "HI3", };
539 static const char *regnames_LO[] =
540 { "LO0", "LO1", "LO2", "LO3", };
542 static const char *regnames_ACX[] =
543 { "ACX0", "ACX1", "ACX2", "ACX3", };
545 static const char *fregnames[] =
546 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
547 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
548 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
549 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
551 #ifdef MIPS_DEBUG_DISAS
552 #define MIPS_DEBUG(fmt, ...) \
553 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
554 TARGET_FMT_lx ": %08x " fmt "\n", \
555 ctx->pc, ctx->opcode , ## __VA_ARGS__)
556 #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
558 #define MIPS_DEBUG(fmt, ...) do { } while(0)
559 #define LOG_DISAS(...) do { } while (0)
562 #define MIPS_INVAL(op) \
564 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
565 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
568 /* General purpose registers moves. */
569 static inline void gen_load_gpr (TCGv t, int reg)
572 tcg_gen_movi_tl(t, 0);
574 tcg_gen_mov_tl(t, cpu_gpr[reg]);
577 static inline void gen_store_gpr (TCGv t, int reg)
580 tcg_gen_mov_tl(cpu_gpr[reg], t);
583 /* Moves to/from ACX register. */
584 static inline void gen_load_ACX (TCGv t, int reg)
586 tcg_gen_mov_tl(t, cpu_ACX[reg]);
589 static inline void gen_store_ACX (TCGv t, int reg)
591 tcg_gen_mov_tl(cpu_ACX[reg], t);
594 /* Moves to/from shadow registers. */
595 static inline void gen_load_srsgpr (int from, int to)
597 TCGv t0 = tcg_temp_new();
600 tcg_gen_movi_tl(t0, 0);
602 TCGv_i32 t2 = tcg_temp_new_i32();
603 TCGv_ptr addr = tcg_temp_new_ptr();
605 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
606 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
607 tcg_gen_andi_i32(t2, t2, 0xf);
608 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
609 tcg_gen_ext_i32_ptr(addr, t2);
610 tcg_gen_add_ptr(addr, cpu_env, addr);
612 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
613 tcg_temp_free_ptr(addr);
614 tcg_temp_free_i32(t2);
616 gen_store_gpr(t0, to);
620 static inline void gen_store_srsgpr (int from, int to)
623 TCGv t0 = tcg_temp_new();
624 TCGv_i32 t2 = tcg_temp_new_i32();
625 TCGv_ptr addr = tcg_temp_new_ptr();
627 gen_load_gpr(t0, from);
628 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
629 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
630 tcg_gen_andi_i32(t2, t2, 0xf);
631 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
632 tcg_gen_ext_i32_ptr(addr, t2);
633 tcg_gen_add_ptr(addr, cpu_env, addr);
635 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
636 tcg_temp_free_ptr(addr);
637 tcg_temp_free_i32(t2);
642 /* Floating point register moves. */
643 static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
645 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
648 static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
650 tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
653 static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
655 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
658 static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
660 tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
663 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
665 if (ctx->hflags & MIPS_HFLAG_F64) {
666 tcg_gen_ld_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d));
668 TCGv_i32 t0 = tcg_temp_new_i32();
669 TCGv_i32 t1 = tcg_temp_new_i32();
670 gen_load_fpr32(t0, reg & ~1);
671 gen_load_fpr32(t1, reg | 1);
672 tcg_gen_concat_i32_i64(t, t0, t1);
673 tcg_temp_free_i32(t0);
674 tcg_temp_free_i32(t1);
678 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
680 if (ctx->hflags & MIPS_HFLAG_F64) {
681 tcg_gen_st_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d));
683 TCGv_i64 t0 = tcg_temp_new_i64();
684 TCGv_i32 t1 = tcg_temp_new_i32();
685 tcg_gen_trunc_i64_i32(t1, t);
686 gen_store_fpr32(t1, reg & ~1);
687 tcg_gen_shri_i64(t0, t, 32);
688 tcg_gen_trunc_i64_i32(t1, t0);
689 gen_store_fpr32(t1, reg | 1);
690 tcg_temp_free_i32(t1);
691 tcg_temp_free_i64(t0);
695 static inline int get_fp_bit (int cc)
704 static inline void gen_save_pc(target_ulong pc)
706 tcg_gen_movi_tl(cpu_PC, pc);
709 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
711 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
712 if (do_save_pc && ctx->pc != ctx->saved_pc) {
713 gen_save_pc(ctx->pc);
714 ctx->saved_pc = ctx->pc;
716 if (ctx->hflags != ctx->saved_hflags) {
717 tcg_gen_movi_i32(hflags, ctx->hflags);
718 ctx->saved_hflags = ctx->hflags;
719 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
725 tcg_gen_movi_tl(btarget, ctx->btarget);
731 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
733 ctx->saved_hflags = ctx->hflags;
734 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
740 ctx->btarget = env->btarget;
746 generate_exception_err (DisasContext *ctx, int excp, int err)
748 TCGv_i32 texcp = tcg_const_i32(excp);
749 TCGv_i32 terr = tcg_const_i32(err);
750 save_cpu_state(ctx, 1);
751 gen_helper_raise_exception_err(texcp, terr);
752 tcg_temp_free_i32(terr);
753 tcg_temp_free_i32(texcp);
757 generate_exception (DisasContext *ctx, int excp)
759 save_cpu_state(ctx, 1);
760 gen_helper_0i(raise_exception, excp);
763 /* Addresses computation */
764 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
766 tcg_gen_add_tl(ret, arg0, arg1);
768 #if defined(TARGET_MIPS64)
769 /* For compatibility with 32-bit code, data reference in user mode
770 with Status_UX = 0 should be casted to 32-bit and sign extended.
771 See the MIPS64 PRA manual, section 4.10. */
772 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
773 !(ctx->hflags & MIPS_HFLAG_UX)) {
774 tcg_gen_ext32s_i64(ret, ret);
779 static inline void check_cp0_enabled(DisasContext *ctx)
781 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
782 generate_exception_err(ctx, EXCP_CpU, 0);
785 static inline void check_cp1_enabled(DisasContext *ctx)
787 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
788 generate_exception_err(ctx, EXCP_CpU, 1);
791 /* Verify that the processor is running with COP1X instructions enabled.
792 This is associated with the nabla symbol in the MIPS32 and MIPS64
795 static inline void check_cop1x(DisasContext *ctx)
797 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
798 generate_exception(ctx, EXCP_RI);
801 /* Verify that the processor is running with 64-bit floating-point
802 operations enabled. */
804 static inline void check_cp1_64bitmode(DisasContext *ctx)
806 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
807 generate_exception(ctx, EXCP_RI);
811 * Verify if floating point register is valid; an operation is not defined
812 * if bit 0 of any register specification is set and the FR bit in the
813 * Status register equals zero, since the register numbers specify an
814 * even-odd pair of adjacent coprocessor general registers. When the FR bit
815 * in the Status register equals one, both even and odd register numbers
816 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
818 * Multiple 64 bit wide registers can be checked by calling
819 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
821 static inline void check_cp1_registers(DisasContext *ctx, int regs)
823 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
824 generate_exception(ctx, EXCP_RI);
827 /* This code generates a "reserved instruction" exception if the
828 CPU does not support the instruction set corresponding to flags. */
829 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
831 if (unlikely(!(env->insn_flags & flags)))
832 generate_exception(ctx, EXCP_RI);
835 /* This code generates a "reserved instruction" exception if 64-bit
836 instructions are not enabled. */
837 static inline void check_mips_64(DisasContext *ctx)
839 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
840 generate_exception(ctx, EXCP_RI);
843 /* Define small wrappers for gen_load_fpr* so that we have a uniform
844 calling interface for 32 and 64-bit FPRs. No sense in changing
845 all callers for gen_load_fpr32 when we need the CTX parameter for
847 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
848 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
849 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
850 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
851 int ft, int fs, int cc) \
853 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
854 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
857 check_cp1_64bitmode(ctx); \
863 check_cp1_registers(ctx, fs | ft); \
871 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
872 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
874 case 0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
875 case 1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
876 case 2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
877 case 3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
878 case 4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
879 case 5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
880 case 6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
881 case 7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
882 case 8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
883 case 9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
884 case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
885 case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
886 case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
887 case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
888 case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
889 case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
892 tcg_temp_free_i##bits (fp0); \
893 tcg_temp_free_i##bits (fp1); \
896 FOP_CONDS(, 0, d, FMT_D, 64)
897 FOP_CONDS(abs, 1, d, FMT_D, 64)
898 FOP_CONDS(, 0, s, FMT_S, 32)
899 FOP_CONDS(abs, 1, s, FMT_S, 32)
900 FOP_CONDS(, 0, ps, FMT_PS, 64)
901 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
903 #undef gen_ldcmp_fpr32
904 #undef gen_ldcmp_fpr64
906 /* load/store instructions. */
907 #define OP_LD(insn,fname) \
908 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
910 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
917 #if defined(TARGET_MIPS64)
923 #define OP_ST(insn,fname) \
924 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
926 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
931 #if defined(TARGET_MIPS64)
936 #ifdef CONFIG_USER_ONLY
937 #define OP_LD_ATOMIC(insn,fname) \
938 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
940 TCGv t0 = tcg_temp_new(); \
941 tcg_gen_mov_tl(t0, arg1); \
942 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
943 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
944 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
948 #define OP_LD_ATOMIC(insn,fname) \
949 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
951 gen_helper_2i(insn, ret, arg1, ctx->mem_idx); \
954 OP_LD_ATOMIC(ll,ld32s);
955 #if defined(TARGET_MIPS64)
956 OP_LD_ATOMIC(lld,ld64);
960 #ifdef CONFIG_USER_ONLY
961 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
962 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
964 TCGv t0 = tcg_temp_new(); \
965 int l1 = gen_new_label(); \
966 int l2 = gen_new_label(); \
968 tcg_gen_andi_tl(t0, arg2, almask); \
969 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
970 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
971 generate_exception(ctx, EXCP_AdES); \
973 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
974 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
975 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
976 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
977 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
978 gen_helper_0i(raise_exception, EXCP_SC); \
980 tcg_gen_movi_tl(t0, 0); \
981 gen_store_gpr(t0, rt); \
985 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
986 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
988 TCGv t0 = tcg_temp_new(); \
989 gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx); \
990 gen_store_gpr(t0, rt); \
994 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
995 #if defined(TARGET_MIPS64)
996 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1000 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1001 int base, int16_t offset)
1004 tcg_gen_movi_tl(addr, offset);
1005 } else if (offset == 0) {
1006 gen_load_gpr(addr, base);
1008 tcg_gen_movi_tl(addr, offset);
1009 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1013 static target_ulong pc_relative_pc (DisasContext *ctx)
1015 target_ulong pc = ctx->pc;
1017 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1018 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1023 pc &= ~(target_ulong)3;
1028 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1029 int rt, int base, int16_t offset)
1031 const char *opn = "ld";
1034 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1035 /* Loongson CPU uses a load to zero register for prefetch.
1036 We emulate it as a NOP. On other CPU we must perform the
1037 actual memory access. */
1042 t0 = tcg_temp_new();
1043 t1 = tcg_temp_new();
1044 gen_base_offset_addr(ctx, t0, base, offset);
1047 #if defined(TARGET_MIPS64)
1049 save_cpu_state(ctx, 0);
1050 op_ld_lwu(t0, t0, ctx);
1051 gen_store_gpr(t0, rt);
1055 save_cpu_state(ctx, 0);
1056 op_ld_ld(t0, t0, ctx);
1057 gen_store_gpr(t0, rt);
1061 save_cpu_state(ctx, 1);
1062 op_ld_lld(t0, t0, ctx);
1063 gen_store_gpr(t0, rt);
1067 save_cpu_state(ctx, 1);
1068 gen_load_gpr(t1, rt);
1069 gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1070 gen_store_gpr(t1, rt);
1074 save_cpu_state(ctx, 1);
1075 gen_load_gpr(t1, rt);
1076 gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1077 gen_store_gpr(t1, rt);
1081 save_cpu_state(ctx, 0);
1082 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1083 gen_op_addr_add(ctx, t0, t0, t1);
1084 op_ld_ld(t0, t0, ctx);
1085 gen_store_gpr(t0, rt);
1090 save_cpu_state(ctx, 0);
1091 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1092 gen_op_addr_add(ctx, t0, t0, t1);
1093 op_ld_lw(t0, t0, ctx);
1094 gen_store_gpr(t0, rt);
1098 save_cpu_state(ctx, 0);
1099 op_ld_lw(t0, t0, ctx);
1100 gen_store_gpr(t0, rt);
1104 save_cpu_state(ctx, 0);
1105 op_ld_lh(t0, t0, ctx);
1106 gen_store_gpr(t0, rt);
1110 save_cpu_state(ctx, 0);
1111 op_ld_lhu(t0, t0, ctx);
1112 gen_store_gpr(t0, rt);
1116 save_cpu_state(ctx, 0);
1117 op_ld_lb(t0, t0, ctx);
1118 gen_store_gpr(t0, rt);
1122 save_cpu_state(ctx, 0);
1123 op_ld_lbu(t0, t0, ctx);
1124 gen_store_gpr(t0, rt);
1128 save_cpu_state(ctx, 1);
1129 gen_load_gpr(t1, rt);
1130 gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1131 gen_store_gpr(t1, rt);
1135 save_cpu_state(ctx, 1);
1136 gen_load_gpr(t1, rt);
1137 gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1138 gen_store_gpr(t1, rt);
1142 save_cpu_state(ctx, 1);
1143 op_ld_ll(t0, t0, ctx);
1144 gen_store_gpr(t0, rt);
1148 (void)opn; /* avoid a compiler warning */
1149 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1155 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1156 int base, int16_t offset)
1158 const char *opn = "st";
1159 TCGv t0 = tcg_temp_new();
1160 TCGv t1 = tcg_temp_new();
1162 gen_base_offset_addr(ctx, t0, base, offset);
1163 gen_load_gpr(t1, rt);
1165 #if defined(TARGET_MIPS64)
1167 save_cpu_state(ctx, 0);
1168 op_st_sd(t1, t0, ctx);
1172 save_cpu_state(ctx, 1);
1173 gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1177 save_cpu_state(ctx, 1);
1178 gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1183 save_cpu_state(ctx, 0);
1184 op_st_sw(t1, t0, ctx);
1188 save_cpu_state(ctx, 0);
1189 op_st_sh(t1, t0, ctx);
1193 save_cpu_state(ctx, 0);
1194 op_st_sb(t1, t0, ctx);
1198 save_cpu_state(ctx, 1);
1199 gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1203 save_cpu_state(ctx, 1);
1204 gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1208 (void)opn; /* avoid a compiler warning */
1209 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1215 /* Store conditional */
1216 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1217 int base, int16_t offset)
1219 const char *opn = "st_cond";
1222 t0 = tcg_temp_local_new();
1224 gen_base_offset_addr(ctx, t0, base, offset);
1225 /* Don't do NOP if destination is zero: we must perform the actual
1228 t1 = tcg_temp_local_new();
1229 gen_load_gpr(t1, rt);
1231 #if defined(TARGET_MIPS64)
1233 save_cpu_state(ctx, 1);
1234 op_st_scd(t1, t0, rt, ctx);
1239 save_cpu_state(ctx, 1);
1240 op_st_sc(t1, t0, rt, ctx);
1244 (void)opn; /* avoid a compiler warning */
1245 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1250 /* Load and store */
1251 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1252 int base, int16_t offset)
1254 const char *opn = "flt_ldst";
1255 TCGv t0 = tcg_temp_new();
1257 gen_base_offset_addr(ctx, t0, base, offset);
1258 /* Don't do NOP if destination is zero: we must perform the actual
1263 TCGv_i32 fp0 = tcg_temp_new_i32();
1265 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1266 tcg_gen_trunc_tl_i32(fp0, t0);
1267 gen_store_fpr32(fp0, ft);
1268 tcg_temp_free_i32(fp0);
1274 TCGv_i32 fp0 = tcg_temp_new_i32();
1275 TCGv t1 = tcg_temp_new();
1277 gen_load_fpr32(fp0, ft);
1278 tcg_gen_extu_i32_tl(t1, fp0);
1279 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1281 tcg_temp_free_i32(fp0);
1287 TCGv_i64 fp0 = tcg_temp_new_i64();
1289 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1290 gen_store_fpr64(ctx, fp0, ft);
1291 tcg_temp_free_i64(fp0);
1297 TCGv_i64 fp0 = tcg_temp_new_i64();
1299 gen_load_fpr64(ctx, fp0, ft);
1300 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1301 tcg_temp_free_i64(fp0);
1307 generate_exception(ctx, EXCP_RI);
1310 (void)opn; /* avoid a compiler warning */
1311 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1316 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1317 uint32_t op, int rt, int rs, int16_t imm)
1319 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1320 check_cp1_enabled(ctx);
1321 gen_flt_ldst(ctx, op, rt, rs, imm);
1323 generate_exception_err(ctx, EXCP_CpU, 1);
1327 /* Arithmetic with immediate operand */
1328 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1329 int rt, int rs, int16_t imm)
1331 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1332 const char *opn = "imm arith";
1334 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1335 /* If no destination, treat it as a NOP.
1336 For addi, we must generate the overflow exception when needed. */
1343 TCGv t0 = tcg_temp_local_new();
1344 TCGv t1 = tcg_temp_new();
1345 TCGv t2 = tcg_temp_new();
1346 int l1 = gen_new_label();
1348 gen_load_gpr(t1, rs);
1349 tcg_gen_addi_tl(t0, t1, uimm);
1350 tcg_gen_ext32s_tl(t0, t0);
1352 tcg_gen_xori_tl(t1, t1, ~uimm);
1353 tcg_gen_xori_tl(t2, t0, uimm);
1354 tcg_gen_and_tl(t1, t1, t2);
1356 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1358 /* operands of same sign, result different sign */
1359 generate_exception(ctx, EXCP_OVERFLOW);
1361 tcg_gen_ext32s_tl(t0, t0);
1362 gen_store_gpr(t0, rt);
1369 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1370 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1372 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1376 #if defined(TARGET_MIPS64)
1379 TCGv t0 = tcg_temp_local_new();
1380 TCGv t1 = tcg_temp_new();
1381 TCGv t2 = tcg_temp_new();
1382 int l1 = gen_new_label();
1384 gen_load_gpr(t1, rs);
1385 tcg_gen_addi_tl(t0, t1, uimm);
1387 tcg_gen_xori_tl(t1, t1, ~uimm);
1388 tcg_gen_xori_tl(t2, t0, uimm);
1389 tcg_gen_and_tl(t1, t1, t2);
1391 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1393 /* operands of same sign, result different sign */
1394 generate_exception(ctx, EXCP_OVERFLOW);
1396 gen_store_gpr(t0, rt);
1403 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1405 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1411 (void)opn; /* avoid a compiler warning */
1412 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1415 /* Logic with immediate operand */
1416 static void gen_logic_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
1419 const char *opn = "imm logic";
1422 /* If no destination, treat it as a NOP. */
1426 uimm = (uint16_t)imm;
1429 if (likely(rs != 0))
1430 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1432 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1437 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1439 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1443 if (likely(rs != 0))
1444 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1446 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1450 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1454 (void)opn; /* avoid a compiler warning */
1455 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1458 /* Set on less than with immediate operand */
1459 static void gen_slt_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
1461 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1462 const char *opn = "imm arith";
1466 /* If no destination, treat it as a NOP. */
1470 t0 = tcg_temp_new();
1471 gen_load_gpr(t0, rs);
1474 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1478 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1482 (void)opn; /* avoid a compiler warning */
1483 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1487 /* Shifts with immediate operand */
1488 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1489 int rt, int rs, int16_t imm)
1491 target_ulong uimm = ((uint16_t)imm) & 0x1f;
1492 const char *opn = "imm shift";
1496 /* If no destination, treat it as a NOP. */
1501 t0 = tcg_temp_new();
1502 gen_load_gpr(t0, rs);
1505 tcg_gen_shli_tl(t0, t0, uimm);
1506 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1510 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1515 tcg_gen_ext32u_tl(t0, t0);
1516 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1518 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1524 TCGv_i32 t1 = tcg_temp_new_i32();
1526 tcg_gen_trunc_tl_i32(t1, t0);
1527 tcg_gen_rotri_i32(t1, t1, uimm);
1528 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1529 tcg_temp_free_i32(t1);
1531 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1535 #if defined(TARGET_MIPS64)
1537 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1541 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1545 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1550 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1552 tcg_gen_mov_tl(cpu_gpr[rt], t0);
1557 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1561 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1565 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1569 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1574 (void)opn; /* avoid a compiler warning */
1575 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1580 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1581 int rd, int rs, int rt)
1583 const char *opn = "arith";
1585 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1586 && opc != OPC_DADD && opc != OPC_DSUB) {
1587 /* If no destination, treat it as a NOP.
1588 For add & sub, we must generate the overflow exception when needed. */
1596 TCGv t0 = tcg_temp_local_new();
1597 TCGv t1 = tcg_temp_new();
1598 TCGv t2 = tcg_temp_new();
1599 int l1 = gen_new_label();
1601 gen_load_gpr(t1, rs);
1602 gen_load_gpr(t2, rt);
1603 tcg_gen_add_tl(t0, t1, t2);
1604 tcg_gen_ext32s_tl(t0, t0);
1605 tcg_gen_xor_tl(t1, t1, t2);
1606 tcg_gen_xor_tl(t2, t0, t2);
1607 tcg_gen_andc_tl(t1, t2, t1);
1609 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1611 /* operands of same sign, result different sign */
1612 generate_exception(ctx, EXCP_OVERFLOW);
1614 gen_store_gpr(t0, rd);
1620 if (rs != 0 && rt != 0) {
1621 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1622 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1623 } else if (rs == 0 && rt != 0) {
1624 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1625 } else if (rs != 0 && rt == 0) {
1626 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1628 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1634 TCGv t0 = tcg_temp_local_new();
1635 TCGv t1 = tcg_temp_new();
1636 TCGv t2 = tcg_temp_new();
1637 int l1 = gen_new_label();
1639 gen_load_gpr(t1, rs);
1640 gen_load_gpr(t2, rt);
1641 tcg_gen_sub_tl(t0, t1, t2);
1642 tcg_gen_ext32s_tl(t0, t0);
1643 tcg_gen_xor_tl(t2, t1, t2);
1644 tcg_gen_xor_tl(t1, t0, t1);
1645 tcg_gen_and_tl(t1, t1, t2);
1647 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1649 /* operands of different sign, first operand and result different sign */
1650 generate_exception(ctx, EXCP_OVERFLOW);
1652 gen_store_gpr(t0, rd);
1658 if (rs != 0 && rt != 0) {
1659 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1660 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1661 } else if (rs == 0 && rt != 0) {
1662 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1663 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1664 } else if (rs != 0 && rt == 0) {
1665 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1667 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1671 #if defined(TARGET_MIPS64)
1674 TCGv t0 = tcg_temp_local_new();
1675 TCGv t1 = tcg_temp_new();
1676 TCGv t2 = tcg_temp_new();
1677 int l1 = gen_new_label();
1679 gen_load_gpr(t1, rs);
1680 gen_load_gpr(t2, rt);
1681 tcg_gen_add_tl(t0, t1, t2);
1682 tcg_gen_xor_tl(t1, t1, t2);
1683 tcg_gen_xor_tl(t2, t0, t2);
1684 tcg_gen_andc_tl(t1, t2, t1);
1686 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1688 /* operands of same sign, result different sign */
1689 generate_exception(ctx, EXCP_OVERFLOW);
1691 gen_store_gpr(t0, rd);
1697 if (rs != 0 && rt != 0) {
1698 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1699 } else if (rs == 0 && rt != 0) {
1700 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1701 } else if (rs != 0 && rt == 0) {
1702 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1704 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1710 TCGv t0 = tcg_temp_local_new();
1711 TCGv t1 = tcg_temp_new();
1712 TCGv t2 = tcg_temp_new();
1713 int l1 = gen_new_label();
1715 gen_load_gpr(t1, rs);
1716 gen_load_gpr(t2, rt);
1717 tcg_gen_sub_tl(t0, t1, t2);
1718 tcg_gen_xor_tl(t2, t1, t2);
1719 tcg_gen_xor_tl(t1, t0, t1);
1720 tcg_gen_and_tl(t1, t1, t2);
1722 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1724 /* operands of different sign, first operand and result different sign */
1725 generate_exception(ctx, EXCP_OVERFLOW);
1727 gen_store_gpr(t0, rd);
1733 if (rs != 0 && rt != 0) {
1734 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1735 } else if (rs == 0 && rt != 0) {
1736 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1737 } else if (rs != 0 && rt == 0) {
1738 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1740 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1746 if (likely(rs != 0 && rt != 0)) {
1747 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1748 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1750 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1755 (void)opn; /* avoid a compiler warning */
1756 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1759 /* Conditional move */
1760 static void gen_cond_move (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
1762 const char *opn = "cond move";
1766 /* If no destination, treat it as a NOP.
1767 For add & sub, we must generate the overflow exception when needed. */
1772 l1 = gen_new_label();
1775 if (likely(rt != 0))
1776 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1782 if (likely(rt != 0))
1783 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1788 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1790 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1793 (void)opn; /* avoid a compiler warning */
1794 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1798 static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
1800 const char *opn = "logic";
1803 /* If no destination, treat it as a NOP. */
1810 if (likely(rs != 0 && rt != 0)) {
1811 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1813 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1818 if (rs != 0 && rt != 0) {
1819 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1820 } else if (rs == 0 && rt != 0) {
1821 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1822 } else if (rs != 0 && rt == 0) {
1823 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1825 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1830 if (likely(rs != 0 && rt != 0)) {
1831 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1832 } else if (rs == 0 && rt != 0) {
1833 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1834 } else if (rs != 0 && rt == 0) {
1835 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1837 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1842 if (likely(rs != 0 && rt != 0)) {
1843 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1844 } else if (rs == 0 && rt != 0) {
1845 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1846 } else if (rs != 0 && rt == 0) {
1847 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1849 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1854 (void)opn; /* avoid a compiler warning */
1855 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1858 /* Set on lower than */
1859 static void gen_slt (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
1861 const char *opn = "slt";
1865 /* If no destination, treat it as a NOP. */
1870 t0 = tcg_temp_new();
1871 t1 = tcg_temp_new();
1872 gen_load_gpr(t0, rs);
1873 gen_load_gpr(t1, rt);
1876 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1880 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1884 (void)opn; /* avoid a compiler warning */
1885 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1891 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1892 int rd, int rs, int rt)
1894 const char *opn = "shifts";
1898 /* If no destination, treat it as a NOP.
1899 For add & sub, we must generate the overflow exception when needed. */
1904 t0 = tcg_temp_new();
1905 t1 = tcg_temp_new();
1906 gen_load_gpr(t0, rs);
1907 gen_load_gpr(t1, rt);
1910 tcg_gen_andi_tl(t0, t0, 0x1f);
1911 tcg_gen_shl_tl(t0, t1, t0);
1912 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1916 tcg_gen_andi_tl(t0, t0, 0x1f);
1917 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1921 tcg_gen_ext32u_tl(t1, t1);
1922 tcg_gen_andi_tl(t0, t0, 0x1f);
1923 tcg_gen_shr_tl(t0, t1, t0);
1924 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1929 TCGv_i32 t2 = tcg_temp_new_i32();
1930 TCGv_i32 t3 = tcg_temp_new_i32();
1932 tcg_gen_trunc_tl_i32(t2, t0);
1933 tcg_gen_trunc_tl_i32(t3, t1);
1934 tcg_gen_andi_i32(t2, t2, 0x1f);
1935 tcg_gen_rotr_i32(t2, t3, t2);
1936 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1937 tcg_temp_free_i32(t2);
1938 tcg_temp_free_i32(t3);
1942 #if defined(TARGET_MIPS64)
1944 tcg_gen_andi_tl(t0, t0, 0x3f);
1945 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1949 tcg_gen_andi_tl(t0, t0, 0x3f);
1950 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1954 tcg_gen_andi_tl(t0, t0, 0x3f);
1955 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1959 tcg_gen_andi_tl(t0, t0, 0x3f);
1960 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1965 (void)opn; /* avoid a compiler warning */
1966 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1971 /* Arithmetic on HI/LO registers */
1972 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1974 const char *opn = "hilo";
1976 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1983 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1987 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1992 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1994 tcg_gen_movi_tl(cpu_HI[0], 0);
1999 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2001 tcg_gen_movi_tl(cpu_LO[0], 0);
2005 (void)opn; /* avoid a compiler warning */
2006 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2009 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2012 const char *opn = "mul/div";
2018 #if defined(TARGET_MIPS64)
2022 t0 = tcg_temp_local_new();
2023 t1 = tcg_temp_local_new();
2026 t0 = tcg_temp_new();
2027 t1 = tcg_temp_new();
2031 gen_load_gpr(t0, rs);
2032 gen_load_gpr(t1, rt);
2036 int l1 = gen_new_label();
2037 int l2 = gen_new_label();
2039 tcg_gen_ext32s_tl(t0, t0);
2040 tcg_gen_ext32s_tl(t1, t1);
2041 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2042 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2043 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2045 tcg_gen_mov_tl(cpu_LO[0], t0);
2046 tcg_gen_movi_tl(cpu_HI[0], 0);
2049 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2050 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2051 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2052 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2059 int l1 = gen_new_label();
2061 tcg_gen_ext32u_tl(t0, t0);
2062 tcg_gen_ext32u_tl(t1, t1);
2063 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2064 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2065 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2066 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2067 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2074 TCGv_i64 t2 = tcg_temp_new_i64();
2075 TCGv_i64 t3 = tcg_temp_new_i64();
2077 tcg_gen_ext_tl_i64(t2, t0);
2078 tcg_gen_ext_tl_i64(t3, t1);
2079 tcg_gen_mul_i64(t2, t2, t3);
2080 tcg_temp_free_i64(t3);
2081 tcg_gen_trunc_i64_tl(t0, t2);
2082 tcg_gen_shri_i64(t2, t2, 32);
2083 tcg_gen_trunc_i64_tl(t1, t2);
2084 tcg_temp_free_i64(t2);
2085 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2086 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2092 TCGv_i64 t2 = tcg_temp_new_i64();
2093 TCGv_i64 t3 = tcg_temp_new_i64();
2095 tcg_gen_ext32u_tl(t0, t0);
2096 tcg_gen_ext32u_tl(t1, t1);
2097 tcg_gen_extu_tl_i64(t2, t0);
2098 tcg_gen_extu_tl_i64(t3, t1);
2099 tcg_gen_mul_i64(t2, t2, t3);
2100 tcg_temp_free_i64(t3);
2101 tcg_gen_trunc_i64_tl(t0, t2);
2102 tcg_gen_shri_i64(t2, t2, 32);
2103 tcg_gen_trunc_i64_tl(t1, t2);
2104 tcg_temp_free_i64(t2);
2105 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2106 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2110 #if defined(TARGET_MIPS64)
2113 int l1 = gen_new_label();
2114 int l2 = gen_new_label();
2116 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2117 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2118 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2119 tcg_gen_mov_tl(cpu_LO[0], t0);
2120 tcg_gen_movi_tl(cpu_HI[0], 0);
2123 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2124 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2131 int l1 = gen_new_label();
2133 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2134 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2135 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2141 gen_helper_dmult(t0, t1);
2145 gen_helper_dmultu(t0, t1);
2151 TCGv_i64 t2 = tcg_temp_new_i64();
2152 TCGv_i64 t3 = tcg_temp_new_i64();
2154 tcg_gen_ext_tl_i64(t2, t0);
2155 tcg_gen_ext_tl_i64(t3, t1);
2156 tcg_gen_mul_i64(t2, t2, t3);
2157 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2158 tcg_gen_add_i64(t2, t2, t3);
2159 tcg_temp_free_i64(t3);
2160 tcg_gen_trunc_i64_tl(t0, t2);
2161 tcg_gen_shri_i64(t2, t2, 32);
2162 tcg_gen_trunc_i64_tl(t1, t2);
2163 tcg_temp_free_i64(t2);
2164 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2165 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2171 TCGv_i64 t2 = tcg_temp_new_i64();
2172 TCGv_i64 t3 = tcg_temp_new_i64();
2174 tcg_gen_ext32u_tl(t0, t0);
2175 tcg_gen_ext32u_tl(t1, t1);
2176 tcg_gen_extu_tl_i64(t2, t0);
2177 tcg_gen_extu_tl_i64(t3, t1);
2178 tcg_gen_mul_i64(t2, t2, t3);
2179 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2180 tcg_gen_add_i64(t2, t2, t3);
2181 tcg_temp_free_i64(t3);
2182 tcg_gen_trunc_i64_tl(t0, t2);
2183 tcg_gen_shri_i64(t2, t2, 32);
2184 tcg_gen_trunc_i64_tl(t1, t2);
2185 tcg_temp_free_i64(t2);
2186 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2187 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2193 TCGv_i64 t2 = tcg_temp_new_i64();
2194 TCGv_i64 t3 = tcg_temp_new_i64();
2196 tcg_gen_ext_tl_i64(t2, t0);
2197 tcg_gen_ext_tl_i64(t3, t1);
2198 tcg_gen_mul_i64(t2, t2, t3);
2199 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2200 tcg_gen_sub_i64(t2, t3, t2);
2201 tcg_temp_free_i64(t3);
2202 tcg_gen_trunc_i64_tl(t0, t2);
2203 tcg_gen_shri_i64(t2, t2, 32);
2204 tcg_gen_trunc_i64_tl(t1, t2);
2205 tcg_temp_free_i64(t2);
2206 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2207 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2213 TCGv_i64 t2 = tcg_temp_new_i64();
2214 TCGv_i64 t3 = tcg_temp_new_i64();
2216 tcg_gen_ext32u_tl(t0, t0);
2217 tcg_gen_ext32u_tl(t1, t1);
2218 tcg_gen_extu_tl_i64(t2, t0);
2219 tcg_gen_extu_tl_i64(t3, t1);
2220 tcg_gen_mul_i64(t2, t2, t3);
2221 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2222 tcg_gen_sub_i64(t2, t3, t2);
2223 tcg_temp_free_i64(t3);
2224 tcg_gen_trunc_i64_tl(t0, t2);
2225 tcg_gen_shri_i64(t2, t2, 32);
2226 tcg_gen_trunc_i64_tl(t1, t2);
2227 tcg_temp_free_i64(t2);
2228 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2229 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2235 generate_exception(ctx, EXCP_RI);
2238 (void)opn; /* avoid a compiler warning */
2239 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2245 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2246 int rd, int rs, int rt)
2248 const char *opn = "mul vr54xx";
2249 TCGv t0 = tcg_temp_new();
2250 TCGv t1 = tcg_temp_new();
2252 gen_load_gpr(t0, rs);
2253 gen_load_gpr(t1, rt);
2256 case OPC_VR54XX_MULS:
2257 gen_helper_muls(t0, t0, t1);
2260 case OPC_VR54XX_MULSU:
2261 gen_helper_mulsu(t0, t0, t1);
2264 case OPC_VR54XX_MACC:
2265 gen_helper_macc(t0, t0, t1);
2268 case OPC_VR54XX_MACCU:
2269 gen_helper_maccu(t0, t0, t1);
2272 case OPC_VR54XX_MSAC:
2273 gen_helper_msac(t0, t0, t1);
2276 case OPC_VR54XX_MSACU:
2277 gen_helper_msacu(t0, t0, t1);
2280 case OPC_VR54XX_MULHI:
2281 gen_helper_mulhi(t0, t0, t1);
2284 case OPC_VR54XX_MULHIU:
2285 gen_helper_mulhiu(t0, t0, t1);
2288 case OPC_VR54XX_MULSHI:
2289 gen_helper_mulshi(t0, t0, t1);
2292 case OPC_VR54XX_MULSHIU:
2293 gen_helper_mulshiu(t0, t0, t1);
2296 case OPC_VR54XX_MACCHI:
2297 gen_helper_macchi(t0, t0, t1);
2300 case OPC_VR54XX_MACCHIU:
2301 gen_helper_macchiu(t0, t0, t1);
2304 case OPC_VR54XX_MSACHI:
2305 gen_helper_msachi(t0, t0, t1);
2308 case OPC_VR54XX_MSACHIU:
2309 gen_helper_msachiu(t0, t0, t1);
2313 MIPS_INVAL("mul vr54xx");
2314 generate_exception(ctx, EXCP_RI);
2317 gen_store_gpr(t0, rd);
2318 (void)opn; /* avoid a compiler warning */
2319 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2326 static void gen_cl (DisasContext *ctx, uint32_t opc,
2329 const char *opn = "CLx";
2337 t0 = tcg_temp_new();
2338 gen_load_gpr(t0, rs);
2341 gen_helper_clo(cpu_gpr[rd], t0);
2345 gen_helper_clz(cpu_gpr[rd], t0);
2348 #if defined(TARGET_MIPS64)
2350 gen_helper_dclo(cpu_gpr[rd], t0);
2354 gen_helper_dclz(cpu_gpr[rd], t0);
2359 (void)opn; /* avoid a compiler warning */
2360 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2364 /* Godson integer instructions */
2365 static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
2366 int rd, int rs, int rt)
2368 const char *opn = "loongson";
2380 case OPC_MULTU_G_2E:
2381 case OPC_MULTU_G_2F:
2382 #if defined(TARGET_MIPS64)
2383 case OPC_DMULT_G_2E:
2384 case OPC_DMULT_G_2F:
2385 case OPC_DMULTU_G_2E:
2386 case OPC_DMULTU_G_2F:
2388 t0 = tcg_temp_new();
2389 t1 = tcg_temp_new();
2392 t0 = tcg_temp_local_new();
2393 t1 = tcg_temp_local_new();
2397 gen_load_gpr(t0, rs);
2398 gen_load_gpr(t1, rt);
2403 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2404 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2407 case OPC_MULTU_G_2E:
2408 case OPC_MULTU_G_2F:
2409 tcg_gen_ext32u_tl(t0, t0);
2410 tcg_gen_ext32u_tl(t1, t1);
2411 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2412 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2418 int l1 = gen_new_label();
2419 int l2 = gen_new_label();
2420 int l3 = gen_new_label();
2421 tcg_gen_ext32s_tl(t0, t0);
2422 tcg_gen_ext32s_tl(t1, t1);
2423 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2424 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2427 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2428 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2429 tcg_gen_mov_tl(cpu_gpr[rd], t0);
2432 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2433 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2441 int l1 = gen_new_label();
2442 int l2 = gen_new_label();
2443 tcg_gen_ext32u_tl(t0, t0);
2444 tcg_gen_ext32u_tl(t1, t1);
2445 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2446 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2449 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2450 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2458 int l1 = gen_new_label();
2459 int l2 = gen_new_label();
2460 int l3 = gen_new_label();
2461 tcg_gen_ext32u_tl(t0, t0);
2462 tcg_gen_ext32u_tl(t1, t1);
2463 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2464 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2465 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2467 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2470 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2471 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2479 int l1 = gen_new_label();
2480 int l2 = gen_new_label();
2481 tcg_gen_ext32u_tl(t0, t0);
2482 tcg_gen_ext32u_tl(t1, t1);
2483 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2484 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2487 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2488 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2493 #if defined(TARGET_MIPS64)
2494 case OPC_DMULT_G_2E:
2495 case OPC_DMULT_G_2F:
2496 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2499 case OPC_DMULTU_G_2E:
2500 case OPC_DMULTU_G_2F:
2501 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2507 int l1 = gen_new_label();
2508 int l2 = gen_new_label();
2509 int l3 = gen_new_label();
2510 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2511 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2514 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2515 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2516 tcg_gen_mov_tl(cpu_gpr[rd], t0);
2519 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2524 case OPC_DDIVU_G_2E:
2525 case OPC_DDIVU_G_2F:
2527 int l1 = gen_new_label();
2528 int l2 = gen_new_label();
2529 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2530 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2533 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2541 int l1 = gen_new_label();
2542 int l2 = gen_new_label();
2543 int l3 = gen_new_label();
2544 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2545 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2546 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2548 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2551 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2556 case OPC_DMODU_G_2E:
2557 case OPC_DMODU_G_2F:
2559 int l1 = gen_new_label();
2560 int l2 = gen_new_label();
2561 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2562 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2565 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2573 (void)opn; /* avoid a compiler warning */
2574 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2580 static void gen_trap (DisasContext *ctx, uint32_t opc,
2581 int rs, int rt, int16_t imm)
2584 TCGv t0 = tcg_temp_new();
2585 TCGv t1 = tcg_temp_new();
2588 /* Load needed operands */
2596 /* Compare two registers */
2598 gen_load_gpr(t0, rs);
2599 gen_load_gpr(t1, rt);
2609 /* Compare register to immediate */
2610 if (rs != 0 || imm != 0) {
2611 gen_load_gpr(t0, rs);
2612 tcg_gen_movi_tl(t1, (int32_t)imm);
2619 case OPC_TEQ: /* rs == rs */
2620 case OPC_TEQI: /* r0 == 0 */
2621 case OPC_TGE: /* rs >= rs */
2622 case OPC_TGEI: /* r0 >= 0 */
2623 case OPC_TGEU: /* rs >= rs unsigned */
2624 case OPC_TGEIU: /* r0 >= 0 unsigned */
2626 generate_exception(ctx, EXCP_TRAP);
2628 case OPC_TLT: /* rs < rs */
2629 case OPC_TLTI: /* r0 < 0 */
2630 case OPC_TLTU: /* rs < rs unsigned */
2631 case OPC_TLTIU: /* r0 < 0 unsigned */
2632 case OPC_TNE: /* rs != rs */
2633 case OPC_TNEI: /* r0 != 0 */
2634 /* Never trap: treat as NOP. */
2638 int l1 = gen_new_label();
2643 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2647 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2651 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2655 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2659 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2663 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2666 generate_exception(ctx, EXCP_TRAP);
2673 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2675 TranslationBlock *tb;
2677 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2678 likely(!ctx->singlestep_enabled)) {
2681 tcg_gen_exit_tb((tcg_target_long)tb + n);
2684 if (ctx->singlestep_enabled) {
2685 save_cpu_state(ctx, 0);
2686 gen_helper_0i(raise_exception, EXCP_DEBUG);
2692 /* Branches (before delay slot) */
2693 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2695 int rs, int rt, int32_t offset)
2697 target_ulong btgt = -1;
2699 int bcond_compute = 0;
2700 TCGv t0 = tcg_temp_new();
2701 TCGv t1 = tcg_temp_new();
2703 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2704 #ifdef MIPS_DEBUG_DISAS
2705 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2707 generate_exception(ctx, EXCP_RI);
2711 /* Load needed operands */
2717 /* Compare two registers */
2719 gen_load_gpr(t0, rs);
2720 gen_load_gpr(t1, rt);
2723 btgt = ctx->pc + insn_bytes + offset;
2739 /* Compare to zero */
2741 gen_load_gpr(t0, rs);
2744 btgt = ctx->pc + insn_bytes + offset;
2751 /* Jump to immediate */
2752 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2758 /* Jump to register */
2759 if (offset != 0 && offset != 16) {
2760 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2761 others are reserved. */
2762 MIPS_INVAL("jump hint");
2763 generate_exception(ctx, EXCP_RI);
2766 gen_load_gpr(btarget, rs);
2769 MIPS_INVAL("branch/jump");
2770 generate_exception(ctx, EXCP_RI);
2773 if (bcond_compute == 0) {
2774 /* No condition to be computed */
2776 case OPC_BEQ: /* rx == rx */
2777 case OPC_BEQL: /* rx == rx likely */
2778 case OPC_BGEZ: /* 0 >= 0 */
2779 case OPC_BGEZL: /* 0 >= 0 likely */
2780 case OPC_BLEZ: /* 0 <= 0 */
2781 case OPC_BLEZL: /* 0 <= 0 likely */
2783 ctx->hflags |= MIPS_HFLAG_B;
2784 MIPS_DEBUG("balways");
2787 case OPC_BGEZAL: /* 0 >= 0 */
2788 case OPC_BGEZALL: /* 0 >= 0 likely */
2789 ctx->hflags |= (opc == OPC_BGEZALS
2791 : MIPS_HFLAG_BDS32);
2792 /* Always take and link */
2794 ctx->hflags |= MIPS_HFLAG_B;
2795 MIPS_DEBUG("balways and link");
2797 case OPC_BNE: /* rx != rx */
2798 case OPC_BGTZ: /* 0 > 0 */
2799 case OPC_BLTZ: /* 0 < 0 */
2801 MIPS_DEBUG("bnever (NOP)");
2804 case OPC_BLTZAL: /* 0 < 0 */
2805 ctx->hflags |= (opc == OPC_BLTZALS
2807 : MIPS_HFLAG_BDS32);
2808 /* Handle as an unconditional branch to get correct delay
2811 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
2812 ctx->hflags |= MIPS_HFLAG_B;
2813 MIPS_DEBUG("bnever and link");
2815 case OPC_BLTZALL: /* 0 < 0 likely */
2816 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2817 /* Skip the instruction in the delay slot */
2818 MIPS_DEBUG("bnever, link and skip");
2821 case OPC_BNEL: /* rx != rx likely */
2822 case OPC_BGTZL: /* 0 > 0 likely */
2823 case OPC_BLTZL: /* 0 < 0 likely */
2824 /* Skip the instruction in the delay slot */
2825 MIPS_DEBUG("bnever and skip");
2829 ctx->hflags |= MIPS_HFLAG_B;
2830 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2834 ctx->hflags |= MIPS_HFLAG_BX;
2839 ctx->hflags |= MIPS_HFLAG_B;
2840 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
2842 : MIPS_HFLAG_BDS32);
2843 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2846 ctx->hflags |= MIPS_HFLAG_BR;
2847 if (insn_bytes == 4)
2848 ctx->hflags |= MIPS_HFLAG_BDS32;
2849 MIPS_DEBUG("jr %s", regnames[rs]);
2855 ctx->hflags |= MIPS_HFLAG_BR;
2856 ctx->hflags |= (opc == OPC_JALRS
2858 : MIPS_HFLAG_BDS32);
2859 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2862 MIPS_INVAL("branch/jump");
2863 generate_exception(ctx, EXCP_RI);
2869 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2870 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2871 regnames[rs], regnames[rt], btgt);
2874 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2875 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2876 regnames[rs], regnames[rt], btgt);
2879 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2880 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2881 regnames[rs], regnames[rt], btgt);
2884 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2885 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2886 regnames[rs], regnames[rt], btgt);
2889 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2890 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2893 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2894 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2898 ctx->hflags |= (opc == OPC_BGEZALS
2900 : MIPS_HFLAG_BDS32);
2901 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2902 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2906 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2908 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2911 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2912 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2915 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2916 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2919 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2920 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2923 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2924 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2927 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2928 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2931 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2932 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2936 ctx->hflags |= (opc == OPC_BLTZALS
2938 : MIPS_HFLAG_BDS32);
2939 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2941 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2943 ctx->hflags |= MIPS_HFLAG_BC;
2946 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2948 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2950 ctx->hflags |= MIPS_HFLAG_BL;
2953 MIPS_INVAL("conditional branch/jump");
2954 generate_exception(ctx, EXCP_RI);
2958 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2959 blink, ctx->hflags, btgt);
2961 ctx->btarget = btgt;
2963 int post_delay = insn_bytes;
2964 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2966 if (opc != OPC_JALRC)
2967 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2969 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2973 if (insn_bytes == 2)
2974 ctx->hflags |= MIPS_HFLAG_B16;
2979 /* special3 bitfield operations */
2980 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2981 int rs, int lsb, int msb)
2983 TCGv t0 = tcg_temp_new();
2984 TCGv t1 = tcg_temp_new();
2987 gen_load_gpr(t1, rs);
2992 tcg_gen_shri_tl(t0, t1, lsb);
2994 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2996 tcg_gen_ext32s_tl(t0, t0);
2999 #if defined(TARGET_MIPS64)
3001 tcg_gen_shri_tl(t0, t1, lsb);
3003 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3007 tcg_gen_shri_tl(t0, t1, lsb + 32);
3008 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3011 tcg_gen_shri_tl(t0, t1, lsb);
3012 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3018 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3019 gen_load_gpr(t0, rt);
3020 tcg_gen_andi_tl(t0, t0, ~mask);
3021 tcg_gen_shli_tl(t1, t1, lsb);
3022 tcg_gen_andi_tl(t1, t1, mask);
3023 tcg_gen_or_tl(t0, t0, t1);
3024 tcg_gen_ext32s_tl(t0, t0);
3026 #if defined(TARGET_MIPS64)
3030 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3031 gen_load_gpr(t0, rt);
3032 tcg_gen_andi_tl(t0, t0, ~mask);
3033 tcg_gen_shli_tl(t1, t1, lsb);
3034 tcg_gen_andi_tl(t1, t1, mask);
3035 tcg_gen_or_tl(t0, t0, t1);
3040 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3041 gen_load_gpr(t0, rt);
3042 tcg_gen_andi_tl(t0, t0, ~mask);
3043 tcg_gen_shli_tl(t1, t1, lsb + 32);
3044 tcg_gen_andi_tl(t1, t1, mask);
3045 tcg_gen_or_tl(t0, t0, t1);
3050 gen_load_gpr(t0, rt);
3051 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3052 gen_load_gpr(t0, rt);
3053 tcg_gen_andi_tl(t0, t0, ~mask);
3054 tcg_gen_shli_tl(t1, t1, lsb);
3055 tcg_gen_andi_tl(t1, t1, mask);
3056 tcg_gen_or_tl(t0, t0, t1);
3061 MIPS_INVAL("bitops");
3062 generate_exception(ctx, EXCP_RI);
3067 gen_store_gpr(t0, rt);
3072 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3077 /* If no destination, treat it as a NOP. */
3082 t0 = tcg_temp_new();
3083 gen_load_gpr(t0, rt);
3087 TCGv t1 = tcg_temp_new();
3089 tcg_gen_shri_tl(t1, t0, 8);
3090 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3091 tcg_gen_shli_tl(t0, t0, 8);
3092 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3093 tcg_gen_or_tl(t0, t0, t1);
3095 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3099 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3102 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3104 #if defined(TARGET_MIPS64)
3107 TCGv t1 = tcg_temp_new();
3109 tcg_gen_shri_tl(t1, t0, 8);
3110 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
3111 tcg_gen_shli_tl(t0, t0, 8);
3112 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
3113 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3119 TCGv t1 = tcg_temp_new();
3121 tcg_gen_shri_tl(t1, t0, 16);
3122 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
3123 tcg_gen_shli_tl(t0, t0, 16);
3124 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
3125 tcg_gen_or_tl(t0, t0, t1);
3126 tcg_gen_shri_tl(t1, t0, 32);
3127 tcg_gen_shli_tl(t0, t0, 32);
3128 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3134 MIPS_INVAL("bsfhl");
3135 generate_exception(ctx, EXCP_RI);
3142 #ifndef CONFIG_USER_ONLY
3143 /* CP0 (MMU and control) */
3144 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
3146 TCGv_i32 t0 = tcg_temp_new_i32();
3148 tcg_gen_ld_i32(t0, cpu_env, off);
3149 tcg_gen_ext_i32_tl(arg, t0);
3150 tcg_temp_free_i32(t0);
3153 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
3155 tcg_gen_ld_tl(arg, cpu_env, off);
3156 tcg_gen_ext32s_tl(arg, arg);
3159 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
3161 TCGv_i32 t0 = tcg_temp_new_i32();
3163 tcg_gen_trunc_tl_i32(t0, arg);
3164 tcg_gen_st_i32(t0, cpu_env, off);
3165 tcg_temp_free_i32(t0);
3168 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
3170 tcg_gen_ext32s_tl(arg, arg);
3171 tcg_gen_st_tl(arg, cpu_env, off);
3174 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3176 const char *rn = "invalid";
3179 check_insn(env, ctx, ISA_MIPS32);
3185 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
3189 check_insn(env, ctx, ASE_MT);
3190 gen_helper_mfc0_mvpcontrol(arg);
3194 check_insn(env, ctx, ASE_MT);
3195 gen_helper_mfc0_mvpconf0(arg);
3199 check_insn(env, ctx, ASE_MT);
3200 gen_helper_mfc0_mvpconf1(arg);
3210 gen_helper_mfc0_random(arg);
3214 check_insn(env, ctx, ASE_MT);
3215 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
3219 check_insn(env, ctx, ASE_MT);
3220 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
3224 check_insn(env, ctx, ASE_MT);
3225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
3229 check_insn(env, ctx, ASE_MT);
3230 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
3234 check_insn(env, ctx, ASE_MT);
3235 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
3239 check_insn(env, ctx, ASE_MT);
3240 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
3241 rn = "VPEScheFBack";
3244 check_insn(env, ctx, ASE_MT);
3245 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
3255 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
3256 tcg_gen_ext32s_tl(arg, arg);
3260 check_insn(env, ctx, ASE_MT);
3261 gen_helper_mfc0_tcstatus(arg);
3265 check_insn(env, ctx, ASE_MT);
3266 gen_helper_mfc0_tcbind(arg);
3270 check_insn(env, ctx, ASE_MT);
3271 gen_helper_mfc0_tcrestart(arg);
3275 check_insn(env, ctx, ASE_MT);
3276 gen_helper_mfc0_tchalt(arg);
3280 check_insn(env, ctx, ASE_MT);
3281 gen_helper_mfc0_tccontext(arg);
3285 check_insn(env, ctx, ASE_MT);
3286 gen_helper_mfc0_tcschedule(arg);
3290 check_insn(env, ctx, ASE_MT);
3291 gen_helper_mfc0_tcschefback(arg);
3301 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
3302 tcg_gen_ext32s_tl(arg, arg);
3312 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
3313 tcg_gen_ext32s_tl(arg, arg);
3317 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3318 rn = "ContextConfig";
3327 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
3331 check_insn(env, ctx, ISA_MIPS32R2);
3332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
3342 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
3346 check_insn(env, ctx, ISA_MIPS32R2);
3347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
3351 check_insn(env, ctx, ISA_MIPS32R2);
3352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
3356 check_insn(env, ctx, ISA_MIPS32R2);
3357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
3361 check_insn(env, ctx, ISA_MIPS32R2);
3362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
3366 check_insn(env, ctx, ISA_MIPS32R2);
3367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
3377 check_insn(env, ctx, ISA_MIPS32R2);
3378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
3388 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
3389 tcg_gen_ext32s_tl(arg, arg);
3399 /* Mark as an IO operation because we read the time. */
3402 gen_helper_mfc0_count(arg);
3406 /* Break the TB to be able to take timer interrupts immediately
3407 after reading count. */
3408 ctx->bstate = BS_STOP;
3411 /* 6,7 are implementation dependent */
3419 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
3420 tcg_gen_ext32s_tl(arg, arg);
3430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
3433 /* 6,7 are implementation dependent */
3441 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
3445 check_insn(env, ctx, ISA_MIPS32R2);
3446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
3450 check_insn(env, ctx, ISA_MIPS32R2);
3451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
3455 check_insn(env, ctx, ISA_MIPS32R2);
3456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
3466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
3476 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
3477 tcg_gen_ext32s_tl(arg, arg);
3487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
3491 check_insn(env, ctx, ISA_MIPS32R2);
3492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
3502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
3506 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
3510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
3514 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
3517 /* 4,5 are reserved */
3518 /* 6,7 are implementation dependent */
3520 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
3524 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
3534 gen_helper_mfc0_lladdr(arg);
3544 gen_helper_1i(mfc0_watchlo, arg, sel);
3554 gen_helper_1i(mfc0_watchhi, arg, sel);
3564 #if defined(TARGET_MIPS64)
3565 check_insn(env, ctx, ISA_MIPS3);
3566 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
3567 tcg_gen_ext32s_tl(arg, arg);
3576 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3579 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
3587 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3588 rn = "'Diagnostic"; /* implementation dependent */
3593 gen_helper_mfc0_debug(arg); /* EJTAG support */
3597 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3598 rn = "TraceControl";
3601 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3602 rn = "TraceControl2";
3605 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3606 rn = "UserTraceData";
3609 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3620 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
3621 tcg_gen_ext32s_tl(arg, arg);
3631 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
3632 rn = "Performance0";
3635 // gen_helper_mfc0_performance1(arg);
3636 rn = "Performance1";
3639 // gen_helper_mfc0_performance2(arg);
3640 rn = "Performance2";
3643 // gen_helper_mfc0_performance3(arg);
3644 rn = "Performance3";
3647 // gen_helper_mfc0_performance4(arg);
3648 rn = "Performance4";
3651 // gen_helper_mfc0_performance5(arg);
3652 rn = "Performance5";
3655 // gen_helper_mfc0_performance6(arg);
3656 rn = "Performance6";
3659 // gen_helper_mfc0_performance7(arg);
3660 rn = "Performance7";
3667 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3673 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
3693 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
3706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
3713 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
3723 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
3724 tcg_gen_ext32s_tl(arg, arg);
3735 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
3745 (void)rn; /* avoid a compiler warning */
3746 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3750 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3751 generate_exception(ctx, EXCP_RI);
3754 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3756 const char *rn = "invalid";
3759 check_insn(env, ctx, ISA_MIPS32);
3768 gen_helper_mtc0_index(arg);
3772 check_insn(env, ctx, ASE_MT);
3773 gen_helper_mtc0_mvpcontrol(arg);
3777 check_insn(env, ctx, ASE_MT);
3782 check_insn(env, ctx, ASE_MT);
3797 check_insn(env, ctx, ASE_MT);
3798 gen_helper_mtc0_vpecontrol(arg);
3802 check_insn(env, ctx, ASE_MT);
3803 gen_helper_mtc0_vpeconf0(arg);
3807 check_insn(env, ctx, ASE_MT);
3808 gen_helper_mtc0_vpeconf1(arg);
3812 check_insn(env, ctx, ASE_MT);
3813 gen_helper_mtc0_yqmask(arg);
3817 check_insn(env, ctx, ASE_MT);
3818 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
3822 check_insn(env, ctx, ASE_MT);
3823 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
3824 rn = "VPEScheFBack";
3827 check_insn(env, ctx, ASE_MT);
3828 gen_helper_mtc0_vpeopt(arg);
3838 gen_helper_mtc0_entrylo0(arg);
3842 check_insn(env, ctx, ASE_MT);
3843 gen_helper_mtc0_tcstatus(arg);
3847 check_insn(env, ctx, ASE_MT);
3848 gen_helper_mtc0_tcbind(arg);
3852 check_insn(env, ctx, ASE_MT);
3853 gen_helper_mtc0_tcrestart(arg);
3857 check_insn(env, ctx, ASE_MT);
3858 gen_helper_mtc0_tchalt(arg);
3862 check_insn(env, ctx, ASE_MT);
3863 gen_helper_mtc0_tccontext(arg);
3867 check_insn(env, ctx, ASE_MT);
3868 gen_helper_mtc0_tcschedule(arg);
3872 check_insn(env, ctx, ASE_MT);
3873 gen_helper_mtc0_tcschefback(arg);
3883 gen_helper_mtc0_entrylo1(arg);
3893 gen_helper_mtc0_context(arg);
3897 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3898 rn = "ContextConfig";
3907 gen_helper_mtc0_pagemask(arg);
3911 check_insn(env, ctx, ISA_MIPS32R2);
3912 gen_helper_mtc0_pagegrain(arg);
3922 gen_helper_mtc0_wired(arg);
3926 check_insn(env, ctx, ISA_MIPS32R2);
3927 gen_helper_mtc0_srsconf0(arg);
3931 check_insn(env, ctx, ISA_MIPS32R2);
3932 gen_helper_mtc0_srsconf1(arg);
3936 check_insn(env, ctx, ISA_MIPS32R2);
3937 gen_helper_mtc0_srsconf2(arg);
3941 check_insn(env, ctx, ISA_MIPS32R2);
3942 gen_helper_mtc0_srsconf3(arg);
3946 check_insn(env, ctx, ISA_MIPS32R2);
3947 gen_helper_mtc0_srsconf4(arg);
3957 check_insn(env, ctx, ISA_MIPS32R2);
3958 gen_helper_mtc0_hwrena(arg);
3972 gen_helper_mtc0_count(arg);
3975 /* 6,7 are implementation dependent */
3983 gen_helper_mtc0_entryhi(arg);
3993 gen_helper_mtc0_compare(arg);
3996 /* 6,7 are implementation dependent */
4004 save_cpu_state(ctx, 1);
4005 gen_helper_mtc0_status(arg);
4006 /* BS_STOP isn't good enough here, hflags may have changed. */
4007 gen_save_pc(ctx->pc + 4);
4008 ctx->bstate = BS_EXCP;
4012 check_insn(env, ctx, ISA_MIPS32R2);
4013 gen_helper_mtc0_intctl(arg);
4014 /* Stop translation as we may have switched the execution mode */
4015 ctx->bstate = BS_STOP;
4019 check_insn(env, ctx, ISA_MIPS32R2);
4020 gen_helper_mtc0_srsctl(arg);
4021 /* Stop translation as we may have switched the execution mode */
4022 ctx->bstate = BS_STOP;
4026 check_insn(env, ctx, ISA_MIPS32R2);
4027 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4028 /* Stop translation as we may have switched the execution mode */
4029 ctx->bstate = BS_STOP;
4039 save_cpu_state(ctx, 1);
4040 gen_helper_mtc0_cause(arg);
4050 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4064 check_insn(env, ctx, ISA_MIPS32R2);
4065 gen_helper_mtc0_ebase(arg);
4075 gen_helper_mtc0_config0(arg);
4077 /* Stop translation as we may have switched the execution mode */
4078 ctx->bstate = BS_STOP;
4081 /* ignored, read only */
4085 gen_helper_mtc0_config2(arg);
4087 /* Stop translation as we may have switched the execution mode */
4088 ctx->bstate = BS_STOP;
4091 /* ignored, read only */
4094 /* 4,5 are reserved */
4095 /* 6,7 are implementation dependent */
4105 rn = "Invalid config selector";
4112 gen_helper_mtc0_lladdr(arg);
4122 gen_helper_1i(mtc0_watchlo, arg, sel);
4132 gen_helper_1i(mtc0_watchhi, arg, sel);
4142 #if defined(TARGET_MIPS64)
4143 check_insn(env, ctx, ISA_MIPS3);
4144 gen_helper_mtc0_xcontext(arg);
4153 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4156 gen_helper_mtc0_framemask(arg);
4165 rn = "Diagnostic"; /* implementation dependent */
4170 gen_helper_mtc0_debug(arg); /* EJTAG support */
4171 /* BS_STOP isn't good enough here, hflags may have changed. */
4172 gen_save_pc(ctx->pc + 4);
4173 ctx->bstate = BS_EXCP;
4177 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
4178 rn = "TraceControl";
4179 /* Stop translation as we may have switched the execution mode */
4180 ctx->bstate = BS_STOP;
4183 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
4184 rn = "TraceControl2";
4185 /* Stop translation as we may have switched the execution mode */
4186 ctx->bstate = BS_STOP;
4189 /* Stop translation as we may have switched the execution mode */
4190 ctx->bstate = BS_STOP;
4191 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
4192 rn = "UserTraceData";
4193 /* Stop translation as we may have switched the execution mode */
4194 ctx->bstate = BS_STOP;
4197 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
4198 /* Stop translation as we may have switched the execution mode */
4199 ctx->bstate = BS_STOP;
4210 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
4220 gen_helper_mtc0_performance0(arg);
4221 rn = "Performance0";
4224 // gen_helper_mtc0_performance1(arg);
4225 rn = "Performance1";
4228 // gen_helper_mtc0_performance2(arg);
4229 rn = "Performance2";
4232 // gen_helper_mtc0_performance3(arg);
4233 rn = "Performance3";
4236 // gen_helper_mtc0_performance4(arg);
4237 rn = "Performance4";
4240 // gen_helper_mtc0_performance5(arg);
4241 rn = "Performance5";
4244 // gen_helper_mtc0_performance6(arg);
4245 rn = "Performance6";
4248 // gen_helper_mtc0_performance7(arg);
4249 rn = "Performance7";
4275 gen_helper_mtc0_taglo(arg);
4282 gen_helper_mtc0_datalo(arg);
4295 gen_helper_mtc0_taghi(arg);
4302 gen_helper_mtc0_datahi(arg);
4313 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
4324 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4330 /* Stop translation as we may have switched the execution mode */
4331 ctx->bstate = BS_STOP;
4336 (void)rn; /* avoid a compiler warning */
4337 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4338 /* For simplicity assume that all writes can cause interrupts. */
4341 ctx->bstate = BS_STOP;
4346 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4347 generate_exception(ctx, EXCP_RI);
4350 #if defined(TARGET_MIPS64)
4351 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4353 const char *rn = "invalid";
4356 check_insn(env, ctx, ISA_MIPS64);
4362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4366 check_insn(env, ctx, ASE_MT);
4367 gen_helper_mfc0_mvpcontrol(arg);
4371 check_insn(env, ctx, ASE_MT);
4372 gen_helper_mfc0_mvpconf0(arg);
4376 check_insn(env, ctx, ASE_MT);
4377 gen_helper_mfc0_mvpconf1(arg);
4387 gen_helper_mfc0_random(arg);
4391 check_insn(env, ctx, ASE_MT);
4392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4396 check_insn(env, ctx, ASE_MT);
4397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4401 check_insn(env, ctx, ASE_MT);
4402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4406 check_insn(env, ctx, ASE_MT);
4407 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
4411 check_insn(env, ctx, ASE_MT);
4412 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
4416 check_insn(env, ctx, ASE_MT);
4417 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4418 rn = "VPEScheFBack";
4421 check_insn(env, ctx, ASE_MT);
4422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4432 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4436 check_insn(env, ctx, ASE_MT);
4437 gen_helper_mfc0_tcstatus(arg);
4441 check_insn(env, ctx, ASE_MT);
4442 gen_helper_mfc0_tcbind(arg);
4446 check_insn(env, ctx, ASE_MT);
4447 gen_helper_dmfc0_tcrestart(arg);
4451 check_insn(env, ctx, ASE_MT);
4452 gen_helper_dmfc0_tchalt(arg);
4456 check_insn(env, ctx, ASE_MT);
4457 gen_helper_dmfc0_tccontext(arg);
4461 check_insn(env, ctx, ASE_MT);
4462 gen_helper_dmfc0_tcschedule(arg);
4466 check_insn(env, ctx, ASE_MT);
4467 gen_helper_dmfc0_tcschefback(arg);
4477 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4487 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4491 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4492 rn = "ContextConfig";
4501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4505 check_insn(env, ctx, ISA_MIPS32R2);
4506 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4516 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4520 check_insn(env, ctx, ISA_MIPS32R2);
4521 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4525 check_insn(env, ctx, ISA_MIPS32R2);
4526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4530 check_insn(env, ctx, ISA_MIPS32R2);
4531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4535 check_insn(env, ctx, ISA_MIPS32R2);
4536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4540 check_insn(env, ctx, ISA_MIPS32R2);
4541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4551 check_insn(env, ctx, ISA_MIPS32R2);
4552 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4562 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4572 /* Mark as an IO operation because we read the time. */
4575 gen_helper_mfc0_count(arg);
4579 /* Break the TB to be able to take timer interrupts immediately
4580 after reading count. */
4581 ctx->bstate = BS_STOP;
4584 /* 6,7 are implementation dependent */
4592 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4605 /* 6,7 are implementation dependent */
4613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4617 check_insn(env, ctx, ISA_MIPS32R2);
4618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4622 check_insn(env, ctx, ISA_MIPS32R2);
4623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4627 check_insn(env, ctx, ISA_MIPS32R2);
4628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4648 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4658 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4662 check_insn(env, ctx, ISA_MIPS32R2);
4663 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4677 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4681 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4685 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4688 /* 6,7 are implementation dependent */
4690 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4694 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4704 gen_helper_dmfc0_lladdr(arg);
4714 gen_helper_1i(dmfc0_watchlo, arg, sel);
4724 gen_helper_1i(mfc0_watchhi, arg, sel);
4734 check_insn(env, ctx, ISA_MIPS3);
4735 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4743 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4746 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4754 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4755 rn = "'Diagnostic"; /* implementation dependent */
4760 gen_helper_mfc0_debug(arg); /* EJTAG support */
4764 // gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4765 rn = "TraceControl";
4768 // gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4769 rn = "TraceControl2";
4772 // gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4773 rn = "UserTraceData";
4776 // gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4787 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4797 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4798 rn = "Performance0";
4801 // gen_helper_dmfc0_performance1(arg);
4802 rn = "Performance1";
4805 // gen_helper_dmfc0_performance2(arg);
4806 rn = "Performance2";
4809 // gen_helper_dmfc0_performance3(arg);
4810 rn = "Performance3";
4813 // gen_helper_dmfc0_performance4(arg);
4814 rn = "Performance4";
4817 // gen_helper_dmfc0_performance5(arg);
4818 rn = "Performance5";
4821 // gen_helper_dmfc0_performance6(arg);
4822 rn = "Performance6";
4825 // gen_helper_dmfc0_performance7(arg);
4826 rn = "Performance7";
4833 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4840 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4853 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4890 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4901 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4911 (void)rn; /* avoid a compiler warning */
4912 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4916 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4917 generate_exception(ctx, EXCP_RI);
4920 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4922 const char *rn = "invalid";
4925 check_insn(env, ctx, ISA_MIPS64);
4934 gen_helper_mtc0_index(arg);
4938 check_insn(env, ctx, ASE_MT);
4939 gen_helper_mtc0_mvpcontrol(arg);
4943 check_insn(env, ctx, ASE_MT);
4948 check_insn(env, ctx, ASE_MT);
4963 check_insn(env, ctx, ASE_MT);
4964 gen_helper_mtc0_vpecontrol(arg);
4968 check_insn(env, ctx, ASE_MT);
4969 gen_helper_mtc0_vpeconf0(arg);
4973 check_insn(env, ctx, ASE_MT);
4974 gen_helper_mtc0_vpeconf1(arg);
4978 check_insn(env, ctx, ASE_MT);
4979 gen_helper_mtc0_yqmask(arg);
4983 check_insn(env, ctx, ASE_MT);
4984 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
4988 check_insn(env, ctx, ASE_MT);
4989 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4990 rn = "VPEScheFBack";
4993 check_insn(env, ctx, ASE_MT);
4994 gen_helper_mtc0_vpeopt(arg);
5004 gen_helper_mtc0_entrylo0(arg);
5008 check_insn(env, ctx, ASE_MT);
5009 gen_helper_mtc0_tcstatus(arg);
5013 check_insn(env, ctx, ASE_MT);
5014 gen_helper_mtc0_tcbind(arg);
5018 check_insn(env, ctx, ASE_MT);
5019 gen_helper_mtc0_tcrestart(arg);
5023 check_insn(env, ctx, ASE_MT);
5024 gen_helper_mtc0_tchalt(arg);
5028 check_insn(env, ctx, ASE_MT);
5029 gen_helper_mtc0_tccontext(arg);
5033 check_insn(env, ctx, ASE_MT);
5034 gen_helper_mtc0_tcschedule(arg);
5038 check_insn(env, ctx, ASE_MT);
5039 gen_helper_mtc0_tcschefback(arg);
5049 gen_helper_mtc0_entrylo1(arg);
5059 gen_helper_mtc0_context(arg);
5063 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
5064 rn = "ContextConfig";
5073 gen_helper_mtc0_pagemask(arg);
5077 check_insn(env, ctx, ISA_MIPS32R2);
5078 gen_helper_mtc0_pagegrain(arg);
5088 gen_helper_mtc0_wired(arg);
5092 check_insn(env, ctx, ISA_MIPS32R2);
5093 gen_helper_mtc0_srsconf0(arg);
5097 check_insn(env, ctx, ISA_MIPS32R2);
5098 gen_helper_mtc0_srsconf1(arg);
5102 check_insn(env, ctx, ISA_MIPS32R2);
5103 gen_helper_mtc0_srsconf2(arg);
5107 check_insn(env, ctx, ISA_MIPS32R2);
5108 gen_helper_mtc0_srsconf3(arg);
5112 check_insn(env, ctx, ISA_MIPS32R2);
5113 gen_helper_mtc0_srsconf4(arg);
5123 check_insn(env, ctx, ISA_MIPS32R2);
5124 gen_helper_mtc0_hwrena(arg);
5138 gen_helper_mtc0_count(arg);
5141 /* 6,7 are implementation dependent */
5145 /* Stop translation as we may have switched the execution mode */
5146 ctx->bstate = BS_STOP;
5151 gen_helper_mtc0_entryhi(arg);
5161 gen_helper_mtc0_compare(arg);
5164 /* 6,7 are implementation dependent */
5168 /* Stop translation as we may have switched the execution mode */
5169 ctx->bstate = BS_STOP;
5174 save_cpu_state(ctx, 1);
5175 gen_helper_mtc0_status(arg);
5176 /* BS_STOP isn't good enough here, hflags may have changed. */
5177 gen_save_pc(ctx->pc + 4);
5178 ctx->bstate = BS_EXCP;
5182 check_insn(env, ctx, ISA_MIPS32R2);
5183 gen_helper_mtc0_intctl(arg);
5184 /* Stop translation as we may have switched the execution mode */
5185 ctx->bstate = BS_STOP;
5189 check_insn(env, ctx, ISA_MIPS32R2);
5190 gen_helper_mtc0_srsctl(arg);
5191 /* Stop translation as we may have switched the execution mode */
5192 ctx->bstate = BS_STOP;
5196 check_insn(env, ctx, ISA_MIPS32R2);
5197 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5198 /* Stop translation as we may have switched the execution mode */
5199 ctx->bstate = BS_STOP;
5209 save_cpu_state(ctx, 1);
5210 /* Mark as an IO operation because we may trigger a software
5215 gen_helper_mtc0_cause(arg);
5219 /* Stop translation as we may have triggered an intetrupt */
5220 ctx->bstate = BS_STOP;
5230 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5244 check_insn(env, ctx, ISA_MIPS32R2);
5245 gen_helper_mtc0_ebase(arg);
5255 gen_helper_mtc0_config0(arg);
5257 /* Stop translation as we may have switched the execution mode */
5258 ctx->bstate = BS_STOP;
5261 /* ignored, read only */
5265 gen_helper_mtc0_config2(arg);
5267 /* Stop translation as we may have switched the execution mode */
5268 ctx->bstate = BS_STOP;
5274 /* 6,7 are implementation dependent */
5276 rn = "Invalid config selector";
5283 gen_helper_mtc0_lladdr(arg);
5293 gen_helper_1i(mtc0_watchlo, arg, sel);
5303 gen_helper_1i(mtc0_watchhi, arg, sel);
5313 check_insn(env, ctx, ISA_MIPS3);
5314 gen_helper_mtc0_xcontext(arg);
5322 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5325 gen_helper_mtc0_framemask(arg);
5334 rn = "Diagnostic"; /* implementation dependent */
5339 gen_helper_mtc0_debug(arg); /* EJTAG support */
5340 /* BS_STOP isn't good enough here, hflags may have changed. */
5341 gen_save_pc(ctx->pc + 4);
5342 ctx->bstate = BS_EXCP;
5346 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5347 /* Stop translation as we may have switched the execution mode */
5348 ctx->bstate = BS_STOP;
5349 rn = "TraceControl";
5352 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5353 /* Stop translation as we may have switched the execution mode */
5354 ctx->bstate = BS_STOP;
5355 rn = "TraceControl2";
5358 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5359 /* Stop translation as we may have switched the execution mode */
5360 ctx->bstate = BS_STOP;
5361 rn = "UserTraceData";
5364 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5365 /* Stop translation as we may have switched the execution mode */
5366 ctx->bstate = BS_STOP;
5377 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5387 gen_helper_mtc0_performance0(arg);
5388 rn = "Performance0";
5391 // gen_helper_mtc0_performance1(arg);
5392 rn = "Performance1";
5395 // gen_helper_mtc0_performance2(arg);
5396 rn = "Performance2";
5399 // gen_helper_mtc0_performance3(arg);
5400 rn = "Performance3";
5403 // gen_helper_mtc0_performance4(arg);
5404 rn = "Performance4";
5407 // gen_helper_mtc0_performance5(arg);
5408 rn = "Performance5";
5411 // gen_helper_mtc0_performance6(arg);
5412 rn = "Performance6";
5415 // gen_helper_mtc0_performance7(arg);
5416 rn = "Performance7";
5442 gen_helper_mtc0_taglo(arg);
5449 gen_helper_mtc0_datalo(arg);
5462 gen_helper_mtc0_taghi(arg);
5469 gen_helper_mtc0_datahi(arg);
5480 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5491 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5497 /* Stop translation as we may have switched the execution mode */
5498 ctx->bstate = BS_STOP;
5503 (void)rn; /* avoid a compiler warning */
5504 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5505 /* For simplicity assume that all writes can cause interrupts. */
5508 ctx->bstate = BS_STOP;
5513 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5514 generate_exception(ctx, EXCP_RI);
5516 #endif /* TARGET_MIPS64 */
5518 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
5519 int u, int sel, int h)
5521 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5522 TCGv t0 = tcg_temp_local_new();
5524 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5525 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5526 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5527 tcg_gen_movi_tl(t0, -1);
5528 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5529 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5530 tcg_gen_movi_tl(t0, -1);
5536 gen_helper_mftc0_vpecontrol(t0);
5539 gen_helper_mftc0_vpeconf0(t0);
5549 gen_helper_mftc0_tcstatus(t0);
5552 gen_helper_mftc0_tcbind(t0);
5555 gen_helper_mftc0_tcrestart(t0);
5558 gen_helper_mftc0_tchalt(t0);
5561 gen_helper_mftc0_tccontext(t0);
5564 gen_helper_mftc0_tcschedule(t0);
5567 gen_helper_mftc0_tcschefback(t0);
5570 gen_mfc0(env, ctx, t0, rt, sel);
5577 gen_helper_mftc0_entryhi(t0);
5580 gen_mfc0(env, ctx, t0, rt, sel);
5586 gen_helper_mftc0_status(t0);
5589 gen_mfc0(env, ctx, t0, rt, sel);
5595 gen_helper_mftc0_cause(t0);
5605 gen_helper_mftc0_epc(t0);
5615 gen_helper_mftc0_ebase(t0);
5625 gen_helper_mftc0_configx(t0, tcg_const_tl(sel));
5635 gen_helper_mftc0_debug(t0);
5638 gen_mfc0(env, ctx, t0, rt, sel);
5643 gen_mfc0(env, ctx, t0, rt, sel);
5645 } else switch (sel) {
5646 /* GPR registers. */
5648 gen_helper_1i(mftgpr, t0, rt);
5650 /* Auxiliary CPU registers */
5654 gen_helper_1i(mftlo, t0, 0);
5657 gen_helper_1i(mfthi, t0, 0);
5660 gen_helper_1i(mftacx, t0, 0);
5663 gen_helper_1i(mftlo, t0, 1);
5666 gen_helper_1i(mfthi, t0, 1);
5669 gen_helper_1i(mftacx, t0, 1);
5672 gen_helper_1i(mftlo, t0, 2);
5675 gen_helper_1i(mfthi, t0, 2);
5678 gen_helper_1i(mftacx, t0, 2);
5681 gen_helper_1i(mftlo, t0, 3);
5684 gen_helper_1i(mfthi, t0, 3);
5687 gen_helper_1i(mftacx, t0, 3);
5690 gen_helper_mftdsp(t0);
5696 /* Floating point (COP1). */
5698 /* XXX: For now we support only a single FPU context. */
5700 TCGv_i32 fp0 = tcg_temp_new_i32();
5702 gen_load_fpr32(fp0, rt);
5703 tcg_gen_ext_i32_tl(t0, fp0);
5704 tcg_temp_free_i32(fp0);
5706 TCGv_i32 fp0 = tcg_temp_new_i32();
5708 gen_load_fpr32h(fp0, rt);
5709 tcg_gen_ext_i32_tl(t0, fp0);
5710 tcg_temp_free_i32(fp0);
5714 /* XXX: For now we support only a single FPU context. */
5715 gen_helper_1i(cfc1, t0, rt);
5717 /* COP2: Not implemented. */
5724 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5725 gen_store_gpr(t0, rd);
5731 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5732 generate_exception(ctx, EXCP_RI);
5735 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
5736 int u, int sel, int h)
5738 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5739 TCGv t0 = tcg_temp_local_new();
5741 gen_load_gpr(t0, rt);
5742 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5743 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5744 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5746 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5747 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5754 gen_helper_mttc0_vpecontrol(t0);
5757 gen_helper_mttc0_vpeconf0(t0);
5767 gen_helper_mttc0_tcstatus(t0);
5770 gen_helper_mttc0_tcbind(t0);
5773 gen_helper_mttc0_tcrestart(t0);
5776 gen_helper_mttc0_tchalt(t0);
5779 gen_helper_mttc0_tccontext(t0);
5782 gen_helper_mttc0_tcschedule(t0);
5785 gen_helper_mttc0_tcschefback(t0);
5788 gen_mtc0(env, ctx, t0, rd, sel);
5795 gen_helper_mttc0_entryhi(t0);
5798 gen_mtc0(env, ctx, t0, rd, sel);
5804 gen_helper_mttc0_status(t0);
5807 gen_mtc0(env, ctx, t0, rd, sel);
5813 gen_helper_mttc0_cause(t0);
5823 gen_helper_mttc0_ebase(t0);
5833 gen_helper_mttc0_debug(t0);
5836 gen_mtc0(env, ctx, t0, rd, sel);
5841 gen_mtc0(env, ctx, t0, rd, sel);
5843 } else switch (sel) {
5844 /* GPR registers. */
5846 gen_helper_1i(mttgpr, t0, rd);
5848 /* Auxiliary CPU registers */
5852 gen_helper_1i(mttlo, t0, 0);
5855 gen_helper_1i(mtthi, t0, 0);
5858 gen_helper_1i(mttacx, t0, 0);
5861 gen_helper_1i(mttlo, t0, 1);
5864 gen_helper_1i(mtthi, t0, 1);
5867 gen_helper_1i(mttacx, t0, 1);
5870 gen_helper_1i(mttlo, t0, 2);
5873 gen_helper_1i(mtthi, t0, 2);
5876 gen_helper_1i(mttacx, t0, 2);
5879 gen_helper_1i(mttlo, t0, 3);
5882 gen_helper_1i(mtthi, t0, 3);
5885 gen_helper_1i(mttacx, t0, 3);
5888 gen_helper_mttdsp(t0);
5894 /* Floating point (COP1). */
5896 /* XXX: For now we support only a single FPU context. */
5898 TCGv_i32 fp0 = tcg_temp_new_i32();
5900 tcg_gen_trunc_tl_i32(fp0, t0);
5901 gen_store_fpr32(fp0, rd);
5902 tcg_temp_free_i32(fp0);
5904 TCGv_i32 fp0 = tcg_temp_new_i32();
5906 tcg_gen_trunc_tl_i32(fp0, t0);
5907 gen_store_fpr32h(fp0, rd);
5908 tcg_temp_free_i32(fp0);
5912 /* XXX: For now we support only a single FPU context. */
5913 gen_helper_1i(ctc1, t0, rd);
5915 /* COP2: Not implemented. */
5922 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5928 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5929 generate_exception(ctx, EXCP_RI);
5932 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5934 const char *opn = "ldst";
5936 check_cp0_enabled(ctx);
5943 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5948 TCGv t0 = tcg_temp_new();
5950 gen_load_gpr(t0, rt);
5951 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5956 #if defined(TARGET_MIPS64)
5958 check_insn(env, ctx, ISA_MIPS3);
5963 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5967 check_insn(env, ctx, ISA_MIPS3);
5969 TCGv t0 = tcg_temp_new();
5971 gen_load_gpr(t0, rt);
5972 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5979 check_insn(env, ctx, ASE_MT);
5984 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5985 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5989 check_insn(env, ctx, ASE_MT);
5990 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5991 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5996 if (!env->tlb->helper_tlbwi)
6002 if (!env->tlb->helper_tlbwr)
6008 if (!env->tlb->helper_tlbp)
6014 if (!env->tlb->helper_tlbr)
6020 check_insn(env, ctx, ISA_MIPS2);
6022 ctx->bstate = BS_EXCP;
6026 check_insn(env, ctx, ISA_MIPS32);
6027 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6029 generate_exception(ctx, EXCP_RI);
6032 ctx->bstate = BS_EXCP;
6037 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6038 /* If we get an exception, we want to restart at next instruction */
6040 save_cpu_state(ctx, 1);
6043 ctx->bstate = BS_EXCP;
6048 generate_exception(ctx, EXCP_RI);
6051 (void)opn; /* avoid a compiler warning */
6052 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6054 #endif /* !CONFIG_USER_ONLY */
6056 /* CP1 Branches (before delay slot) */
6057 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
6058 int32_t cc, int32_t offset)
6060 target_ulong btarget;
6061 const char *opn = "cp1 cond branch";
6062 TCGv_i32 t0 = tcg_temp_new_i32();
6065 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6067 btarget = ctx->pc + 4 + offset;
6071 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6072 tcg_gen_not_i32(t0, t0);
6073 tcg_gen_andi_i32(t0, t0, 1);
6074 tcg_gen_extu_i32_tl(bcond, t0);
6078 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6079 tcg_gen_not_i32(t0, t0);
6080 tcg_gen_andi_i32(t0, t0, 1);
6081 tcg_gen_extu_i32_tl(bcond, t0);
6085 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6086 tcg_gen_andi_i32(t0, t0, 1);
6087 tcg_gen_extu_i32_tl(bcond, t0);
6091 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6092 tcg_gen_andi_i32(t0, t0, 1);
6093 tcg_gen_extu_i32_tl(bcond, t0);
6096 ctx->hflags |= MIPS_HFLAG_BL;
6100 TCGv_i32 t1 = tcg_temp_new_i32();
6101 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6102 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6103 tcg_gen_nand_i32(t0, t0, t1);
6104 tcg_temp_free_i32(t1);
6105 tcg_gen_andi_i32(t0, t0, 1);
6106 tcg_gen_extu_i32_tl(bcond, t0);
6112 TCGv_i32 t1 = tcg_temp_new_i32();
6113 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6114 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6115 tcg_gen_or_i32(t0, t0, t1);
6116 tcg_temp_free_i32(t1);
6117 tcg_gen_andi_i32(t0, t0, 1);
6118 tcg_gen_extu_i32_tl(bcond, t0);
6124 TCGv_i32 t1 = tcg_temp_new_i32();
6125 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6126 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6127 tcg_gen_and_i32(t0, t0, t1);
6128 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6129 tcg_gen_and_i32(t0, t0, t1);
6130 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6131 tcg_gen_nand_i32(t0, t0, t1);
6132 tcg_temp_free_i32(t1);
6133 tcg_gen_andi_i32(t0, t0, 1);
6134 tcg_gen_extu_i32_tl(bcond, t0);
6140 TCGv_i32 t1 = tcg_temp_new_i32();
6141 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6142 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6143 tcg_gen_or_i32(t0, t0, t1);
6144 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6145 tcg_gen_or_i32(t0, t0, t1);
6146 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6147 tcg_gen_or_i32(t0, t0, t1);
6148 tcg_temp_free_i32(t1);
6149 tcg_gen_andi_i32(t0, t0, 1);
6150 tcg_gen_extu_i32_tl(bcond, t0);
6154 ctx->hflags |= MIPS_HFLAG_BC;
6158 generate_exception (ctx, EXCP_RI);
6161 (void)opn; /* avoid a compiler warning */
6162 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6163 ctx->hflags, btarget);
6164 ctx->btarget = btarget;
6167 tcg_temp_free_i32(t0);
6170 /* Coprocessor 1 (FPU) */
6172 #define FOP(func, fmt) (((fmt) << 21) | (func))
6175 OPC_ADD_S = FOP(0, FMT_S),
6176 OPC_SUB_S = FOP(1, FMT_S),
6177 OPC_MUL_S = FOP(2, FMT_S),
6178 OPC_DIV_S = FOP(3, FMT_S),
6179 OPC_SQRT_S = FOP(4, FMT_S),
6180 OPC_ABS_S = FOP(5, FMT_S),
6181 OPC_MOV_S = FOP(6, FMT_S),
6182 OPC_NEG_S = FOP(7, FMT_S),
6183 OPC_ROUND_L_S = FOP(8, FMT_S),
6184 OPC_TRUNC_L_S = FOP(9, FMT_S),
6185 OPC_CEIL_L_S = FOP(10, FMT_S),
6186 OPC_FLOOR_L_S = FOP(11, FMT_S),
6187 OPC_ROUND_W_S = FOP(12, FMT_S),
6188 OPC_TRUNC_W_S = FOP(13, FMT_S),
6189 OPC_CEIL_W_S = FOP(14, FMT_S),
6190 OPC_FLOOR_W_S = FOP(15, FMT_S),
6191 OPC_MOVCF_S = FOP(17, FMT_S),
6192 OPC_MOVZ_S = FOP(18, FMT_S),
6193 OPC_MOVN_S = FOP(19, FMT_S),
6194 OPC_RECIP_S = FOP(21, FMT_S),
6195 OPC_RSQRT_S = FOP(22, FMT_S),
6196 OPC_RECIP2_S = FOP(28, FMT_S),
6197 OPC_RECIP1_S = FOP(29, FMT_S),
6198 OPC_RSQRT1_S = FOP(30, FMT_S),
6199 OPC_RSQRT2_S = FOP(31, FMT_S),
6200 OPC_CVT_D_S = FOP(33, FMT_S),
6201 OPC_CVT_W_S = FOP(36, FMT_S),
6202 OPC_CVT_L_S = FOP(37, FMT_S),
6203 OPC_CVT_PS_S = FOP(38, FMT_S),
6204 OPC_CMP_F_S = FOP (48, FMT_S),
6205 OPC_CMP_UN_S = FOP (49, FMT_S),
6206 OPC_CMP_EQ_S = FOP (50, FMT_S),
6207 OPC_CMP_UEQ_S = FOP (51, FMT_S),
6208 OPC_CMP_OLT_S = FOP (52, FMT_S),
6209 OPC_CMP_ULT_S = FOP (53, FMT_S),
6210 OPC_CMP_OLE_S = FOP (54, FMT_S),
6211 OPC_CMP_ULE_S = FOP (55, FMT_S),
6212 OPC_CMP_SF_S = FOP (56, FMT_S),
6213 OPC_CMP_NGLE_S = FOP (57, FMT_S),
6214 OPC_CMP_SEQ_S = FOP (58, FMT_S),
6215 OPC_CMP_NGL_S = FOP (59, FMT_S),
6216 OPC_CMP_LT_S = FOP (60, FMT_S),
6217 OPC_CMP_NGE_S = FOP (61, FMT_S),
6218 OPC_CMP_LE_S = FOP (62, FMT_S),
6219 OPC_CMP_NGT_S = FOP (63, FMT_S),
6221 OPC_ADD_D = FOP(0, FMT_D),
6222 OPC_SUB_D = FOP(1, FMT_D),
6223 OPC_MUL_D = FOP(2, FMT_D),
6224 OPC_DIV_D = FOP(3, FMT_D),
6225 OPC_SQRT_D = FOP(4, FMT_D),
6226 OPC_ABS_D = FOP(5, FMT_D),
6227 OPC_MOV_D = FOP(6, FMT_D),
6228 OPC_NEG_D = FOP(7, FMT_D),
6229 OPC_ROUND_L_D = FOP(8, FMT_D),
6230 OPC_TRUNC_L_D = FOP(9, FMT_D),
6231 OPC_CEIL_L_D = FOP(10, FMT_D),
6232 OPC_FLOOR_L_D = FOP(11, FMT_D),
6233 OPC_ROUND_W_D = FOP(12, FMT_D),
6234 OPC_TRUNC_W_D = FOP(13, FMT_D),
6235 OPC_CEIL_W_D = FOP(14, FMT_D),
6236 OPC_FLOOR_W_D = FOP(15, FMT_D),
6237 OPC_MOVCF_D = FOP(17, FMT_D),
6238 OPC_MOVZ_D = FOP(18, FMT_D),
6239 OPC_MOVN_D = FOP(19, FMT_D),
6240 OPC_RECIP_D = FOP(21, FMT_D),
6241 OPC_RSQRT_D = FOP(22, FMT_D),
6242 OPC_RECIP2_D = FOP(28, FMT_D),
6243 OPC_RECIP1_D = FOP(29, FMT_D),
6244 OPC_RSQRT1_D = FOP(30, FMT_D),
6245 OPC_RSQRT2_D = FOP(31, FMT_D),
6246 OPC_CVT_S_D = FOP(32, FMT_D),
6247 OPC_CVT_W_D = FOP(36, FMT_D),
6248 OPC_CVT_L_D = FOP(37, FMT_D),
6249 OPC_CMP_F_D = FOP (48, FMT_D),
6250 OPC_CMP_UN_D = FOP (49, FMT_D),
6251 OPC_CMP_EQ_D = FOP (50, FMT_D),
6252 OPC_CMP_UEQ_D = FOP (51, FMT_D),
6253 OPC_CMP_OLT_D = FOP (52, FMT_D),
6254 OPC_CMP_ULT_D = FOP (53, FMT_D),
6255 OPC_CMP_OLE_D = FOP (54, FMT_D),
6256 OPC_CMP_ULE_D = FOP (55, FMT_D),
6257 OPC_CMP_SF_D = FOP (56, FMT_D),
6258 OPC_CMP_NGLE_D = FOP (57, FMT_D),
6259 OPC_CMP_SEQ_D = FOP (58, FMT_D),
6260 OPC_CMP_NGL_D = FOP (59, FMT_D),
6261 OPC_CMP_LT_D = FOP (60, FMT_D),
6262 OPC_CMP_NGE_D = FOP (61, FMT_D),
6263 OPC_CMP_LE_D = FOP (62, FMT_D),
6264 OPC_CMP_NGT_D = FOP (63, FMT_D),
6266 OPC_CVT_S_W = FOP(32, FMT_W),
6267 OPC_CVT_D_W = FOP(33, FMT_W),
6268 OPC_CVT_S_L = FOP(32, FMT_L),
6269 OPC_CVT_D_L = FOP(33, FMT_L),
6270 OPC_CVT_PS_PW = FOP(38, FMT_W),
6272 OPC_ADD_PS = FOP(0, FMT_PS),
6273 OPC_SUB_PS = FOP(1, FMT_PS),
6274 OPC_MUL_PS = FOP(2, FMT_PS),
6275 OPC_DIV_PS = FOP(3, FMT_PS),
6276 OPC_ABS_PS = FOP(5, FMT_PS),
6277 OPC_MOV_PS = FOP(6, FMT_PS),
6278 OPC_NEG_PS = FOP(7, FMT_PS),
6279 OPC_MOVCF_PS = FOP(17, FMT_PS),
6280 OPC_MOVZ_PS = FOP(18, FMT_PS),
6281 OPC_MOVN_PS = FOP(19, FMT_PS),
6282 OPC_ADDR_PS = FOP(24, FMT_PS),
6283 OPC_MULR_PS = FOP(26, FMT_PS),
6284 OPC_RECIP2_PS = FOP(28, FMT_PS),
6285 OPC_RECIP1_PS = FOP(29, FMT_PS),
6286 OPC_RSQRT1_PS = FOP(30, FMT_PS),
6287 OPC_RSQRT2_PS = FOP(31, FMT_PS),
6289 OPC_CVT_S_PU = FOP(32, FMT_PS),
6290 OPC_CVT_PW_PS = FOP(36, FMT_PS),
6291 OPC_CVT_S_PL = FOP(40, FMT_PS),
6292 OPC_PLL_PS = FOP(44, FMT_PS),
6293 OPC_PLU_PS = FOP(45, FMT_PS),
6294 OPC_PUL_PS = FOP(46, FMT_PS),
6295 OPC_PUU_PS = FOP(47, FMT_PS),
6296 OPC_CMP_F_PS = FOP (48, FMT_PS),
6297 OPC_CMP_UN_PS = FOP (49, FMT_PS),
6298 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
6299 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
6300 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
6301 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
6302 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
6303 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
6304 OPC_CMP_SF_PS = FOP (56, FMT_PS),
6305 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
6306 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
6307 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
6308 OPC_CMP_LT_PS = FOP (60, FMT_PS),
6309 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
6310 OPC_CMP_LE_PS = FOP (62, FMT_PS),
6311 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
6314 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6316 const char *opn = "cp1 move";
6317 TCGv t0 = tcg_temp_new();
6322 TCGv_i32 fp0 = tcg_temp_new_i32();
6324 gen_load_fpr32(fp0, fs);
6325 tcg_gen_ext_i32_tl(t0, fp0);
6326 tcg_temp_free_i32(fp0);
6328 gen_store_gpr(t0, rt);
6332 gen_load_gpr(t0, rt);
6334 TCGv_i32 fp0 = tcg_temp_new_i32();
6336 tcg_gen_trunc_tl_i32(fp0, t0);
6337 gen_store_fpr32(fp0, fs);
6338 tcg_temp_free_i32(fp0);
6343 gen_helper_1i(cfc1, t0, fs);
6344 gen_store_gpr(t0, rt);
6348 gen_load_gpr(t0, rt);
6349 gen_helper_1i(ctc1, t0, fs);
6352 #if defined(TARGET_MIPS64)
6354 gen_load_fpr64(ctx, t0, fs);
6355 gen_store_gpr(t0, rt);
6359 gen_load_gpr(t0, rt);
6360 gen_store_fpr64(ctx, t0, fs);
6366 TCGv_i32 fp0 = tcg_temp_new_i32();
6368 gen_load_fpr32h(fp0, fs);
6369 tcg_gen_ext_i32_tl(t0, fp0);
6370 tcg_temp_free_i32(fp0);
6372 gen_store_gpr(t0, rt);
6376 gen_load_gpr(t0, rt);
6378 TCGv_i32 fp0 = tcg_temp_new_i32();
6380 tcg_gen_trunc_tl_i32(fp0, t0);
6381 gen_store_fpr32h(fp0, fs);
6382 tcg_temp_free_i32(fp0);
6388 generate_exception (ctx, EXCP_RI);
6391 (void)opn; /* avoid a compiler warning */
6392 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6398 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6414 l1 = gen_new_label();
6415 t0 = tcg_temp_new_i32();
6416 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6417 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6418 tcg_temp_free_i32(t0);
6420 tcg_gen_movi_tl(cpu_gpr[rd], 0);
6422 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6427 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6430 TCGv_i32 t0 = tcg_temp_new_i32();
6431 int l1 = gen_new_label();
6438 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6439 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6440 gen_load_fpr32(t0, fs);
6441 gen_store_fpr32(t0, fd);
6443 tcg_temp_free_i32(t0);
6446 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6449 TCGv_i32 t0 = tcg_temp_new_i32();
6451 int l1 = gen_new_label();
6458 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6459 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6460 tcg_temp_free_i32(t0);
6461 fp0 = tcg_temp_new_i64();
6462 gen_load_fpr64(ctx, fp0, fs);
6463 gen_store_fpr64(ctx, fp0, fd);
6464 tcg_temp_free_i64(fp0);
6468 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6471 TCGv_i32 t0 = tcg_temp_new_i32();
6472 int l1 = gen_new_label();
6473 int l2 = gen_new_label();
6480 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6481 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6482 gen_load_fpr32(t0, fs);
6483 gen_store_fpr32(t0, fd);
6486 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6487 tcg_gen_brcondi_i32(cond, t0, 0, l2);
6488 gen_load_fpr32h(t0, fs);
6489 gen_store_fpr32h(t0, fd);
6490 tcg_temp_free_i32(t0);
6495 static void gen_farith (DisasContext *ctx, enum fopcode op1,
6496 int ft, int fs, int fd, int cc)
6498 const char *opn = "farith";
6499 const char *condnames[] = {
6517 const char *condnames_abs[] = {
6535 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6536 uint32_t func = ctx->opcode & 0x3f;
6541 TCGv_i32 fp0 = tcg_temp_new_i32();
6542 TCGv_i32 fp1 = tcg_temp_new_i32();
6544 gen_load_fpr32(fp0, fs);
6545 gen_load_fpr32(fp1, ft);
6546 gen_helper_float_add_s(fp0, fp0, fp1);
6547 tcg_temp_free_i32(fp1);
6548 gen_store_fpr32(fp0, fd);
6549 tcg_temp_free_i32(fp0);
6556 TCGv_i32 fp0 = tcg_temp_new_i32();
6557 TCGv_i32 fp1 = tcg_temp_new_i32();
6559 gen_load_fpr32(fp0, fs);
6560 gen_load_fpr32(fp1, ft);
6561 gen_helper_float_sub_s(fp0, fp0, fp1);
6562 tcg_temp_free_i32(fp1);
6563 gen_store_fpr32(fp0, fd);
6564 tcg_temp_free_i32(fp0);
6571 TCGv_i32 fp0 = tcg_temp_new_i32();
6572 TCGv_i32 fp1 = tcg_temp_new_i32();
6574 gen_load_fpr32(fp0, fs);
6575 gen_load_fpr32(fp1, ft);
6576 gen_helper_float_mul_s(fp0, fp0, fp1);
6577 tcg_temp_free_i32(fp1);
6578 gen_store_fpr32(fp0, fd);
6579 tcg_temp_free_i32(fp0);
6586 TCGv_i32 fp0 = tcg_temp_new_i32();
6587 TCGv_i32 fp1 = tcg_temp_new_i32();
6589 gen_load_fpr32(fp0, fs);
6590 gen_load_fpr32(fp1, ft);
6591 gen_helper_float_div_s(fp0, fp0, fp1);
6592 tcg_temp_free_i32(fp1);
6593 gen_store_fpr32(fp0, fd);
6594 tcg_temp_free_i32(fp0);
6601 TCGv_i32 fp0 = tcg_temp_new_i32();
6603 gen_load_fpr32(fp0, fs);
6604 gen_helper_float_sqrt_s(fp0, fp0);
6605 gen_store_fpr32(fp0, fd);
6606 tcg_temp_free_i32(fp0);
6612 TCGv_i32 fp0 = tcg_temp_new_i32();
6614 gen_load_fpr32(fp0, fs);
6615 gen_helper_float_abs_s(fp0, fp0);
6616 gen_store_fpr32(fp0, fd);
6617 tcg_temp_free_i32(fp0);
6623 TCGv_i32 fp0 = tcg_temp_new_i32();
6625 gen_load_fpr32(fp0, fs);
6626 gen_store_fpr32(fp0, fd);
6627 tcg_temp_free_i32(fp0);
6633 TCGv_i32 fp0 = tcg_temp_new_i32();
6635 gen_load_fpr32(fp0, fs);
6636 gen_helper_float_chs_s(fp0, fp0);
6637 gen_store_fpr32(fp0, fd);
6638 tcg_temp_free_i32(fp0);
6643 check_cp1_64bitmode(ctx);
6645 TCGv_i32 fp32 = tcg_temp_new_i32();
6646 TCGv_i64 fp64 = tcg_temp_new_i64();
6648 gen_load_fpr32(fp32, fs);
6649 gen_helper_float_roundl_s(fp64, fp32);
6650 tcg_temp_free_i32(fp32);
6651 gen_store_fpr64(ctx, fp64, fd);
6652 tcg_temp_free_i64(fp64);
6657 check_cp1_64bitmode(ctx);
6659 TCGv_i32 fp32 = tcg_temp_new_i32();
6660 TCGv_i64 fp64 = tcg_temp_new_i64();
6662 gen_load_fpr32(fp32, fs);
6663 gen_helper_float_truncl_s(fp64, fp32);
6664 tcg_temp_free_i32(fp32);
6665 gen_store_fpr64(ctx, fp64, fd);
6666 tcg_temp_free_i64(fp64);
6671 check_cp1_64bitmode(ctx);
6673 TCGv_i32 fp32 = tcg_temp_new_i32();
6674 TCGv_i64 fp64 = tcg_temp_new_i64();
6676 gen_load_fpr32(fp32, fs);
6677 gen_helper_float_ceill_s(fp64, fp32);
6678 tcg_temp_free_i32(fp32);
6679 gen_store_fpr64(ctx, fp64, fd);
6680 tcg_temp_free_i64(fp64);
6685 check_cp1_64bitmode(ctx);
6687 TCGv_i32 fp32 = tcg_temp_new_i32();
6688 TCGv_i64 fp64 = tcg_temp_new_i64();
6690 gen_load_fpr32(fp32, fs);
6691 gen_helper_float_floorl_s(fp64, fp32);
6692 tcg_temp_free_i32(fp32);
6693 gen_store_fpr64(ctx, fp64, fd);
6694 tcg_temp_free_i64(fp64);
6700 TCGv_i32 fp0 = tcg_temp_new_i32();
6702 gen_load_fpr32(fp0, fs);
6703 gen_helper_float_roundw_s(fp0, fp0);
6704 gen_store_fpr32(fp0, fd);
6705 tcg_temp_free_i32(fp0);
6711 TCGv_i32 fp0 = tcg_temp_new_i32();
6713 gen_load_fpr32(fp0, fs);
6714 gen_helper_float_truncw_s(fp0, fp0);
6715 gen_store_fpr32(fp0, fd);
6716 tcg_temp_free_i32(fp0);
6722 TCGv_i32 fp0 = tcg_temp_new_i32();
6724 gen_load_fpr32(fp0, fs);
6725 gen_helper_float_ceilw_s(fp0, fp0);
6726 gen_store_fpr32(fp0, fd);
6727 tcg_temp_free_i32(fp0);
6733 TCGv_i32 fp0 = tcg_temp_new_i32();
6735 gen_load_fpr32(fp0, fs);
6736 gen_helper_float_floorw_s(fp0, fp0);
6737 gen_store_fpr32(fp0, fd);
6738 tcg_temp_free_i32(fp0);
6743 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6748 int l1 = gen_new_label();
6752 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6754 fp0 = tcg_temp_new_i32();
6755 gen_load_fpr32(fp0, fs);
6756 gen_store_fpr32(fp0, fd);
6757 tcg_temp_free_i32(fp0);
6764 int l1 = gen_new_label();
6768 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6769 fp0 = tcg_temp_new_i32();
6770 gen_load_fpr32(fp0, fs);
6771 gen_store_fpr32(fp0, fd);
6772 tcg_temp_free_i32(fp0);
6781 TCGv_i32 fp0 = tcg_temp_new_i32();
6783 gen_load_fpr32(fp0, fs);
6784 gen_helper_float_recip_s(fp0, fp0);
6785 gen_store_fpr32(fp0, fd);
6786 tcg_temp_free_i32(fp0);
6793 TCGv_i32 fp0 = tcg_temp_new_i32();
6795 gen_load_fpr32(fp0, fs);
6796 gen_helper_float_rsqrt_s(fp0, fp0);
6797 gen_store_fpr32(fp0, fd);
6798 tcg_temp_free_i32(fp0);
6803 check_cp1_64bitmode(ctx);
6805 TCGv_i32 fp0 = tcg_temp_new_i32();
6806 TCGv_i32 fp1 = tcg_temp_new_i32();
6808 gen_load_fpr32(fp0, fs);
6809 gen_load_fpr32(fp1, ft);
6810 gen_helper_float_recip2_s(fp0, fp0, fp1);
6811 tcg_temp_free_i32(fp1);
6812 gen_store_fpr32(fp0, fd);
6813 tcg_temp_free_i32(fp0);
6818 check_cp1_64bitmode(ctx);
6820 TCGv_i32 fp0 = tcg_temp_new_i32();
6822 gen_load_fpr32(fp0, fs);
6823 gen_helper_float_recip1_s(fp0, fp0);
6824 gen_store_fpr32(fp0, fd);
6825 tcg_temp_free_i32(fp0);
6830 check_cp1_64bitmode(ctx);
6832 TCGv_i32 fp0 = tcg_temp_new_i32();
6834 gen_load_fpr32(fp0, fs);
6835 gen_helper_float_rsqrt1_s(fp0, fp0);
6836 gen_store_fpr32(fp0, fd);
6837 tcg_temp_free_i32(fp0);
6842 check_cp1_64bitmode(ctx);
6844 TCGv_i32 fp0 = tcg_temp_new_i32();
6845 TCGv_i32 fp1 = tcg_temp_new_i32();
6847 gen_load_fpr32(fp0, fs);
6848 gen_load_fpr32(fp1, ft);
6849 gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6850 tcg_temp_free_i32(fp1);
6851 gen_store_fpr32(fp0, fd);
6852 tcg_temp_free_i32(fp0);
6857 check_cp1_registers(ctx, fd);
6859 TCGv_i32 fp32 = tcg_temp_new_i32();
6860 TCGv_i64 fp64 = tcg_temp_new_i64();
6862 gen_load_fpr32(fp32, fs);
6863 gen_helper_float_cvtd_s(fp64, fp32);
6864 tcg_temp_free_i32(fp32);
6865 gen_store_fpr64(ctx, fp64, fd);
6866 tcg_temp_free_i64(fp64);
6872 TCGv_i32 fp0 = tcg_temp_new_i32();
6874 gen_load_fpr32(fp0, fs);
6875 gen_helper_float_cvtw_s(fp0, fp0);
6876 gen_store_fpr32(fp0, fd);
6877 tcg_temp_free_i32(fp0);
6882 check_cp1_64bitmode(ctx);
6884 TCGv_i32 fp32 = tcg_temp_new_i32();
6885 TCGv_i64 fp64 = tcg_temp_new_i64();
6887 gen_load_fpr32(fp32, fs);
6888 gen_helper_float_cvtl_s(fp64, fp32);
6889 tcg_temp_free_i32(fp32);
6890 gen_store_fpr64(ctx, fp64, fd);
6891 tcg_temp_free_i64(fp64);
6896 check_cp1_64bitmode(ctx);
6898 TCGv_i64 fp64 = tcg_temp_new_i64();
6899 TCGv_i32 fp32_0 = tcg_temp_new_i32();
6900 TCGv_i32 fp32_1 = tcg_temp_new_i32();
6902 gen_load_fpr32(fp32_0, fs);
6903 gen_load_fpr32(fp32_1, ft);
6904 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
6905 tcg_temp_free_i32(fp32_1);
6906 tcg_temp_free_i32(fp32_0);
6907 gen_store_fpr64(ctx, fp64, fd);
6908 tcg_temp_free_i64(fp64);
6921 case OPC_CMP_NGLE_S:
6928 if (ctx->opcode & (1 << 6)) {
6929 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6930 opn = condnames_abs[func-48];
6932 gen_cmp_s(ctx, func-48, ft, fs, cc);
6933 opn = condnames[func-48];
6937 check_cp1_registers(ctx, fs | ft | fd);
6939 TCGv_i64 fp0 = tcg_temp_new_i64();
6940 TCGv_i64 fp1 = tcg_temp_new_i64();
6942 gen_load_fpr64(ctx, fp0, fs);
6943 gen_load_fpr64(ctx, fp1, ft);
6944 gen_helper_float_add_d(fp0, fp0, fp1);
6945 tcg_temp_free_i64(fp1);
6946 gen_store_fpr64(ctx, fp0, fd);
6947 tcg_temp_free_i64(fp0);
6953 check_cp1_registers(ctx, fs | ft | fd);
6955 TCGv_i64 fp0 = tcg_temp_new_i64();
6956 TCGv_i64 fp1 = tcg_temp_new_i64();
6958 gen_load_fpr64(ctx, fp0, fs);
6959 gen_load_fpr64(ctx, fp1, ft);
6960 gen_helper_float_sub_d(fp0, fp0, fp1);
6961 tcg_temp_free_i64(fp1);
6962 gen_store_fpr64(ctx, fp0, fd);
6963 tcg_temp_free_i64(fp0);
6969 check_cp1_registers(ctx, fs | ft | fd);
6971 TCGv_i64 fp0 = tcg_temp_new_i64();
6972 TCGv_i64 fp1 = tcg_temp_new_i64();
6974 gen_load_fpr64(ctx, fp0, fs);
6975 gen_load_fpr64(ctx, fp1, ft);
6976 gen_helper_float_mul_d(fp0, fp0, fp1);
6977 tcg_temp_free_i64(fp1);
6978 gen_store_fpr64(ctx, fp0, fd);
6979 tcg_temp_free_i64(fp0);
6985 check_cp1_registers(ctx, fs | ft | fd);
6987 TCGv_i64 fp0 = tcg_temp_new_i64();
6988 TCGv_i64 fp1 = tcg_temp_new_i64();
6990 gen_load_fpr64(ctx, fp0, fs);
6991 gen_load_fpr64(ctx, fp1, ft);
6992 gen_helper_float_div_d(fp0, fp0, fp1);
6993 tcg_temp_free_i64(fp1);
6994 gen_store_fpr64(ctx, fp0, fd);
6995 tcg_temp_free_i64(fp0);
7001 check_cp1_registers(ctx, fs | fd);
7003 TCGv_i64 fp0 = tcg_temp_new_i64();
7005 gen_load_fpr64(ctx, fp0, fs);
7006 gen_helper_float_sqrt_d(fp0, fp0);
7007 gen_store_fpr64(ctx, fp0, fd);
7008 tcg_temp_free_i64(fp0);
7013 check_cp1_registers(ctx, fs | fd);
7015 TCGv_i64 fp0 = tcg_temp_new_i64();
7017 gen_load_fpr64(ctx, fp0, fs);
7018 gen_helper_float_abs_d(fp0, fp0);
7019 gen_store_fpr64(ctx, fp0, fd);
7020 tcg_temp_free_i64(fp0);
7025 check_cp1_registers(ctx, fs | fd);
7027 TCGv_i64 fp0 = tcg_temp_new_i64();
7029 gen_load_fpr64(ctx, fp0, fs);
7030 gen_store_fpr64(ctx, fp0, fd);
7031 tcg_temp_free_i64(fp0);
7036 check_cp1_registers(ctx, fs | fd);
7038 TCGv_i64 fp0 = tcg_temp_new_i64();
7040 gen_load_fpr64(ctx, fp0, fs);
7041 gen_helper_float_chs_d(fp0, fp0);
7042 gen_store_fpr64(ctx, fp0, fd);
7043 tcg_temp_free_i64(fp0);
7048 check_cp1_64bitmode(ctx);
7050 TCGv_i64 fp0 = tcg_temp_new_i64();
7052 gen_load_fpr64(ctx, fp0, fs);
7053 gen_helper_float_roundl_d(fp0, fp0);
7054 gen_store_fpr64(ctx, fp0, fd);
7055 tcg_temp_free_i64(fp0);
7060 check_cp1_64bitmode(ctx);
7062 TCGv_i64 fp0 = tcg_temp_new_i64();
7064 gen_load_fpr64(ctx, fp0, fs);
7065 gen_helper_float_truncl_d(fp0, fp0);
7066 gen_store_fpr64(ctx, fp0, fd);
7067 tcg_temp_free_i64(fp0);
7072 check_cp1_64bitmode(ctx);
7074 TCGv_i64 fp0 = tcg_temp_new_i64();
7076 gen_load_fpr64(ctx, fp0, fs);
7077 gen_helper_float_ceill_d(fp0, fp0);
7078 gen_store_fpr64(ctx, fp0, fd);
7079 tcg_temp_free_i64(fp0);
7084 check_cp1_64bitmode(ctx);
7086 TCGv_i64 fp0 = tcg_temp_new_i64();
7088 gen_load_fpr64(ctx, fp0, fs);
7089 gen_helper_float_floorl_d(fp0, fp0);
7090 gen_store_fpr64(ctx, fp0, fd);
7091 tcg_temp_free_i64(fp0);
7096 check_cp1_registers(ctx, fs);
7098 TCGv_i32 fp32 = tcg_temp_new_i32();
7099 TCGv_i64 fp64 = tcg_temp_new_i64();
7101 gen_load_fpr64(ctx, fp64, fs);
7102 gen_helper_float_roundw_d(fp32, fp64);
7103 tcg_temp_free_i64(fp64);
7104 gen_store_fpr32(fp32, fd);
7105 tcg_temp_free_i32(fp32);
7110 check_cp1_registers(ctx, fs);
7112 TCGv_i32 fp32 = tcg_temp_new_i32();
7113 TCGv_i64 fp64 = tcg_temp_new_i64();
7115 gen_load_fpr64(ctx, fp64, fs);
7116 gen_helper_float_truncw_d(fp32, fp64);
7117 tcg_temp_free_i64(fp64);
7118 gen_store_fpr32(fp32, fd);
7119 tcg_temp_free_i32(fp32);
7124 check_cp1_registers(ctx, fs);
7126 TCGv_i32 fp32 = tcg_temp_new_i32();
7127 TCGv_i64 fp64 = tcg_temp_new_i64();
7129 gen_load_fpr64(ctx, fp64, fs);
7130 gen_helper_float_ceilw_d(fp32, fp64);
7131 tcg_temp_free_i64(fp64);
7132 gen_store_fpr32(fp32, fd);
7133 tcg_temp_free_i32(fp32);
7138 check_cp1_registers(ctx, fs);
7140 TCGv_i32 fp32 = tcg_temp_new_i32();
7141 TCGv_i64 fp64 = tcg_temp_new_i64();
7143 gen_load_fpr64(ctx, fp64, fs);
7144 gen_helper_float_floorw_d(fp32, fp64);
7145 tcg_temp_free_i64(fp64);
7146 gen_store_fpr32(fp32, fd);
7147 tcg_temp_free_i32(fp32);
7152 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7157 int l1 = gen_new_label();
7161 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7163 fp0 = tcg_temp_new_i64();
7164 gen_load_fpr64(ctx, fp0, fs);
7165 gen_store_fpr64(ctx, fp0, fd);
7166 tcg_temp_free_i64(fp0);
7173 int l1 = gen_new_label();
7177 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7178 fp0 = tcg_temp_new_i64();
7179 gen_load_fpr64(ctx, fp0, fs);
7180 gen_store_fpr64(ctx, fp0, fd);
7181 tcg_temp_free_i64(fp0);
7188 check_cp1_64bitmode(ctx);
7190 TCGv_i64 fp0 = tcg_temp_new_i64();
7192 gen_load_fpr64(ctx, fp0, fs);
7193 gen_helper_float_recip_d(fp0, fp0);
7194 gen_store_fpr64(ctx, fp0, fd);
7195 tcg_temp_free_i64(fp0);
7200 check_cp1_64bitmode(ctx);
7202 TCGv_i64 fp0 = tcg_temp_new_i64();
7204 gen_load_fpr64(ctx, fp0, fs);
7205 gen_helper_float_rsqrt_d(fp0, fp0);
7206 gen_store_fpr64(ctx, fp0, fd);
7207 tcg_temp_free_i64(fp0);
7212 check_cp1_64bitmode(ctx);
7214 TCGv_i64 fp0 = tcg_temp_new_i64();
7215 TCGv_i64 fp1 = tcg_temp_new_i64();
7217 gen_load_fpr64(ctx, fp0, fs);
7218 gen_load_fpr64(ctx, fp1, ft);
7219 gen_helper_float_recip2_d(fp0, fp0, fp1);
7220 tcg_temp_free_i64(fp1);
7221 gen_store_fpr64(ctx, fp0, fd);
7222 tcg_temp_free_i64(fp0);
7227 check_cp1_64bitmode(ctx);
7229 TCGv_i64 fp0 = tcg_temp_new_i64();
7231 gen_load_fpr64(ctx, fp0, fs);
7232 gen_helper_float_recip1_d(fp0, fp0);
7233 gen_store_fpr64(ctx, fp0, fd);
7234 tcg_temp_free_i64(fp0);
7239 check_cp1_64bitmode(ctx);
7241 TCGv_i64 fp0 = tcg_temp_new_i64();
7243 gen_load_fpr64(ctx, fp0, fs);
7244 gen_helper_float_rsqrt1_d(fp0, fp0);
7245 gen_store_fpr64(ctx, fp0, fd);
7246 tcg_temp_free_i64(fp0);
7251 check_cp1_64bitmode(ctx);
7253 TCGv_i64 fp0 = tcg_temp_new_i64();
7254 TCGv_i64 fp1 = tcg_temp_new_i64();
7256 gen_load_fpr64(ctx, fp0, fs);
7257 gen_load_fpr64(ctx, fp1, ft);
7258 gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
7259 tcg_temp_free_i64(fp1);
7260 gen_store_fpr64(ctx, fp0, fd);
7261 tcg_temp_free_i64(fp0);
7274 case OPC_CMP_NGLE_D:
7281 if (ctx->opcode & (1 << 6)) {
7282 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
7283 opn = condnames_abs[func-48];
7285 gen_cmp_d(ctx, func-48, ft, fs, cc);
7286 opn = condnames[func-48];
7290 check_cp1_registers(ctx, fs);
7292 TCGv_i32 fp32 = tcg_temp_new_i32();
7293 TCGv_i64 fp64 = tcg_temp_new_i64();
7295 gen_load_fpr64(ctx, fp64, fs);
7296 gen_helper_float_cvts_d(fp32, fp64);
7297 tcg_temp_free_i64(fp64);
7298 gen_store_fpr32(fp32, fd);
7299 tcg_temp_free_i32(fp32);
7304 check_cp1_registers(ctx, fs);
7306 TCGv_i32 fp32 = tcg_temp_new_i32();
7307 TCGv_i64 fp64 = tcg_temp_new_i64();
7309 gen_load_fpr64(ctx, fp64, fs);
7310 gen_helper_float_cvtw_d(fp32, fp64);
7311 tcg_temp_free_i64(fp64);
7312 gen_store_fpr32(fp32, fd);
7313 tcg_temp_free_i32(fp32);
7318 check_cp1_64bitmode(ctx);
7320 TCGv_i64 fp0 = tcg_temp_new_i64();
7322 gen_load_fpr64(ctx, fp0, fs);
7323 gen_helper_float_cvtl_d(fp0, fp0);
7324 gen_store_fpr64(ctx, fp0, fd);
7325 tcg_temp_free_i64(fp0);
7331 TCGv_i32 fp0 = tcg_temp_new_i32();
7333 gen_load_fpr32(fp0, fs);
7334 gen_helper_float_cvts_w(fp0, fp0);
7335 gen_store_fpr32(fp0, fd);
7336 tcg_temp_free_i32(fp0);
7341 check_cp1_registers(ctx, fd);
7343 TCGv_i32 fp32 = tcg_temp_new_i32();
7344 TCGv_i64 fp64 = tcg_temp_new_i64();
7346 gen_load_fpr32(fp32, fs);
7347 gen_helper_float_cvtd_w(fp64, fp32);
7348 tcg_temp_free_i32(fp32);
7349 gen_store_fpr64(ctx, fp64, fd);
7350 tcg_temp_free_i64(fp64);
7355 check_cp1_64bitmode(ctx);
7357 TCGv_i32 fp32 = tcg_temp_new_i32();
7358 TCGv_i64 fp64 = tcg_temp_new_i64();
7360 gen_load_fpr64(ctx, fp64, fs);
7361 gen_helper_float_cvts_l(fp32, fp64);
7362 tcg_temp_free_i64(fp64);
7363 gen_store_fpr32(fp32, fd);
7364 tcg_temp_free_i32(fp32);
7369 check_cp1_64bitmode(ctx);
7371 TCGv_i64 fp0 = tcg_temp_new_i64();
7373 gen_load_fpr64(ctx, fp0, fs);
7374 gen_helper_float_cvtd_l(fp0, fp0);
7375 gen_store_fpr64(ctx, fp0, fd);
7376 tcg_temp_free_i64(fp0);
7381 check_cp1_64bitmode(ctx);
7383 TCGv_i64 fp0 = tcg_temp_new_i64();
7385 gen_load_fpr64(ctx, fp0, fs);
7386 gen_helper_float_cvtps_pw(fp0, fp0);
7387 gen_store_fpr64(ctx, fp0, fd);
7388 tcg_temp_free_i64(fp0);
7393 check_cp1_64bitmode(ctx);
7395 TCGv_i64 fp0 = tcg_temp_new_i64();
7396 TCGv_i64 fp1 = tcg_temp_new_i64();
7398 gen_load_fpr64(ctx, fp0, fs);
7399 gen_load_fpr64(ctx, fp1, ft);
7400 gen_helper_float_add_ps(fp0, fp0, fp1);
7401 tcg_temp_free_i64(fp1);
7402 gen_store_fpr64(ctx, fp0, fd);
7403 tcg_temp_free_i64(fp0);
7408 check_cp1_64bitmode(ctx);
7410 TCGv_i64 fp0 = tcg_temp_new_i64();
7411 TCGv_i64 fp1 = tcg_temp_new_i64();
7413 gen_load_fpr64(ctx, fp0, fs);
7414 gen_load_fpr64(ctx, fp1, ft);
7415 gen_helper_float_sub_ps(fp0, fp0, fp1);
7416 tcg_temp_free_i64(fp1);
7417 gen_store_fpr64(ctx, fp0, fd);
7418 tcg_temp_free_i64(fp0);
7423 check_cp1_64bitmode(ctx);
7425 TCGv_i64 fp0 = tcg_temp_new_i64();
7426 TCGv_i64 fp1 = tcg_temp_new_i64();
7428 gen_load_fpr64(ctx, fp0, fs);
7429 gen_load_fpr64(ctx, fp1, ft);
7430 gen_helper_float_mul_ps(fp0, fp0, fp1);
7431 tcg_temp_free_i64(fp1);
7432 gen_store_fpr64(ctx, fp0, fd);
7433 tcg_temp_free_i64(fp0);
7438 check_cp1_64bitmode(ctx);
7440 TCGv_i64 fp0 = tcg_temp_new_i64();
7442 gen_load_fpr64(ctx, fp0, fs);
7443 gen_helper_float_abs_ps(fp0, fp0);
7444 gen_store_fpr64(ctx, fp0, fd);
7445 tcg_temp_free_i64(fp0);
7450 check_cp1_64bitmode(ctx);
7452 TCGv_i64 fp0 = tcg_temp_new_i64();
7454 gen_load_fpr64(ctx, fp0, fs);
7455 gen_store_fpr64(ctx, fp0, fd);
7456 tcg_temp_free_i64(fp0);
7461 check_cp1_64bitmode(ctx);
7463 TCGv_i64 fp0 = tcg_temp_new_i64();
7465 gen_load_fpr64(ctx, fp0, fs);
7466 gen_helper_float_chs_ps(fp0, fp0);
7467 gen_store_fpr64(ctx, fp0, fd);
7468 tcg_temp_free_i64(fp0);
7473 check_cp1_64bitmode(ctx);
7474 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7478 check_cp1_64bitmode(ctx);
7480 int l1 = gen_new_label();
7484 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7485 fp0 = tcg_temp_new_i64();
7486 gen_load_fpr64(ctx, fp0, fs);
7487 gen_store_fpr64(ctx, fp0, fd);
7488 tcg_temp_free_i64(fp0);
7494 check_cp1_64bitmode(ctx);
7496 int l1 = gen_new_label();
7500 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7501 fp0 = tcg_temp_new_i64();
7502 gen_load_fpr64(ctx, fp0, fs);
7503 gen_store_fpr64(ctx, fp0, fd);
7504 tcg_temp_free_i64(fp0);
7511 check_cp1_64bitmode(ctx);
7513 TCGv_i64 fp0 = tcg_temp_new_i64();
7514 TCGv_i64 fp1 = tcg_temp_new_i64();
7516 gen_load_fpr64(ctx, fp0, ft);
7517 gen_load_fpr64(ctx, fp1, fs);
7518 gen_helper_float_addr_ps(fp0, fp0, fp1);
7519 tcg_temp_free_i64(fp1);
7520 gen_store_fpr64(ctx, fp0, fd);
7521 tcg_temp_free_i64(fp0);
7526 check_cp1_64bitmode(ctx);
7528 TCGv_i64 fp0 = tcg_temp_new_i64();
7529 TCGv_i64 fp1 = tcg_temp_new_i64();
7531 gen_load_fpr64(ctx, fp0, ft);
7532 gen_load_fpr64(ctx, fp1, fs);
7533 gen_helper_float_mulr_ps(fp0, fp0, fp1);
7534 tcg_temp_free_i64(fp1);
7535 gen_store_fpr64(ctx, fp0, fd);
7536 tcg_temp_free_i64(fp0);
7541 check_cp1_64bitmode(ctx);
7543 TCGv_i64 fp0 = tcg_temp_new_i64();
7544 TCGv_i64 fp1 = tcg_temp_new_i64();
7546 gen_load_fpr64(ctx, fp0, fs);
7547 gen_load_fpr64(ctx, fp1, ft);
7548 gen_helper_float_recip2_ps(fp0, fp0, fp1);
7549 tcg_temp_free_i64(fp1);
7550 gen_store_fpr64(ctx, fp0, fd);
7551 tcg_temp_free_i64(fp0);
7556 check_cp1_64bitmode(ctx);
7558 TCGv_i64 fp0 = tcg_temp_new_i64();
7560 gen_load_fpr64(ctx, fp0, fs);
7561 gen_helper_float_recip1_ps(fp0, fp0);
7562 gen_store_fpr64(ctx, fp0, fd);
7563 tcg_temp_free_i64(fp0);
7568 check_cp1_64bitmode(ctx);
7570 TCGv_i64 fp0 = tcg_temp_new_i64();
7572 gen_load_fpr64(ctx, fp0, fs);
7573 gen_helper_float_rsqrt1_ps(fp0, fp0);
7574 gen_store_fpr64(ctx, fp0, fd);
7575 tcg_temp_free_i64(fp0);
7580 check_cp1_64bitmode(ctx);
7582 TCGv_i64 fp0 = tcg_temp_new_i64();
7583 TCGv_i64 fp1 = tcg_temp_new_i64();
7585 gen_load_fpr64(ctx, fp0, fs);
7586 gen_load_fpr64(ctx, fp1, ft);
7587 gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7588 tcg_temp_free_i64(fp1);
7589 gen_store_fpr64(ctx, fp0, fd);
7590 tcg_temp_free_i64(fp0);
7595 check_cp1_64bitmode(ctx);
7597 TCGv_i32 fp0 = tcg_temp_new_i32();
7599 gen_load_fpr32h(fp0, fs);
7600 gen_helper_float_cvts_pu(fp0, fp0);
7601 gen_store_fpr32(fp0, fd);
7602 tcg_temp_free_i32(fp0);
7607 check_cp1_64bitmode(ctx);
7609 TCGv_i64 fp0 = tcg_temp_new_i64();
7611 gen_load_fpr64(ctx, fp0, fs);
7612 gen_helper_float_cvtpw_ps(fp0, fp0);
7613 gen_store_fpr64(ctx, fp0, fd);
7614 tcg_temp_free_i64(fp0);
7619 check_cp1_64bitmode(ctx);
7621 TCGv_i32 fp0 = tcg_temp_new_i32();
7623 gen_load_fpr32(fp0, fs);
7624 gen_helper_float_cvts_pl(fp0, fp0);
7625 gen_store_fpr32(fp0, fd);
7626 tcg_temp_free_i32(fp0);
7631 check_cp1_64bitmode(ctx);
7633 TCGv_i32 fp0 = tcg_temp_new_i32();
7634 TCGv_i32 fp1 = tcg_temp_new_i32();
7636 gen_load_fpr32(fp0, fs);
7637 gen_load_fpr32(fp1, ft);
7638 gen_store_fpr32h(fp0, fd);
7639 gen_store_fpr32(fp1, fd);
7640 tcg_temp_free_i32(fp0);
7641 tcg_temp_free_i32(fp1);
7646 check_cp1_64bitmode(ctx);
7648 TCGv_i32 fp0 = tcg_temp_new_i32();
7649 TCGv_i32 fp1 = tcg_temp_new_i32();
7651 gen_load_fpr32(fp0, fs);
7652 gen_load_fpr32h(fp1, ft);
7653 gen_store_fpr32(fp1, fd);
7654 gen_store_fpr32h(fp0, fd);
7655 tcg_temp_free_i32(fp0);
7656 tcg_temp_free_i32(fp1);
7661 check_cp1_64bitmode(ctx);
7663 TCGv_i32 fp0 = tcg_temp_new_i32();
7664 TCGv_i32 fp1 = tcg_temp_new_i32();
7666 gen_load_fpr32h(fp0, fs);
7667 gen_load_fpr32(fp1, ft);
7668 gen_store_fpr32(fp1, fd);
7669 gen_store_fpr32h(fp0, fd);
7670 tcg_temp_free_i32(fp0);
7671 tcg_temp_free_i32(fp1);
7676 check_cp1_64bitmode(ctx);
7678 TCGv_i32 fp0 = tcg_temp_new_i32();
7679 TCGv_i32 fp1 = tcg_temp_new_i32();
7681 gen_load_fpr32h(fp0, fs);
7682 gen_load_fpr32h(fp1, ft);
7683 gen_store_fpr32(fp1, fd);
7684 gen_store_fpr32h(fp0, fd);
7685 tcg_temp_free_i32(fp0);
7686 tcg_temp_free_i32(fp1);
7693 case OPC_CMP_UEQ_PS:
7694 case OPC_CMP_OLT_PS:
7695 case OPC_CMP_ULT_PS:
7696 case OPC_CMP_OLE_PS:
7697 case OPC_CMP_ULE_PS:
7699 case OPC_CMP_NGLE_PS:
7700 case OPC_CMP_SEQ_PS:
7701 case OPC_CMP_NGL_PS:
7703 case OPC_CMP_NGE_PS:
7705 case OPC_CMP_NGT_PS:
7706 if (ctx->opcode & (1 << 6)) {
7707 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
7708 opn = condnames_abs[func-48];
7710 gen_cmp_ps(ctx, func-48, ft, fs, cc);
7711 opn = condnames[func-48];
7716 generate_exception (ctx, EXCP_RI);
7719 (void)opn; /* avoid a compiler warning */
7722 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7725 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7728 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7733 /* Coprocessor 3 (FPU) */
7734 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7735 int fd, int fs, int base, int index)
7737 const char *opn = "extended float load/store";
7739 TCGv t0 = tcg_temp_new();
7742 gen_load_gpr(t0, index);
7743 } else if (index == 0) {
7744 gen_load_gpr(t0, base);
7746 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
7748 /* Don't do NOP if destination is zero: we must perform the actual
7750 save_cpu_state(ctx, 0);
7755 TCGv_i32 fp0 = tcg_temp_new_i32();
7757 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7758 tcg_gen_trunc_tl_i32(fp0, t0);
7759 gen_store_fpr32(fp0, fd);
7760 tcg_temp_free_i32(fp0);
7766 check_cp1_registers(ctx, fd);
7768 TCGv_i64 fp0 = tcg_temp_new_i64();
7770 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7771 gen_store_fpr64(ctx, fp0, fd);
7772 tcg_temp_free_i64(fp0);
7777 check_cp1_64bitmode(ctx);
7778 tcg_gen_andi_tl(t0, t0, ~0x7);
7780 TCGv_i64 fp0 = tcg_temp_new_i64();
7782 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7783 gen_store_fpr64(ctx, fp0, fd);
7784 tcg_temp_free_i64(fp0);
7791 TCGv_i32 fp0 = tcg_temp_new_i32();
7792 TCGv t1 = tcg_temp_new();
7794 gen_load_fpr32(fp0, fs);
7795 tcg_gen_extu_i32_tl(t1, fp0);
7796 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7797 tcg_temp_free_i32(fp0);
7805 check_cp1_registers(ctx, fs);
7807 TCGv_i64 fp0 = tcg_temp_new_i64();
7809 gen_load_fpr64(ctx, fp0, fs);
7810 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7811 tcg_temp_free_i64(fp0);
7817 check_cp1_64bitmode(ctx);
7818 tcg_gen_andi_tl(t0, t0, ~0x7);
7820 TCGv_i64 fp0 = tcg_temp_new_i64();
7822 gen_load_fpr64(ctx, fp0, fs);
7823 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7824 tcg_temp_free_i64(fp0);
7831 (void)opn; (void)store; /* avoid compiler warnings */
7832 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7833 regnames[index], regnames[base]);
7836 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7837 int fd, int fr, int fs, int ft)
7839 const char *opn = "flt3_arith";
7843 check_cp1_64bitmode(ctx);
7845 TCGv t0 = tcg_temp_local_new();
7846 TCGv_i32 fp = tcg_temp_new_i32();
7847 TCGv_i32 fph = tcg_temp_new_i32();
7848 int l1 = gen_new_label();
7849 int l2 = gen_new_label();
7851 gen_load_gpr(t0, fr);
7852 tcg_gen_andi_tl(t0, t0, 0x7);
7854 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7855 gen_load_fpr32(fp, fs);
7856 gen_load_fpr32h(fph, fs);
7857 gen_store_fpr32(fp, fd);
7858 gen_store_fpr32h(fph, fd);
7861 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7863 #ifdef TARGET_WORDS_BIGENDIAN
7864 gen_load_fpr32(fp, fs);
7865 gen_load_fpr32h(fph, ft);
7866 gen_store_fpr32h(fp, fd);
7867 gen_store_fpr32(fph, fd);
7869 gen_load_fpr32h(fph, fs);
7870 gen_load_fpr32(fp, ft);
7871 gen_store_fpr32(fph, fd);
7872 gen_store_fpr32h(fp, fd);
7875 tcg_temp_free_i32(fp);
7876 tcg_temp_free_i32(fph);
7883 TCGv_i32 fp0 = tcg_temp_new_i32();
7884 TCGv_i32 fp1 = tcg_temp_new_i32();
7885 TCGv_i32 fp2 = tcg_temp_new_i32();
7887 gen_load_fpr32(fp0, fs);
7888 gen_load_fpr32(fp1, ft);
7889 gen_load_fpr32(fp2, fr);
7890 gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7891 tcg_temp_free_i32(fp0);
7892 tcg_temp_free_i32(fp1);
7893 gen_store_fpr32(fp2, fd);
7894 tcg_temp_free_i32(fp2);
7900 check_cp1_registers(ctx, fd | fs | ft | fr);
7902 TCGv_i64 fp0 = tcg_temp_new_i64();
7903 TCGv_i64 fp1 = tcg_temp_new_i64();
7904 TCGv_i64 fp2 = tcg_temp_new_i64();
7906 gen_load_fpr64(ctx, fp0, fs);
7907 gen_load_fpr64(ctx, fp1, ft);
7908 gen_load_fpr64(ctx, fp2, fr);
7909 gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7910 tcg_temp_free_i64(fp0);
7911 tcg_temp_free_i64(fp1);
7912 gen_store_fpr64(ctx, fp2, fd);
7913 tcg_temp_free_i64(fp2);
7918 check_cp1_64bitmode(ctx);
7920 TCGv_i64 fp0 = tcg_temp_new_i64();
7921 TCGv_i64 fp1 = tcg_temp_new_i64();
7922 TCGv_i64 fp2 = tcg_temp_new_i64();
7924 gen_load_fpr64(ctx, fp0, fs);
7925 gen_load_fpr64(ctx, fp1, ft);
7926 gen_load_fpr64(ctx, fp2, fr);
7927 gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7928 tcg_temp_free_i64(fp0);
7929 tcg_temp_free_i64(fp1);
7930 gen_store_fpr64(ctx, fp2, fd);
7931 tcg_temp_free_i64(fp2);
7938 TCGv_i32 fp0 = tcg_temp_new_i32();
7939 TCGv_i32 fp1 = tcg_temp_new_i32();
7940 TCGv_i32 fp2 = tcg_temp_new_i32();
7942 gen_load_fpr32(fp0, fs);
7943 gen_load_fpr32(fp1, ft);
7944 gen_load_fpr32(fp2, fr);
7945 gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7946 tcg_temp_free_i32(fp0);
7947 tcg_temp_free_i32(fp1);
7948 gen_store_fpr32(fp2, fd);
7949 tcg_temp_free_i32(fp2);
7955 check_cp1_registers(ctx, fd | fs | ft | fr);
7957 TCGv_i64 fp0 = tcg_temp_new_i64();
7958 TCGv_i64 fp1 = tcg_temp_new_i64();
7959 TCGv_i64 fp2 = tcg_temp_new_i64();
7961 gen_load_fpr64(ctx, fp0, fs);
7962 gen_load_fpr64(ctx, fp1, ft);
7963 gen_load_fpr64(ctx, fp2, fr);
7964 gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7965 tcg_temp_free_i64(fp0);
7966 tcg_temp_free_i64(fp1);
7967 gen_store_fpr64(ctx, fp2, fd);
7968 tcg_temp_free_i64(fp2);
7973 check_cp1_64bitmode(ctx);
7975 TCGv_i64 fp0 = tcg_temp_new_i64();
7976 TCGv_i64 fp1 = tcg_temp_new_i64();
7977 TCGv_i64 fp2 = tcg_temp_new_i64();
7979 gen_load_fpr64(ctx, fp0, fs);
7980 gen_load_fpr64(ctx, fp1, ft);
7981 gen_load_fpr64(ctx, fp2, fr);
7982 gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7983 tcg_temp_free_i64(fp0);
7984 tcg_temp_free_i64(fp1);
7985 gen_store_fpr64(ctx, fp2, fd);
7986 tcg_temp_free_i64(fp2);
7993 TCGv_i32 fp0 = tcg_temp_new_i32();
7994 TCGv_i32 fp1 = tcg_temp_new_i32();
7995 TCGv_i32 fp2 = tcg_temp_new_i32();
7997 gen_load_fpr32(fp0, fs);
7998 gen_load_fpr32(fp1, ft);
7999 gen_load_fpr32(fp2, fr);
8000 gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
8001 tcg_temp_free_i32(fp0);
8002 tcg_temp_free_i32(fp1);
8003 gen_store_fpr32(fp2, fd);
8004 tcg_temp_free_i32(fp2);
8010 check_cp1_registers(ctx, fd | fs | ft | fr);
8012 TCGv_i64 fp0 = tcg_temp_new_i64();
8013 TCGv_i64 fp1 = tcg_temp_new_i64();
8014 TCGv_i64 fp2 = tcg_temp_new_i64();
8016 gen_load_fpr64(ctx, fp0, fs);
8017 gen_load_fpr64(ctx, fp1, ft);
8018 gen_load_fpr64(ctx, fp2, fr);
8019 gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
8020 tcg_temp_free_i64(fp0);
8021 tcg_temp_free_i64(fp1);
8022 gen_store_fpr64(ctx, fp2, fd);
8023 tcg_temp_free_i64(fp2);
8028 check_cp1_64bitmode(ctx);
8030 TCGv_i64 fp0 = tcg_temp_new_i64();
8031 TCGv_i64 fp1 = tcg_temp_new_i64();
8032 TCGv_i64 fp2 = tcg_temp_new_i64();
8034 gen_load_fpr64(ctx, fp0, fs);
8035 gen_load_fpr64(ctx, fp1, ft);
8036 gen_load_fpr64(ctx, fp2, fr);
8037 gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
8038 tcg_temp_free_i64(fp0);
8039 tcg_temp_free_i64(fp1);
8040 gen_store_fpr64(ctx, fp2, fd);
8041 tcg_temp_free_i64(fp2);
8048 TCGv_i32 fp0 = tcg_temp_new_i32();
8049 TCGv_i32 fp1 = tcg_temp_new_i32();
8050 TCGv_i32 fp2 = tcg_temp_new_i32();
8052 gen_load_fpr32(fp0, fs);
8053 gen_load_fpr32(fp1, ft);
8054 gen_load_fpr32(fp2, fr);
8055 gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
8056 tcg_temp_free_i32(fp0);
8057 tcg_temp_free_i32(fp1);
8058 gen_store_fpr32(fp2, fd);
8059 tcg_temp_free_i32(fp2);
8065 check_cp1_registers(ctx, fd | fs | ft | fr);
8067 TCGv_i64 fp0 = tcg_temp_new_i64();
8068 TCGv_i64 fp1 = tcg_temp_new_i64();
8069 TCGv_i64 fp2 = tcg_temp_new_i64();
8071 gen_load_fpr64(ctx, fp0, fs);
8072 gen_load_fpr64(ctx, fp1, ft);
8073 gen_load_fpr64(ctx, fp2, fr);
8074 gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
8075 tcg_temp_free_i64(fp0);
8076 tcg_temp_free_i64(fp1);
8077 gen_store_fpr64(ctx, fp2, fd);
8078 tcg_temp_free_i64(fp2);
8083 check_cp1_64bitmode(ctx);
8085 TCGv_i64 fp0 = tcg_temp_new_i64();
8086 TCGv_i64 fp1 = tcg_temp_new_i64();
8087 TCGv_i64 fp2 = tcg_temp_new_i64();
8089 gen_load_fpr64(ctx, fp0, fs);
8090 gen_load_fpr64(ctx, fp1, ft);
8091 gen_load_fpr64(ctx, fp2, fr);
8092 gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
8093 tcg_temp_free_i64(fp0);
8094 tcg_temp_free_i64(fp1);
8095 gen_store_fpr64(ctx, fp2, fd);
8096 tcg_temp_free_i64(fp2);
8102 generate_exception (ctx, EXCP_RI);
8105 (void)opn; /* avoid a compiler warning */
8106 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
8107 fregnames[fs], fregnames[ft]);
8111 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
8115 #if !defined(CONFIG_USER_ONLY)
8116 /* The Linux kernel will emulate rdhwr if it's not supported natively.
8117 Therefore only check the ISA in system mode. */
8118 check_insn(env, ctx, ISA_MIPS32R2);
8120 t0 = tcg_temp_new();
8124 save_cpu_state(ctx, 1);
8125 gen_helper_rdhwr_cpunum(t0);
8126 gen_store_gpr(t0, rt);
8129 save_cpu_state(ctx, 1);
8130 gen_helper_rdhwr_synci_step(t0);
8131 gen_store_gpr(t0, rt);
8134 save_cpu_state(ctx, 1);
8135 gen_helper_rdhwr_cc(t0);
8136 gen_store_gpr(t0, rt);
8139 save_cpu_state(ctx, 1);
8140 gen_helper_rdhwr_ccres(t0);
8141 gen_store_gpr(t0, rt);
8144 #if defined(CONFIG_USER_ONLY)
8145 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
8146 gen_store_gpr(t0, rt);
8149 /* XXX: Some CPUs implement this in hardware.
8150 Not supported yet. */
8152 default: /* Invalid */
8153 MIPS_INVAL("rdhwr");
8154 generate_exception(ctx, EXCP_RI);
8160 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
8163 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8164 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8165 /* Branches completion */
8166 ctx->hflags &= ~MIPS_HFLAG_BMASK;
8167 ctx->bstate = BS_BRANCH;
8168 save_cpu_state(ctx, 0);
8169 /* FIXME: Need to clear can_do_io. */
8170 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
8172 /* unconditional branch */
8173 MIPS_DEBUG("unconditional branch");
8174 if (proc_hflags & MIPS_HFLAG_BX) {
8175 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
8177 gen_goto_tb(ctx, 0, ctx->btarget);
8180 /* blikely taken case */
8181 MIPS_DEBUG("blikely branch taken");
8182 gen_goto_tb(ctx, 0, ctx->btarget);
8185 /* Conditional branch */
8186 MIPS_DEBUG("conditional branch");
8188 int l1 = gen_new_label();
8190 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8191 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
8193 gen_goto_tb(ctx, 0, ctx->btarget);
8197 /* unconditional branch to register */
8198 MIPS_DEBUG("branch to register");
8199 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
8200 TCGv t0 = tcg_temp_new();
8201 TCGv_i32 t1 = tcg_temp_new_i32();
8203 tcg_gen_andi_tl(t0, btarget, 0x1);
8204 tcg_gen_trunc_tl_i32(t1, t0);
8206 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
8207 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
8208 tcg_gen_or_i32(hflags, hflags, t1);
8209 tcg_temp_free_i32(t1);
8211 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
8213 tcg_gen_mov_tl(cpu_PC, btarget);
8215 if (ctx->singlestep_enabled) {
8216 save_cpu_state(ctx, 0);
8217 gen_helper_0i(raise_exception, EXCP_DEBUG);
8222 MIPS_DEBUG("unknown branch");
8228 /* ISA extensions (ASEs) */
8229 /* MIPS16 extension to MIPS32 */
8231 /* MIPS16 major opcodes */
8233 M16_OPC_ADDIUSP = 0x00,
8234 M16_OPC_ADDIUPC = 0x01,
8237 M16_OPC_BEQZ = 0x04,
8238 M16_OPC_BNEQZ = 0x05,
8239 M16_OPC_SHIFT = 0x06,
8241 M16_OPC_RRIA = 0x08,
8242 M16_OPC_ADDIU8 = 0x09,
8243 M16_OPC_SLTI = 0x0a,
8244 M16_OPC_SLTIU = 0x0b,
8247 M16_OPC_CMPI = 0x0e,
8251 M16_OPC_LWSP = 0x12,
8255 M16_OPC_LWPC = 0x16,
8259 M16_OPC_SWSP = 0x1a,
8263 M16_OPC_EXTEND = 0x1e,
8267 /* I8 funct field */
8286 /* RR funct field */
8320 /* I64 funct field */
8332 /* RR ry field for CNVT */
8334 RR_RY_CNVT_ZEB = 0x0,
8335 RR_RY_CNVT_ZEH = 0x1,
8336 RR_RY_CNVT_ZEW = 0x2,
8337 RR_RY_CNVT_SEB = 0x4,
8338 RR_RY_CNVT_SEH = 0x5,
8339 RR_RY_CNVT_SEW = 0x6,
8342 static int xlat (int r)
8344 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
8349 static void gen_mips16_save (DisasContext *ctx,
8350 int xsregs, int aregs,
8351 int do_ra, int do_s0, int do_s1,
8354 TCGv t0 = tcg_temp_new();
8355 TCGv t1 = tcg_temp_new();
8385 generate_exception(ctx, EXCP_RI);
8391 gen_base_offset_addr(ctx, t0, 29, 12);
8392 gen_load_gpr(t1, 7);
8393 op_st_sw(t1, t0, ctx);
8396 gen_base_offset_addr(ctx, t0, 29, 8);
8397 gen_load_gpr(t1, 6);
8398 op_st_sw(t1, t0, ctx);
8401 gen_base_offset_addr(ctx, t0, 29, 4);
8402 gen_load_gpr(t1, 5);
8403 op_st_sw(t1, t0, ctx);
8406 gen_base_offset_addr(ctx, t0, 29, 0);
8407 gen_load_gpr(t1, 4);
8408 op_st_sw(t1, t0, ctx);
8411 gen_load_gpr(t0, 29);
8413 #define DECR_AND_STORE(reg) do { \
8414 tcg_gen_subi_tl(t0, t0, 4); \
8415 gen_load_gpr(t1, reg); \
8416 op_st_sw(t1, t0, ctx); \
8480 generate_exception(ctx, EXCP_RI);
8496 #undef DECR_AND_STORE
8498 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8503 static void gen_mips16_restore (DisasContext *ctx,
8504 int xsregs, int aregs,
8505 int do_ra, int do_s0, int do_s1,
8509 TCGv t0 = tcg_temp_new();
8510 TCGv t1 = tcg_temp_new();
8512 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8514 #define DECR_AND_LOAD(reg) do { \
8515 tcg_gen_subi_tl(t0, t0, 4); \
8516 op_ld_lw(t1, t0, ctx); \
8517 gen_store_gpr(t1, reg); \
8581 generate_exception(ctx, EXCP_RI);
8597 #undef DECR_AND_LOAD
8599 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8604 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8605 int is_64_bit, int extended)
8609 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8610 generate_exception(ctx, EXCP_RI);
8614 t0 = tcg_temp_new();
8616 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8617 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8619 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8625 #if defined(TARGET_MIPS64)
8626 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
8627 int ry, int funct, int16_t offset,
8633 offset = extended ? offset : offset << 3;
8634 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
8638 offset = extended ? offset : offset << 3;
8639 gen_st(ctx, OPC_SD, ry, 29, offset);
8643 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8644 gen_st(ctx, OPC_SD, 31, 29, offset);
8648 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8649 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8652 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8653 generate_exception(ctx, EXCP_RI);
8655 offset = extended ? offset : offset << 3;
8656 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
8661 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8662 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8666 offset = extended ? offset : offset << 2;
8667 gen_addiupc(ctx, ry, offset, 1, extended);
8671 offset = extended ? offset : offset << 2;
8672 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8678 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
8681 int extend = lduw_code(ctx->pc + 2);
8682 int op, rx, ry, funct, sa;
8683 int16_t imm, offset;
8685 ctx->opcode = (ctx->opcode << 16) | extend;
8686 op = (ctx->opcode >> 11) & 0x1f;
8687 sa = (ctx->opcode >> 22) & 0x1f;
8688 funct = (ctx->opcode >> 8) & 0x7;
8689 rx = xlat((ctx->opcode >> 8) & 0x7);
8690 ry = xlat((ctx->opcode >> 5) & 0x7);
8691 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8692 | ((ctx->opcode >> 21) & 0x3f) << 5
8693 | (ctx->opcode & 0x1f));
8695 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8698 case M16_OPC_ADDIUSP:
8699 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8701 case M16_OPC_ADDIUPC:
8702 gen_addiupc(ctx, rx, imm, 0, 1);
8705 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8706 /* No delay slot, so just process as a normal instruction */
8709 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8710 /* No delay slot, so just process as a normal instruction */
8713 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8714 /* No delay slot, so just process as a normal instruction */
8717 switch (ctx->opcode & 0x3) {
8719 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8722 #if defined(TARGET_MIPS64)
8724 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8726 generate_exception(ctx, EXCP_RI);
8730 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8733 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8737 #if defined(TARGET_MIPS64)
8740 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
8744 imm = ctx->opcode & 0xf;
8745 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8746 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8747 imm = (int16_t) (imm << 1) >> 1;
8748 if ((ctx->opcode >> 4) & 0x1) {
8749 #if defined(TARGET_MIPS64)
8751 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8753 generate_exception(ctx, EXCP_RI);
8756 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8759 case M16_OPC_ADDIU8:
8760 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8763 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8766 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8771 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8774 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8777 gen_st(ctx, OPC_SW, 31, 29, imm);
8780 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8784 int xsregs = (ctx->opcode >> 24) & 0x7;
8785 int aregs = (ctx->opcode >> 16) & 0xf;
8786 int do_ra = (ctx->opcode >> 6) & 0x1;
8787 int do_s0 = (ctx->opcode >> 5) & 0x1;
8788 int do_s1 = (ctx->opcode >> 4) & 0x1;
8789 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8790 | (ctx->opcode & 0xf)) << 3;
8792 if (ctx->opcode & (1 << 7)) {
8793 gen_mips16_save(ctx, xsregs, aregs,
8794 do_ra, do_s0, do_s1,
8797 gen_mips16_restore(ctx, xsregs, aregs,
8798 do_ra, do_s0, do_s1,
8804 generate_exception(ctx, EXCP_RI);
8809 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8812 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8814 #if defined(TARGET_MIPS64)
8816 gen_st(ctx, OPC_SD, ry, rx, offset);
8820 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8823 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
8826 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
8829 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
8832 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
8835 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
8838 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
8840 #if defined(TARGET_MIPS64)
8842 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
8846 gen_st(ctx, OPC_SB, ry, rx, offset);
8849 gen_st(ctx, OPC_SH, ry, rx, offset);
8852 gen_st(ctx, OPC_SW, rx, 29, offset);
8855 gen_st(ctx, OPC_SW, ry, rx, offset);
8857 #if defined(TARGET_MIPS64)
8859 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8863 generate_exception(ctx, EXCP_RI);
8870 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
8875 int op, cnvt_op, op1, offset;
8879 op = (ctx->opcode >> 11) & 0x1f;
8880 sa = (ctx->opcode >> 2) & 0x7;
8881 sa = sa == 0 ? 8 : sa;
8882 rx = xlat((ctx->opcode >> 8) & 0x7);
8883 cnvt_op = (ctx->opcode >> 5) & 0x7;
8884 ry = xlat((ctx->opcode >> 5) & 0x7);
8885 op1 = offset = ctx->opcode & 0x1f;
8890 case M16_OPC_ADDIUSP:
8892 int16_t imm = ((uint8_t) ctx->opcode) << 2;
8894 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8897 case M16_OPC_ADDIUPC:
8898 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8901 offset = (ctx->opcode & 0x7ff) << 1;
8902 offset = (int16_t)(offset << 4) >> 4;
8903 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8904 /* No delay slot, so just process as a normal instruction */
8907 offset = lduw_code(ctx->pc + 2);
8908 offset = (((ctx->opcode & 0x1f) << 21)
8909 | ((ctx->opcode >> 5) & 0x1f) << 16
8911 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8912 gen_compute_branch(ctx, op, 4, rx, ry, offset);
8917 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8918 /* No delay slot, so just process as a normal instruction */
8921 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8922 /* No delay slot, so just process as a normal instruction */
8925 switch (ctx->opcode & 0x3) {
8927 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8930 #if defined(TARGET_MIPS64)
8932 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8934 generate_exception(ctx, EXCP_RI);
8938 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8941 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8945 #if defined(TARGET_MIPS64)
8948 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
8953 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8955 if ((ctx->opcode >> 4) & 1) {
8956 #if defined(TARGET_MIPS64)
8958 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8960 generate_exception(ctx, EXCP_RI);
8963 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8967 case M16_OPC_ADDIU8:
8969 int16_t imm = (int8_t) ctx->opcode;
8971 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8976 int16_t imm = (uint8_t) ctx->opcode;
8978 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8983 int16_t imm = (uint8_t) ctx->opcode;
8985 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8992 funct = (ctx->opcode >> 8) & 0x7;
8995 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8996 ((int8_t)ctx->opcode) << 1);
8999 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9000 ((int8_t)ctx->opcode) << 1);
9003 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9006 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9007 ((int8_t)ctx->opcode) << 3);
9011 int do_ra = ctx->opcode & (1 << 6);
9012 int do_s0 = ctx->opcode & (1 << 5);
9013 int do_s1 = ctx->opcode & (1 << 4);
9014 int framesize = ctx->opcode & 0xf;
9016 if (framesize == 0) {
9019 framesize = framesize << 3;
9022 if (ctx->opcode & (1 << 7)) {
9023 gen_mips16_save(ctx, 0, 0,
9024 do_ra, do_s0, do_s1, framesize);
9026 gen_mips16_restore(ctx, 0, 0,
9027 do_ra, do_s0, do_s1, framesize);
9033 int rz = xlat(ctx->opcode & 0x7);
9035 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9036 ((ctx->opcode >> 5) & 0x7);
9037 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9041 reg32 = ctx->opcode & 0x1f;
9042 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9045 generate_exception(ctx, EXCP_RI);
9052 int16_t imm = (uint8_t) ctx->opcode;
9054 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9059 int16_t imm = (uint8_t) ctx->opcode;
9061 gen_logic_imm(env, OPC_XORI, 24, rx, imm);
9064 #if defined(TARGET_MIPS64)
9067 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9071 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9074 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9077 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9080 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
9083 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9086 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9089 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9091 #if defined (TARGET_MIPS64)
9094 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
9098 gen_st(ctx, OPC_SB, ry, rx, offset);
9101 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9104 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9107 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9111 int rz = xlat((ctx->opcode >> 2) & 0x7);
9114 switch (ctx->opcode & 0x3) {
9116 mips32_op = OPC_ADDU;
9119 mips32_op = OPC_SUBU;
9121 #if defined(TARGET_MIPS64)
9123 mips32_op = OPC_DADDU;
9127 mips32_op = OPC_DSUBU;
9132 generate_exception(ctx, EXCP_RI);
9136 gen_arith(env, ctx, mips32_op, rz, rx, ry);
9145 int nd = (ctx->opcode >> 7) & 0x1;
9146 int link = (ctx->opcode >> 6) & 0x1;
9147 int ra = (ctx->opcode >> 5) & 0x1;
9150 op = nd ? OPC_JALRC : OPC_JALRS;
9155 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
9162 /* XXX: not clear which exception should be raised
9163 * when in debug mode...
9165 check_insn(env, ctx, ISA_MIPS32);
9166 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9167 generate_exception(ctx, EXCP_DBp);
9169 generate_exception(ctx, EXCP_DBp);
9173 gen_slt(env, OPC_SLT, 24, rx, ry);
9176 gen_slt(env, OPC_SLTU, 24, rx, ry);
9179 generate_exception(ctx, EXCP_BREAK);
9182 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
9185 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
9188 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
9190 #if defined (TARGET_MIPS64)
9193 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
9197 gen_logic(env, OPC_XOR, 24, rx, ry);
9200 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
9203 gen_logic(env, OPC_AND, rx, rx, ry);
9206 gen_logic(env, OPC_OR, rx, rx, ry);
9209 gen_logic(env, OPC_XOR, rx, rx, ry);
9212 gen_logic(env, OPC_NOR, rx, ry, 0);
9215 gen_HILO(ctx, OPC_MFHI, rx);
9219 case RR_RY_CNVT_ZEB:
9220 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9222 case RR_RY_CNVT_ZEH:
9223 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9225 case RR_RY_CNVT_SEB:
9226 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9228 case RR_RY_CNVT_SEH:
9229 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9231 #if defined (TARGET_MIPS64)
9232 case RR_RY_CNVT_ZEW:
9234 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9236 case RR_RY_CNVT_SEW:
9238 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9242 generate_exception(ctx, EXCP_RI);
9247 gen_HILO(ctx, OPC_MFLO, rx);
9249 #if defined (TARGET_MIPS64)
9252 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
9256 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
9260 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
9264 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
9268 gen_muldiv(ctx, OPC_MULT, rx, ry);
9271 gen_muldiv(ctx, OPC_MULTU, rx, ry);
9274 gen_muldiv(ctx, OPC_DIV, rx, ry);
9277 gen_muldiv(ctx, OPC_DIVU, rx, ry);
9279 #if defined (TARGET_MIPS64)
9282 gen_muldiv(ctx, OPC_DMULT, rx, ry);
9286 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
9290 gen_muldiv(ctx, OPC_DDIV, rx, ry);
9294 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
9298 generate_exception(ctx, EXCP_RI);
9302 case M16_OPC_EXTEND:
9303 decode_extended_mips16_opc(env, ctx, is_branch);
9306 #if defined(TARGET_MIPS64)
9308 funct = (ctx->opcode >> 8) & 0x7;
9309 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
9313 generate_exception(ctx, EXCP_RI);
9320 /* microMIPS extension to MIPS32 */
9322 /* microMIPS32 major opcodes */
9361 /* 0x20 is reserved */
9371 /* 0x28 and 0x29 are reserved */
9381 /* 0x30 and 0x31 are reserved */
9391 /* 0x38 and 0x39 are reserved */
9402 /* POOL32A encoding of minor opcode field */
9405 /* These opcodes are distinguished only by bits 9..6; those bits are
9406 * what are recorded below. */
9432 /* The following can be distinguished by their lower 6 bits. */
9438 /* POOL32AXF encoding of minor opcode field extension */
9452 /* bits 13..12 for 0x01 */
9458 /* bits 13..12 for 0x2a */
9464 /* bits 13..12 for 0x32 */
9468 /* bits 15..12 for 0x2c */
9484 /* bits 15..12 for 0x34 */
9492 /* bits 15..12 for 0x3c */
9494 JR = 0x0, /* alias */
9499 /* bits 15..12 for 0x05 */
9503 /* bits 15..12 for 0x0d */
9513 /* bits 15..12 for 0x15 */
9519 /* bits 15..12 for 0x1d */
9523 /* bits 15..12 for 0x2d */
9528 /* bits 15..12 for 0x35 */
9535 /* POOL32B encoding of minor opcode field (bits 15..12) */
9551 /* POOL32C encoding of minor opcode field (bits 15..12) */
9559 /* 0xa is reserved */
9566 /* 0x6 is reserved */
9572 /* POOL32F encoding of minor opcode field (bits 5..0) */
9575 /* These are the bit 7..6 values */
9586 /* These are the bit 8..6 values */
9630 CABS_COND_FMT = 0x1c, /* MIPS3D */
9634 /* POOL32Fxf encoding of minor opcode extension field */
9672 /* POOL32I encoding of minor opcode field (bits 25..21) */
9697 /* These overlap and are distinguished by bit16 of the instruction */
9706 /* POOL16A encoding of minor opcode field */
9713 /* POOL16B encoding of minor opcode field */
9720 /* POOL16C encoding of minor opcode field */
9740 /* POOL16D encoding of minor opcode field */
9747 /* POOL16E encoding of minor opcode field */
9754 static int mmreg (int r)
9756 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9761 /* Used for 16-bit store instructions. */
9762 static int mmreg2 (int r)
9764 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
9769 #define uMIPS_RD(op) ((op >> 7) & 0x7)
9770 #define uMIPS_RS(op) ((op >> 4) & 0x7)
9771 #define uMIPS_RS2(op) uMIPS_RS(op)
9772 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
9773 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
9774 #define uMIPS_RS5(op) (op & 0x1f)
9776 /* Signed immediate */
9777 #define SIMM(op, start, width) \
9778 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
9781 /* Zero-extended immediate */
9782 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
9784 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
9786 int rd = mmreg(uMIPS_RD(ctx->opcode));
9788 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9791 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
9793 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
9794 int rd = mmreg(uMIPS_RD(ctx->opcode));
9795 int rs = mmreg(uMIPS_RS(ctx->opcode));
9797 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9800 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
9802 int encoded = ZIMM(ctx->opcode, 1, 9);
9806 decoded = 256 + encoded;
9807 } else if (encoded <= 255) {
9809 } else if (encoded <= 509) {
9810 decoded = encoded - 512;
9812 decoded = encoded - 768;
9815 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9818 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
9820 int imm = SIMM(ctx->opcode, 1, 4);
9821 int rd = (ctx->opcode >> 5) & 0x1f;
9823 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9826 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
9828 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
9829 31, 32, 63, 64, 255, 32768, 65535 };
9830 int rd = mmreg(uMIPS_RD(ctx->opcode));
9831 int rs = mmreg(uMIPS_RS(ctx->opcode));
9832 int encoded = ZIMM(ctx->opcode, 0, 4);
9834 gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9837 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
9838 int base, int16_t offset)
9843 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9844 generate_exception(ctx, EXCP_RI);
9848 t0 = tcg_temp_new();
9850 gen_base_offset_addr(ctx, t0, base, offset);
9852 t1 = tcg_const_tl(reglist);
9853 t2 = tcg_const_i32(ctx->mem_idx);
9855 save_cpu_state(ctx, 1);
9858 gen_helper_lwm(t0, t1, t2);
9861 gen_helper_swm(t0, t1, t2);
9863 #ifdef TARGET_MIPS64
9865 gen_helper_ldm(t0, t1, t2);
9868 gen_helper_sdm(t0, t1, t2);
9872 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9875 tcg_temp_free_i32(t2);
9879 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
9881 int rd = mmreg((ctx->opcode >> 3) & 0x7);
9882 int rs = mmreg(ctx->opcode & 0x7);
9885 switch (((ctx->opcode) >> 4) & 0x3f) {
9890 gen_logic(env, OPC_NOR, rd, rs, 0);
9896 gen_logic(env, OPC_XOR, rd, rd, rs);
9902 gen_logic(env, OPC_AND, rd, rd, rs);
9908 gen_logic(env, OPC_OR, rd, rd, rs);
9915 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9916 int offset = ZIMM(ctx->opcode, 0, 4);
9918 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
9927 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9928 int offset = ZIMM(ctx->opcode, 0, 4);
9930 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
9937 int reg = ctx->opcode & 0x1f;
9939 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9946 int reg = ctx->opcode & 0x1f;
9948 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9949 /* Let normal delay slot handling in our caller take us
9950 to the branch target. */
9962 int reg = ctx->opcode & 0x1f;
9964 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9970 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9974 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9977 generate_exception(ctx, EXCP_BREAK);
9980 /* XXX: not clear which exception should be raised
9981 * when in debug mode...
9983 check_insn(env, ctx, ISA_MIPS32);
9984 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9985 generate_exception(ctx, EXCP_DBp);
9987 generate_exception(ctx, EXCP_DBp);
9993 int imm = ZIMM(ctx->opcode, 0, 5);
9995 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
9996 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
9997 /* Let normal delay slot handling in our caller take us
9998 to the branch target. */
10002 generate_exception(ctx, EXCP_RI);
10007 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10009 TCGv t0 = tcg_temp_new();
10010 TCGv t1 = tcg_temp_new();
10012 gen_load_gpr(t0, base);
10015 gen_load_gpr(t1, index);
10016 tcg_gen_shli_tl(t1, t1, 2);
10017 gen_op_addr_add(ctx, t0, t1, t0);
10020 save_cpu_state(ctx, 0);
10021 op_ld_lw(t1, t0, ctx);
10022 gen_store_gpr(t1, rd);
10028 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10029 int base, int16_t offset)
10031 const char *opn = "ldst_pair";
10034 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10035 generate_exception(ctx, EXCP_RI);
10039 t0 = tcg_temp_new();
10040 t1 = tcg_temp_new();
10042 gen_base_offset_addr(ctx, t0, base, offset);
10047 generate_exception(ctx, EXCP_RI);
10050 save_cpu_state(ctx, 0);
10051 op_ld_lw(t1, t0, ctx);
10052 gen_store_gpr(t1, rd);
10053 tcg_gen_movi_tl(t1, 4);
10054 gen_op_addr_add(ctx, t0, t0, t1);
10055 op_ld_lw(t1, t0, ctx);
10056 gen_store_gpr(t1, rd+1);
10060 save_cpu_state(ctx, 0);
10061 gen_load_gpr(t1, rd);
10062 op_st_sw(t1, t0, ctx);
10063 tcg_gen_movi_tl(t1, 4);
10064 gen_op_addr_add(ctx, t0, t0, t1);
10065 gen_load_gpr(t1, rd+1);
10066 op_st_sw(t1, t0, ctx);
10069 #ifdef TARGET_MIPS64
10072 generate_exception(ctx, EXCP_RI);
10075 save_cpu_state(ctx, 0);
10076 op_ld_ld(t1, t0, ctx);
10077 gen_store_gpr(t1, rd);
10078 tcg_gen_movi_tl(t1, 8);
10079 gen_op_addr_add(ctx, t0, t0, t1);
10080 op_ld_ld(t1, t0, ctx);
10081 gen_store_gpr(t1, rd+1);
10085 save_cpu_state(ctx, 0);
10086 gen_load_gpr(t1, rd);
10087 op_st_sd(t1, t0, ctx);
10088 tcg_gen_movi_tl(t1, 8);
10089 gen_op_addr_add(ctx, t0, t0, t1);
10090 gen_load_gpr(t1, rd+1);
10091 op_st_sd(t1, t0, ctx);
10096 (void)opn; /* avoid a compiler warning */
10097 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
10102 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
10105 int extension = (ctx->opcode >> 6) & 0x3f;
10106 int minor = (ctx->opcode >> 12) & 0xf;
10107 uint32_t mips32_op;
10109 switch (extension) {
10111 mips32_op = OPC_TEQ;
10114 mips32_op = OPC_TGE;
10117 mips32_op = OPC_TGEU;
10120 mips32_op = OPC_TLT;
10123 mips32_op = OPC_TLTU;
10126 mips32_op = OPC_TNE;
10128 gen_trap(ctx, mips32_op, rs, rt, -1);
10130 #ifndef CONFIG_USER_ONLY
10133 check_cp0_enabled(ctx);
10135 /* Treat as NOP. */
10138 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
10142 check_cp0_enabled(ctx);
10144 TCGv t0 = tcg_temp_new();
10146 gen_load_gpr(t0, rt);
10147 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
10155 gen_bshfl(ctx, OPC_SEB, rs, rt);
10158 gen_bshfl(ctx, OPC_SEH, rs, rt);
10161 mips32_op = OPC_CLO;
10164 mips32_op = OPC_CLZ;
10166 check_insn(env, ctx, ISA_MIPS32);
10167 gen_cl(ctx, mips32_op, rt, rs);
10170 gen_rdhwr(env, ctx, rt, rs);
10173 gen_bshfl(ctx, OPC_WSBH, rs, rt);
10176 mips32_op = OPC_MULT;
10179 mips32_op = OPC_MULTU;
10182 mips32_op = OPC_DIV;
10185 mips32_op = OPC_DIVU;
10188 mips32_op = OPC_MADD;
10191 mips32_op = OPC_MADDU;
10194 mips32_op = OPC_MSUB;
10197 mips32_op = OPC_MSUBU;
10199 check_insn(env, ctx, ISA_MIPS32);
10200 gen_muldiv(ctx, mips32_op, rs, rt);
10203 goto pool32axf_invalid;
10214 generate_exception_err(ctx, EXCP_CpU, 2);
10217 goto pool32axf_invalid;
10224 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
10229 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
10233 goto pool32axf_invalid;
10239 check_cp0_enabled(ctx);
10240 check_insn(env, ctx, ISA_MIPS32R2);
10241 gen_load_srsgpr(rt, rs);
10244 check_cp0_enabled(ctx);
10245 check_insn(env, ctx, ISA_MIPS32R2);
10246 gen_store_srsgpr(rt, rs);
10249 goto pool32axf_invalid;
10252 #ifndef CONFIG_USER_ONLY
10256 mips32_op = OPC_TLBP;
10259 mips32_op = OPC_TLBR;
10262 mips32_op = OPC_TLBWI;
10265 mips32_op = OPC_TLBWR;
10268 mips32_op = OPC_WAIT;
10271 mips32_op = OPC_DERET;
10274 mips32_op = OPC_ERET;
10276 gen_cp0(env, ctx, mips32_op, rt, rs);
10279 goto pool32axf_invalid;
10285 check_cp0_enabled(ctx);
10287 TCGv t0 = tcg_temp_new();
10289 save_cpu_state(ctx, 1);
10291 gen_store_gpr(t0, rs);
10292 /* Stop translation as we may have switched the execution mode */
10293 ctx->bstate = BS_STOP;
10298 check_cp0_enabled(ctx);
10300 TCGv t0 = tcg_temp_new();
10302 save_cpu_state(ctx, 1);
10304 gen_store_gpr(t0, rs);
10305 /* Stop translation as we may have switched the execution mode */
10306 ctx->bstate = BS_STOP;
10311 goto pool32axf_invalid;
10321 generate_exception(ctx, EXCP_SYSCALL);
10322 ctx->bstate = BS_STOP;
10325 check_insn(env, ctx, ISA_MIPS32);
10326 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10327 generate_exception(ctx, EXCP_DBp);
10329 generate_exception(ctx, EXCP_DBp);
10333 goto pool32axf_invalid;
10339 gen_HILO(ctx, OPC_MFHI, rs);
10342 gen_HILO(ctx, OPC_MFLO, rs);
10345 gen_HILO(ctx, OPC_MTHI, rs);
10348 gen_HILO(ctx, OPC_MTLO, rs);
10351 goto pool32axf_invalid;
10356 MIPS_INVAL("pool32axf");
10357 generate_exception(ctx, EXCP_RI);
10362 /* Values for microMIPS fmt field. Variable-width, depending on which
10363 formats the instruction supports. */
10382 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
10384 int extension = (ctx->opcode >> 6) & 0x3ff;
10385 uint32_t mips32_op;
10387 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
10388 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
10389 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
10391 switch (extension) {
10392 case FLOAT_1BIT_FMT(CFC1, 0):
10393 mips32_op = OPC_CFC1;
10395 case FLOAT_1BIT_FMT(CTC1, 0):
10396 mips32_op = OPC_CTC1;
10398 case FLOAT_1BIT_FMT(MFC1, 0):
10399 mips32_op = OPC_MFC1;
10401 case FLOAT_1BIT_FMT(MTC1, 0):
10402 mips32_op = OPC_MTC1;
10404 case FLOAT_1BIT_FMT(MFHC1, 0):
10405 mips32_op = OPC_MFHC1;
10407 case FLOAT_1BIT_FMT(MTHC1, 0):
10408 mips32_op = OPC_MTHC1;
10410 gen_cp1(ctx, mips32_op, rt, rs);
10413 /* Reciprocal square root */
10414 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10415 mips32_op = OPC_RSQRT_S;
10417 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10418 mips32_op = OPC_RSQRT_D;
10422 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10423 mips32_op = OPC_SQRT_S;
10425 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10426 mips32_op = OPC_SQRT_D;
10430 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10431 mips32_op = OPC_RECIP_S;
10433 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10434 mips32_op = OPC_RECIP_D;
10438 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10439 mips32_op = OPC_FLOOR_L_S;
10441 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10442 mips32_op = OPC_FLOOR_L_D;
10444 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10445 mips32_op = OPC_FLOOR_W_S;
10447 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10448 mips32_op = OPC_FLOOR_W_D;
10452 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10453 mips32_op = OPC_CEIL_L_S;
10455 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10456 mips32_op = OPC_CEIL_L_D;
10458 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10459 mips32_op = OPC_CEIL_W_S;
10461 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10462 mips32_op = OPC_CEIL_W_D;
10466 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10467 mips32_op = OPC_TRUNC_L_S;
10469 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10470 mips32_op = OPC_TRUNC_L_D;
10472 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10473 mips32_op = OPC_TRUNC_W_S;
10475 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10476 mips32_op = OPC_TRUNC_W_D;
10480 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10481 mips32_op = OPC_ROUND_L_S;
10483 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10484 mips32_op = OPC_ROUND_L_D;
10486 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10487 mips32_op = OPC_ROUND_W_S;
10489 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10490 mips32_op = OPC_ROUND_W_D;
10493 /* Integer to floating-point conversion */
10494 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10495 mips32_op = OPC_CVT_L_S;
10497 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10498 mips32_op = OPC_CVT_L_D;
10500 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10501 mips32_op = OPC_CVT_W_S;
10503 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10504 mips32_op = OPC_CVT_W_D;
10507 /* Paired-foo conversions */
10508 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10509 mips32_op = OPC_CVT_S_PL;
10511 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10512 mips32_op = OPC_CVT_S_PU;
10514 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10515 mips32_op = OPC_CVT_PW_PS;
10517 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10518 mips32_op = OPC_CVT_PS_PW;
10521 /* Floating-point moves */
10522 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10523 mips32_op = OPC_MOV_S;
10525 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10526 mips32_op = OPC_MOV_D;
10528 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10529 mips32_op = OPC_MOV_PS;
10532 /* Absolute value */
10533 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10534 mips32_op = OPC_ABS_S;
10536 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10537 mips32_op = OPC_ABS_D;
10539 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10540 mips32_op = OPC_ABS_PS;
10544 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10545 mips32_op = OPC_NEG_S;
10547 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10548 mips32_op = OPC_NEG_D;
10550 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10551 mips32_op = OPC_NEG_PS;
10554 /* Reciprocal square root step */
10555 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10556 mips32_op = OPC_RSQRT1_S;
10558 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10559 mips32_op = OPC_RSQRT1_D;
10561 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10562 mips32_op = OPC_RSQRT1_PS;
10565 /* Reciprocal step */
10566 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10567 mips32_op = OPC_RECIP1_S;
10569 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10570 mips32_op = OPC_RECIP1_S;
10572 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10573 mips32_op = OPC_RECIP1_PS;
10576 /* Conversions from double */
10577 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10578 mips32_op = OPC_CVT_D_S;
10580 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10581 mips32_op = OPC_CVT_D_W;
10583 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10584 mips32_op = OPC_CVT_D_L;
10587 /* Conversions from single */
10588 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10589 mips32_op = OPC_CVT_S_D;
10591 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10592 mips32_op = OPC_CVT_S_W;
10594 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10595 mips32_op = OPC_CVT_S_L;
10597 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10600 /* Conditional moves on floating-point codes */
10601 case COND_FLOAT_MOV(MOVT, 0):
10602 case COND_FLOAT_MOV(MOVT, 1):
10603 case COND_FLOAT_MOV(MOVT, 2):
10604 case COND_FLOAT_MOV(MOVT, 3):
10605 case COND_FLOAT_MOV(MOVT, 4):
10606 case COND_FLOAT_MOV(MOVT, 5):
10607 case COND_FLOAT_MOV(MOVT, 6):
10608 case COND_FLOAT_MOV(MOVT, 7):
10609 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
10611 case COND_FLOAT_MOV(MOVF, 0):
10612 case COND_FLOAT_MOV(MOVF, 1):
10613 case COND_FLOAT_MOV(MOVF, 2):
10614 case COND_FLOAT_MOV(MOVF, 3):
10615 case COND_FLOAT_MOV(MOVF, 4):
10616 case COND_FLOAT_MOV(MOVF, 5):
10617 case COND_FLOAT_MOV(MOVF, 6):
10618 case COND_FLOAT_MOV(MOVF, 7):
10619 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
10622 MIPS_INVAL("pool32fxf");
10623 generate_exception(ctx, EXCP_RI);
10628 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
10629 uint16_t insn_hw1, int *is_branch)
10633 int rt, rs, rd, rr;
10635 uint32_t op, minor, mips32_op;
10636 uint32_t cond, fmt, cc;
10638 insn = lduw_code(ctx->pc + 2);
10639 ctx->opcode = (ctx->opcode << 16) | insn;
10641 rt = (ctx->opcode >> 21) & 0x1f;
10642 rs = (ctx->opcode >> 16) & 0x1f;
10643 rd = (ctx->opcode >> 11) & 0x1f;
10644 rr = (ctx->opcode >> 6) & 0x1f;
10645 imm = (int16_t) ctx->opcode;
10647 op = (ctx->opcode >> 26) & 0x3f;
10650 minor = ctx->opcode & 0x3f;
10653 minor = (ctx->opcode >> 6) & 0xf;
10656 mips32_op = OPC_SLL;
10659 mips32_op = OPC_SRA;
10662 mips32_op = OPC_SRL;
10665 mips32_op = OPC_ROTR;
10667 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10670 goto pool32a_invalid;
10674 minor = (ctx->opcode >> 6) & 0xf;
10678 mips32_op = OPC_ADD;
10681 mips32_op = OPC_ADDU;
10684 mips32_op = OPC_SUB;
10687 mips32_op = OPC_SUBU;
10690 mips32_op = OPC_MUL;
10692 gen_arith(env, ctx, mips32_op, rd, rs, rt);
10696 mips32_op = OPC_SLLV;
10699 mips32_op = OPC_SRLV;
10702 mips32_op = OPC_SRAV;
10705 mips32_op = OPC_ROTRV;
10707 gen_shift(env, ctx, mips32_op, rd, rs, rt);
10709 /* Logical operations */
10711 mips32_op = OPC_AND;
10714 mips32_op = OPC_OR;
10717 mips32_op = OPC_NOR;
10720 mips32_op = OPC_XOR;
10722 gen_logic(env, mips32_op, rd, rs, rt);
10724 /* Set less than */
10726 mips32_op = OPC_SLT;
10729 mips32_op = OPC_SLTU;
10731 gen_slt(env, mips32_op, rd, rs, rt);
10734 goto pool32a_invalid;
10738 minor = (ctx->opcode >> 6) & 0xf;
10740 /* Conditional moves */
10742 mips32_op = OPC_MOVN;
10745 mips32_op = OPC_MOVZ;
10747 gen_cond_move(env, mips32_op, rd, rs, rt);
10750 gen_ldxs(ctx, rs, rt, rd);
10753 goto pool32a_invalid;
10757 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10760 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10763 gen_pool32axf(env, ctx, rt, rs, is_branch);
10766 generate_exception(ctx, EXCP_BREAK);
10770 MIPS_INVAL("pool32a");
10771 generate_exception(ctx, EXCP_RI);
10776 minor = (ctx->opcode >> 12) & 0xf;
10779 check_cp0_enabled(ctx);
10780 /* Treat as no-op. */
10784 /* COP2: Not implemented. */
10785 generate_exception_err(ctx, EXCP_CpU, 2);
10789 #ifdef TARGET_MIPS64
10793 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10797 #ifdef TARGET_MIPS64
10801 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10804 MIPS_INVAL("pool32b");
10805 generate_exception(ctx, EXCP_RI);
10810 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10811 minor = ctx->opcode & 0x3f;
10812 check_cp1_enabled(ctx);
10815 mips32_op = OPC_ALNV_PS;
10818 mips32_op = OPC_MADD_S;
10821 mips32_op = OPC_MADD_D;
10824 mips32_op = OPC_MADD_PS;
10827 mips32_op = OPC_MSUB_S;
10830 mips32_op = OPC_MSUB_D;
10833 mips32_op = OPC_MSUB_PS;
10836 mips32_op = OPC_NMADD_S;
10839 mips32_op = OPC_NMADD_D;
10842 mips32_op = OPC_NMADD_PS;
10845 mips32_op = OPC_NMSUB_S;
10848 mips32_op = OPC_NMSUB_D;
10851 mips32_op = OPC_NMSUB_PS;
10853 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10855 case CABS_COND_FMT:
10856 cond = (ctx->opcode >> 6) & 0xf;
10857 cc = (ctx->opcode >> 13) & 0x7;
10858 fmt = (ctx->opcode >> 10) & 0x3;
10861 gen_cmpabs_s(ctx, cond, rt, rs, cc);
10864 gen_cmpabs_d(ctx, cond, rt, rs, cc);
10867 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10870 goto pool32f_invalid;
10874 cond = (ctx->opcode >> 6) & 0xf;
10875 cc = (ctx->opcode >> 13) & 0x7;
10876 fmt = (ctx->opcode >> 10) & 0x3;
10879 gen_cmp_s(ctx, cond, rt, rs, cc);
10882 gen_cmp_d(ctx, cond, rt, rs, cc);
10885 gen_cmp_ps(ctx, cond, rt, rs, cc);
10888 goto pool32f_invalid;
10892 gen_pool32fxf(env, ctx, rt, rs);
10896 switch ((ctx->opcode >> 6) & 0x7) {
10898 mips32_op = OPC_PLL_PS;
10901 mips32_op = OPC_PLU_PS;
10904 mips32_op = OPC_PUL_PS;
10907 mips32_op = OPC_PUU_PS;
10910 mips32_op = OPC_CVT_PS_S;
10912 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10915 goto pool32f_invalid;
10920 switch ((ctx->opcode >> 6) & 0x7) {
10922 mips32_op = OPC_LWXC1;
10925 mips32_op = OPC_SWXC1;
10928 mips32_op = OPC_LDXC1;
10931 mips32_op = OPC_SDXC1;
10934 mips32_op = OPC_LUXC1;
10937 mips32_op = OPC_SUXC1;
10939 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10942 goto pool32f_invalid;
10947 fmt = (ctx->opcode >> 9) & 0x3;
10948 switch ((ctx->opcode >> 6) & 0x7) {
10952 mips32_op = OPC_RSQRT2_S;
10955 mips32_op = OPC_RSQRT2_D;
10958 mips32_op = OPC_RSQRT2_PS;
10961 goto pool32f_invalid;
10967 mips32_op = OPC_RECIP2_S;
10970 mips32_op = OPC_RECIP2_D;
10973 mips32_op = OPC_RECIP2_PS;
10976 goto pool32f_invalid;
10980 mips32_op = OPC_ADDR_PS;
10983 mips32_op = OPC_MULR_PS;
10985 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10988 goto pool32f_invalid;
10992 /* MOV[FT].fmt and PREFX */
10993 cc = (ctx->opcode >> 13) & 0x7;
10994 fmt = (ctx->opcode >> 9) & 0x3;
10995 switch ((ctx->opcode >> 6) & 0x7) {
10999 gen_movcf_s(rs, rt, cc, 0);
11002 gen_movcf_d(ctx, rs, rt, cc, 0);
11005 gen_movcf_ps(rs, rt, cc, 0);
11008 goto pool32f_invalid;
11014 gen_movcf_s(rs, rt, cc, 1);
11017 gen_movcf_d(ctx, rs, rt, cc, 1);
11020 gen_movcf_ps(rs, rt, cc, 1);
11023 goto pool32f_invalid;
11029 goto pool32f_invalid;
11032 #define FINSN_3ARG_SDPS(prfx) \
11033 switch ((ctx->opcode >> 8) & 0x3) { \
11035 mips32_op = OPC_##prfx##_S; \
11038 mips32_op = OPC_##prfx##_D; \
11040 case FMT_SDPS_PS: \
11041 mips32_op = OPC_##prfx##_PS; \
11044 goto pool32f_invalid; \
11047 /* regular FP ops */
11048 switch ((ctx->opcode >> 6) & 0x3) {
11050 FINSN_3ARG_SDPS(ADD);
11053 FINSN_3ARG_SDPS(SUB);
11056 FINSN_3ARG_SDPS(MUL);
11059 fmt = (ctx->opcode >> 8) & 0x3;
11061 mips32_op = OPC_DIV_D;
11062 } else if (fmt == 0) {
11063 mips32_op = OPC_DIV_S;
11065 goto pool32f_invalid;
11069 goto pool32f_invalid;
11074 switch ((ctx->opcode >> 6) & 0x3) {
11076 FINSN_3ARG_SDPS(MOVN);
11079 FINSN_3ARG_SDPS(MOVZ);
11082 goto pool32f_invalid;
11086 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11090 MIPS_INVAL("pool32f");
11091 generate_exception(ctx, EXCP_RI);
11095 generate_exception_err(ctx, EXCP_CpU, 1);
11099 minor = (ctx->opcode >> 21) & 0x1f;
11102 mips32_op = OPC_BLTZ;
11105 mips32_op = OPC_BLTZAL;
11108 mips32_op = OPC_BLTZALS;
11111 mips32_op = OPC_BGEZ;
11114 mips32_op = OPC_BGEZAL;
11117 mips32_op = OPC_BGEZALS;
11120 mips32_op = OPC_BLEZ;
11123 mips32_op = OPC_BGTZ;
11125 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
11131 mips32_op = OPC_TLTI;
11134 mips32_op = OPC_TGEI;
11137 mips32_op = OPC_TLTIU;
11140 mips32_op = OPC_TGEIU;
11143 mips32_op = OPC_TNEI;
11146 mips32_op = OPC_TEQI;
11148 gen_trap(ctx, mips32_op, rs, -1, imm);
11153 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
11154 4, rs, 0, imm << 1);
11155 /* Compact branches don't have a delay slot, so just let
11156 the normal delay slot handling take us to the branch
11160 gen_logic_imm(env, OPC_LUI, rs, -1, imm);
11166 /* COP2: Not implemented. */
11167 generate_exception_err(ctx, EXCP_CpU, 2);
11170 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
11173 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
11176 mips32_op = OPC_BC1FANY4;
11179 mips32_op = OPC_BC1TANY4;
11182 check_insn(env, ctx, ASE_MIPS3D);
11185 gen_compute_branch1(env, ctx, mips32_op,
11186 (ctx->opcode >> 18) & 0x7, imm << 1);
11191 /* MIPS DSP: not implemented */
11194 MIPS_INVAL("pool32i");
11195 generate_exception(ctx, EXCP_RI);
11200 minor = (ctx->opcode >> 12) & 0xf;
11203 mips32_op = OPC_LWL;
11206 mips32_op = OPC_SWL;
11209 mips32_op = OPC_LWR;
11212 mips32_op = OPC_SWR;
11214 #if defined(TARGET_MIPS64)
11216 mips32_op = OPC_LDL;
11219 mips32_op = OPC_SDL;
11222 mips32_op = OPC_LDR;
11225 mips32_op = OPC_SDR;
11228 mips32_op = OPC_LWU;
11231 mips32_op = OPC_LLD;
11235 mips32_op = OPC_LL;
11238 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11241 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11244 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
11246 #if defined(TARGET_MIPS64)
11248 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
11252 /* Treat as no-op */
11255 MIPS_INVAL("pool32c");
11256 generate_exception(ctx, EXCP_RI);
11261 mips32_op = OPC_ADDI;
11264 mips32_op = OPC_ADDIU;
11266 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
11269 /* Logical operations */
11271 mips32_op = OPC_ORI;
11274 mips32_op = OPC_XORI;
11277 mips32_op = OPC_ANDI;
11279 gen_logic_imm(env, mips32_op, rt, rs, imm);
11282 /* Set less than immediate */
11284 mips32_op = OPC_SLTI;
11287 mips32_op = OPC_SLTIU;
11289 gen_slt_imm(env, mips32_op, rt, rs, imm);
11292 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11293 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
11297 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
11298 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
11302 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
11306 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
11310 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
11311 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11315 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
11316 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11319 /* Floating point (COP1) */
11321 mips32_op = OPC_LWC1;
11324 mips32_op = OPC_LDC1;
11327 mips32_op = OPC_SWC1;
11330 mips32_op = OPC_SDC1;
11332 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
11336 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
11337 int offset = SIMM(ctx->opcode, 0, 23) << 2;
11339 gen_addiupc(ctx, reg, offset, 0, 0);
11342 /* Loads and stores */
11344 mips32_op = OPC_LB;
11347 mips32_op = OPC_LBU;
11350 mips32_op = OPC_LH;
11353 mips32_op = OPC_LHU;
11356 mips32_op = OPC_LW;
11358 #ifdef TARGET_MIPS64
11360 mips32_op = OPC_LD;
11363 mips32_op = OPC_SD;
11367 mips32_op = OPC_SB;
11370 mips32_op = OPC_SH;
11373 mips32_op = OPC_SW;
11376 gen_ld(env, ctx, mips32_op, rt, rs, imm);
11379 gen_st(ctx, mips32_op, rt, rs, imm);
11382 generate_exception(ctx, EXCP_RI);
11387 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
11391 /* make sure instructions are on a halfword boundary */
11392 if (ctx->pc & 0x1) {
11393 env->CP0_BadVAddr = ctx->pc;
11394 generate_exception(ctx, EXCP_AdEL);
11395 ctx->bstate = BS_STOP;
11399 op = (ctx->opcode >> 10) & 0x3f;
11400 /* Enforce properly-sized instructions in a delay slot */
11401 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11402 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
11436 case POOL48A: /* ??? */
11441 if (bits & MIPS_HFLAG_BDS16) {
11442 generate_exception(ctx, EXCP_RI);
11443 /* Just stop translation; the user is confused. */
11444 ctx->bstate = BS_STOP;
11469 if (bits & MIPS_HFLAG_BDS32) {
11470 generate_exception(ctx, EXCP_RI);
11471 /* Just stop translation; the user is confused. */
11472 ctx->bstate = BS_STOP;
11483 int rd = mmreg(uMIPS_RD(ctx->opcode));
11484 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11485 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11488 switch (ctx->opcode & 0x1) {
11497 gen_arith(env, ctx, opc, rd, rs1, rs2);
11502 int rd = mmreg(uMIPS_RD(ctx->opcode));
11503 int rs = mmreg(uMIPS_RS(ctx->opcode));
11504 int amount = (ctx->opcode >> 1) & 0x7;
11506 amount = amount == 0 ? 8 : amount;
11508 switch (ctx->opcode & 0x1) {
11517 gen_shift_imm(env, ctx, opc, rd, rs, amount);
11521 gen_pool16c_insn(env, ctx, is_branch);
11525 int rd = mmreg(uMIPS_RD(ctx->opcode));
11526 int rb = 28; /* GP */
11527 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11529 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11533 if (ctx->opcode & 1) {
11534 generate_exception(ctx, EXCP_RI);
11537 int enc_dest = uMIPS_RD(ctx->opcode);
11538 int enc_rt = uMIPS_RS2(ctx->opcode);
11539 int enc_rs = uMIPS_RS1(ctx->opcode);
11540 int rd, rs, re, rt;
11541 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11542 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11543 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11545 rd = rd_enc[enc_dest];
11546 re = re_enc[enc_dest];
11547 rs = rs_rt_enc[enc_rs];
11548 rt = rs_rt_enc[enc_rt];
11550 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11551 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11556 int rd = mmreg(uMIPS_RD(ctx->opcode));
11557 int rb = mmreg(uMIPS_RS(ctx->opcode));
11558 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11559 offset = (offset == 0xf ? -1 : offset);
11561 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
11566 int rd = mmreg(uMIPS_RD(ctx->opcode));
11567 int rb = mmreg(uMIPS_RS(ctx->opcode));
11568 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11570 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
11575 int rd = (ctx->opcode >> 5) & 0x1f;
11576 int rb = 29; /* SP */
11577 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11579 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11584 int rd = mmreg(uMIPS_RD(ctx->opcode));
11585 int rb = mmreg(uMIPS_RS(ctx->opcode));
11586 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11588 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11593 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11594 int rb = mmreg(uMIPS_RS(ctx->opcode));
11595 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11597 gen_st(ctx, OPC_SB, rd, rb, offset);
11602 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11603 int rb = mmreg(uMIPS_RS(ctx->opcode));
11604 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11606 gen_st(ctx, OPC_SH, rd, rb, offset);
11611 int rd = (ctx->opcode >> 5) & 0x1f;
11612 int rb = 29; /* SP */
11613 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11615 gen_st(ctx, OPC_SW, rd, rb, offset);
11620 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11621 int rb = mmreg(uMIPS_RS(ctx->opcode));
11622 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11624 gen_st(ctx, OPC_SW, rd, rb, offset);
11629 int rd = uMIPS_RD5(ctx->opcode);
11630 int rs = uMIPS_RS5(ctx->opcode);
11632 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11636 gen_andi16(env, ctx);
11639 switch (ctx->opcode & 0x1) {
11641 gen_addius5(env, ctx);
11644 gen_addiusp(env, ctx);
11649 switch (ctx->opcode & 0x1) {
11651 gen_addiur2(env, ctx);
11654 gen_addiur1sp(env, ctx);
11659 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11660 SIMM(ctx->opcode, 0, 10) << 1);
11665 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
11666 mmreg(uMIPS_RD(ctx->opcode)),
11667 0, SIMM(ctx->opcode, 0, 7) << 1);
11672 int reg = mmreg(uMIPS_RD(ctx->opcode));
11673 int imm = ZIMM(ctx->opcode, 0, 7);
11675 imm = (imm == 0x7f ? -1 : imm);
11676 tcg_gen_movi_tl(cpu_gpr[reg], imm);
11686 generate_exception(ctx, EXCP_RI);
11689 decode_micromips32_opc (env, ctx, op, is_branch);
11696 /* SmartMIPS extension to MIPS32 */
11698 #if defined(TARGET_MIPS64)
11700 /* MDMX extension to MIPS64 */
11704 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
11707 int rs, rt, rd, sa;
11708 uint32_t op, op1, op2;
11711 /* make sure instructions are on a word boundary */
11712 if (ctx->pc & 0x3) {
11713 env->CP0_BadVAddr = ctx->pc;
11714 generate_exception(ctx, EXCP_AdEL);
11718 /* Handle blikely not taken case */
11719 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11720 int l1 = gen_new_label();
11722 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
11723 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11724 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
11725 gen_goto_tb(ctx, 1, ctx->pc + 4);
11729 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11730 tcg_gen_debug_insn_start(ctx->pc);
11732 op = MASK_OP_MAJOR(ctx->opcode);
11733 rs = (ctx->opcode >> 21) & 0x1f;
11734 rt = (ctx->opcode >> 16) & 0x1f;
11735 rd = (ctx->opcode >> 11) & 0x1f;
11736 sa = (ctx->opcode >> 6) & 0x1f;
11737 imm = (int16_t)ctx->opcode;
11740 op1 = MASK_SPECIAL(ctx->opcode);
11742 case OPC_SLL: /* Shift with immediate */
11744 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11747 switch ((ctx->opcode >> 21) & 0x1f) {
11749 /* rotr is decoded as srl on non-R2 CPUs */
11750 if (env->insn_flags & ISA_MIPS32R2) {
11755 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11758 generate_exception(ctx, EXCP_RI);
11762 case OPC_MOVN: /* Conditional move */
11764 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11765 INSN_LOONGSON2E | INSN_LOONGSON2F);
11766 gen_cond_move(env, op1, rd, rs, rt);
11768 case OPC_ADD ... OPC_SUBU:
11769 gen_arith(env, ctx, op1, rd, rs, rt);
11771 case OPC_SLLV: /* Shifts */
11773 gen_shift(env, ctx, op1, rd, rs, rt);
11776 switch ((ctx->opcode >> 6) & 0x1f) {
11778 /* rotrv is decoded as srlv on non-R2 CPUs */
11779 if (env->insn_flags & ISA_MIPS32R2) {
11784 gen_shift(env, ctx, op1, rd, rs, rt);
11787 generate_exception(ctx, EXCP_RI);
11791 case OPC_SLT: /* Set on less than */
11793 gen_slt(env, op1, rd, rs, rt);
11795 case OPC_AND: /* Logic*/
11799 gen_logic(env, op1, rd, rs, rt);
11801 case OPC_MULT ... OPC_DIVU:
11803 check_insn(env, ctx, INSN_VR54XX);
11804 op1 = MASK_MUL_VR54XX(ctx->opcode);
11805 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11807 gen_muldiv(ctx, op1, rs, rt);
11809 case OPC_JR ... OPC_JALR:
11810 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11813 case OPC_TGE ... OPC_TEQ: /* Traps */
11815 gen_trap(ctx, op1, rs, rt, -1);
11817 case OPC_MFHI: /* Move from HI/LO */
11819 gen_HILO(ctx, op1, rd);
11822 case OPC_MTLO: /* Move to HI/LO */
11823 gen_HILO(ctx, op1, rs);
11825 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
11826 #ifdef MIPS_STRICT_STANDARD
11827 MIPS_INVAL("PMON / selsl");
11828 generate_exception(ctx, EXCP_RI);
11830 gen_helper_0i(pmon, sa);
11834 generate_exception(ctx, EXCP_SYSCALL);
11835 ctx->bstate = BS_STOP;
11838 generate_exception(ctx, EXCP_BREAK);
11841 #ifdef MIPS_STRICT_STANDARD
11842 MIPS_INVAL("SPIM");
11843 generate_exception(ctx, EXCP_RI);
11845 /* Implemented as RI exception for now. */
11846 MIPS_INVAL("spim (unofficial)");
11847 generate_exception(ctx, EXCP_RI);
11851 /* Treat as NOP. */
11855 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11856 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11857 check_cp1_enabled(ctx);
11858 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
11859 (ctx->opcode >> 16) & 1);
11861 generate_exception_err(ctx, EXCP_CpU, 1);
11865 #if defined(TARGET_MIPS64)
11866 /* MIPS64 specific opcodes */
11871 check_insn(env, ctx, ISA_MIPS3);
11872 check_mips_64(ctx);
11873 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11876 switch ((ctx->opcode >> 21) & 0x1f) {
11878 /* drotr is decoded as dsrl on non-R2 CPUs */
11879 if (env->insn_flags & ISA_MIPS32R2) {
11884 check_insn(env, ctx, ISA_MIPS3);
11885 check_mips_64(ctx);
11886 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11889 generate_exception(ctx, EXCP_RI);
11894 switch ((ctx->opcode >> 21) & 0x1f) {
11896 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11897 if (env->insn_flags & ISA_MIPS32R2) {
11902 check_insn(env, ctx, ISA_MIPS3);
11903 check_mips_64(ctx);
11904 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11907 generate_exception(ctx, EXCP_RI);
11911 case OPC_DADD ... OPC_DSUBU:
11912 check_insn(env, ctx, ISA_MIPS3);
11913 check_mips_64(ctx);
11914 gen_arith(env, ctx, op1, rd, rs, rt);
11918 check_insn(env, ctx, ISA_MIPS3);
11919 check_mips_64(ctx);
11920 gen_shift(env, ctx, op1, rd, rs, rt);
11923 switch ((ctx->opcode >> 6) & 0x1f) {
11925 /* drotrv is decoded as dsrlv on non-R2 CPUs */
11926 if (env->insn_flags & ISA_MIPS32R2) {
11931 check_insn(env, ctx, ISA_MIPS3);
11932 check_mips_64(ctx);
11933 gen_shift(env, ctx, op1, rd, rs, rt);
11936 generate_exception(ctx, EXCP_RI);
11940 case OPC_DMULT ... OPC_DDIVU:
11941 check_insn(env, ctx, ISA_MIPS3);
11942 check_mips_64(ctx);
11943 gen_muldiv(ctx, op1, rs, rt);
11946 default: /* Invalid */
11947 MIPS_INVAL("special");
11948 generate_exception(ctx, EXCP_RI);
11953 op1 = MASK_SPECIAL2(ctx->opcode);
11955 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
11956 case OPC_MSUB ... OPC_MSUBU:
11957 check_insn(env, ctx, ISA_MIPS32);
11958 gen_muldiv(ctx, op1, rs, rt);
11961 gen_arith(env, ctx, op1, rd, rs, rt);
11965 check_insn(env, ctx, ISA_MIPS32);
11966 gen_cl(ctx, op1, rd, rs);
11969 /* XXX: not clear which exception should be raised
11970 * when in debug mode...
11972 check_insn(env, ctx, ISA_MIPS32);
11973 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11974 generate_exception(ctx, EXCP_DBp);
11976 generate_exception(ctx, EXCP_DBp);
11978 /* Treat as NOP. */
11981 case OPC_DIVU_G_2F:
11982 case OPC_MULT_G_2F:
11983 case OPC_MULTU_G_2F:
11985 case OPC_MODU_G_2F:
11986 check_insn(env, ctx, INSN_LOONGSON2F);
11987 gen_loongson_integer(ctx, op1, rd, rs, rt);
11989 #if defined(TARGET_MIPS64)
11992 check_insn(env, ctx, ISA_MIPS64);
11993 check_mips_64(ctx);
11994 gen_cl(ctx, op1, rd, rs);
11996 case OPC_DMULT_G_2F:
11997 case OPC_DMULTU_G_2F:
11998 case OPC_DDIV_G_2F:
11999 case OPC_DDIVU_G_2F:
12000 case OPC_DMOD_G_2F:
12001 case OPC_DMODU_G_2F:
12002 check_insn(env, ctx, INSN_LOONGSON2F);
12003 gen_loongson_integer(ctx, op1, rd, rs, rt);
12006 default: /* Invalid */
12007 MIPS_INVAL("special2");
12008 generate_exception(ctx, EXCP_RI);
12013 op1 = MASK_SPECIAL3(ctx->opcode);
12017 check_insn(env, ctx, ISA_MIPS32R2);
12018 gen_bitops(ctx, op1, rt, rs, sa, rd);
12021 check_insn(env, ctx, ISA_MIPS32R2);
12022 op2 = MASK_BSHFL(ctx->opcode);
12023 gen_bshfl(ctx, op2, rt, rd);
12026 gen_rdhwr(env, ctx, rt, rd);
12029 check_insn(env, ctx, ASE_MT);
12031 TCGv t0 = tcg_temp_new();
12032 TCGv t1 = tcg_temp_new();
12034 gen_load_gpr(t0, rt);
12035 gen_load_gpr(t1, rs);
12036 gen_helper_fork(t0, t1);
12042 check_insn(env, ctx, ASE_MT);
12044 TCGv t0 = tcg_temp_new();
12046 save_cpu_state(ctx, 1);
12047 gen_load_gpr(t0, rs);
12048 gen_helper_yield(t0, t0);
12049 gen_store_gpr(t0, rd);
12053 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
12054 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
12055 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
12056 check_insn(env, ctx, INSN_LOONGSON2E);
12057 gen_loongson_integer(ctx, op1, rd, rs, rt);
12059 #if defined(TARGET_MIPS64)
12060 case OPC_DEXTM ... OPC_DEXT:
12061 case OPC_DINSM ... OPC_DINS:
12062 check_insn(env, ctx, ISA_MIPS64R2);
12063 check_mips_64(ctx);
12064 gen_bitops(ctx, op1, rt, rs, sa, rd);
12067 check_insn(env, ctx, ISA_MIPS64R2);
12068 check_mips_64(ctx);
12069 op2 = MASK_DBSHFL(ctx->opcode);
12070 gen_bshfl(ctx, op2, rt, rd);
12072 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
12073 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
12074 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
12075 check_insn(env, ctx, INSN_LOONGSON2E);
12076 gen_loongson_integer(ctx, op1, rd, rs, rt);
12079 default: /* Invalid */
12080 MIPS_INVAL("special3");
12081 generate_exception(ctx, EXCP_RI);
12086 op1 = MASK_REGIMM(ctx->opcode);
12088 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
12089 case OPC_BLTZAL ... OPC_BGEZALL:
12090 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
12093 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
12095 gen_trap(ctx, op1, rs, -1, imm);
12098 check_insn(env, ctx, ISA_MIPS32R2);
12099 /* Treat as NOP. */
12101 default: /* Invalid */
12102 MIPS_INVAL("regimm");
12103 generate_exception(ctx, EXCP_RI);
12108 check_cp0_enabled(ctx);
12109 op1 = MASK_CP0(ctx->opcode);
12115 #if defined(TARGET_MIPS64)
12119 #ifndef CONFIG_USER_ONLY
12120 gen_cp0(env, ctx, op1, rt, rd);
12121 #endif /* !CONFIG_USER_ONLY */
12123 case OPC_C0_FIRST ... OPC_C0_LAST:
12124 #ifndef CONFIG_USER_ONLY
12125 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
12126 #endif /* !CONFIG_USER_ONLY */
12129 #ifndef CONFIG_USER_ONLY
12131 TCGv t0 = tcg_temp_new();
12133 op2 = MASK_MFMC0(ctx->opcode);
12136 check_insn(env, ctx, ASE_MT);
12137 gen_helper_dmt(t0);
12138 gen_store_gpr(t0, rt);
12141 check_insn(env, ctx, ASE_MT);
12142 gen_helper_emt(t0);
12143 gen_store_gpr(t0, rt);
12146 check_insn(env, ctx, ASE_MT);
12147 gen_helper_dvpe(t0);
12148 gen_store_gpr(t0, rt);
12151 check_insn(env, ctx, ASE_MT);
12152 gen_helper_evpe(t0);
12153 gen_store_gpr(t0, rt);
12156 check_insn(env, ctx, ISA_MIPS32R2);
12157 save_cpu_state(ctx, 1);
12159 gen_store_gpr(t0, rt);
12160 /* Stop translation as we may have switched the execution mode */
12161 ctx->bstate = BS_STOP;
12164 check_insn(env, ctx, ISA_MIPS32R2);
12165 save_cpu_state(ctx, 1);
12167 gen_store_gpr(t0, rt);
12168 /* Stop translation as we may have switched the execution mode */
12169 ctx->bstate = BS_STOP;
12171 default: /* Invalid */
12172 MIPS_INVAL("mfmc0");
12173 generate_exception(ctx, EXCP_RI);
12178 #endif /* !CONFIG_USER_ONLY */
12181 check_insn(env, ctx, ISA_MIPS32R2);
12182 gen_load_srsgpr(rt, rd);
12185 check_insn(env, ctx, ISA_MIPS32R2);
12186 gen_store_srsgpr(rt, rd);
12190 generate_exception(ctx, EXCP_RI);
12194 case OPC_ADDI: /* Arithmetic with immediate opcode */
12196 gen_arith_imm(env, ctx, op, rt, rs, imm);
12198 case OPC_SLTI: /* Set on less than with immediate opcode */
12200 gen_slt_imm(env, op, rt, rs, imm);
12202 case OPC_ANDI: /* Arithmetic with immediate opcode */
12206 gen_logic_imm(env, op, rt, rs, imm);
12208 case OPC_J ... OPC_JAL: /* Jump */
12209 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12210 gen_compute_branch(ctx, op, 4, rs, rt, offset);
12213 case OPC_BEQ ... OPC_BGTZ: /* Branch */
12214 case OPC_BEQL ... OPC_BGTZL:
12215 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
12218 case OPC_LB ... OPC_LWR: /* Load and stores */
12220 gen_ld(env, ctx, op, rt, rs, imm);
12222 case OPC_SB ... OPC_SW:
12224 gen_st(ctx, op, rt, rs, imm);
12227 gen_st_cond(ctx, op, rt, rs, imm);
12230 check_cp0_enabled(ctx);
12231 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
12232 /* Treat as NOP. */
12235 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12236 /* Treat as NOP. */
12239 /* Floating point (COP1). */
12244 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12248 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12249 check_cp1_enabled(ctx);
12250 op1 = MASK_CP1(ctx->opcode);
12254 check_insn(env, ctx, ISA_MIPS32R2);
12259 gen_cp1(ctx, op1, rt, rd);
12261 #if defined(TARGET_MIPS64)
12264 check_insn(env, ctx, ISA_MIPS3);
12265 gen_cp1(ctx, op1, rt, rd);
12271 check_insn(env, ctx, ASE_MIPS3D);
12274 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
12275 (rt >> 2) & 0x7, imm << 2);
12283 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
12288 generate_exception (ctx, EXCP_RI);
12292 generate_exception_err(ctx, EXCP_CpU, 1);
12302 /* COP2: Not implemented. */
12303 generate_exception_err(ctx, EXCP_CpU, 2);
12307 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12308 check_cp1_enabled(ctx);
12309 op1 = MASK_CP3(ctx->opcode);
12317 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
12320 /* Treat as NOP. */
12335 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
12339 generate_exception (ctx, EXCP_RI);
12343 generate_exception_err(ctx, EXCP_CpU, 1);
12347 #if defined(TARGET_MIPS64)
12348 /* MIPS64 opcodes */
12350 case OPC_LDL ... OPC_LDR:
12353 check_insn(env, ctx, ISA_MIPS3);
12354 check_mips_64(ctx);
12355 gen_ld(env, ctx, op, rt, rs, imm);
12357 case OPC_SDL ... OPC_SDR:
12359 check_insn(env, ctx, ISA_MIPS3);
12360 check_mips_64(ctx);
12361 gen_st(ctx, op, rt, rs, imm);
12364 check_insn(env, ctx, ISA_MIPS3);
12365 check_mips_64(ctx);
12366 gen_st_cond(ctx, op, rt, rs, imm);
12370 check_insn(env, ctx, ISA_MIPS3);
12371 check_mips_64(ctx);
12372 gen_arith_imm(env, ctx, op, rt, rs, imm);
12376 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
12377 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12378 gen_compute_branch(ctx, op, 4, rs, rt, offset);
12382 check_insn(env, ctx, ASE_MDMX);
12383 /* MDMX: Not implemented. */
12384 default: /* Invalid */
12385 MIPS_INVAL("major opcode");
12386 generate_exception(ctx, EXCP_RI);
12392 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
12396 target_ulong pc_start;
12397 uint16_t *gen_opc_end;
12406 qemu_log("search pc %d\n", search_pc);
12409 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
12412 ctx.singlestep_enabled = env->singlestep_enabled;
12414 ctx.bstate = BS_NONE;
12415 /* Restore delay slot state from the tb context. */
12416 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
12417 restore_cpu_state(env, &ctx);
12418 #ifdef CONFIG_USER_ONLY
12419 ctx.mem_idx = MIPS_HFLAG_UM;
12421 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
12424 max_insns = tb->cflags & CF_COUNT_MASK;
12425 if (max_insns == 0)
12426 max_insns = CF_COUNT_MASK;
12427 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
12428 gen_icount_start();
12429 while (ctx.bstate == BS_NONE) {
12430 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
12431 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
12432 if (bp->pc == ctx.pc) {
12433 save_cpu_state(&ctx, 1);
12434 ctx.bstate = BS_BRANCH;
12435 gen_helper_0i(raise_exception, EXCP_DEBUG);
12436 /* Include the breakpoint location or the tb won't
12437 * be flushed when it must be. */
12439 goto done_generating;
12445 j = gen_opc_ptr - gen_opc_buf;
12449 gen_opc_instr_start[lj++] = 0;
12451 gen_opc_pc[lj] = ctx.pc;
12452 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12453 gen_opc_instr_start[lj] = 1;
12454 gen_opc_icount[lj] = num_insns;
12456 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12460 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12461 ctx.opcode = ldl_code(ctx.pc);
12463 decode_opc(env, &ctx, &is_branch);
12464 } else if (env->insn_flags & ASE_MICROMIPS) {
12465 ctx.opcode = lduw_code(ctx.pc);
12466 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12467 } else if (env->insn_flags & ASE_MIPS16) {
12468 ctx.opcode = lduw_code(ctx.pc);
12469 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12471 generate_exception(&ctx, EXCP_RI);
12472 ctx.bstate = BS_STOP;
12476 handle_delay_slot(env, &ctx, insn_bytes);
12478 ctx.pc += insn_bytes;
12482 /* Execute a branch and its delay slot as a single instruction.
12483 This is what GDB expects and is consistent with what the
12484 hardware does (e.g. if a delay slot instruction faults, the
12485 reported PC is the PC of the branch). */
12486 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12489 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12492 if (gen_opc_ptr >= gen_opc_end)
12495 if (num_insns >= max_insns)
12501 if (tb->cflags & CF_LAST_IO)
12503 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12504 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12505 gen_helper_0i(raise_exception, EXCP_DEBUG);
12507 switch (ctx.bstate) {
12509 gen_goto_tb(&ctx, 0, ctx.pc);
12512 save_cpu_state(&ctx, 0);
12513 gen_goto_tb(&ctx, 0, ctx.pc);
12516 tcg_gen_exit_tb(0);
12524 gen_icount_end(tb, num_insns);
12525 *gen_opc_ptr = INDEX_op_end;
12527 j = gen_opc_ptr - gen_opc_buf;
12530 gen_opc_instr_start[lj++] = 0;
12532 tb->size = ctx.pc - pc_start;
12533 tb->icount = num_insns;
12537 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12538 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12539 log_target_disas(pc_start, ctx.pc - pc_start, 0);
12545 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
12547 gen_intermediate_code_internal(env, tb, 0);
12550 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
12552 gen_intermediate_code_internal(env, tb, 1);
12555 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
12559 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12561 #define printfpr(fp) \
12564 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12565 " fd:%13g fs:%13g psu: %13g\n", \
12566 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
12567 (double)(fp)->fd, \
12568 (double)(fp)->fs[FP_ENDIAN_IDX], \
12569 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
12572 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
12573 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
12574 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12575 " fd:%13g fs:%13g psu:%13g\n", \
12576 tmp.w[FP_ENDIAN_IDX], tmp.d, \
12578 (double)tmp.fs[FP_ENDIAN_IDX], \
12579 (double)tmp.fs[!FP_ENDIAN_IDX]); \
12584 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
12585 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
12586 get_float_exception_flags(&env->active_fpu.fp_status));
12587 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12588 fpu_fprintf(f, "%3s: ", fregnames[i]);
12589 printfpr(&env->active_fpu.fpr[i]);
12595 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12596 /* Debug help: The architecture requires 32bit code to maintain proper
12597 sign-extended values on 64bit machines. */
12599 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12602 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
12603 fprintf_function cpu_fprintf,
12608 if (!SIGN_EXT_P(env->active_tc.PC))
12609 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12610 if (!SIGN_EXT_P(env->active_tc.HI[0]))
12611 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12612 if (!SIGN_EXT_P(env->active_tc.LO[0]))
12613 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12614 if (!SIGN_EXT_P(env->btarget))
12615 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12617 for (i = 0; i < 32; i++) {
12618 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12619 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12622 if (!SIGN_EXT_P(env->CP0_EPC))
12623 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12624 if (!SIGN_EXT_P(env->lladdr))
12625 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12629 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
12634 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
12635 " LO=0x" TARGET_FMT_lx " ds %04x "
12636 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
12637 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
12638 env->hflags, env->btarget, env->bcond);
12639 for (i = 0; i < 32; i++) {
12641 cpu_fprintf(f, "GPR%02d:", i);
12642 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12644 cpu_fprintf(f, "\n");
12647 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
12648 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
12649 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
12650 env->CP0_Config0, env->CP0_Config1, env->lladdr);
12651 if (env->hflags & MIPS_HFLAG_FPU)
12652 fpu_dump_state(env, f, cpu_fprintf, flags);
12653 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12654 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
12658 static void mips_tcg_init(void)
12663 /* Initialize various static tables. */
12667 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
12668 TCGV_UNUSED(cpu_gpr[0]);
12669 for (i = 1; i < 32; i++)
12670 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
12671 offsetof(CPUMIPSState, active_tc.gpr[i]),
12673 cpu_PC = tcg_global_mem_new(TCG_AREG0,
12674 offsetof(CPUMIPSState, active_tc.PC), "PC");
12675 for (i = 0; i < MIPS_DSP_ACC; i++) {
12676 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
12677 offsetof(CPUMIPSState, active_tc.HI[i]),
12679 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12680 offsetof(CPUMIPSState, active_tc.LO[i]),
12682 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12683 offsetof(CPUMIPSState, active_tc.ACX[i]),
12686 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12687 offsetof(CPUMIPSState, active_tc.DSPControl),
12689 bcond = tcg_global_mem_new(TCG_AREG0,
12690 offsetof(CPUMIPSState, bcond), "bcond");
12691 btarget = tcg_global_mem_new(TCG_AREG0,
12692 offsetof(CPUMIPSState, btarget), "btarget");
12693 hflags = tcg_global_mem_new_i32(TCG_AREG0,
12694 offsetof(CPUMIPSState, hflags), "hflags");
12696 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12697 offsetof(CPUMIPSState, active_fpu.fcr0),
12699 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12700 offsetof(CPUMIPSState, active_fpu.fcr31),
12703 /* register helpers */
12704 #define GEN_HELPER 2
12705 #include "helper.h"
12710 #include "translate_init.c"
12712 MIPSCPU *cpu_mips_init(const char *cpu_model)
12716 const mips_def_t *def;
12718 def = cpu_mips_find_by_name(cpu_model);
12721 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
12723 env->cpu_model = def;
12724 env->cpu_model_str = cpu_model;
12726 #ifndef CONFIG_USER_ONLY
12727 mmu_init(env, def);
12729 fpu_init(env, def);
12730 mvp_init(env, def);
12732 cpu_reset(CPU(cpu));
12733 qemu_init_vcpu(env);
12737 void cpu_state_reset(CPUMIPSState *env)
12739 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12740 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12741 log_cpu_state(env, 0);
12744 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12747 /* Reset registers to their default values */
12748 env->CP0_PRid = env->cpu_model->CP0_PRid;
12749 env->CP0_Config0 = env->cpu_model->CP0_Config0;
12750 #ifdef TARGET_WORDS_BIGENDIAN
12751 env->CP0_Config0 |= (1 << CP0C0_BE);
12753 env->CP0_Config1 = env->cpu_model->CP0_Config1;
12754 env->CP0_Config2 = env->cpu_model->CP0_Config2;
12755 env->CP0_Config3 = env->cpu_model->CP0_Config3;
12756 env->CP0_Config6 = env->cpu_model->CP0_Config6;
12757 env->CP0_Config7 = env->cpu_model->CP0_Config7;
12758 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
12759 << env->cpu_model->CP0_LLAddr_shift;
12760 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
12761 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
12762 env->CCRes = env->cpu_model->CCRes;
12763 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
12764 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
12765 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
12766 env->current_tc = 0;
12767 env->SEGBITS = env->cpu_model->SEGBITS;
12768 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
12769 #if defined(TARGET_MIPS64)
12770 if (env->cpu_model->insn_flags & ISA_MIPS3) {
12771 env->SEGMask |= 3ULL << 62;
12774 env->PABITS = env->cpu_model->PABITS;
12775 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
12776 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
12777 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
12778 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
12779 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
12780 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
12781 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
12782 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
12783 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
12784 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
12785 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
12786 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
12787 env->insn_flags = env->cpu_model->insn_flags;
12789 #if defined(CONFIG_USER_ONLY)
12790 env->hflags = MIPS_HFLAG_UM;
12791 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
12792 hardware registers. */
12793 env->CP0_HWREna |= 0x0000000F;
12794 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12795 env->hflags |= MIPS_HFLAG_FPU;
12797 #ifdef TARGET_MIPS64
12798 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
12799 env->hflags |= MIPS_HFLAG_F64;
12803 if (env->hflags & MIPS_HFLAG_BMASK) {
12804 /* If the exception was raised from a delay slot,
12805 come back to the jump. */
12806 env->CP0_ErrorEPC = env->active_tc.PC - 4;
12808 env->CP0_ErrorEPC = env->active_tc.PC;
12810 env->active_tc.PC = (int32_t)0xBFC00000;
12811 env->CP0_Random = env->tlb->nb_tlb - 1;
12812 env->tlb->tlb_in_use = env->tlb->nb_tlb;
12813 env->CP0_Wired = 0;
12814 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
12815 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12816 /* vectored interrupts not implemented, timer on int 7,
12817 no performance counters. */
12818 env->CP0_IntCtl = 0xe0000000;
12822 for (i = 0; i < 7; i++) {
12823 env->CP0_WatchLo[i] = 0;
12824 env->CP0_WatchHi[i] = 0x80000000;
12826 env->CP0_WatchLo[7] = 0;
12827 env->CP0_WatchHi[7] = 0;
12829 /* Count register increments in debug mode, EJTAG version 1 */
12830 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12831 env->hflags = MIPS_HFLAG_CP0;
12833 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
12836 /* Only TC0 on VPE 0 starts as active. */
12837 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
12838 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
12839 env->tcs[i].CP0_TCHalt = 1;
12841 env->active_tc.CP0_TCHalt = 1;
12844 if (!env->cpu_index) {
12845 /* VPE0 starts up enabled. */
12846 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
12847 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
12849 /* TC0 starts up unhalted. */
12851 env->active_tc.CP0_TCHalt = 0;
12852 env->tcs[0].CP0_TCHalt = 0;
12853 /* With thread 0 active. */
12854 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
12855 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
12859 #if defined(TARGET_MIPS64)
12860 if (env->cpu_model->insn_flags & ISA_MIPS3) {
12861 env->hflags |= MIPS_HFLAG_64;
12864 env->exception_index = EXCP_NONE;
12867 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
12869 env->active_tc.PC = gen_opc_pc[pc_pos];
12870 env->hflags &= ~MIPS_HFLAG_BMASK;
12871 env->hflags |= gen_opc_hflags[pc_pos];