net: broadcast hub packets if at least one port can receive
[qemu/kevin.git] / target-mips / translate.c
bloba884f751bcf6453a4c510d0490ca26748d1a13db
1 /*
2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
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/>.
23 #include "cpu.h"
24 #include "disas.h"
25 #include "tcg-op.h"
27 #include "helper.h"
28 #define GEN_HELPER 1
29 #include "helper.h"
31 //#define MIPS_DEBUG_DISAS
32 //#define MIPS_DEBUG_SIGN_EXTENSIONS
34 /* MIPS major opcodes */
35 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
37 enum {
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 */
61 OPC_J = (0x02 << 26),
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,
74 /* Load and stores */
75 OPC_LDL = (0x1A << 26),
76 OPC_LDR = (0x1B << 26),
77 OPC_LB = (0x20 << 26),
78 OPC_LH = (0x21 << 26),
79 OPC_LWL = (0x22 << 26),
80 OPC_LW = (0x23 << 26),
81 OPC_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)
121 enum {
122 /* Shifts */
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,
170 /* Jumps */
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),
175 /* Traps */
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,
193 /* 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))
212 enum {
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))
232 enum {
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)
255 enum {
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,
262 /* Loongson 2F */
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,
275 /* Misc */
276 OPC_CLZ = 0x20 | OPC_SPECIAL2,
277 OPC_CLO = 0x21 | OPC_SPECIAL2,
278 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
279 OPC_DCLO = 0x25 | OPC_SPECIAL2,
280 /* Special */
281 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
284 /* Special3 opcodes */
285 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
287 enum {
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,
302 /* Loongson 2E */
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,
317 /* BSHFL opcodes */
318 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
320 enum {
321 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
322 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
323 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
326 /* DBSHFL opcodes */
327 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
329 enum {
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))
337 enum {
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,
352 /* MFMC0 opcodes */
353 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
355 enum {
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)
367 enum {
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 */
382 enum {
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 */
394 enum {
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))
418 enum {
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,
425 enum {
426 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
427 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
430 enum {
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))
437 enum {
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)
451 enum {
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); \
490 } while(0)
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); \
496 } while(0)
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); \
502 } while(0)
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); \
508 } while(0)
510 typedef struct DisasContext {
511 struct TranslationBlock *tb;
512 target_ulong pc, saved_pc;
513 uint32_t opcode;
514 int singlestep_enabled;
515 /* Routine used to access memory */
516 int mem_idx;
517 uint32_t hflags, saved_hflags;
518 int bstate;
519 target_ulong btarget;
520 } DisasContext;
522 enum {
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__)
557 #else
558 #define MIPS_DEBUG(fmt, ...) do { } while(0)
559 #define LOG_DISAS(...) do { } while (0)
560 #endif
562 #define MIPS_INVAL(op) \
563 do { \
564 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
565 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
566 } while (0)
568 /* General purpose registers moves. */
569 static inline void gen_load_gpr (TCGv t, int reg)
571 if (reg == 0)
572 tcg_gen_movi_tl(t, 0);
573 else
574 tcg_gen_mov_tl(t, cpu_gpr[reg]);
577 static inline void gen_store_gpr (TCGv t, int reg)
579 if (reg != 0)
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();
599 if (from == 0)
600 tcg_gen_movi_tl(t0, 0);
601 else {
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);
617 tcg_temp_free(t0);
620 static inline void gen_store_srsgpr (int from, int to)
622 if (to != 0) {
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);
638 tcg_temp_free(t0);
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));
667 } else {
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));
682 } else {
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)
697 if (cc)
698 return 24 + cc;
699 else
700 return 23;
703 /* Tests */
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) {
720 case MIPS_HFLAG_BR:
721 break;
722 case MIPS_HFLAG_BC:
723 case MIPS_HFLAG_BL:
724 case MIPS_HFLAG_B:
725 tcg_gen_movi_tl(btarget, ctx->btarget);
726 break;
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) {
735 case MIPS_HFLAG_BR:
736 break;
737 case MIPS_HFLAG_BC:
738 case MIPS_HFLAG_BL:
739 case MIPS_HFLAG_B:
740 ctx->btarget = env->btarget;
741 break;
745 static inline void
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);
756 static inline void
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);
776 #endif
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
793 opcode tables. */
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
846 this one use. */
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 (); \
855 switch (ifmt) { \
856 case FMT_PS: \
857 check_cp1_64bitmode(ctx); \
858 break; \
859 case FMT_D: \
860 if (abs) { \
861 check_cop1x(ctx); \
863 check_cp1_registers(ctx, fs | ft); \
864 break; \
865 case FMT_S: \
866 if (abs) { \
867 check_cop1x(ctx); \
869 break; \
871 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
872 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
873 switch (n) { \
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;\
890 default: abort(); \
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)
902 #undef FOP_CONDS
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); \
912 OP_LD(lb,ld8s);
913 OP_LD(lbu,ld8u);
914 OP_LD(lh,ld16s);
915 OP_LD(lhu,ld16u);
916 OP_LD(lw,ld32s);
917 #if defined(TARGET_MIPS64)
918 OP_LD(lwu,ld32u);
919 OP_LD(ld,ld64);
920 #endif
921 #undef OP_LD
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); \
928 OP_ST(sb,st8);
929 OP_ST(sh,st16);
930 OP_ST(sw,st32);
931 #if defined(TARGET_MIPS64)
932 OP_ST(sd,st64);
933 #endif
934 #undef OP_ST
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)); \
945 tcg_temp_free(t0); \
947 #else
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); \
953 #endif
954 OP_LD_ATOMIC(ll,ld32s);
955 #if defined(TARGET_MIPS64)
956 OP_LD_ATOMIC(lld,ld64);
957 #endif
958 #undef OP_LD_ATOMIC
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); \
972 gen_set_label(l1); \
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); \
979 gen_set_label(l2); \
980 tcg_gen_movi_tl(t0, 0); \
981 gen_store_gpr(t0, rt); \
982 tcg_temp_free(t0); \
984 #else
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); \
991 tcg_temp_free(t0); \
993 #endif
994 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
995 #if defined(TARGET_MIPS64)
996 OP_ST_ATOMIC(scd,st64,ld64,0x7);
997 #endif
998 #undef OP_ST_ATOMIC
1000 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1001 int base, int16_t offset)
1003 if (base == 0) {
1004 tcg_gen_movi_tl(addr, offset);
1005 } else if (offset == 0) {
1006 gen_load_gpr(addr, base);
1007 } else {
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;
1020 pc -= branch_bytes;
1023 pc &= ~(target_ulong)3;
1024 return pc;
1027 /* Load */
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";
1032 TCGv t0, t1;
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. */
1038 MIPS_DEBUG("NOP");
1039 return;
1042 t0 = tcg_temp_new();
1043 t1 = tcg_temp_new();
1044 gen_base_offset_addr(ctx, t0, base, offset);
1046 switch (opc) {
1047 #if defined(TARGET_MIPS64)
1048 case OPC_LWU:
1049 save_cpu_state(ctx, 0);
1050 op_ld_lwu(t0, t0, ctx);
1051 gen_store_gpr(t0, rt);
1052 opn = "lwu";
1053 break;
1054 case OPC_LD:
1055 save_cpu_state(ctx, 0);
1056 op_ld_ld(t0, t0, ctx);
1057 gen_store_gpr(t0, rt);
1058 opn = "ld";
1059 break;
1060 case OPC_LLD:
1061 save_cpu_state(ctx, 1);
1062 op_ld_lld(t0, t0, ctx);
1063 gen_store_gpr(t0, rt);
1064 opn = "lld";
1065 break;
1066 case OPC_LDL:
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);
1071 opn = "ldl";
1072 break;
1073 case OPC_LDR:
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);
1078 opn = "ldr";
1079 break;
1080 case OPC_LDPC:
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);
1086 opn = "ldpc";
1087 break;
1088 #endif
1089 case OPC_LWPC:
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);
1095 opn = "lwpc";
1096 break;
1097 case OPC_LW:
1098 save_cpu_state(ctx, 0);
1099 op_ld_lw(t0, t0, ctx);
1100 gen_store_gpr(t0, rt);
1101 opn = "lw";
1102 break;
1103 case OPC_LH:
1104 save_cpu_state(ctx, 0);
1105 op_ld_lh(t0, t0, ctx);
1106 gen_store_gpr(t0, rt);
1107 opn = "lh";
1108 break;
1109 case OPC_LHU:
1110 save_cpu_state(ctx, 0);
1111 op_ld_lhu(t0, t0, ctx);
1112 gen_store_gpr(t0, rt);
1113 opn = "lhu";
1114 break;
1115 case OPC_LB:
1116 save_cpu_state(ctx, 0);
1117 op_ld_lb(t0, t0, ctx);
1118 gen_store_gpr(t0, rt);
1119 opn = "lb";
1120 break;
1121 case OPC_LBU:
1122 save_cpu_state(ctx, 0);
1123 op_ld_lbu(t0, t0, ctx);
1124 gen_store_gpr(t0, rt);
1125 opn = "lbu";
1126 break;
1127 case OPC_LWL:
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);
1132 opn = "lwl";
1133 break;
1134 case OPC_LWR:
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);
1139 opn = "lwr";
1140 break;
1141 case OPC_LL:
1142 save_cpu_state(ctx, 1);
1143 op_ld_ll(t0, t0, ctx);
1144 gen_store_gpr(t0, rt);
1145 opn = "ll";
1146 break;
1148 (void)opn; /* avoid a compiler warning */
1149 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1150 tcg_temp_free(t0);
1151 tcg_temp_free(t1);
1154 /* Store */
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);
1164 switch (opc) {
1165 #if defined(TARGET_MIPS64)
1166 case OPC_SD:
1167 save_cpu_state(ctx, 0);
1168 op_st_sd(t1, t0, ctx);
1169 opn = "sd";
1170 break;
1171 case OPC_SDL:
1172 save_cpu_state(ctx, 1);
1173 gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1174 opn = "sdl";
1175 break;
1176 case OPC_SDR:
1177 save_cpu_state(ctx, 1);
1178 gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1179 opn = "sdr";
1180 break;
1181 #endif
1182 case OPC_SW:
1183 save_cpu_state(ctx, 0);
1184 op_st_sw(t1, t0, ctx);
1185 opn = "sw";
1186 break;
1187 case OPC_SH:
1188 save_cpu_state(ctx, 0);
1189 op_st_sh(t1, t0, ctx);
1190 opn = "sh";
1191 break;
1192 case OPC_SB:
1193 save_cpu_state(ctx, 0);
1194 op_st_sb(t1, t0, ctx);
1195 opn = "sb";
1196 break;
1197 case OPC_SWL:
1198 save_cpu_state(ctx, 1);
1199 gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1200 opn = "swl";
1201 break;
1202 case OPC_SWR:
1203 save_cpu_state(ctx, 1);
1204 gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1205 opn = "swr";
1206 break;
1208 (void)opn; /* avoid a compiler warning */
1209 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1210 tcg_temp_free(t0);
1211 tcg_temp_free(t1);
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";
1220 TCGv t0, t1;
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
1226 memory access. */
1228 t1 = tcg_temp_local_new();
1229 gen_load_gpr(t1, rt);
1230 switch (opc) {
1231 #if defined(TARGET_MIPS64)
1232 case OPC_SCD:
1233 save_cpu_state(ctx, 1);
1234 op_st_scd(t1, t0, rt, ctx);
1235 opn = "scd";
1236 break;
1237 #endif
1238 case OPC_SC:
1239 save_cpu_state(ctx, 1);
1240 op_st_sc(t1, t0, rt, ctx);
1241 opn = "sc";
1242 break;
1244 (void)opn; /* avoid a compiler warning */
1245 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1246 tcg_temp_free(t1);
1247 tcg_temp_free(t0);
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
1259 memory access. */
1260 switch (opc) {
1261 case OPC_LWC1:
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);
1270 opn = "lwc1";
1271 break;
1272 case OPC_SWC1:
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);
1280 tcg_temp_free(t1);
1281 tcg_temp_free_i32(fp0);
1283 opn = "swc1";
1284 break;
1285 case OPC_LDC1:
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);
1293 opn = "ldc1";
1294 break;
1295 case OPC_SDC1:
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);
1303 opn = "sdc1";
1304 break;
1305 default:
1306 MIPS_INVAL(opn);
1307 generate_exception(ctx, EXCP_RI);
1308 goto out;
1310 (void)opn; /* avoid a compiler warning */
1311 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1312 out:
1313 tcg_temp_free(t0);
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);
1322 } else {
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. */
1337 MIPS_DEBUG("NOP");
1338 return;
1340 switch (opc) {
1341 case OPC_ADDI:
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);
1355 tcg_temp_free(t2);
1356 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1357 tcg_temp_free(t1);
1358 /* operands of same sign, result different sign */
1359 generate_exception(ctx, EXCP_OVERFLOW);
1360 gen_set_label(l1);
1361 tcg_gen_ext32s_tl(t0, t0);
1362 gen_store_gpr(t0, rt);
1363 tcg_temp_free(t0);
1365 opn = "addi";
1366 break;
1367 case OPC_ADDIU:
1368 if (rs != 0) {
1369 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1370 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1371 } else {
1372 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1374 opn = "addiu";
1375 break;
1376 #if defined(TARGET_MIPS64)
1377 case OPC_DADDI:
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);
1390 tcg_temp_free(t2);
1391 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1392 tcg_temp_free(t1);
1393 /* operands of same sign, result different sign */
1394 generate_exception(ctx, EXCP_OVERFLOW);
1395 gen_set_label(l1);
1396 gen_store_gpr(t0, rt);
1397 tcg_temp_free(t0);
1399 opn = "daddi";
1400 break;
1401 case OPC_DADDIU:
1402 if (rs != 0) {
1403 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1404 } else {
1405 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1407 opn = "daddiu";
1408 break;
1409 #endif
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)
1418 target_ulong uimm;
1419 const char *opn = "imm logic";
1421 if (rt == 0) {
1422 /* If no destination, treat it as a NOP. */
1423 MIPS_DEBUG("NOP");
1424 return;
1426 uimm = (uint16_t)imm;
1427 switch (opc) {
1428 case OPC_ANDI:
1429 if (likely(rs != 0))
1430 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1431 else
1432 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1433 opn = "andi";
1434 break;
1435 case OPC_ORI:
1436 if (rs != 0)
1437 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1438 else
1439 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1440 opn = "ori";
1441 break;
1442 case OPC_XORI:
1443 if (likely(rs != 0))
1444 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1445 else
1446 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1447 opn = "xori";
1448 break;
1449 case OPC_LUI:
1450 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1451 opn = "lui";
1452 break;
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";
1463 TCGv t0;
1465 if (rt == 0) {
1466 /* If no destination, treat it as a NOP. */
1467 MIPS_DEBUG("NOP");
1468 return;
1470 t0 = tcg_temp_new();
1471 gen_load_gpr(t0, rs);
1472 switch (opc) {
1473 case OPC_SLTI:
1474 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1475 opn = "slti";
1476 break;
1477 case OPC_SLTIU:
1478 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1479 opn = "sltiu";
1480 break;
1482 (void)opn; /* avoid a compiler warning */
1483 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1484 tcg_temp_free(t0);
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";
1493 TCGv t0;
1495 if (rt == 0) {
1496 /* If no destination, treat it as a NOP. */
1497 MIPS_DEBUG("NOP");
1498 return;
1501 t0 = tcg_temp_new();
1502 gen_load_gpr(t0, rs);
1503 switch (opc) {
1504 case OPC_SLL:
1505 tcg_gen_shli_tl(t0, t0, uimm);
1506 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1507 opn = "sll";
1508 break;
1509 case OPC_SRA:
1510 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1511 opn = "sra";
1512 break;
1513 case OPC_SRL:
1514 if (uimm != 0) {
1515 tcg_gen_ext32u_tl(t0, t0);
1516 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1517 } else {
1518 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1520 opn = "srl";
1521 break;
1522 case OPC_ROTR:
1523 if (uimm != 0) {
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);
1530 } else {
1531 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1533 opn = "rotr";
1534 break;
1535 #if defined(TARGET_MIPS64)
1536 case OPC_DSLL:
1537 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1538 opn = "dsll";
1539 break;
1540 case OPC_DSRA:
1541 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1542 opn = "dsra";
1543 break;
1544 case OPC_DSRL:
1545 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1546 opn = "dsrl";
1547 break;
1548 case OPC_DROTR:
1549 if (uimm != 0) {
1550 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1551 } else {
1552 tcg_gen_mov_tl(cpu_gpr[rt], t0);
1554 opn = "drotr";
1555 break;
1556 case OPC_DSLL32:
1557 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1558 opn = "dsll32";
1559 break;
1560 case OPC_DSRA32:
1561 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1562 opn = "dsra32";
1563 break;
1564 case OPC_DSRL32:
1565 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1566 opn = "dsrl32";
1567 break;
1568 case OPC_DROTR32:
1569 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1570 opn = "drotr32";
1571 break;
1572 #endif
1574 (void)opn; /* avoid a compiler warning */
1575 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1576 tcg_temp_free(t0);
1579 /* Arithmetic */
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. */
1589 MIPS_DEBUG("NOP");
1590 return;
1593 switch (opc) {
1594 case OPC_ADD:
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);
1608 tcg_temp_free(t2);
1609 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1610 tcg_temp_free(t1);
1611 /* operands of same sign, result different sign */
1612 generate_exception(ctx, EXCP_OVERFLOW);
1613 gen_set_label(l1);
1614 gen_store_gpr(t0, rd);
1615 tcg_temp_free(t0);
1617 opn = "add";
1618 break;
1619 case OPC_ADDU:
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]);
1627 } else {
1628 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1630 opn = "addu";
1631 break;
1632 case OPC_SUB:
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);
1646 tcg_temp_free(t2);
1647 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1648 tcg_temp_free(t1);
1649 /* operands of different sign, first operand and result different sign */
1650 generate_exception(ctx, EXCP_OVERFLOW);
1651 gen_set_label(l1);
1652 gen_store_gpr(t0, rd);
1653 tcg_temp_free(t0);
1655 opn = "sub";
1656 break;
1657 case OPC_SUBU:
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]);
1666 } else {
1667 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1669 opn = "subu";
1670 break;
1671 #if defined(TARGET_MIPS64)
1672 case OPC_DADD:
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);
1685 tcg_temp_free(t2);
1686 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1687 tcg_temp_free(t1);
1688 /* operands of same sign, result different sign */
1689 generate_exception(ctx, EXCP_OVERFLOW);
1690 gen_set_label(l1);
1691 gen_store_gpr(t0, rd);
1692 tcg_temp_free(t0);
1694 opn = "dadd";
1695 break;
1696 case OPC_DADDU:
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]);
1703 } else {
1704 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1706 opn = "daddu";
1707 break;
1708 case OPC_DSUB:
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);
1721 tcg_temp_free(t2);
1722 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1723 tcg_temp_free(t1);
1724 /* operands of different sign, first operand and result different sign */
1725 generate_exception(ctx, EXCP_OVERFLOW);
1726 gen_set_label(l1);
1727 gen_store_gpr(t0, rd);
1728 tcg_temp_free(t0);
1730 opn = "dsub";
1731 break;
1732 case OPC_DSUBU:
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]);
1739 } else {
1740 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1742 opn = "dsubu";
1743 break;
1744 #endif
1745 case OPC_MUL:
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]);
1749 } else {
1750 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1752 opn = "mul";
1753 break;
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";
1763 int l1;
1765 if (rd == 0) {
1766 /* If no destination, treat it as a NOP.
1767 For add & sub, we must generate the overflow exception when needed. */
1768 MIPS_DEBUG("NOP");
1769 return;
1772 l1 = gen_new_label();
1773 switch (opc) {
1774 case OPC_MOVN:
1775 if (likely(rt != 0))
1776 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1777 else
1778 tcg_gen_br(l1);
1779 opn = "movn";
1780 break;
1781 case OPC_MOVZ:
1782 if (likely(rt != 0))
1783 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1784 opn = "movz";
1785 break;
1787 if (rs != 0)
1788 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1789 else
1790 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1791 gen_set_label(l1);
1793 (void)opn; /* avoid a compiler warning */
1794 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1797 /* Logic */
1798 static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
1800 const char *opn = "logic";
1802 if (rd == 0) {
1803 /* If no destination, treat it as a NOP. */
1804 MIPS_DEBUG("NOP");
1805 return;
1808 switch (opc) {
1809 case OPC_AND:
1810 if (likely(rs != 0 && rt != 0)) {
1811 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1812 } else {
1813 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1815 opn = "and";
1816 break;
1817 case OPC_NOR:
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]);
1824 } else {
1825 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1827 opn = "nor";
1828 break;
1829 case OPC_OR:
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]);
1836 } else {
1837 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1839 opn = "or";
1840 break;
1841 case OPC_XOR:
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]);
1848 } else {
1849 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1851 opn = "xor";
1852 break;
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";
1862 TCGv t0, t1;
1864 if (rd == 0) {
1865 /* If no destination, treat it as a NOP. */
1866 MIPS_DEBUG("NOP");
1867 return;
1870 t0 = tcg_temp_new();
1871 t1 = tcg_temp_new();
1872 gen_load_gpr(t0, rs);
1873 gen_load_gpr(t1, rt);
1874 switch (opc) {
1875 case OPC_SLT:
1876 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1877 opn = "slt";
1878 break;
1879 case OPC_SLTU:
1880 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1881 opn = "sltu";
1882 break;
1884 (void)opn; /* avoid a compiler warning */
1885 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1886 tcg_temp_free(t0);
1887 tcg_temp_free(t1);
1890 /* Shifts */
1891 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1892 int rd, int rs, int rt)
1894 const char *opn = "shifts";
1895 TCGv t0, t1;
1897 if (rd == 0) {
1898 /* If no destination, treat it as a NOP.
1899 For add & sub, we must generate the overflow exception when needed. */
1900 MIPS_DEBUG("NOP");
1901 return;
1904 t0 = tcg_temp_new();
1905 t1 = tcg_temp_new();
1906 gen_load_gpr(t0, rs);
1907 gen_load_gpr(t1, rt);
1908 switch (opc) {
1909 case OPC_SLLV:
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);
1913 opn = "sllv";
1914 break;
1915 case OPC_SRAV:
1916 tcg_gen_andi_tl(t0, t0, 0x1f);
1917 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1918 opn = "srav";
1919 break;
1920 case OPC_SRLV:
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);
1925 opn = "srlv";
1926 break;
1927 case OPC_ROTRV:
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);
1939 opn = "rotrv";
1941 break;
1942 #if defined(TARGET_MIPS64)
1943 case OPC_DSLLV:
1944 tcg_gen_andi_tl(t0, t0, 0x3f);
1945 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1946 opn = "dsllv";
1947 break;
1948 case OPC_DSRAV:
1949 tcg_gen_andi_tl(t0, t0, 0x3f);
1950 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1951 opn = "dsrav";
1952 break;
1953 case OPC_DSRLV:
1954 tcg_gen_andi_tl(t0, t0, 0x3f);
1955 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1956 opn = "dsrlv";
1957 break;
1958 case OPC_DROTRV:
1959 tcg_gen_andi_tl(t0, t0, 0x3f);
1960 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1961 opn = "drotrv";
1962 break;
1963 #endif
1965 (void)opn; /* avoid a compiler warning */
1966 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1967 tcg_temp_free(t0);
1968 tcg_temp_free(t1);
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)) {
1977 /* Treat as NOP. */
1978 MIPS_DEBUG("NOP");
1979 return;
1981 switch (opc) {
1982 case OPC_MFHI:
1983 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1984 opn = "mfhi";
1985 break;
1986 case OPC_MFLO:
1987 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1988 opn = "mflo";
1989 break;
1990 case OPC_MTHI:
1991 if (reg != 0)
1992 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1993 else
1994 tcg_gen_movi_tl(cpu_HI[0], 0);
1995 opn = "mthi";
1996 break;
1997 case OPC_MTLO:
1998 if (reg != 0)
1999 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2000 else
2001 tcg_gen_movi_tl(cpu_LO[0], 0);
2002 opn = "mtlo";
2003 break;
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,
2010 int rs, int rt)
2012 const char *opn = "mul/div";
2013 TCGv t0, t1;
2015 switch (opc) {
2016 case OPC_DIV:
2017 case OPC_DIVU:
2018 #if defined(TARGET_MIPS64)
2019 case OPC_DDIV:
2020 case OPC_DDIVU:
2021 #endif
2022 t0 = tcg_temp_local_new();
2023 t1 = tcg_temp_local_new();
2024 break;
2025 default:
2026 t0 = tcg_temp_new();
2027 t1 = tcg_temp_new();
2028 break;
2031 gen_load_gpr(t0, rs);
2032 gen_load_gpr(t1, rt);
2033 switch (opc) {
2034 case OPC_DIV:
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);
2047 tcg_gen_br(l1);
2048 gen_set_label(l2);
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]);
2053 gen_set_label(l1);
2055 opn = "div";
2056 break;
2057 case OPC_DIVU:
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]);
2068 gen_set_label(l1);
2070 opn = "divu";
2071 break;
2072 case OPC_MULT:
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);
2088 opn = "mult";
2089 break;
2090 case OPC_MULTU:
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);
2108 opn = "multu";
2109 break;
2110 #if defined(TARGET_MIPS64)
2111 case OPC_DDIV:
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);
2121 tcg_gen_br(l1);
2122 gen_set_label(l2);
2123 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2124 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2125 gen_set_label(l1);
2127 opn = "ddiv";
2128 break;
2129 case OPC_DDIVU:
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);
2136 gen_set_label(l1);
2138 opn = "ddivu";
2139 break;
2140 case OPC_DMULT:
2141 gen_helper_dmult(t0, t1);
2142 opn = "dmult";
2143 break;
2144 case OPC_DMULTU:
2145 gen_helper_dmultu(t0, t1);
2146 opn = "dmultu";
2147 break;
2148 #endif
2149 case OPC_MADD:
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);
2167 opn = "madd";
2168 break;
2169 case OPC_MADDU:
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);
2189 opn = "maddu";
2190 break;
2191 case OPC_MSUB:
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);
2209 opn = "msub";
2210 break;
2211 case OPC_MSUBU:
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);
2231 opn = "msubu";
2232 break;
2233 default:
2234 MIPS_INVAL(opn);
2235 generate_exception(ctx, EXCP_RI);
2236 goto out;
2238 (void)opn; /* avoid a compiler warning */
2239 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2240 out:
2241 tcg_temp_free(t0);
2242 tcg_temp_free(t1);
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);
2255 switch (opc) {
2256 case OPC_VR54XX_MULS:
2257 gen_helper_muls(t0, t0, t1);
2258 opn = "muls";
2259 break;
2260 case OPC_VR54XX_MULSU:
2261 gen_helper_mulsu(t0, t0, t1);
2262 opn = "mulsu";
2263 break;
2264 case OPC_VR54XX_MACC:
2265 gen_helper_macc(t0, t0, t1);
2266 opn = "macc";
2267 break;
2268 case OPC_VR54XX_MACCU:
2269 gen_helper_maccu(t0, t0, t1);
2270 opn = "maccu";
2271 break;
2272 case OPC_VR54XX_MSAC:
2273 gen_helper_msac(t0, t0, t1);
2274 opn = "msac";
2275 break;
2276 case OPC_VR54XX_MSACU:
2277 gen_helper_msacu(t0, t0, t1);
2278 opn = "msacu";
2279 break;
2280 case OPC_VR54XX_MULHI:
2281 gen_helper_mulhi(t0, t0, t1);
2282 opn = "mulhi";
2283 break;
2284 case OPC_VR54XX_MULHIU:
2285 gen_helper_mulhiu(t0, t0, t1);
2286 opn = "mulhiu";
2287 break;
2288 case OPC_VR54XX_MULSHI:
2289 gen_helper_mulshi(t0, t0, t1);
2290 opn = "mulshi";
2291 break;
2292 case OPC_VR54XX_MULSHIU:
2293 gen_helper_mulshiu(t0, t0, t1);
2294 opn = "mulshiu";
2295 break;
2296 case OPC_VR54XX_MACCHI:
2297 gen_helper_macchi(t0, t0, t1);
2298 opn = "macchi";
2299 break;
2300 case OPC_VR54XX_MACCHIU:
2301 gen_helper_macchiu(t0, t0, t1);
2302 opn = "macchiu";
2303 break;
2304 case OPC_VR54XX_MSACHI:
2305 gen_helper_msachi(t0, t0, t1);
2306 opn = "msachi";
2307 break;
2308 case OPC_VR54XX_MSACHIU:
2309 gen_helper_msachiu(t0, t0, t1);
2310 opn = "msachiu";
2311 break;
2312 default:
2313 MIPS_INVAL("mul vr54xx");
2314 generate_exception(ctx, EXCP_RI);
2315 goto out;
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]);
2321 out:
2322 tcg_temp_free(t0);
2323 tcg_temp_free(t1);
2326 static void gen_cl (DisasContext *ctx, uint32_t opc,
2327 int rd, int rs)
2329 const char *opn = "CLx";
2330 TCGv t0;
2332 if (rd == 0) {
2333 /* Treat as NOP. */
2334 MIPS_DEBUG("NOP");
2335 return;
2337 t0 = tcg_temp_new();
2338 gen_load_gpr(t0, rs);
2339 switch (opc) {
2340 case OPC_CLO:
2341 gen_helper_clo(cpu_gpr[rd], t0);
2342 opn = "clo";
2343 break;
2344 case OPC_CLZ:
2345 gen_helper_clz(cpu_gpr[rd], t0);
2346 opn = "clz";
2347 break;
2348 #if defined(TARGET_MIPS64)
2349 case OPC_DCLO:
2350 gen_helper_dclo(cpu_gpr[rd], t0);
2351 opn = "dclo";
2352 break;
2353 case OPC_DCLZ:
2354 gen_helper_dclz(cpu_gpr[rd], t0);
2355 opn = "dclz";
2356 break;
2357 #endif
2359 (void)opn; /* avoid a compiler warning */
2360 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2361 tcg_temp_free(t0);
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";
2369 TCGv t0, t1;
2371 if (rd == 0) {
2372 /* Treat as NOP. */
2373 MIPS_DEBUG("NOP");
2374 return;
2377 switch (opc) {
2378 case OPC_MULT_G_2E:
2379 case OPC_MULT_G_2F:
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:
2387 #endif
2388 t0 = tcg_temp_new();
2389 t1 = tcg_temp_new();
2390 break;
2391 default:
2392 t0 = tcg_temp_local_new();
2393 t1 = tcg_temp_local_new();
2394 break;
2397 gen_load_gpr(t0, rs);
2398 gen_load_gpr(t1, rt);
2400 switch (opc) {
2401 case OPC_MULT_G_2E:
2402 case OPC_MULT_G_2F:
2403 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2404 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2405 opn = "mult.g";
2406 break;
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]);
2413 opn = "multu.g";
2414 break;
2415 case OPC_DIV_G_2E:
2416 case OPC_DIV_G_2F:
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);
2425 tcg_gen_br(l3);
2426 gen_set_label(l1);
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);
2430 tcg_gen_br(l3);
2431 gen_set_label(l2);
2432 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2433 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2434 gen_set_label(l3);
2436 opn = "div.g";
2437 break;
2438 case OPC_DIVU_G_2E:
2439 case OPC_DIVU_G_2F:
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);
2447 tcg_gen_br(l2);
2448 gen_set_label(l1);
2449 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2450 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2451 gen_set_label(l2);
2453 opn = "divu.g";
2454 break;
2455 case OPC_MOD_G_2E:
2456 case OPC_MOD_G_2F:
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);
2466 gen_set_label(l1);
2467 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2468 tcg_gen_br(l3);
2469 gen_set_label(l2);
2470 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2471 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2472 gen_set_label(l3);
2474 opn = "mod.g";
2475 break;
2476 case OPC_MODU_G_2E:
2477 case OPC_MODU_G_2F:
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);
2485 tcg_gen_br(l2);
2486 gen_set_label(l1);
2487 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2488 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2489 gen_set_label(l2);
2491 opn = "modu.g";
2492 break;
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);
2497 opn = "dmult.g";
2498 break;
2499 case OPC_DMULTU_G_2E:
2500 case OPC_DMULTU_G_2F:
2501 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2502 opn = "dmultu.g";
2503 break;
2504 case OPC_DDIV_G_2E:
2505 case OPC_DDIV_G_2F:
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);
2512 tcg_gen_br(l3);
2513 gen_set_label(l1);
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);
2517 tcg_gen_br(l3);
2518 gen_set_label(l2);
2519 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2520 gen_set_label(l3);
2522 opn = "ddiv.g";
2523 break;
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);
2531 tcg_gen_br(l2);
2532 gen_set_label(l1);
2533 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2534 gen_set_label(l2);
2536 opn = "ddivu.g";
2537 break;
2538 case OPC_DMOD_G_2E:
2539 case OPC_DMOD_G_2F:
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);
2547 gen_set_label(l1);
2548 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2549 tcg_gen_br(l3);
2550 gen_set_label(l2);
2551 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2552 gen_set_label(l3);
2554 opn = "dmod.g";
2555 break;
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);
2563 tcg_gen_br(l2);
2564 gen_set_label(l1);
2565 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2566 gen_set_label(l2);
2568 opn = "dmodu.g";
2569 break;
2570 #endif
2573 (void)opn; /* avoid a compiler warning */
2574 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2575 tcg_temp_free(t0);
2576 tcg_temp_free(t1);
2579 /* Traps */
2580 static void gen_trap (DisasContext *ctx, uint32_t opc,
2581 int rs, int rt, int16_t imm)
2583 int cond;
2584 TCGv t0 = tcg_temp_new();
2585 TCGv t1 = tcg_temp_new();
2587 cond = 0;
2588 /* Load needed operands */
2589 switch (opc) {
2590 case OPC_TEQ:
2591 case OPC_TGE:
2592 case OPC_TGEU:
2593 case OPC_TLT:
2594 case OPC_TLTU:
2595 case OPC_TNE:
2596 /* Compare two registers */
2597 if (rs != rt) {
2598 gen_load_gpr(t0, rs);
2599 gen_load_gpr(t1, rt);
2600 cond = 1;
2602 break;
2603 case OPC_TEQI:
2604 case OPC_TGEI:
2605 case OPC_TGEIU:
2606 case OPC_TLTI:
2607 case OPC_TLTIU:
2608 case OPC_TNEI:
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);
2613 cond = 1;
2615 break;
2617 if (cond == 0) {
2618 switch (opc) {
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 */
2625 /* Always trap */
2626 generate_exception(ctx, EXCP_TRAP);
2627 break;
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. */
2635 break;
2637 } else {
2638 int l1 = gen_new_label();
2640 switch (opc) {
2641 case OPC_TEQ:
2642 case OPC_TEQI:
2643 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2644 break;
2645 case OPC_TGE:
2646 case OPC_TGEI:
2647 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2648 break;
2649 case OPC_TGEU:
2650 case OPC_TGEIU:
2651 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2652 break;
2653 case OPC_TLT:
2654 case OPC_TLTI:
2655 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2656 break;
2657 case OPC_TLTU:
2658 case OPC_TLTIU:
2659 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2660 break;
2661 case OPC_TNE:
2662 case OPC_TNEI:
2663 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2664 break;
2666 generate_exception(ctx, EXCP_TRAP);
2667 gen_set_label(l1);
2669 tcg_temp_free(t0);
2670 tcg_temp_free(t1);
2673 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2675 TranslationBlock *tb;
2676 tb = ctx->tb;
2677 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2678 likely(!ctx->singlestep_enabled)) {
2679 tcg_gen_goto_tb(n);
2680 gen_save_pc(dest);
2681 tcg_gen_exit_tb((tcg_target_long)tb + n);
2682 } else {
2683 gen_save_pc(dest);
2684 if (ctx->singlestep_enabled) {
2685 save_cpu_state(ctx, 0);
2686 gen_helper_0i(raise_exception, EXCP_DEBUG);
2688 tcg_gen_exit_tb(0);
2692 /* Branches (before delay slot) */
2693 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2694 int insn_bytes,
2695 int rs, int rt, int32_t offset)
2697 target_ulong btgt = -1;
2698 int blink = 0;
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);
2706 #endif
2707 generate_exception(ctx, EXCP_RI);
2708 goto out;
2711 /* Load needed operands */
2712 switch (opc) {
2713 case OPC_BEQ:
2714 case OPC_BEQL:
2715 case OPC_BNE:
2716 case OPC_BNEL:
2717 /* Compare two registers */
2718 if (rs != rt) {
2719 gen_load_gpr(t0, rs);
2720 gen_load_gpr(t1, rt);
2721 bcond_compute = 1;
2723 btgt = ctx->pc + insn_bytes + offset;
2724 break;
2725 case OPC_BGEZ:
2726 case OPC_BGEZAL:
2727 case OPC_BGEZALS:
2728 case OPC_BGEZALL:
2729 case OPC_BGEZL:
2730 case OPC_BGTZ:
2731 case OPC_BGTZL:
2732 case OPC_BLEZ:
2733 case OPC_BLEZL:
2734 case OPC_BLTZ:
2735 case OPC_BLTZAL:
2736 case OPC_BLTZALS:
2737 case OPC_BLTZALL:
2738 case OPC_BLTZL:
2739 /* Compare to zero */
2740 if (rs != 0) {
2741 gen_load_gpr(t0, rs);
2742 bcond_compute = 1;
2744 btgt = ctx->pc + insn_bytes + offset;
2745 break;
2746 case OPC_J:
2747 case OPC_JAL:
2748 case OPC_JALX:
2749 case OPC_JALS:
2750 case OPC_JALXS:
2751 /* Jump to immediate */
2752 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2753 break;
2754 case OPC_JR:
2755 case OPC_JALR:
2756 case OPC_JALRC:
2757 case OPC_JALRS:
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);
2764 goto out;
2766 gen_load_gpr(btarget, rs);
2767 break;
2768 default:
2769 MIPS_INVAL("branch/jump");
2770 generate_exception(ctx, EXCP_RI);
2771 goto out;
2773 if (bcond_compute == 0) {
2774 /* No condition to be computed */
2775 switch (opc) {
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 */
2782 /* Always take */
2783 ctx->hflags |= MIPS_HFLAG_B;
2784 MIPS_DEBUG("balways");
2785 break;
2786 case OPC_BGEZALS:
2787 case OPC_BGEZAL: /* 0 >= 0 */
2788 case OPC_BGEZALL: /* 0 >= 0 likely */
2789 ctx->hflags |= (opc == OPC_BGEZALS
2790 ? MIPS_HFLAG_BDS16
2791 : MIPS_HFLAG_BDS32);
2792 /* Always take and link */
2793 blink = 31;
2794 ctx->hflags |= MIPS_HFLAG_B;
2795 MIPS_DEBUG("balways and link");
2796 break;
2797 case OPC_BNE: /* rx != rx */
2798 case OPC_BGTZ: /* 0 > 0 */
2799 case OPC_BLTZ: /* 0 < 0 */
2800 /* Treat as NOP. */
2801 MIPS_DEBUG("bnever (NOP)");
2802 goto out;
2803 case OPC_BLTZALS:
2804 case OPC_BLTZAL: /* 0 < 0 */
2805 ctx->hflags |= (opc == OPC_BLTZALS
2806 ? MIPS_HFLAG_BDS16
2807 : MIPS_HFLAG_BDS32);
2808 /* Handle as an unconditional branch to get correct delay
2809 slot checking. */
2810 blink = 31;
2811 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
2812 ctx->hflags |= MIPS_HFLAG_B;
2813 MIPS_DEBUG("bnever and link");
2814 break;
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");
2819 ctx->pc += 4;
2820 goto out;
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");
2826 ctx->pc += 4;
2827 goto out;
2828 case OPC_J:
2829 ctx->hflags |= MIPS_HFLAG_B;
2830 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2831 break;
2832 case OPC_JALXS:
2833 case OPC_JALX:
2834 ctx->hflags |= MIPS_HFLAG_BX;
2835 /* Fallthrough */
2836 case OPC_JALS:
2837 case OPC_JAL:
2838 blink = 31;
2839 ctx->hflags |= MIPS_HFLAG_B;
2840 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
2841 ? MIPS_HFLAG_BDS16
2842 : MIPS_HFLAG_BDS32);
2843 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2844 break;
2845 case OPC_JR:
2846 ctx->hflags |= MIPS_HFLAG_BR;
2847 if (insn_bytes == 4)
2848 ctx->hflags |= MIPS_HFLAG_BDS32;
2849 MIPS_DEBUG("jr %s", regnames[rs]);
2850 break;
2851 case OPC_JALRS:
2852 case OPC_JALR:
2853 case OPC_JALRC:
2854 blink = rt;
2855 ctx->hflags |= MIPS_HFLAG_BR;
2856 ctx->hflags |= (opc == OPC_JALRS
2857 ? MIPS_HFLAG_BDS16
2858 : MIPS_HFLAG_BDS32);
2859 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2860 break;
2861 default:
2862 MIPS_INVAL("branch/jump");
2863 generate_exception(ctx, EXCP_RI);
2864 goto out;
2866 } else {
2867 switch (opc) {
2868 case OPC_BEQ:
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);
2872 goto not_likely;
2873 case OPC_BEQL:
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);
2877 goto likely;
2878 case OPC_BNE:
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);
2882 goto not_likely;
2883 case OPC_BNEL:
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);
2887 goto likely;
2888 case OPC_BGEZ:
2889 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2890 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2891 goto not_likely;
2892 case OPC_BGEZL:
2893 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2894 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2895 goto likely;
2896 case OPC_BGEZALS:
2897 case OPC_BGEZAL:
2898 ctx->hflags |= (opc == OPC_BGEZALS
2899 ? MIPS_HFLAG_BDS16
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);
2903 blink = 31;
2904 goto not_likely;
2905 case OPC_BGEZALL:
2906 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2907 blink = 31;
2908 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2909 goto likely;
2910 case OPC_BGTZ:
2911 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2912 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2913 goto not_likely;
2914 case OPC_BGTZL:
2915 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2916 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2917 goto likely;
2918 case OPC_BLEZ:
2919 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2920 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2921 goto not_likely;
2922 case OPC_BLEZL:
2923 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2924 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2925 goto likely;
2926 case OPC_BLTZ:
2927 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2928 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2929 goto not_likely;
2930 case OPC_BLTZL:
2931 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2932 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2933 goto likely;
2934 case OPC_BLTZALS:
2935 case OPC_BLTZAL:
2936 ctx->hflags |= (opc == OPC_BLTZALS
2937 ? MIPS_HFLAG_BDS16
2938 : MIPS_HFLAG_BDS32);
2939 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2940 blink = 31;
2941 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2942 not_likely:
2943 ctx->hflags |= MIPS_HFLAG_BC;
2944 break;
2945 case OPC_BLTZALL:
2946 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2947 blink = 31;
2948 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2949 likely:
2950 ctx->hflags |= MIPS_HFLAG_BL;
2951 break;
2952 default:
2953 MIPS_INVAL("conditional branch/jump");
2954 generate_exception(ctx, EXCP_RI);
2955 goto out;
2958 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2959 blink, ctx->hflags, btgt);
2961 ctx->btarget = btgt;
2962 if (blink > 0) {
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);
2972 out:
2973 if (insn_bytes == 2)
2974 ctx->hflags |= MIPS_HFLAG_B16;
2975 tcg_temp_free(t0);
2976 tcg_temp_free(t1);
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();
2985 target_ulong mask;
2987 gen_load_gpr(t1, rs);
2988 switch (opc) {
2989 case OPC_EXT:
2990 if (lsb + msb > 31)
2991 goto fail;
2992 tcg_gen_shri_tl(t0, t1, lsb);
2993 if (msb != 31) {
2994 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2995 } else {
2996 tcg_gen_ext32s_tl(t0, t0);
2998 break;
2999 #if defined(TARGET_MIPS64)
3000 case OPC_DEXTM:
3001 tcg_gen_shri_tl(t0, t1, lsb);
3002 if (msb != 31) {
3003 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3005 break;
3006 case OPC_DEXTU:
3007 tcg_gen_shri_tl(t0, t1, lsb + 32);
3008 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3009 break;
3010 case OPC_DEXT:
3011 tcg_gen_shri_tl(t0, t1, lsb);
3012 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3013 break;
3014 #endif
3015 case OPC_INS:
3016 if (lsb > msb)
3017 goto fail;
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);
3025 break;
3026 #if defined(TARGET_MIPS64)
3027 case OPC_DINSM:
3028 if (lsb > msb)
3029 goto fail;
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);
3036 break;
3037 case OPC_DINSU:
3038 if (lsb > msb)
3039 goto fail;
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);
3046 break;
3047 case OPC_DINS:
3048 if (lsb > msb)
3049 goto fail;
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);
3057 break;
3058 #endif
3059 default:
3060 fail:
3061 MIPS_INVAL("bitops");
3062 generate_exception(ctx, EXCP_RI);
3063 tcg_temp_free(t0);
3064 tcg_temp_free(t1);
3065 return;
3067 gen_store_gpr(t0, rt);
3068 tcg_temp_free(t0);
3069 tcg_temp_free(t1);
3072 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3074 TCGv t0;
3076 if (rd == 0) {
3077 /* If no destination, treat it as a NOP. */
3078 MIPS_DEBUG("NOP");
3079 return;
3082 t0 = tcg_temp_new();
3083 gen_load_gpr(t0, rt);
3084 switch (op2) {
3085 case OPC_WSBH:
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);
3094 tcg_temp_free(t1);
3095 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3097 break;
3098 case OPC_SEB:
3099 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3100 break;
3101 case OPC_SEH:
3102 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3103 break;
3104 #if defined(TARGET_MIPS64)
3105 case OPC_DSBH:
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);
3114 tcg_temp_free(t1);
3116 break;
3117 case OPC_DSHD:
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);
3129 tcg_temp_free(t1);
3131 break;
3132 #endif
3133 default:
3134 MIPS_INVAL("bsfhl");
3135 generate_exception(ctx, EXCP_RI);
3136 tcg_temp_free(t0);
3137 return;
3139 tcg_temp_free(t0);
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";
3178 if (sel != 0)
3179 check_insn(env, ctx, ISA_MIPS32);
3181 switch (reg) {
3182 case 0:
3183 switch (sel) {
3184 case 0:
3185 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
3186 rn = "Index";
3187 break;
3188 case 1:
3189 check_insn(env, ctx, ASE_MT);
3190 gen_helper_mfc0_mvpcontrol(arg);
3191 rn = "MVPControl";
3192 break;
3193 case 2:
3194 check_insn(env, ctx, ASE_MT);
3195 gen_helper_mfc0_mvpconf0(arg);
3196 rn = "MVPConf0";
3197 break;
3198 case 3:
3199 check_insn(env, ctx, ASE_MT);
3200 gen_helper_mfc0_mvpconf1(arg);
3201 rn = "MVPConf1";
3202 break;
3203 default:
3204 goto die;
3206 break;
3207 case 1:
3208 switch (sel) {
3209 case 0:
3210 gen_helper_mfc0_random(arg);
3211 rn = "Random";
3212 break;
3213 case 1:
3214 check_insn(env, ctx, ASE_MT);
3215 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
3216 rn = "VPEControl";
3217 break;
3218 case 2:
3219 check_insn(env, ctx, ASE_MT);
3220 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
3221 rn = "VPEConf0";
3222 break;
3223 case 3:
3224 check_insn(env, ctx, ASE_MT);
3225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
3226 rn = "VPEConf1";
3227 break;
3228 case 4:
3229 check_insn(env, ctx, ASE_MT);
3230 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
3231 rn = "YQMask";
3232 break;
3233 case 5:
3234 check_insn(env, ctx, ASE_MT);
3235 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
3236 rn = "VPESchedule";
3237 break;
3238 case 6:
3239 check_insn(env, ctx, ASE_MT);
3240 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
3241 rn = "VPEScheFBack";
3242 break;
3243 case 7:
3244 check_insn(env, ctx, ASE_MT);
3245 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
3246 rn = "VPEOpt";
3247 break;
3248 default:
3249 goto die;
3251 break;
3252 case 2:
3253 switch (sel) {
3254 case 0:
3255 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
3256 tcg_gen_ext32s_tl(arg, arg);
3257 rn = "EntryLo0";
3258 break;
3259 case 1:
3260 check_insn(env, ctx, ASE_MT);
3261 gen_helper_mfc0_tcstatus(arg);
3262 rn = "TCStatus";
3263 break;
3264 case 2:
3265 check_insn(env, ctx, ASE_MT);
3266 gen_helper_mfc0_tcbind(arg);
3267 rn = "TCBind";
3268 break;
3269 case 3:
3270 check_insn(env, ctx, ASE_MT);
3271 gen_helper_mfc0_tcrestart(arg);
3272 rn = "TCRestart";
3273 break;
3274 case 4:
3275 check_insn(env, ctx, ASE_MT);
3276 gen_helper_mfc0_tchalt(arg);
3277 rn = "TCHalt";
3278 break;
3279 case 5:
3280 check_insn(env, ctx, ASE_MT);
3281 gen_helper_mfc0_tccontext(arg);
3282 rn = "TCContext";
3283 break;
3284 case 6:
3285 check_insn(env, ctx, ASE_MT);
3286 gen_helper_mfc0_tcschedule(arg);
3287 rn = "TCSchedule";
3288 break;
3289 case 7:
3290 check_insn(env, ctx, ASE_MT);
3291 gen_helper_mfc0_tcschefback(arg);
3292 rn = "TCScheFBack";
3293 break;
3294 default:
3295 goto die;
3297 break;
3298 case 3:
3299 switch (sel) {
3300 case 0:
3301 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
3302 tcg_gen_ext32s_tl(arg, arg);
3303 rn = "EntryLo1";
3304 break;
3305 default:
3306 goto die;
3308 break;
3309 case 4:
3310 switch (sel) {
3311 case 0:
3312 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
3313 tcg_gen_ext32s_tl(arg, arg);
3314 rn = "Context";
3315 break;
3316 case 1:
3317 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3318 rn = "ContextConfig";
3319 // break;
3320 default:
3321 goto die;
3323 break;
3324 case 5:
3325 switch (sel) {
3326 case 0:
3327 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
3328 rn = "PageMask";
3329 break;
3330 case 1:
3331 check_insn(env, ctx, ISA_MIPS32R2);
3332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
3333 rn = "PageGrain";
3334 break;
3335 default:
3336 goto die;
3338 break;
3339 case 6:
3340 switch (sel) {
3341 case 0:
3342 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
3343 rn = "Wired";
3344 break;
3345 case 1:
3346 check_insn(env, ctx, ISA_MIPS32R2);
3347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
3348 rn = "SRSConf0";
3349 break;
3350 case 2:
3351 check_insn(env, ctx, ISA_MIPS32R2);
3352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
3353 rn = "SRSConf1";
3354 break;
3355 case 3:
3356 check_insn(env, ctx, ISA_MIPS32R2);
3357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
3358 rn = "SRSConf2";
3359 break;
3360 case 4:
3361 check_insn(env, ctx, ISA_MIPS32R2);
3362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
3363 rn = "SRSConf3";
3364 break;
3365 case 5:
3366 check_insn(env, ctx, ISA_MIPS32R2);
3367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
3368 rn = "SRSConf4";
3369 break;
3370 default:
3371 goto die;
3373 break;
3374 case 7:
3375 switch (sel) {
3376 case 0:
3377 check_insn(env, ctx, ISA_MIPS32R2);
3378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
3379 rn = "HWREna";
3380 break;
3381 default:
3382 goto die;
3384 break;
3385 case 8:
3386 switch (sel) {
3387 case 0:
3388 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
3389 tcg_gen_ext32s_tl(arg, arg);
3390 rn = "BadVAddr";
3391 break;
3392 default:
3393 goto die;
3395 break;
3396 case 9:
3397 switch (sel) {
3398 case 0:
3399 /* Mark as an IO operation because we read the time. */
3400 if (use_icount)
3401 gen_io_start();
3402 gen_helper_mfc0_count(arg);
3403 if (use_icount) {
3404 gen_io_end();
3406 /* Break the TB to be able to take timer interrupts immediately
3407 after reading count. */
3408 ctx->bstate = BS_STOP;
3409 rn = "Count";
3410 break;
3411 /* 6,7 are implementation dependent */
3412 default:
3413 goto die;
3415 break;
3416 case 10:
3417 switch (sel) {
3418 case 0:
3419 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
3420 tcg_gen_ext32s_tl(arg, arg);
3421 rn = "EntryHi";
3422 break;
3423 default:
3424 goto die;
3426 break;
3427 case 11:
3428 switch (sel) {
3429 case 0:
3430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
3431 rn = "Compare";
3432 break;
3433 /* 6,7 are implementation dependent */
3434 default:
3435 goto die;
3437 break;
3438 case 12:
3439 switch (sel) {
3440 case 0:
3441 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
3442 rn = "Status";
3443 break;
3444 case 1:
3445 check_insn(env, ctx, ISA_MIPS32R2);
3446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
3447 rn = "IntCtl";
3448 break;
3449 case 2:
3450 check_insn(env, ctx, ISA_MIPS32R2);
3451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
3452 rn = "SRSCtl";
3453 break;
3454 case 3:
3455 check_insn(env, ctx, ISA_MIPS32R2);
3456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
3457 rn = "SRSMap";
3458 break;
3459 default:
3460 goto die;
3462 break;
3463 case 13:
3464 switch (sel) {
3465 case 0:
3466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
3467 rn = "Cause";
3468 break;
3469 default:
3470 goto die;
3472 break;
3473 case 14:
3474 switch (sel) {
3475 case 0:
3476 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
3477 tcg_gen_ext32s_tl(arg, arg);
3478 rn = "EPC";
3479 break;
3480 default:
3481 goto die;
3483 break;
3484 case 15:
3485 switch (sel) {
3486 case 0:
3487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
3488 rn = "PRid";
3489 break;
3490 case 1:
3491 check_insn(env, ctx, ISA_MIPS32R2);
3492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
3493 rn = "EBase";
3494 break;
3495 default:
3496 goto die;
3498 break;
3499 case 16:
3500 switch (sel) {
3501 case 0:
3502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
3503 rn = "Config";
3504 break;
3505 case 1:
3506 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
3507 rn = "Config1";
3508 break;
3509 case 2:
3510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
3511 rn = "Config2";
3512 break;
3513 case 3:
3514 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
3515 rn = "Config3";
3516 break;
3517 /* 4,5 are reserved */
3518 /* 6,7 are implementation dependent */
3519 case 6:
3520 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
3521 rn = "Config6";
3522 break;
3523 case 7:
3524 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
3525 rn = "Config7";
3526 break;
3527 default:
3528 goto die;
3530 break;
3531 case 17:
3532 switch (sel) {
3533 case 0:
3534 gen_helper_mfc0_lladdr(arg);
3535 rn = "LLAddr";
3536 break;
3537 default:
3538 goto die;
3540 break;
3541 case 18:
3542 switch (sel) {
3543 case 0 ... 7:
3544 gen_helper_1i(mfc0_watchlo, arg, sel);
3545 rn = "WatchLo";
3546 break;
3547 default:
3548 goto die;
3550 break;
3551 case 19:
3552 switch (sel) {
3553 case 0 ...7:
3554 gen_helper_1i(mfc0_watchhi, arg, sel);
3555 rn = "WatchHi";
3556 break;
3557 default:
3558 goto die;
3560 break;
3561 case 20:
3562 switch (sel) {
3563 case 0:
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);
3568 rn = "XContext";
3569 break;
3570 #endif
3571 default:
3572 goto die;
3574 break;
3575 case 21:
3576 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3577 switch (sel) {
3578 case 0:
3579 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
3580 rn = "Framemask";
3581 break;
3582 default:
3583 goto die;
3585 break;
3586 case 22:
3587 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3588 rn = "'Diagnostic"; /* implementation dependent */
3589 break;
3590 case 23:
3591 switch (sel) {
3592 case 0:
3593 gen_helper_mfc0_debug(arg); /* EJTAG support */
3594 rn = "Debug";
3595 break;
3596 case 1:
3597 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3598 rn = "TraceControl";
3599 // break;
3600 case 2:
3601 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3602 rn = "TraceControl2";
3603 // break;
3604 case 3:
3605 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3606 rn = "UserTraceData";
3607 // break;
3608 case 4:
3609 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3610 rn = "TraceBPC";
3611 // break;
3612 default:
3613 goto die;
3615 break;
3616 case 24:
3617 switch (sel) {
3618 case 0:
3619 /* EJTAG support */
3620 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
3621 tcg_gen_ext32s_tl(arg, arg);
3622 rn = "DEPC";
3623 break;
3624 default:
3625 goto die;
3627 break;
3628 case 25:
3629 switch (sel) {
3630 case 0:
3631 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
3632 rn = "Performance0";
3633 break;
3634 case 1:
3635 // gen_helper_mfc0_performance1(arg);
3636 rn = "Performance1";
3637 // break;
3638 case 2:
3639 // gen_helper_mfc0_performance2(arg);
3640 rn = "Performance2";
3641 // break;
3642 case 3:
3643 // gen_helper_mfc0_performance3(arg);
3644 rn = "Performance3";
3645 // break;
3646 case 4:
3647 // gen_helper_mfc0_performance4(arg);
3648 rn = "Performance4";
3649 // break;
3650 case 5:
3651 // gen_helper_mfc0_performance5(arg);
3652 rn = "Performance5";
3653 // break;
3654 case 6:
3655 // gen_helper_mfc0_performance6(arg);
3656 rn = "Performance6";
3657 // break;
3658 case 7:
3659 // gen_helper_mfc0_performance7(arg);
3660 rn = "Performance7";
3661 // break;
3662 default:
3663 goto die;
3665 break;
3666 case 26:
3667 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3668 rn = "ECC";
3669 break;
3670 case 27:
3671 switch (sel) {
3672 case 0 ... 3:
3673 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3674 rn = "CacheErr";
3675 break;
3676 default:
3677 goto die;
3679 break;
3680 case 28:
3681 switch (sel) {
3682 case 0:
3683 case 2:
3684 case 4:
3685 case 6:
3686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
3687 rn = "TagLo";
3688 break;
3689 case 1:
3690 case 3:
3691 case 5:
3692 case 7:
3693 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
3694 rn = "DataLo";
3695 break;
3696 default:
3697 goto die;
3699 break;
3700 case 29:
3701 switch (sel) {
3702 case 0:
3703 case 2:
3704 case 4:
3705 case 6:
3706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
3707 rn = "TagHi";
3708 break;
3709 case 1:
3710 case 3:
3711 case 5:
3712 case 7:
3713 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
3714 rn = "DataHi";
3715 break;
3716 default:
3717 goto die;
3719 break;
3720 case 30:
3721 switch (sel) {
3722 case 0:
3723 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
3724 tcg_gen_ext32s_tl(arg, arg);
3725 rn = "ErrorEPC";
3726 break;
3727 default:
3728 goto die;
3730 break;
3731 case 31:
3732 switch (sel) {
3733 case 0:
3734 /* EJTAG support */
3735 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
3736 rn = "DESAVE";
3737 break;
3738 default:
3739 goto die;
3741 break;
3742 default:
3743 goto die;
3745 (void)rn; /* avoid a compiler warning */
3746 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3747 return;
3749 die:
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";
3758 if (sel != 0)
3759 check_insn(env, ctx, ISA_MIPS32);
3761 if (use_icount)
3762 gen_io_start();
3764 switch (reg) {
3765 case 0:
3766 switch (sel) {
3767 case 0:
3768 gen_helper_mtc0_index(arg);
3769 rn = "Index";
3770 break;
3771 case 1:
3772 check_insn(env, ctx, ASE_MT);
3773 gen_helper_mtc0_mvpcontrol(arg);
3774 rn = "MVPControl";
3775 break;
3776 case 2:
3777 check_insn(env, ctx, ASE_MT);
3778 /* ignored */
3779 rn = "MVPConf0";
3780 break;
3781 case 3:
3782 check_insn(env, ctx, ASE_MT);
3783 /* ignored */
3784 rn = "MVPConf1";
3785 break;
3786 default:
3787 goto die;
3789 break;
3790 case 1:
3791 switch (sel) {
3792 case 0:
3793 /* ignored */
3794 rn = "Random";
3795 break;
3796 case 1:
3797 check_insn(env, ctx, ASE_MT);
3798 gen_helper_mtc0_vpecontrol(arg);
3799 rn = "VPEControl";
3800 break;
3801 case 2:
3802 check_insn(env, ctx, ASE_MT);
3803 gen_helper_mtc0_vpeconf0(arg);
3804 rn = "VPEConf0";
3805 break;
3806 case 3:
3807 check_insn(env, ctx, ASE_MT);
3808 gen_helper_mtc0_vpeconf1(arg);
3809 rn = "VPEConf1";
3810 break;
3811 case 4:
3812 check_insn(env, ctx, ASE_MT);
3813 gen_helper_mtc0_yqmask(arg);
3814 rn = "YQMask";
3815 break;
3816 case 5:
3817 check_insn(env, ctx, ASE_MT);
3818 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
3819 rn = "VPESchedule";
3820 break;
3821 case 6:
3822 check_insn(env, ctx, ASE_MT);
3823 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
3824 rn = "VPEScheFBack";
3825 break;
3826 case 7:
3827 check_insn(env, ctx, ASE_MT);
3828 gen_helper_mtc0_vpeopt(arg);
3829 rn = "VPEOpt";
3830 break;
3831 default:
3832 goto die;
3834 break;
3835 case 2:
3836 switch (sel) {
3837 case 0:
3838 gen_helper_mtc0_entrylo0(arg);
3839 rn = "EntryLo0";
3840 break;
3841 case 1:
3842 check_insn(env, ctx, ASE_MT);
3843 gen_helper_mtc0_tcstatus(arg);
3844 rn = "TCStatus";
3845 break;
3846 case 2:
3847 check_insn(env, ctx, ASE_MT);
3848 gen_helper_mtc0_tcbind(arg);
3849 rn = "TCBind";
3850 break;
3851 case 3:
3852 check_insn(env, ctx, ASE_MT);
3853 gen_helper_mtc0_tcrestart(arg);
3854 rn = "TCRestart";
3855 break;
3856 case 4:
3857 check_insn(env, ctx, ASE_MT);
3858 gen_helper_mtc0_tchalt(arg);
3859 rn = "TCHalt";
3860 break;
3861 case 5:
3862 check_insn(env, ctx, ASE_MT);
3863 gen_helper_mtc0_tccontext(arg);
3864 rn = "TCContext";
3865 break;
3866 case 6:
3867 check_insn(env, ctx, ASE_MT);
3868 gen_helper_mtc0_tcschedule(arg);
3869 rn = "TCSchedule";
3870 break;
3871 case 7:
3872 check_insn(env, ctx, ASE_MT);
3873 gen_helper_mtc0_tcschefback(arg);
3874 rn = "TCScheFBack";
3875 break;
3876 default:
3877 goto die;
3879 break;
3880 case 3:
3881 switch (sel) {
3882 case 0:
3883 gen_helper_mtc0_entrylo1(arg);
3884 rn = "EntryLo1";
3885 break;
3886 default:
3887 goto die;
3889 break;
3890 case 4:
3891 switch (sel) {
3892 case 0:
3893 gen_helper_mtc0_context(arg);
3894 rn = "Context";
3895 break;
3896 case 1:
3897 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3898 rn = "ContextConfig";
3899 // break;
3900 default:
3901 goto die;
3903 break;
3904 case 5:
3905 switch (sel) {
3906 case 0:
3907 gen_helper_mtc0_pagemask(arg);
3908 rn = "PageMask";
3909 break;
3910 case 1:
3911 check_insn(env, ctx, ISA_MIPS32R2);
3912 gen_helper_mtc0_pagegrain(arg);
3913 rn = "PageGrain";
3914 break;
3915 default:
3916 goto die;
3918 break;
3919 case 6:
3920 switch (sel) {
3921 case 0:
3922 gen_helper_mtc0_wired(arg);
3923 rn = "Wired";
3924 break;
3925 case 1:
3926 check_insn(env, ctx, ISA_MIPS32R2);
3927 gen_helper_mtc0_srsconf0(arg);
3928 rn = "SRSConf0";
3929 break;
3930 case 2:
3931 check_insn(env, ctx, ISA_MIPS32R2);
3932 gen_helper_mtc0_srsconf1(arg);
3933 rn = "SRSConf1";
3934 break;
3935 case 3:
3936 check_insn(env, ctx, ISA_MIPS32R2);
3937 gen_helper_mtc0_srsconf2(arg);
3938 rn = "SRSConf2";
3939 break;
3940 case 4:
3941 check_insn(env, ctx, ISA_MIPS32R2);
3942 gen_helper_mtc0_srsconf3(arg);
3943 rn = "SRSConf3";
3944 break;
3945 case 5:
3946 check_insn(env, ctx, ISA_MIPS32R2);
3947 gen_helper_mtc0_srsconf4(arg);
3948 rn = "SRSConf4";
3949 break;
3950 default:
3951 goto die;
3953 break;
3954 case 7:
3955 switch (sel) {
3956 case 0:
3957 check_insn(env, ctx, ISA_MIPS32R2);
3958 gen_helper_mtc0_hwrena(arg);
3959 rn = "HWREna";
3960 break;
3961 default:
3962 goto die;
3964 break;
3965 case 8:
3966 /* ignored */
3967 rn = "BadVAddr";
3968 break;
3969 case 9:
3970 switch (sel) {
3971 case 0:
3972 gen_helper_mtc0_count(arg);
3973 rn = "Count";
3974 break;
3975 /* 6,7 are implementation dependent */
3976 default:
3977 goto die;
3979 break;
3980 case 10:
3981 switch (sel) {
3982 case 0:
3983 gen_helper_mtc0_entryhi(arg);
3984 rn = "EntryHi";
3985 break;
3986 default:
3987 goto die;
3989 break;
3990 case 11:
3991 switch (sel) {
3992 case 0:
3993 gen_helper_mtc0_compare(arg);
3994 rn = "Compare";
3995 break;
3996 /* 6,7 are implementation dependent */
3997 default:
3998 goto die;
4000 break;
4001 case 12:
4002 switch (sel) {
4003 case 0:
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;
4009 rn = "Status";
4010 break;
4011 case 1:
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;
4016 rn = "IntCtl";
4017 break;
4018 case 2:
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;
4023 rn = "SRSCtl";
4024 break;
4025 case 3:
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;
4030 rn = "SRSMap";
4031 break;
4032 default:
4033 goto die;
4035 break;
4036 case 13:
4037 switch (sel) {
4038 case 0:
4039 save_cpu_state(ctx, 1);
4040 gen_helper_mtc0_cause(arg);
4041 rn = "Cause";
4042 break;
4043 default:
4044 goto die;
4046 break;
4047 case 14:
4048 switch (sel) {
4049 case 0:
4050 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4051 rn = "EPC";
4052 break;
4053 default:
4054 goto die;
4056 break;
4057 case 15:
4058 switch (sel) {
4059 case 0:
4060 /* ignored */
4061 rn = "PRid";
4062 break;
4063 case 1:
4064 check_insn(env, ctx, ISA_MIPS32R2);
4065 gen_helper_mtc0_ebase(arg);
4066 rn = "EBase";
4067 break;
4068 default:
4069 goto die;
4071 break;
4072 case 16:
4073 switch (sel) {
4074 case 0:
4075 gen_helper_mtc0_config0(arg);
4076 rn = "Config";
4077 /* Stop translation as we may have switched the execution mode */
4078 ctx->bstate = BS_STOP;
4079 break;
4080 case 1:
4081 /* ignored, read only */
4082 rn = "Config1";
4083 break;
4084 case 2:
4085 gen_helper_mtc0_config2(arg);
4086 rn = "Config2";
4087 /* Stop translation as we may have switched the execution mode */
4088 ctx->bstate = BS_STOP;
4089 break;
4090 case 3:
4091 /* ignored, read only */
4092 rn = "Config3";
4093 break;
4094 /* 4,5 are reserved */
4095 /* 6,7 are implementation dependent */
4096 case 6:
4097 /* ignored */
4098 rn = "Config6";
4099 break;
4100 case 7:
4101 /* ignored */
4102 rn = "Config7";
4103 break;
4104 default:
4105 rn = "Invalid config selector";
4106 goto die;
4108 break;
4109 case 17:
4110 switch (sel) {
4111 case 0:
4112 gen_helper_mtc0_lladdr(arg);
4113 rn = "LLAddr";
4114 break;
4115 default:
4116 goto die;
4118 break;
4119 case 18:
4120 switch (sel) {
4121 case 0 ... 7:
4122 gen_helper_1i(mtc0_watchlo, arg, sel);
4123 rn = "WatchLo";
4124 break;
4125 default:
4126 goto die;
4128 break;
4129 case 19:
4130 switch (sel) {
4131 case 0 ... 7:
4132 gen_helper_1i(mtc0_watchhi, arg, sel);
4133 rn = "WatchHi";
4134 break;
4135 default:
4136 goto die;
4138 break;
4139 case 20:
4140 switch (sel) {
4141 case 0:
4142 #if defined(TARGET_MIPS64)
4143 check_insn(env, ctx, ISA_MIPS3);
4144 gen_helper_mtc0_xcontext(arg);
4145 rn = "XContext";
4146 break;
4147 #endif
4148 default:
4149 goto die;
4151 break;
4152 case 21:
4153 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4154 switch (sel) {
4155 case 0:
4156 gen_helper_mtc0_framemask(arg);
4157 rn = "Framemask";
4158 break;
4159 default:
4160 goto die;
4162 break;
4163 case 22:
4164 /* ignored */
4165 rn = "Diagnostic"; /* implementation dependent */
4166 break;
4167 case 23:
4168 switch (sel) {
4169 case 0:
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;
4174 rn = "Debug";
4175 break;
4176 case 1:
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;
4181 // break;
4182 case 2:
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;
4187 // break;
4188 case 3:
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;
4195 // break;
4196 case 4:
4197 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
4198 /* Stop translation as we may have switched the execution mode */
4199 ctx->bstate = BS_STOP;
4200 rn = "TraceBPC";
4201 // break;
4202 default:
4203 goto die;
4205 break;
4206 case 24:
4207 switch (sel) {
4208 case 0:
4209 /* EJTAG support */
4210 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
4211 rn = "DEPC";
4212 break;
4213 default:
4214 goto die;
4216 break;
4217 case 25:
4218 switch (sel) {
4219 case 0:
4220 gen_helper_mtc0_performance0(arg);
4221 rn = "Performance0";
4222 break;
4223 case 1:
4224 // gen_helper_mtc0_performance1(arg);
4225 rn = "Performance1";
4226 // break;
4227 case 2:
4228 // gen_helper_mtc0_performance2(arg);
4229 rn = "Performance2";
4230 // break;
4231 case 3:
4232 // gen_helper_mtc0_performance3(arg);
4233 rn = "Performance3";
4234 // break;
4235 case 4:
4236 // gen_helper_mtc0_performance4(arg);
4237 rn = "Performance4";
4238 // break;
4239 case 5:
4240 // gen_helper_mtc0_performance5(arg);
4241 rn = "Performance5";
4242 // break;
4243 case 6:
4244 // gen_helper_mtc0_performance6(arg);
4245 rn = "Performance6";
4246 // break;
4247 case 7:
4248 // gen_helper_mtc0_performance7(arg);
4249 rn = "Performance7";
4250 // break;
4251 default:
4252 goto die;
4254 break;
4255 case 26:
4256 /* ignored */
4257 rn = "ECC";
4258 break;
4259 case 27:
4260 switch (sel) {
4261 case 0 ... 3:
4262 /* ignored */
4263 rn = "CacheErr";
4264 break;
4265 default:
4266 goto die;
4268 break;
4269 case 28:
4270 switch (sel) {
4271 case 0:
4272 case 2:
4273 case 4:
4274 case 6:
4275 gen_helper_mtc0_taglo(arg);
4276 rn = "TagLo";
4277 break;
4278 case 1:
4279 case 3:
4280 case 5:
4281 case 7:
4282 gen_helper_mtc0_datalo(arg);
4283 rn = "DataLo";
4284 break;
4285 default:
4286 goto die;
4288 break;
4289 case 29:
4290 switch (sel) {
4291 case 0:
4292 case 2:
4293 case 4:
4294 case 6:
4295 gen_helper_mtc0_taghi(arg);
4296 rn = "TagHi";
4297 break;
4298 case 1:
4299 case 3:
4300 case 5:
4301 case 7:
4302 gen_helper_mtc0_datahi(arg);
4303 rn = "DataHi";
4304 break;
4305 default:
4306 rn = "invalid sel";
4307 goto die;
4309 break;
4310 case 30:
4311 switch (sel) {
4312 case 0:
4313 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
4314 rn = "ErrorEPC";
4315 break;
4316 default:
4317 goto die;
4319 break;
4320 case 31:
4321 switch (sel) {
4322 case 0:
4323 /* EJTAG support */
4324 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4325 rn = "DESAVE";
4326 break;
4327 default:
4328 goto die;
4330 /* Stop translation as we may have switched the execution mode */
4331 ctx->bstate = BS_STOP;
4332 break;
4333 default:
4334 goto die;
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. */
4339 if (use_icount) {
4340 gen_io_end();
4341 ctx->bstate = BS_STOP;
4343 return;
4345 die:
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";
4355 if (sel != 0)
4356 check_insn(env, ctx, ISA_MIPS64);
4358 switch (reg) {
4359 case 0:
4360 switch (sel) {
4361 case 0:
4362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4363 rn = "Index";
4364 break;
4365 case 1:
4366 check_insn(env, ctx, ASE_MT);
4367 gen_helper_mfc0_mvpcontrol(arg);
4368 rn = "MVPControl";
4369 break;
4370 case 2:
4371 check_insn(env, ctx, ASE_MT);
4372 gen_helper_mfc0_mvpconf0(arg);
4373 rn = "MVPConf0";
4374 break;
4375 case 3:
4376 check_insn(env, ctx, ASE_MT);
4377 gen_helper_mfc0_mvpconf1(arg);
4378 rn = "MVPConf1";
4379 break;
4380 default:
4381 goto die;
4383 break;
4384 case 1:
4385 switch (sel) {
4386 case 0:
4387 gen_helper_mfc0_random(arg);
4388 rn = "Random";
4389 break;
4390 case 1:
4391 check_insn(env, ctx, ASE_MT);
4392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4393 rn = "VPEControl";
4394 break;
4395 case 2:
4396 check_insn(env, ctx, ASE_MT);
4397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4398 rn = "VPEConf0";
4399 break;
4400 case 3:
4401 check_insn(env, ctx, ASE_MT);
4402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4403 rn = "VPEConf1";
4404 break;
4405 case 4:
4406 check_insn(env, ctx, ASE_MT);
4407 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
4408 rn = "YQMask";
4409 break;
4410 case 5:
4411 check_insn(env, ctx, ASE_MT);
4412 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
4413 rn = "VPESchedule";
4414 break;
4415 case 6:
4416 check_insn(env, ctx, ASE_MT);
4417 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4418 rn = "VPEScheFBack";
4419 break;
4420 case 7:
4421 check_insn(env, ctx, ASE_MT);
4422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4423 rn = "VPEOpt";
4424 break;
4425 default:
4426 goto die;
4428 break;
4429 case 2:
4430 switch (sel) {
4431 case 0:
4432 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4433 rn = "EntryLo0";
4434 break;
4435 case 1:
4436 check_insn(env, ctx, ASE_MT);
4437 gen_helper_mfc0_tcstatus(arg);
4438 rn = "TCStatus";
4439 break;
4440 case 2:
4441 check_insn(env, ctx, ASE_MT);
4442 gen_helper_mfc0_tcbind(arg);
4443 rn = "TCBind";
4444 break;
4445 case 3:
4446 check_insn(env, ctx, ASE_MT);
4447 gen_helper_dmfc0_tcrestart(arg);
4448 rn = "TCRestart";
4449 break;
4450 case 4:
4451 check_insn(env, ctx, ASE_MT);
4452 gen_helper_dmfc0_tchalt(arg);
4453 rn = "TCHalt";
4454 break;
4455 case 5:
4456 check_insn(env, ctx, ASE_MT);
4457 gen_helper_dmfc0_tccontext(arg);
4458 rn = "TCContext";
4459 break;
4460 case 6:
4461 check_insn(env, ctx, ASE_MT);
4462 gen_helper_dmfc0_tcschedule(arg);
4463 rn = "TCSchedule";
4464 break;
4465 case 7:
4466 check_insn(env, ctx, ASE_MT);
4467 gen_helper_dmfc0_tcschefback(arg);
4468 rn = "TCScheFBack";
4469 break;
4470 default:
4471 goto die;
4473 break;
4474 case 3:
4475 switch (sel) {
4476 case 0:
4477 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4478 rn = "EntryLo1";
4479 break;
4480 default:
4481 goto die;
4483 break;
4484 case 4:
4485 switch (sel) {
4486 case 0:
4487 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4488 rn = "Context";
4489 break;
4490 case 1:
4491 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4492 rn = "ContextConfig";
4493 // break;
4494 default:
4495 goto die;
4497 break;
4498 case 5:
4499 switch (sel) {
4500 case 0:
4501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4502 rn = "PageMask";
4503 break;
4504 case 1:
4505 check_insn(env, ctx, ISA_MIPS32R2);
4506 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4507 rn = "PageGrain";
4508 break;
4509 default:
4510 goto die;
4512 break;
4513 case 6:
4514 switch (sel) {
4515 case 0:
4516 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4517 rn = "Wired";
4518 break;
4519 case 1:
4520 check_insn(env, ctx, ISA_MIPS32R2);
4521 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4522 rn = "SRSConf0";
4523 break;
4524 case 2:
4525 check_insn(env, ctx, ISA_MIPS32R2);
4526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4527 rn = "SRSConf1";
4528 break;
4529 case 3:
4530 check_insn(env, ctx, ISA_MIPS32R2);
4531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4532 rn = "SRSConf2";
4533 break;
4534 case 4:
4535 check_insn(env, ctx, ISA_MIPS32R2);
4536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4537 rn = "SRSConf3";
4538 break;
4539 case 5:
4540 check_insn(env, ctx, ISA_MIPS32R2);
4541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4542 rn = "SRSConf4";
4543 break;
4544 default:
4545 goto die;
4547 break;
4548 case 7:
4549 switch (sel) {
4550 case 0:
4551 check_insn(env, ctx, ISA_MIPS32R2);
4552 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4553 rn = "HWREna";
4554 break;
4555 default:
4556 goto die;
4558 break;
4559 case 8:
4560 switch (sel) {
4561 case 0:
4562 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4563 rn = "BadVAddr";
4564 break;
4565 default:
4566 goto die;
4568 break;
4569 case 9:
4570 switch (sel) {
4571 case 0:
4572 /* Mark as an IO operation because we read the time. */
4573 if (use_icount)
4574 gen_io_start();
4575 gen_helper_mfc0_count(arg);
4576 if (use_icount) {
4577 gen_io_end();
4579 /* Break the TB to be able to take timer interrupts immediately
4580 after reading count. */
4581 ctx->bstate = BS_STOP;
4582 rn = "Count";
4583 break;
4584 /* 6,7 are implementation dependent */
4585 default:
4586 goto die;
4588 break;
4589 case 10:
4590 switch (sel) {
4591 case 0:
4592 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4593 rn = "EntryHi";
4594 break;
4595 default:
4596 goto die;
4598 break;
4599 case 11:
4600 switch (sel) {
4601 case 0:
4602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4603 rn = "Compare";
4604 break;
4605 /* 6,7 are implementation dependent */
4606 default:
4607 goto die;
4609 break;
4610 case 12:
4611 switch (sel) {
4612 case 0:
4613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4614 rn = "Status";
4615 break;
4616 case 1:
4617 check_insn(env, ctx, ISA_MIPS32R2);
4618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4619 rn = "IntCtl";
4620 break;
4621 case 2:
4622 check_insn(env, ctx, ISA_MIPS32R2);
4623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4624 rn = "SRSCtl";
4625 break;
4626 case 3:
4627 check_insn(env, ctx, ISA_MIPS32R2);
4628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4629 rn = "SRSMap";
4630 break;
4631 default:
4632 goto die;
4634 break;
4635 case 13:
4636 switch (sel) {
4637 case 0:
4638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4639 rn = "Cause";
4640 break;
4641 default:
4642 goto die;
4644 break;
4645 case 14:
4646 switch (sel) {
4647 case 0:
4648 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4649 rn = "EPC";
4650 break;
4651 default:
4652 goto die;
4654 break;
4655 case 15:
4656 switch (sel) {
4657 case 0:
4658 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4659 rn = "PRid";
4660 break;
4661 case 1:
4662 check_insn(env, ctx, ISA_MIPS32R2);
4663 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4664 rn = "EBase";
4665 break;
4666 default:
4667 goto die;
4669 break;
4670 case 16:
4671 switch (sel) {
4672 case 0:
4673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4674 rn = "Config";
4675 break;
4676 case 1:
4677 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4678 rn = "Config1";
4679 break;
4680 case 2:
4681 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4682 rn = "Config2";
4683 break;
4684 case 3:
4685 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4686 rn = "Config3";
4687 break;
4688 /* 6,7 are implementation dependent */
4689 case 6:
4690 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4691 rn = "Config6";
4692 break;
4693 case 7:
4694 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4695 rn = "Config7";
4696 break;
4697 default:
4698 goto die;
4700 break;
4701 case 17:
4702 switch (sel) {
4703 case 0:
4704 gen_helper_dmfc0_lladdr(arg);
4705 rn = "LLAddr";
4706 break;
4707 default:
4708 goto die;
4710 break;
4711 case 18:
4712 switch (sel) {
4713 case 0 ... 7:
4714 gen_helper_1i(dmfc0_watchlo, arg, sel);
4715 rn = "WatchLo";
4716 break;
4717 default:
4718 goto die;
4720 break;
4721 case 19:
4722 switch (sel) {
4723 case 0 ... 7:
4724 gen_helper_1i(mfc0_watchhi, arg, sel);
4725 rn = "WatchHi";
4726 break;
4727 default:
4728 goto die;
4730 break;
4731 case 20:
4732 switch (sel) {
4733 case 0:
4734 check_insn(env, ctx, ISA_MIPS3);
4735 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4736 rn = "XContext";
4737 break;
4738 default:
4739 goto die;
4741 break;
4742 case 21:
4743 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4744 switch (sel) {
4745 case 0:
4746 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4747 rn = "Framemask";
4748 break;
4749 default:
4750 goto die;
4752 break;
4753 case 22:
4754 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4755 rn = "'Diagnostic"; /* implementation dependent */
4756 break;
4757 case 23:
4758 switch (sel) {
4759 case 0:
4760 gen_helper_mfc0_debug(arg); /* EJTAG support */
4761 rn = "Debug";
4762 break;
4763 case 1:
4764 // gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4765 rn = "TraceControl";
4766 // break;
4767 case 2:
4768 // gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4769 rn = "TraceControl2";
4770 // break;
4771 case 3:
4772 // gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4773 rn = "UserTraceData";
4774 // break;
4775 case 4:
4776 // gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4777 rn = "TraceBPC";
4778 // break;
4779 default:
4780 goto die;
4782 break;
4783 case 24:
4784 switch (sel) {
4785 case 0:
4786 /* EJTAG support */
4787 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4788 rn = "DEPC";
4789 break;
4790 default:
4791 goto die;
4793 break;
4794 case 25:
4795 switch (sel) {
4796 case 0:
4797 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4798 rn = "Performance0";
4799 break;
4800 case 1:
4801 // gen_helper_dmfc0_performance1(arg);
4802 rn = "Performance1";
4803 // break;
4804 case 2:
4805 // gen_helper_dmfc0_performance2(arg);
4806 rn = "Performance2";
4807 // break;
4808 case 3:
4809 // gen_helper_dmfc0_performance3(arg);
4810 rn = "Performance3";
4811 // break;
4812 case 4:
4813 // gen_helper_dmfc0_performance4(arg);
4814 rn = "Performance4";
4815 // break;
4816 case 5:
4817 // gen_helper_dmfc0_performance5(arg);
4818 rn = "Performance5";
4819 // break;
4820 case 6:
4821 // gen_helper_dmfc0_performance6(arg);
4822 rn = "Performance6";
4823 // break;
4824 case 7:
4825 // gen_helper_dmfc0_performance7(arg);
4826 rn = "Performance7";
4827 // break;
4828 default:
4829 goto die;
4831 break;
4832 case 26:
4833 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4834 rn = "ECC";
4835 break;
4836 case 27:
4837 switch (sel) {
4838 /* ignored */
4839 case 0 ... 3:
4840 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4841 rn = "CacheErr";
4842 break;
4843 default:
4844 goto die;
4846 break;
4847 case 28:
4848 switch (sel) {
4849 case 0:
4850 case 2:
4851 case 4:
4852 case 6:
4853 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4854 rn = "TagLo";
4855 break;
4856 case 1:
4857 case 3:
4858 case 5:
4859 case 7:
4860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4861 rn = "DataLo";
4862 break;
4863 default:
4864 goto die;
4866 break;
4867 case 29:
4868 switch (sel) {
4869 case 0:
4870 case 2:
4871 case 4:
4872 case 6:
4873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4874 rn = "TagHi";
4875 break;
4876 case 1:
4877 case 3:
4878 case 5:
4879 case 7:
4880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4881 rn = "DataHi";
4882 break;
4883 default:
4884 goto die;
4886 break;
4887 case 30:
4888 switch (sel) {
4889 case 0:
4890 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4891 rn = "ErrorEPC";
4892 break;
4893 default:
4894 goto die;
4896 break;
4897 case 31:
4898 switch (sel) {
4899 case 0:
4900 /* EJTAG support */
4901 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4902 rn = "DESAVE";
4903 break;
4904 default:
4905 goto die;
4907 break;
4908 default:
4909 goto die;
4911 (void)rn; /* avoid a compiler warning */
4912 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4913 return;
4915 die:
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";
4924 if (sel != 0)
4925 check_insn(env, ctx, ISA_MIPS64);
4927 if (use_icount)
4928 gen_io_start();
4930 switch (reg) {
4931 case 0:
4932 switch (sel) {
4933 case 0:
4934 gen_helper_mtc0_index(arg);
4935 rn = "Index";
4936 break;
4937 case 1:
4938 check_insn(env, ctx, ASE_MT);
4939 gen_helper_mtc0_mvpcontrol(arg);
4940 rn = "MVPControl";
4941 break;
4942 case 2:
4943 check_insn(env, ctx, ASE_MT);
4944 /* ignored */
4945 rn = "MVPConf0";
4946 break;
4947 case 3:
4948 check_insn(env, ctx, ASE_MT);
4949 /* ignored */
4950 rn = "MVPConf1";
4951 break;
4952 default:
4953 goto die;
4955 break;
4956 case 1:
4957 switch (sel) {
4958 case 0:
4959 /* ignored */
4960 rn = "Random";
4961 break;
4962 case 1:
4963 check_insn(env, ctx, ASE_MT);
4964 gen_helper_mtc0_vpecontrol(arg);
4965 rn = "VPEControl";
4966 break;
4967 case 2:
4968 check_insn(env, ctx, ASE_MT);
4969 gen_helper_mtc0_vpeconf0(arg);
4970 rn = "VPEConf0";
4971 break;
4972 case 3:
4973 check_insn(env, ctx, ASE_MT);
4974 gen_helper_mtc0_vpeconf1(arg);
4975 rn = "VPEConf1";
4976 break;
4977 case 4:
4978 check_insn(env, ctx, ASE_MT);
4979 gen_helper_mtc0_yqmask(arg);
4980 rn = "YQMask";
4981 break;
4982 case 5:
4983 check_insn(env, ctx, ASE_MT);
4984 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
4985 rn = "VPESchedule";
4986 break;
4987 case 6:
4988 check_insn(env, ctx, ASE_MT);
4989 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4990 rn = "VPEScheFBack";
4991 break;
4992 case 7:
4993 check_insn(env, ctx, ASE_MT);
4994 gen_helper_mtc0_vpeopt(arg);
4995 rn = "VPEOpt";
4996 break;
4997 default:
4998 goto die;
5000 break;
5001 case 2:
5002 switch (sel) {
5003 case 0:
5004 gen_helper_mtc0_entrylo0(arg);
5005 rn = "EntryLo0";
5006 break;
5007 case 1:
5008 check_insn(env, ctx, ASE_MT);
5009 gen_helper_mtc0_tcstatus(arg);
5010 rn = "TCStatus";
5011 break;
5012 case 2:
5013 check_insn(env, ctx, ASE_MT);
5014 gen_helper_mtc0_tcbind(arg);
5015 rn = "TCBind";
5016 break;
5017 case 3:
5018 check_insn(env, ctx, ASE_MT);
5019 gen_helper_mtc0_tcrestart(arg);
5020 rn = "TCRestart";
5021 break;
5022 case 4:
5023 check_insn(env, ctx, ASE_MT);
5024 gen_helper_mtc0_tchalt(arg);
5025 rn = "TCHalt";
5026 break;
5027 case 5:
5028 check_insn(env, ctx, ASE_MT);
5029 gen_helper_mtc0_tccontext(arg);
5030 rn = "TCContext";
5031 break;
5032 case 6:
5033 check_insn(env, ctx, ASE_MT);
5034 gen_helper_mtc0_tcschedule(arg);
5035 rn = "TCSchedule";
5036 break;
5037 case 7:
5038 check_insn(env, ctx, ASE_MT);
5039 gen_helper_mtc0_tcschefback(arg);
5040 rn = "TCScheFBack";
5041 break;
5042 default:
5043 goto die;
5045 break;
5046 case 3:
5047 switch (sel) {
5048 case 0:
5049 gen_helper_mtc0_entrylo1(arg);
5050 rn = "EntryLo1";
5051 break;
5052 default:
5053 goto die;
5055 break;
5056 case 4:
5057 switch (sel) {
5058 case 0:
5059 gen_helper_mtc0_context(arg);
5060 rn = "Context";
5061 break;
5062 case 1:
5063 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
5064 rn = "ContextConfig";
5065 // break;
5066 default:
5067 goto die;
5069 break;
5070 case 5:
5071 switch (sel) {
5072 case 0:
5073 gen_helper_mtc0_pagemask(arg);
5074 rn = "PageMask";
5075 break;
5076 case 1:
5077 check_insn(env, ctx, ISA_MIPS32R2);
5078 gen_helper_mtc0_pagegrain(arg);
5079 rn = "PageGrain";
5080 break;
5081 default:
5082 goto die;
5084 break;
5085 case 6:
5086 switch (sel) {
5087 case 0:
5088 gen_helper_mtc0_wired(arg);
5089 rn = "Wired";
5090 break;
5091 case 1:
5092 check_insn(env, ctx, ISA_MIPS32R2);
5093 gen_helper_mtc0_srsconf0(arg);
5094 rn = "SRSConf0";
5095 break;
5096 case 2:
5097 check_insn(env, ctx, ISA_MIPS32R2);
5098 gen_helper_mtc0_srsconf1(arg);
5099 rn = "SRSConf1";
5100 break;
5101 case 3:
5102 check_insn(env, ctx, ISA_MIPS32R2);
5103 gen_helper_mtc0_srsconf2(arg);
5104 rn = "SRSConf2";
5105 break;
5106 case 4:
5107 check_insn(env, ctx, ISA_MIPS32R2);
5108 gen_helper_mtc0_srsconf3(arg);
5109 rn = "SRSConf3";
5110 break;
5111 case 5:
5112 check_insn(env, ctx, ISA_MIPS32R2);
5113 gen_helper_mtc0_srsconf4(arg);
5114 rn = "SRSConf4";
5115 break;
5116 default:
5117 goto die;
5119 break;
5120 case 7:
5121 switch (sel) {
5122 case 0:
5123 check_insn(env, ctx, ISA_MIPS32R2);
5124 gen_helper_mtc0_hwrena(arg);
5125 rn = "HWREna";
5126 break;
5127 default:
5128 goto die;
5130 break;
5131 case 8:
5132 /* ignored */
5133 rn = "BadVAddr";
5134 break;
5135 case 9:
5136 switch (sel) {
5137 case 0:
5138 gen_helper_mtc0_count(arg);
5139 rn = "Count";
5140 break;
5141 /* 6,7 are implementation dependent */
5142 default:
5143 goto die;
5145 /* Stop translation as we may have switched the execution mode */
5146 ctx->bstate = BS_STOP;
5147 break;
5148 case 10:
5149 switch (sel) {
5150 case 0:
5151 gen_helper_mtc0_entryhi(arg);
5152 rn = "EntryHi";
5153 break;
5154 default:
5155 goto die;
5157 break;
5158 case 11:
5159 switch (sel) {
5160 case 0:
5161 gen_helper_mtc0_compare(arg);
5162 rn = "Compare";
5163 break;
5164 /* 6,7 are implementation dependent */
5165 default:
5166 goto die;
5168 /* Stop translation as we may have switched the execution mode */
5169 ctx->bstate = BS_STOP;
5170 break;
5171 case 12:
5172 switch (sel) {
5173 case 0:
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;
5179 rn = "Status";
5180 break;
5181 case 1:
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;
5186 rn = "IntCtl";
5187 break;
5188 case 2:
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;
5193 rn = "SRSCtl";
5194 break;
5195 case 3:
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;
5200 rn = "SRSMap";
5201 break;
5202 default:
5203 goto die;
5205 break;
5206 case 13:
5207 switch (sel) {
5208 case 0:
5209 save_cpu_state(ctx, 1);
5210 /* Mark as an IO operation because we may trigger a software
5211 interrupt. */
5212 if (use_icount) {
5213 gen_io_start();
5215 gen_helper_mtc0_cause(arg);
5216 if (use_icount) {
5217 gen_io_end();
5219 /* Stop translation as we may have triggered an intetrupt */
5220 ctx->bstate = BS_STOP;
5221 rn = "Cause";
5222 break;
5223 default:
5224 goto die;
5226 break;
5227 case 14:
5228 switch (sel) {
5229 case 0:
5230 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5231 rn = "EPC";
5232 break;
5233 default:
5234 goto die;
5236 break;
5237 case 15:
5238 switch (sel) {
5239 case 0:
5240 /* ignored */
5241 rn = "PRid";
5242 break;
5243 case 1:
5244 check_insn(env, ctx, ISA_MIPS32R2);
5245 gen_helper_mtc0_ebase(arg);
5246 rn = "EBase";
5247 break;
5248 default:
5249 goto die;
5251 break;
5252 case 16:
5253 switch (sel) {
5254 case 0:
5255 gen_helper_mtc0_config0(arg);
5256 rn = "Config";
5257 /* Stop translation as we may have switched the execution mode */
5258 ctx->bstate = BS_STOP;
5259 break;
5260 case 1:
5261 /* ignored, read only */
5262 rn = "Config1";
5263 break;
5264 case 2:
5265 gen_helper_mtc0_config2(arg);
5266 rn = "Config2";
5267 /* Stop translation as we may have switched the execution mode */
5268 ctx->bstate = BS_STOP;
5269 break;
5270 case 3:
5271 /* ignored */
5272 rn = "Config3";
5273 break;
5274 /* 6,7 are implementation dependent */
5275 default:
5276 rn = "Invalid config selector";
5277 goto die;
5279 break;
5280 case 17:
5281 switch (sel) {
5282 case 0:
5283 gen_helper_mtc0_lladdr(arg);
5284 rn = "LLAddr";
5285 break;
5286 default:
5287 goto die;
5289 break;
5290 case 18:
5291 switch (sel) {
5292 case 0 ... 7:
5293 gen_helper_1i(mtc0_watchlo, arg, sel);
5294 rn = "WatchLo";
5295 break;
5296 default:
5297 goto die;
5299 break;
5300 case 19:
5301 switch (sel) {
5302 case 0 ... 7:
5303 gen_helper_1i(mtc0_watchhi, arg, sel);
5304 rn = "WatchHi";
5305 break;
5306 default:
5307 goto die;
5309 break;
5310 case 20:
5311 switch (sel) {
5312 case 0:
5313 check_insn(env, ctx, ISA_MIPS3);
5314 gen_helper_mtc0_xcontext(arg);
5315 rn = "XContext";
5316 break;
5317 default:
5318 goto die;
5320 break;
5321 case 21:
5322 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5323 switch (sel) {
5324 case 0:
5325 gen_helper_mtc0_framemask(arg);
5326 rn = "Framemask";
5327 break;
5328 default:
5329 goto die;
5331 break;
5332 case 22:
5333 /* ignored */
5334 rn = "Diagnostic"; /* implementation dependent */
5335 break;
5336 case 23:
5337 switch (sel) {
5338 case 0:
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;
5343 rn = "Debug";
5344 break;
5345 case 1:
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";
5350 // break;
5351 case 2:
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";
5356 // break;
5357 case 3:
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";
5362 // break;
5363 case 4:
5364 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5365 /* Stop translation as we may have switched the execution mode */
5366 ctx->bstate = BS_STOP;
5367 rn = "TraceBPC";
5368 // break;
5369 default:
5370 goto die;
5372 break;
5373 case 24:
5374 switch (sel) {
5375 case 0:
5376 /* EJTAG support */
5377 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5378 rn = "DEPC";
5379 break;
5380 default:
5381 goto die;
5383 break;
5384 case 25:
5385 switch (sel) {
5386 case 0:
5387 gen_helper_mtc0_performance0(arg);
5388 rn = "Performance0";
5389 break;
5390 case 1:
5391 // gen_helper_mtc0_performance1(arg);
5392 rn = "Performance1";
5393 // break;
5394 case 2:
5395 // gen_helper_mtc0_performance2(arg);
5396 rn = "Performance2";
5397 // break;
5398 case 3:
5399 // gen_helper_mtc0_performance3(arg);
5400 rn = "Performance3";
5401 // break;
5402 case 4:
5403 // gen_helper_mtc0_performance4(arg);
5404 rn = "Performance4";
5405 // break;
5406 case 5:
5407 // gen_helper_mtc0_performance5(arg);
5408 rn = "Performance5";
5409 // break;
5410 case 6:
5411 // gen_helper_mtc0_performance6(arg);
5412 rn = "Performance6";
5413 // break;
5414 case 7:
5415 // gen_helper_mtc0_performance7(arg);
5416 rn = "Performance7";
5417 // break;
5418 default:
5419 goto die;
5421 break;
5422 case 26:
5423 /* ignored */
5424 rn = "ECC";
5425 break;
5426 case 27:
5427 switch (sel) {
5428 case 0 ... 3:
5429 /* ignored */
5430 rn = "CacheErr";
5431 break;
5432 default:
5433 goto die;
5435 break;
5436 case 28:
5437 switch (sel) {
5438 case 0:
5439 case 2:
5440 case 4:
5441 case 6:
5442 gen_helper_mtc0_taglo(arg);
5443 rn = "TagLo";
5444 break;
5445 case 1:
5446 case 3:
5447 case 5:
5448 case 7:
5449 gen_helper_mtc0_datalo(arg);
5450 rn = "DataLo";
5451 break;
5452 default:
5453 goto die;
5455 break;
5456 case 29:
5457 switch (sel) {
5458 case 0:
5459 case 2:
5460 case 4:
5461 case 6:
5462 gen_helper_mtc0_taghi(arg);
5463 rn = "TagHi";
5464 break;
5465 case 1:
5466 case 3:
5467 case 5:
5468 case 7:
5469 gen_helper_mtc0_datahi(arg);
5470 rn = "DataHi";
5471 break;
5472 default:
5473 rn = "invalid sel";
5474 goto die;
5476 break;
5477 case 30:
5478 switch (sel) {
5479 case 0:
5480 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5481 rn = "ErrorEPC";
5482 break;
5483 default:
5484 goto die;
5486 break;
5487 case 31:
5488 switch (sel) {
5489 case 0:
5490 /* EJTAG support */
5491 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5492 rn = "DESAVE";
5493 break;
5494 default:
5495 goto die;
5497 /* Stop translation as we may have switched the execution mode */
5498 ctx->bstate = BS_STOP;
5499 break;
5500 default:
5501 goto die;
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. */
5506 if (use_icount) {
5507 gen_io_end();
5508 ctx->bstate = BS_STOP;
5510 return;
5512 die:
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);
5531 else if (u == 0) {
5532 switch (rt) {
5533 case 1:
5534 switch (sel) {
5535 case 1:
5536 gen_helper_mftc0_vpecontrol(t0);
5537 break;
5538 case 2:
5539 gen_helper_mftc0_vpeconf0(t0);
5540 break;
5541 default:
5542 goto die;
5543 break;
5545 break;
5546 case 2:
5547 switch (sel) {
5548 case 1:
5549 gen_helper_mftc0_tcstatus(t0);
5550 break;
5551 case 2:
5552 gen_helper_mftc0_tcbind(t0);
5553 break;
5554 case 3:
5555 gen_helper_mftc0_tcrestart(t0);
5556 break;
5557 case 4:
5558 gen_helper_mftc0_tchalt(t0);
5559 break;
5560 case 5:
5561 gen_helper_mftc0_tccontext(t0);
5562 break;
5563 case 6:
5564 gen_helper_mftc0_tcschedule(t0);
5565 break;
5566 case 7:
5567 gen_helper_mftc0_tcschefback(t0);
5568 break;
5569 default:
5570 gen_mfc0(env, ctx, t0, rt, sel);
5571 break;
5573 break;
5574 case 10:
5575 switch (sel) {
5576 case 0:
5577 gen_helper_mftc0_entryhi(t0);
5578 break;
5579 default:
5580 gen_mfc0(env, ctx, t0, rt, sel);
5581 break;
5583 case 12:
5584 switch (sel) {
5585 case 0:
5586 gen_helper_mftc0_status(t0);
5587 break;
5588 default:
5589 gen_mfc0(env, ctx, t0, rt, sel);
5590 break;
5592 case 13:
5593 switch (sel) {
5594 case 0:
5595 gen_helper_mftc0_cause(t0);
5596 break;
5597 default:
5598 goto die;
5599 break;
5601 break;
5602 case 14:
5603 switch (sel) {
5604 case 0:
5605 gen_helper_mftc0_epc(t0);
5606 break;
5607 default:
5608 goto die;
5609 break;
5611 break;
5612 case 15:
5613 switch (sel) {
5614 case 1:
5615 gen_helper_mftc0_ebase(t0);
5616 break;
5617 default:
5618 goto die;
5619 break;
5621 break;
5622 case 16:
5623 switch (sel) {
5624 case 0 ... 7:
5625 gen_helper_mftc0_configx(t0, tcg_const_tl(sel));
5626 break;
5627 default:
5628 goto die;
5629 break;
5631 break;
5632 case 23:
5633 switch (sel) {
5634 case 0:
5635 gen_helper_mftc0_debug(t0);
5636 break;
5637 default:
5638 gen_mfc0(env, ctx, t0, rt, sel);
5639 break;
5641 break;
5642 default:
5643 gen_mfc0(env, ctx, t0, rt, sel);
5645 } else switch (sel) {
5646 /* GPR registers. */
5647 case 0:
5648 gen_helper_1i(mftgpr, t0, rt);
5649 break;
5650 /* Auxiliary CPU registers */
5651 case 1:
5652 switch (rt) {
5653 case 0:
5654 gen_helper_1i(mftlo, t0, 0);
5655 break;
5656 case 1:
5657 gen_helper_1i(mfthi, t0, 0);
5658 break;
5659 case 2:
5660 gen_helper_1i(mftacx, t0, 0);
5661 break;
5662 case 4:
5663 gen_helper_1i(mftlo, t0, 1);
5664 break;
5665 case 5:
5666 gen_helper_1i(mfthi, t0, 1);
5667 break;
5668 case 6:
5669 gen_helper_1i(mftacx, t0, 1);
5670 break;
5671 case 8:
5672 gen_helper_1i(mftlo, t0, 2);
5673 break;
5674 case 9:
5675 gen_helper_1i(mfthi, t0, 2);
5676 break;
5677 case 10:
5678 gen_helper_1i(mftacx, t0, 2);
5679 break;
5680 case 12:
5681 gen_helper_1i(mftlo, t0, 3);
5682 break;
5683 case 13:
5684 gen_helper_1i(mfthi, t0, 3);
5685 break;
5686 case 14:
5687 gen_helper_1i(mftacx, t0, 3);
5688 break;
5689 case 16:
5690 gen_helper_mftdsp(t0);
5691 break;
5692 default:
5693 goto die;
5695 break;
5696 /* Floating point (COP1). */
5697 case 2:
5698 /* XXX: For now we support only a single FPU context. */
5699 if (h == 0) {
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);
5705 } else {
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);
5712 break;
5713 case 3:
5714 /* XXX: For now we support only a single FPU context. */
5715 gen_helper_1i(cfc1, t0, rt);
5716 break;
5717 /* COP2: Not implemented. */
5718 case 4:
5719 case 5:
5720 /* fall through */
5721 default:
5722 goto die;
5724 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5725 gen_store_gpr(t0, rd);
5726 tcg_temp_free(t0);
5727 return;
5729 die:
5730 tcg_temp_free(t0);
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))))
5745 /* NOP */ ;
5746 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5747 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5748 /* NOP */ ;
5749 else if (u == 0) {
5750 switch (rd) {
5751 case 1:
5752 switch (sel) {
5753 case 1:
5754 gen_helper_mttc0_vpecontrol(t0);
5755 break;
5756 case 2:
5757 gen_helper_mttc0_vpeconf0(t0);
5758 break;
5759 default:
5760 goto die;
5761 break;
5763 break;
5764 case 2:
5765 switch (sel) {
5766 case 1:
5767 gen_helper_mttc0_tcstatus(t0);
5768 break;
5769 case 2:
5770 gen_helper_mttc0_tcbind(t0);
5771 break;
5772 case 3:
5773 gen_helper_mttc0_tcrestart(t0);
5774 break;
5775 case 4:
5776 gen_helper_mttc0_tchalt(t0);
5777 break;
5778 case 5:
5779 gen_helper_mttc0_tccontext(t0);
5780 break;
5781 case 6:
5782 gen_helper_mttc0_tcschedule(t0);
5783 break;
5784 case 7:
5785 gen_helper_mttc0_tcschefback(t0);
5786 break;
5787 default:
5788 gen_mtc0(env, ctx, t0, rd, sel);
5789 break;
5791 break;
5792 case 10:
5793 switch (sel) {
5794 case 0:
5795 gen_helper_mttc0_entryhi(t0);
5796 break;
5797 default:
5798 gen_mtc0(env, ctx, t0, rd, sel);
5799 break;
5801 case 12:
5802 switch (sel) {
5803 case 0:
5804 gen_helper_mttc0_status(t0);
5805 break;
5806 default:
5807 gen_mtc0(env, ctx, t0, rd, sel);
5808 break;
5810 case 13:
5811 switch (sel) {
5812 case 0:
5813 gen_helper_mttc0_cause(t0);
5814 break;
5815 default:
5816 goto die;
5817 break;
5819 break;
5820 case 15:
5821 switch (sel) {
5822 case 1:
5823 gen_helper_mttc0_ebase(t0);
5824 break;
5825 default:
5826 goto die;
5827 break;
5829 break;
5830 case 23:
5831 switch (sel) {
5832 case 0:
5833 gen_helper_mttc0_debug(t0);
5834 break;
5835 default:
5836 gen_mtc0(env, ctx, t0, rd, sel);
5837 break;
5839 break;
5840 default:
5841 gen_mtc0(env, ctx, t0, rd, sel);
5843 } else switch (sel) {
5844 /* GPR registers. */
5845 case 0:
5846 gen_helper_1i(mttgpr, t0, rd);
5847 break;
5848 /* Auxiliary CPU registers */
5849 case 1:
5850 switch (rd) {
5851 case 0:
5852 gen_helper_1i(mttlo, t0, 0);
5853 break;
5854 case 1:
5855 gen_helper_1i(mtthi, t0, 0);
5856 break;
5857 case 2:
5858 gen_helper_1i(mttacx, t0, 0);
5859 break;
5860 case 4:
5861 gen_helper_1i(mttlo, t0, 1);
5862 break;
5863 case 5:
5864 gen_helper_1i(mtthi, t0, 1);
5865 break;
5866 case 6:
5867 gen_helper_1i(mttacx, t0, 1);
5868 break;
5869 case 8:
5870 gen_helper_1i(mttlo, t0, 2);
5871 break;
5872 case 9:
5873 gen_helper_1i(mtthi, t0, 2);
5874 break;
5875 case 10:
5876 gen_helper_1i(mttacx, t0, 2);
5877 break;
5878 case 12:
5879 gen_helper_1i(mttlo, t0, 3);
5880 break;
5881 case 13:
5882 gen_helper_1i(mtthi, t0, 3);
5883 break;
5884 case 14:
5885 gen_helper_1i(mttacx, t0, 3);
5886 break;
5887 case 16:
5888 gen_helper_mttdsp(t0);
5889 break;
5890 default:
5891 goto die;
5893 break;
5894 /* Floating point (COP1). */
5895 case 2:
5896 /* XXX: For now we support only a single FPU context. */
5897 if (h == 0) {
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);
5903 } else {
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);
5910 break;
5911 case 3:
5912 /* XXX: For now we support only a single FPU context. */
5913 gen_helper_1i(ctc1, t0, rd);
5914 break;
5915 /* COP2: Not implemented. */
5916 case 4:
5917 case 5:
5918 /* fall through */
5919 default:
5920 goto die;
5922 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5923 tcg_temp_free(t0);
5924 return;
5926 die:
5927 tcg_temp_free(t0);
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);
5937 switch (opc) {
5938 case OPC_MFC0:
5939 if (rt == 0) {
5940 /* Treat as NOP. */
5941 return;
5943 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5944 opn = "mfc0";
5945 break;
5946 case OPC_MTC0:
5948 TCGv t0 = tcg_temp_new();
5950 gen_load_gpr(t0, rt);
5951 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5952 tcg_temp_free(t0);
5954 opn = "mtc0";
5955 break;
5956 #if defined(TARGET_MIPS64)
5957 case OPC_DMFC0:
5958 check_insn(env, ctx, ISA_MIPS3);
5959 if (rt == 0) {
5960 /* Treat as NOP. */
5961 return;
5963 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5964 opn = "dmfc0";
5965 break;
5966 case OPC_DMTC0:
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);
5973 tcg_temp_free(t0);
5975 opn = "dmtc0";
5976 break;
5977 #endif
5978 case OPC_MFTR:
5979 check_insn(env, ctx, ASE_MT);
5980 if (rd == 0) {
5981 /* Treat as NOP. */
5982 return;
5984 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5985 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5986 opn = "mftr";
5987 break;
5988 case OPC_MTTR:
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);
5992 opn = "mttr";
5993 break;
5994 case OPC_TLBWI:
5995 opn = "tlbwi";
5996 if (!env->tlb->helper_tlbwi)
5997 goto die;
5998 gen_helper_tlbwi();
5999 break;
6000 case OPC_TLBWR:
6001 opn = "tlbwr";
6002 if (!env->tlb->helper_tlbwr)
6003 goto die;
6004 gen_helper_tlbwr();
6005 break;
6006 case OPC_TLBP:
6007 opn = "tlbp";
6008 if (!env->tlb->helper_tlbp)
6009 goto die;
6010 gen_helper_tlbp();
6011 break;
6012 case OPC_TLBR:
6013 opn = "tlbr";
6014 if (!env->tlb->helper_tlbr)
6015 goto die;
6016 gen_helper_tlbr();
6017 break;
6018 case OPC_ERET:
6019 opn = "eret";
6020 check_insn(env, ctx, ISA_MIPS2);
6021 gen_helper_eret();
6022 ctx->bstate = BS_EXCP;
6023 break;
6024 case OPC_DERET:
6025 opn = "deret";
6026 check_insn(env, ctx, ISA_MIPS32);
6027 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6028 MIPS_INVAL(opn);
6029 generate_exception(ctx, EXCP_RI);
6030 } else {
6031 gen_helper_deret();
6032 ctx->bstate = BS_EXCP;
6034 break;
6035 case OPC_WAIT:
6036 opn = "wait";
6037 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6038 /* If we get an exception, we want to restart at next instruction */
6039 ctx->pc += 4;
6040 save_cpu_state(ctx, 1);
6041 ctx->pc -= 4;
6042 gen_helper_wait();
6043 ctx->bstate = BS_EXCP;
6044 break;
6045 default:
6046 die:
6047 MIPS_INVAL(opn);
6048 generate_exception(ctx, EXCP_RI);
6049 return;
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();
6064 if (cc != 0)
6065 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6067 btarget = ctx->pc + 4 + offset;
6069 switch (op) {
6070 case OPC_BC1F:
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);
6075 opn = "bc1f";
6076 goto not_likely;
6077 case OPC_BC1FL:
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);
6082 opn = "bc1fl";
6083 goto likely;
6084 case OPC_BC1T:
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);
6088 opn = "bc1t";
6089 goto not_likely;
6090 case OPC_BC1TL:
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);
6094 opn = "bc1tl";
6095 likely:
6096 ctx->hflags |= MIPS_HFLAG_BL;
6097 break;
6098 case OPC_BC1FANY2:
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);
6108 opn = "bc1any2f";
6109 goto not_likely;
6110 case OPC_BC1TANY2:
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);
6120 opn = "bc1any2t";
6121 goto not_likely;
6122 case OPC_BC1FANY4:
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);
6136 opn = "bc1any4f";
6137 goto not_likely;
6138 case OPC_BC1TANY4:
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);
6152 opn = "bc1any4t";
6153 not_likely:
6154 ctx->hflags |= MIPS_HFLAG_BC;
6155 break;
6156 default:
6157 MIPS_INVAL(opn);
6158 generate_exception (ctx, EXCP_RI);
6159 goto out;
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;
6166 out:
6167 tcg_temp_free_i32(t0);
6170 /* Coprocessor 1 (FPU) */
6172 #define FOP(func, fmt) (((fmt) << 21) | (func))
6174 enum fopcode {
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();
6319 switch (opc) {
6320 case OPC_MFC1:
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);
6329 opn = "mfc1";
6330 break;
6331 case OPC_MTC1:
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);
6340 opn = "mtc1";
6341 break;
6342 case OPC_CFC1:
6343 gen_helper_1i(cfc1, t0, fs);
6344 gen_store_gpr(t0, rt);
6345 opn = "cfc1";
6346 break;
6347 case OPC_CTC1:
6348 gen_load_gpr(t0, rt);
6349 gen_helper_1i(ctc1, t0, fs);
6350 opn = "ctc1";
6351 break;
6352 #if defined(TARGET_MIPS64)
6353 case OPC_DMFC1:
6354 gen_load_fpr64(ctx, t0, fs);
6355 gen_store_gpr(t0, rt);
6356 opn = "dmfc1";
6357 break;
6358 case OPC_DMTC1:
6359 gen_load_gpr(t0, rt);
6360 gen_store_fpr64(ctx, t0, fs);
6361 opn = "dmtc1";
6362 break;
6363 #endif
6364 case OPC_MFHC1:
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);
6373 opn = "mfhc1";
6374 break;
6375 case OPC_MTHC1:
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);
6384 opn = "mthc1";
6385 break;
6386 default:
6387 MIPS_INVAL(opn);
6388 generate_exception (ctx, EXCP_RI);
6389 goto out;
6391 (void)opn; /* avoid a compiler warning */
6392 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6394 out:
6395 tcg_temp_free(t0);
6398 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6400 int l1;
6401 TCGCond cond;
6402 TCGv_i32 t0;
6404 if (rd == 0) {
6405 /* Treat as NOP. */
6406 return;
6409 if (tf)
6410 cond = TCG_COND_EQ;
6411 else
6412 cond = TCG_COND_NE;
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);
6419 if (rs == 0) {
6420 tcg_gen_movi_tl(cpu_gpr[rd], 0);
6421 } else {
6422 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6424 gen_set_label(l1);
6427 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6429 int cond;
6430 TCGv_i32 t0 = tcg_temp_new_i32();
6431 int l1 = gen_new_label();
6433 if (tf)
6434 cond = TCG_COND_EQ;
6435 else
6436 cond = TCG_COND_NE;
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);
6442 gen_set_label(l1);
6443 tcg_temp_free_i32(t0);
6446 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6448 int cond;
6449 TCGv_i32 t0 = tcg_temp_new_i32();
6450 TCGv_i64 fp0;
6451 int l1 = gen_new_label();
6453 if (tf)
6454 cond = TCG_COND_EQ;
6455 else
6456 cond = TCG_COND_NE;
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);
6465 gen_set_label(l1);
6468 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6470 int cond;
6471 TCGv_i32 t0 = tcg_temp_new_i32();
6472 int l1 = gen_new_label();
6473 int l2 = gen_new_label();
6475 if (tf)
6476 cond = TCG_COND_EQ;
6477 else
6478 cond = TCG_COND_NE;
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);
6484 gen_set_label(l1);
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);
6491 gen_set_label(l2);
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[] = {
6500 "c.f",
6501 "c.un",
6502 "c.eq",
6503 "c.ueq",
6504 "c.olt",
6505 "c.ult",
6506 "c.ole",
6507 "c.ule",
6508 "c.sf",
6509 "c.ngle",
6510 "c.seq",
6511 "c.ngl",
6512 "c.lt",
6513 "c.nge",
6514 "c.le",
6515 "c.ngt",
6517 const char *condnames_abs[] = {
6518 "cabs.f",
6519 "cabs.un",
6520 "cabs.eq",
6521 "cabs.ueq",
6522 "cabs.olt",
6523 "cabs.ult",
6524 "cabs.ole",
6525 "cabs.ule",
6526 "cabs.sf",
6527 "cabs.ngle",
6528 "cabs.seq",
6529 "cabs.ngl",
6530 "cabs.lt",
6531 "cabs.nge",
6532 "cabs.le",
6533 "cabs.ngt",
6535 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6536 uint32_t func = ctx->opcode & 0x3f;
6538 switch (op1) {
6539 case OPC_ADD_S:
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);
6551 opn = "add.s";
6552 optype = BINOP;
6553 break;
6554 case OPC_SUB_S:
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);
6566 opn = "sub.s";
6567 optype = BINOP;
6568 break;
6569 case OPC_MUL_S:
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);
6581 opn = "mul.s";
6582 optype = BINOP;
6583 break;
6584 case OPC_DIV_S:
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);
6596 opn = "div.s";
6597 optype = BINOP;
6598 break;
6599 case OPC_SQRT_S:
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);
6608 opn = "sqrt.s";
6609 break;
6610 case OPC_ABS_S:
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);
6619 opn = "abs.s";
6620 break;
6621 case OPC_MOV_S:
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);
6629 opn = "mov.s";
6630 break;
6631 case OPC_NEG_S:
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);
6640 opn = "neg.s";
6641 break;
6642 case OPC_ROUND_L_S:
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);
6654 opn = "round.l.s";
6655 break;
6656 case OPC_TRUNC_L_S:
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);
6668 opn = "trunc.l.s";
6669 break;
6670 case OPC_CEIL_L_S:
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);
6682 opn = "ceil.l.s";
6683 break;
6684 case OPC_FLOOR_L_S:
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);
6696 opn = "floor.l.s";
6697 break;
6698 case OPC_ROUND_W_S:
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);
6707 opn = "round.w.s";
6708 break;
6709 case OPC_TRUNC_W_S:
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);
6718 opn = "trunc.w.s";
6719 break;
6720 case OPC_CEIL_W_S:
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);
6729 opn = "ceil.w.s";
6730 break;
6731 case OPC_FLOOR_W_S:
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);
6740 opn = "floor.w.s";
6741 break;
6742 case OPC_MOVCF_S:
6743 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6744 opn = "movcf.s";
6745 break;
6746 case OPC_MOVZ_S:
6748 int l1 = gen_new_label();
6749 TCGv_i32 fp0;
6751 if (ft != 0) {
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);
6758 gen_set_label(l1);
6760 opn = "movz.s";
6761 break;
6762 case OPC_MOVN_S:
6764 int l1 = gen_new_label();
6765 TCGv_i32 fp0;
6767 if (ft != 0) {
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);
6773 gen_set_label(l1);
6776 opn = "movn.s";
6777 break;
6778 case OPC_RECIP_S:
6779 check_cop1x(ctx);
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);
6788 opn = "recip.s";
6789 break;
6790 case OPC_RSQRT_S:
6791 check_cop1x(ctx);
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);
6800 opn = "rsqrt.s";
6801 break;
6802 case OPC_RECIP2_S:
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);
6815 opn = "recip2.s";
6816 break;
6817 case OPC_RECIP1_S:
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);
6827 opn = "recip1.s";
6828 break;
6829 case OPC_RSQRT1_S:
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);
6839 opn = "rsqrt1.s";
6840 break;
6841 case OPC_RSQRT2_S:
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);
6854 opn = "rsqrt2.s";
6855 break;
6856 case OPC_CVT_D_S:
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);
6868 opn = "cvt.d.s";
6869 break;
6870 case OPC_CVT_W_S:
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);
6879 opn = "cvt.w.s";
6880 break;
6881 case OPC_CVT_L_S:
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);
6893 opn = "cvt.l.s";
6894 break;
6895 case OPC_CVT_PS_S:
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);
6910 opn = "cvt.ps.s";
6911 break;
6912 case OPC_CMP_F_S:
6913 case OPC_CMP_UN_S:
6914 case OPC_CMP_EQ_S:
6915 case OPC_CMP_UEQ_S:
6916 case OPC_CMP_OLT_S:
6917 case OPC_CMP_ULT_S:
6918 case OPC_CMP_OLE_S:
6919 case OPC_CMP_ULE_S:
6920 case OPC_CMP_SF_S:
6921 case OPC_CMP_NGLE_S:
6922 case OPC_CMP_SEQ_S:
6923 case OPC_CMP_NGL_S:
6924 case OPC_CMP_LT_S:
6925 case OPC_CMP_NGE_S:
6926 case OPC_CMP_LE_S:
6927 case OPC_CMP_NGT_S:
6928 if (ctx->opcode & (1 << 6)) {
6929 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6930 opn = condnames_abs[func-48];
6931 } else {
6932 gen_cmp_s(ctx, func-48, ft, fs, cc);
6933 opn = condnames[func-48];
6935 break;
6936 case OPC_ADD_D:
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);
6949 opn = "add.d";
6950 optype = BINOP;
6951 break;
6952 case OPC_SUB_D:
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);
6965 opn = "sub.d";
6966 optype = BINOP;
6967 break;
6968 case OPC_MUL_D:
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);
6981 opn = "mul.d";
6982 optype = BINOP;
6983 break;
6984 case OPC_DIV_D:
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);
6997 opn = "div.d";
6998 optype = BINOP;
6999 break;
7000 case OPC_SQRT_D:
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);
7010 opn = "sqrt.d";
7011 break;
7012 case OPC_ABS_D:
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);
7022 opn = "abs.d";
7023 break;
7024 case OPC_MOV_D:
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);
7033 opn = "mov.d";
7034 break;
7035 case OPC_NEG_D:
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);
7045 opn = "neg.d";
7046 break;
7047 case OPC_ROUND_L_D:
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);
7057 opn = "round.l.d";
7058 break;
7059 case OPC_TRUNC_L_D:
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);
7069 opn = "trunc.l.d";
7070 break;
7071 case OPC_CEIL_L_D:
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);
7081 opn = "ceil.l.d";
7082 break;
7083 case OPC_FLOOR_L_D:
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);
7093 opn = "floor.l.d";
7094 break;
7095 case OPC_ROUND_W_D:
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);
7107 opn = "round.w.d";
7108 break;
7109 case OPC_TRUNC_W_D:
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);
7121 opn = "trunc.w.d";
7122 break;
7123 case OPC_CEIL_W_D:
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);
7135 opn = "ceil.w.d";
7136 break;
7137 case OPC_FLOOR_W_D:
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);
7149 opn = "floor.w.d";
7150 break;
7151 case OPC_MOVCF_D:
7152 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7153 opn = "movcf.d";
7154 break;
7155 case OPC_MOVZ_D:
7157 int l1 = gen_new_label();
7158 TCGv_i64 fp0;
7160 if (ft != 0) {
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);
7167 gen_set_label(l1);
7169 opn = "movz.d";
7170 break;
7171 case OPC_MOVN_D:
7173 int l1 = gen_new_label();
7174 TCGv_i64 fp0;
7176 if (ft != 0) {
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);
7182 gen_set_label(l1);
7185 opn = "movn.d";
7186 break;
7187 case OPC_RECIP_D:
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);
7197 opn = "recip.d";
7198 break;
7199 case OPC_RSQRT_D:
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);
7209 opn = "rsqrt.d";
7210 break;
7211 case OPC_RECIP2_D:
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);
7224 opn = "recip2.d";
7225 break;
7226 case OPC_RECIP1_D:
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);
7236 opn = "recip1.d";
7237 break;
7238 case OPC_RSQRT1_D:
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);
7248 opn = "rsqrt1.d";
7249 break;
7250 case OPC_RSQRT2_D:
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);
7263 opn = "rsqrt2.d";
7264 break;
7265 case OPC_CMP_F_D:
7266 case OPC_CMP_UN_D:
7267 case OPC_CMP_EQ_D:
7268 case OPC_CMP_UEQ_D:
7269 case OPC_CMP_OLT_D:
7270 case OPC_CMP_ULT_D:
7271 case OPC_CMP_OLE_D:
7272 case OPC_CMP_ULE_D:
7273 case OPC_CMP_SF_D:
7274 case OPC_CMP_NGLE_D:
7275 case OPC_CMP_SEQ_D:
7276 case OPC_CMP_NGL_D:
7277 case OPC_CMP_LT_D:
7278 case OPC_CMP_NGE_D:
7279 case OPC_CMP_LE_D:
7280 case OPC_CMP_NGT_D:
7281 if (ctx->opcode & (1 << 6)) {
7282 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
7283 opn = condnames_abs[func-48];
7284 } else {
7285 gen_cmp_d(ctx, func-48, ft, fs, cc);
7286 opn = condnames[func-48];
7288 break;
7289 case OPC_CVT_S_D:
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);
7301 opn = "cvt.s.d";
7302 break;
7303 case OPC_CVT_W_D:
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);
7315 opn = "cvt.w.d";
7316 break;
7317 case OPC_CVT_L_D:
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);
7327 opn = "cvt.l.d";
7328 break;
7329 case OPC_CVT_S_W:
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);
7338 opn = "cvt.s.w";
7339 break;
7340 case OPC_CVT_D_W:
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);
7352 opn = "cvt.d.w";
7353 break;
7354 case OPC_CVT_S_L:
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);
7366 opn = "cvt.s.l";
7367 break;
7368 case OPC_CVT_D_L:
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);
7378 opn = "cvt.d.l";
7379 break;
7380 case OPC_CVT_PS_PW:
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);
7390 opn = "cvt.ps.pw";
7391 break;
7392 case OPC_ADD_PS:
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);
7405 opn = "add.ps";
7406 break;
7407 case OPC_SUB_PS:
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);
7420 opn = "sub.ps";
7421 break;
7422 case OPC_MUL_PS:
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);
7435 opn = "mul.ps";
7436 break;
7437 case OPC_ABS_PS:
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);
7447 opn = "abs.ps";
7448 break;
7449 case OPC_MOV_PS:
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);
7458 opn = "mov.ps";
7459 break;
7460 case OPC_NEG_PS:
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);
7470 opn = "neg.ps";
7471 break;
7472 case OPC_MOVCF_PS:
7473 check_cp1_64bitmode(ctx);
7474 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7475 opn = "movcf.ps";
7476 break;
7477 case OPC_MOVZ_PS:
7478 check_cp1_64bitmode(ctx);
7480 int l1 = gen_new_label();
7481 TCGv_i64 fp0;
7483 if (ft != 0)
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);
7489 gen_set_label(l1);
7491 opn = "movz.ps";
7492 break;
7493 case OPC_MOVN_PS:
7494 check_cp1_64bitmode(ctx);
7496 int l1 = gen_new_label();
7497 TCGv_i64 fp0;
7499 if (ft != 0) {
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);
7505 gen_set_label(l1);
7508 opn = "movn.ps";
7509 break;
7510 case OPC_ADDR_PS:
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);
7523 opn = "addr.ps";
7524 break;
7525 case OPC_MULR_PS:
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);
7538 opn = "mulr.ps";
7539 break;
7540 case OPC_RECIP2_PS:
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);
7553 opn = "recip2.ps";
7554 break;
7555 case OPC_RECIP1_PS:
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);
7565 opn = "recip1.ps";
7566 break;
7567 case OPC_RSQRT1_PS:
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);
7577 opn = "rsqrt1.ps";
7578 break;
7579 case OPC_RSQRT2_PS:
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);
7592 opn = "rsqrt2.ps";
7593 break;
7594 case OPC_CVT_S_PU:
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);
7604 opn = "cvt.s.pu";
7605 break;
7606 case OPC_CVT_PW_PS:
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);
7616 opn = "cvt.pw.ps";
7617 break;
7618 case OPC_CVT_S_PL:
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);
7628 opn = "cvt.s.pl";
7629 break;
7630 case OPC_PLL_PS:
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);
7643 opn = "pll.ps";
7644 break;
7645 case OPC_PLU_PS:
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);
7658 opn = "plu.ps";
7659 break;
7660 case OPC_PUL_PS:
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);
7673 opn = "pul.ps";
7674 break;
7675 case OPC_PUU_PS:
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);
7688 opn = "puu.ps";
7689 break;
7690 case OPC_CMP_F_PS:
7691 case OPC_CMP_UN_PS:
7692 case OPC_CMP_EQ_PS:
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:
7698 case OPC_CMP_SF_PS:
7699 case OPC_CMP_NGLE_PS:
7700 case OPC_CMP_SEQ_PS:
7701 case OPC_CMP_NGL_PS:
7702 case OPC_CMP_LT_PS:
7703 case OPC_CMP_NGE_PS:
7704 case OPC_CMP_LE_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];
7709 } else {
7710 gen_cmp_ps(ctx, func-48, ft, fs, cc);
7711 opn = condnames[func-48];
7713 break;
7714 default:
7715 MIPS_INVAL(opn);
7716 generate_exception (ctx, EXCP_RI);
7717 return;
7719 (void)opn; /* avoid a compiler warning */
7720 switch (optype) {
7721 case BINOP:
7722 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7723 break;
7724 case CMPOP:
7725 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7726 break;
7727 default:
7728 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7729 break;
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";
7738 int store = 0;
7739 TCGv t0 = tcg_temp_new();
7741 if (base == 0) {
7742 gen_load_gpr(t0, index);
7743 } else if (index == 0) {
7744 gen_load_gpr(t0, base);
7745 } else {
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
7749 memory access. */
7750 save_cpu_state(ctx, 0);
7751 switch (opc) {
7752 case OPC_LWXC1:
7753 check_cop1x(ctx);
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);
7762 opn = "lwxc1";
7763 break;
7764 case OPC_LDXC1:
7765 check_cop1x(ctx);
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);
7774 opn = "ldxc1";
7775 break;
7776 case OPC_LUXC1:
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);
7786 opn = "luxc1";
7787 break;
7788 case OPC_SWXC1:
7789 check_cop1x(ctx);
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);
7798 tcg_temp_free(t1);
7800 opn = "swxc1";
7801 store = 1;
7802 break;
7803 case OPC_SDXC1:
7804 check_cop1x(ctx);
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);
7813 opn = "sdxc1";
7814 store = 1;
7815 break;
7816 case OPC_SUXC1:
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);
7826 opn = "suxc1";
7827 store = 1;
7828 break;
7830 tcg_temp_free(t0);
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";
7841 switch (opc) {
7842 case OPC_ALNV_PS:
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);
7859 tcg_gen_br(l2);
7860 gen_set_label(l1);
7861 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7862 tcg_temp_free(t0);
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);
7868 #else
7869 gen_load_fpr32h(fph, fs);
7870 gen_load_fpr32(fp, ft);
7871 gen_store_fpr32(fph, fd);
7872 gen_store_fpr32h(fp, fd);
7873 #endif
7874 gen_set_label(l2);
7875 tcg_temp_free_i32(fp);
7876 tcg_temp_free_i32(fph);
7878 opn = "alnv.ps";
7879 break;
7880 case OPC_MADD_S:
7881 check_cop1x(ctx);
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);
7896 opn = "madd.s";
7897 break;
7898 case OPC_MADD_D:
7899 check_cop1x(ctx);
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);
7915 opn = "madd.d";
7916 break;
7917 case OPC_MADD_PS:
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);
7933 opn = "madd.ps";
7934 break;
7935 case OPC_MSUB_S:
7936 check_cop1x(ctx);
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);
7951 opn = "msub.s";
7952 break;
7953 case OPC_MSUB_D:
7954 check_cop1x(ctx);
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);
7970 opn = "msub.d";
7971 break;
7972 case OPC_MSUB_PS:
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);
7988 opn = "msub.ps";
7989 break;
7990 case OPC_NMADD_S:
7991 check_cop1x(ctx);
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);
8006 opn = "nmadd.s";
8007 break;
8008 case OPC_NMADD_D:
8009 check_cop1x(ctx);
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);
8025 opn = "nmadd.d";
8026 break;
8027 case OPC_NMADD_PS:
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);
8043 opn = "nmadd.ps";
8044 break;
8045 case OPC_NMSUB_S:
8046 check_cop1x(ctx);
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);
8061 opn = "nmsub.s";
8062 break;
8063 case OPC_NMSUB_D:
8064 check_cop1x(ctx);
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);
8080 opn = "nmsub.d";
8081 break;
8082 case OPC_NMSUB_PS:
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);
8098 opn = "nmsub.ps";
8099 break;
8100 default:
8101 MIPS_INVAL(opn);
8102 generate_exception (ctx, EXCP_RI);
8103 return;
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]);
8110 static void
8111 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
8113 TCGv t0;
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);
8119 #endif
8120 t0 = tcg_temp_new();
8122 switch (rd) {
8123 case 0:
8124 save_cpu_state(ctx, 1);
8125 gen_helper_rdhwr_cpunum(t0);
8126 gen_store_gpr(t0, rt);
8127 break;
8128 case 1:
8129 save_cpu_state(ctx, 1);
8130 gen_helper_rdhwr_synci_step(t0);
8131 gen_store_gpr(t0, rt);
8132 break;
8133 case 2:
8134 save_cpu_state(ctx, 1);
8135 gen_helper_rdhwr_cc(t0);
8136 gen_store_gpr(t0, rt);
8137 break;
8138 case 3:
8139 save_cpu_state(ctx, 1);
8140 gen_helper_rdhwr_ccres(t0);
8141 gen_store_gpr(t0, rt);
8142 break;
8143 case 29:
8144 #if defined(CONFIG_USER_ONLY)
8145 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
8146 gen_store_gpr(t0, rt);
8147 break;
8148 #else
8149 /* XXX: Some CPUs implement this in hardware.
8150 Not supported yet. */
8151 #endif
8152 default: /* Invalid */
8153 MIPS_INVAL("rdhwr");
8154 generate_exception(ctx, EXCP_RI);
8155 break;
8157 tcg_temp_free(t0);
8160 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
8161 int insn_bytes)
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) {
8171 case MIPS_HFLAG_B:
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);
8178 break;
8179 case MIPS_HFLAG_BL:
8180 /* blikely taken case */
8181 MIPS_DEBUG("blikely branch taken");
8182 gen_goto_tb(ctx, 0, ctx->btarget);
8183 break;
8184 case MIPS_HFLAG_BC:
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);
8192 gen_set_label(l1);
8193 gen_goto_tb(ctx, 0, ctx->btarget);
8195 break;
8196 case MIPS_HFLAG_BR:
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);
8205 tcg_temp_free(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);
8212 } else {
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);
8219 tcg_gen_exit_tb(0);
8220 break;
8221 default:
8222 MIPS_DEBUG("unknown branch");
8223 break;
8228 /* ISA extensions (ASEs) */
8229 /* MIPS16 extension to MIPS32 */
8231 /* MIPS16 major opcodes */
8232 enum {
8233 M16_OPC_ADDIUSP = 0x00,
8234 M16_OPC_ADDIUPC = 0x01,
8235 M16_OPC_B = 0x02,
8236 M16_OPC_JAL = 0x03,
8237 M16_OPC_BEQZ = 0x04,
8238 M16_OPC_BNEQZ = 0x05,
8239 M16_OPC_SHIFT = 0x06,
8240 M16_OPC_LD = 0x07,
8241 M16_OPC_RRIA = 0x08,
8242 M16_OPC_ADDIU8 = 0x09,
8243 M16_OPC_SLTI = 0x0a,
8244 M16_OPC_SLTIU = 0x0b,
8245 M16_OPC_I8 = 0x0c,
8246 M16_OPC_LI = 0x0d,
8247 M16_OPC_CMPI = 0x0e,
8248 M16_OPC_SD = 0x0f,
8249 M16_OPC_LB = 0x10,
8250 M16_OPC_LH = 0x11,
8251 M16_OPC_LWSP = 0x12,
8252 M16_OPC_LW = 0x13,
8253 M16_OPC_LBU = 0x14,
8254 M16_OPC_LHU = 0x15,
8255 M16_OPC_LWPC = 0x16,
8256 M16_OPC_LWU = 0x17,
8257 M16_OPC_SB = 0x18,
8258 M16_OPC_SH = 0x19,
8259 M16_OPC_SWSP = 0x1a,
8260 M16_OPC_SW = 0x1b,
8261 M16_OPC_RRR = 0x1c,
8262 M16_OPC_RR = 0x1d,
8263 M16_OPC_EXTEND = 0x1e,
8264 M16_OPC_I64 = 0x1f
8267 /* I8 funct field */
8268 enum {
8269 I8_BTEQZ = 0x0,
8270 I8_BTNEZ = 0x1,
8271 I8_SWRASP = 0x2,
8272 I8_ADJSP = 0x3,
8273 I8_SVRS = 0x4,
8274 I8_MOV32R = 0x5,
8275 I8_MOVR32 = 0x7
8278 /* RRR f field */
8279 enum {
8280 RRR_DADDU = 0x0,
8281 RRR_ADDU = 0x1,
8282 RRR_DSUBU = 0x2,
8283 RRR_SUBU = 0x3
8286 /* RR funct field */
8287 enum {
8288 RR_JR = 0x00,
8289 RR_SDBBP = 0x01,
8290 RR_SLT = 0x02,
8291 RR_SLTU = 0x03,
8292 RR_SLLV = 0x04,
8293 RR_BREAK = 0x05,
8294 RR_SRLV = 0x06,
8295 RR_SRAV = 0x07,
8296 RR_DSRL = 0x08,
8297 RR_CMP = 0x0a,
8298 RR_NEG = 0x0b,
8299 RR_AND = 0x0c,
8300 RR_OR = 0x0d,
8301 RR_XOR = 0x0e,
8302 RR_NOT = 0x0f,
8303 RR_MFHI = 0x10,
8304 RR_CNVT = 0x11,
8305 RR_MFLO = 0x12,
8306 RR_DSRA = 0x13,
8307 RR_DSLLV = 0x14,
8308 RR_DSRLV = 0x16,
8309 RR_DSRAV = 0x17,
8310 RR_MULT = 0x18,
8311 RR_MULTU = 0x19,
8312 RR_DIV = 0x1a,
8313 RR_DIVU = 0x1b,
8314 RR_DMULT = 0x1c,
8315 RR_DMULTU = 0x1d,
8316 RR_DDIV = 0x1e,
8317 RR_DDIVU = 0x1f
8320 /* I64 funct field */
8321 enum {
8322 I64_LDSP = 0x0,
8323 I64_SDSP = 0x1,
8324 I64_SDRASP = 0x2,
8325 I64_DADJSP = 0x3,
8326 I64_LDPC = 0x4,
8327 I64_DADDIU5 = 0x5,
8328 I64_DADDIUPC = 0x6,
8329 I64_DADDIUSP = 0x7
8332 /* RR ry field for CNVT */
8333 enum {
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 };
8346 return map[r];
8349 static void gen_mips16_save (DisasContext *ctx,
8350 int xsregs, int aregs,
8351 int do_ra, int do_s0, int do_s1,
8352 int framesize)
8354 TCGv t0 = tcg_temp_new();
8355 TCGv t1 = tcg_temp_new();
8356 int args, astatic;
8358 switch (aregs) {
8359 case 0:
8360 case 1:
8361 case 2:
8362 case 3:
8363 case 11:
8364 args = 0;
8365 break;
8366 case 4:
8367 case 5:
8368 case 6:
8369 case 7:
8370 args = 1;
8371 break;
8372 case 8:
8373 case 9:
8374 case 10:
8375 args = 2;
8376 break;
8377 case 12:
8378 case 13:
8379 args = 3;
8380 break;
8381 case 14:
8382 args = 4;
8383 break;
8384 default:
8385 generate_exception(ctx, EXCP_RI);
8386 return;
8389 switch (args) {
8390 case 4:
8391 gen_base_offset_addr(ctx, t0, 29, 12);
8392 gen_load_gpr(t1, 7);
8393 op_st_sw(t1, t0, ctx);
8394 /* Fall through */
8395 case 3:
8396 gen_base_offset_addr(ctx, t0, 29, 8);
8397 gen_load_gpr(t1, 6);
8398 op_st_sw(t1, t0, ctx);
8399 /* Fall through */
8400 case 2:
8401 gen_base_offset_addr(ctx, t0, 29, 4);
8402 gen_load_gpr(t1, 5);
8403 op_st_sw(t1, t0, ctx);
8404 /* Fall through */
8405 case 1:
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); \
8417 } while (0)
8419 if (do_ra) {
8420 DECR_AND_STORE(31);
8423 switch (xsregs) {
8424 case 7:
8425 DECR_AND_STORE(30);
8426 /* Fall through */
8427 case 6:
8428 DECR_AND_STORE(23);
8429 /* Fall through */
8430 case 5:
8431 DECR_AND_STORE(22);
8432 /* Fall through */
8433 case 4:
8434 DECR_AND_STORE(21);
8435 /* Fall through */
8436 case 3:
8437 DECR_AND_STORE(20);
8438 /* Fall through */
8439 case 2:
8440 DECR_AND_STORE(19);
8441 /* Fall through */
8442 case 1:
8443 DECR_AND_STORE(18);
8446 if (do_s1) {
8447 DECR_AND_STORE(17);
8449 if (do_s0) {
8450 DECR_AND_STORE(16);
8453 switch (aregs) {
8454 case 0:
8455 case 4:
8456 case 8:
8457 case 12:
8458 case 14:
8459 astatic = 0;
8460 break;
8461 case 1:
8462 case 5:
8463 case 9:
8464 case 13:
8465 astatic = 1;
8466 break;
8467 case 2:
8468 case 6:
8469 case 10:
8470 astatic = 2;
8471 break;
8472 case 3:
8473 case 7:
8474 astatic = 3;
8475 break;
8476 case 11:
8477 astatic = 4;
8478 break;
8479 default:
8480 generate_exception(ctx, EXCP_RI);
8481 return;
8484 if (astatic > 0) {
8485 DECR_AND_STORE(7);
8486 if (astatic > 1) {
8487 DECR_AND_STORE(6);
8488 if (astatic > 2) {
8489 DECR_AND_STORE(5);
8490 if (astatic > 3) {
8491 DECR_AND_STORE(4);
8496 #undef DECR_AND_STORE
8498 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8499 tcg_temp_free(t0);
8500 tcg_temp_free(t1);
8503 static void gen_mips16_restore (DisasContext *ctx,
8504 int xsregs, int aregs,
8505 int do_ra, int do_s0, int do_s1,
8506 int framesize)
8508 int astatic;
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); \
8518 } while (0)
8520 if (do_ra) {
8521 DECR_AND_LOAD(31);
8524 switch (xsregs) {
8525 case 7:
8526 DECR_AND_LOAD(30);
8527 /* Fall through */
8528 case 6:
8529 DECR_AND_LOAD(23);
8530 /* Fall through */
8531 case 5:
8532 DECR_AND_LOAD(22);
8533 /* Fall through */
8534 case 4:
8535 DECR_AND_LOAD(21);
8536 /* Fall through */
8537 case 3:
8538 DECR_AND_LOAD(20);
8539 /* Fall through */
8540 case 2:
8541 DECR_AND_LOAD(19);
8542 /* Fall through */
8543 case 1:
8544 DECR_AND_LOAD(18);
8547 if (do_s1) {
8548 DECR_AND_LOAD(17);
8550 if (do_s0) {
8551 DECR_AND_LOAD(16);
8554 switch (aregs) {
8555 case 0:
8556 case 4:
8557 case 8:
8558 case 12:
8559 case 14:
8560 astatic = 0;
8561 break;
8562 case 1:
8563 case 5:
8564 case 9:
8565 case 13:
8566 astatic = 1;
8567 break;
8568 case 2:
8569 case 6:
8570 case 10:
8571 astatic = 2;
8572 break;
8573 case 3:
8574 case 7:
8575 astatic = 3;
8576 break;
8577 case 11:
8578 astatic = 4;
8579 break;
8580 default:
8581 generate_exception(ctx, EXCP_RI);
8582 return;
8585 if (astatic > 0) {
8586 DECR_AND_LOAD(7);
8587 if (astatic > 1) {
8588 DECR_AND_LOAD(6);
8589 if (astatic > 2) {
8590 DECR_AND_LOAD(5);
8591 if (astatic > 3) {
8592 DECR_AND_LOAD(4);
8597 #undef DECR_AND_LOAD
8599 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8600 tcg_temp_free(t0);
8601 tcg_temp_free(t1);
8604 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8605 int is_64_bit, int extended)
8607 TCGv t0;
8609 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8610 generate_exception(ctx, EXCP_RI);
8611 return;
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);
8618 if (!is_64_bit) {
8619 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8622 tcg_temp_free(t0);
8625 #if defined(TARGET_MIPS64)
8626 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
8627 int ry, int funct, int16_t offset,
8628 int extended)
8630 switch (funct) {
8631 case I64_LDSP:
8632 check_mips_64(ctx);
8633 offset = extended ? offset : offset << 3;
8634 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
8635 break;
8636 case I64_SDSP:
8637 check_mips_64(ctx);
8638 offset = extended ? offset : offset << 3;
8639 gen_st(ctx, OPC_SD, ry, 29, offset);
8640 break;
8641 case I64_SDRASP:
8642 check_mips_64(ctx);
8643 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8644 gen_st(ctx, OPC_SD, 31, 29, offset);
8645 break;
8646 case I64_DADJSP:
8647 check_mips_64(ctx);
8648 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8649 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8650 break;
8651 case I64_LDPC:
8652 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8653 generate_exception(ctx, EXCP_RI);
8654 } else {
8655 offset = extended ? offset : offset << 3;
8656 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
8658 break;
8659 case I64_DADDIU5:
8660 check_mips_64(ctx);
8661 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8662 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8663 break;
8664 case I64_DADDIUPC:
8665 check_mips_64(ctx);
8666 offset = extended ? offset : offset << 2;
8667 gen_addiupc(ctx, ry, offset, 1, extended);
8668 break;
8669 case I64_DADDIUSP:
8670 check_mips_64(ctx);
8671 offset = extended ? offset : offset << 2;
8672 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8673 break;
8676 #endif
8678 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
8679 int *is_branch)
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
8696 counterparts. */
8697 switch (op) {
8698 case M16_OPC_ADDIUSP:
8699 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8700 break;
8701 case M16_OPC_ADDIUPC:
8702 gen_addiupc(ctx, rx, imm, 0, 1);
8703 break;
8704 case M16_OPC_B:
8705 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8706 /* No delay slot, so just process as a normal instruction */
8707 break;
8708 case M16_OPC_BEQZ:
8709 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8710 /* No delay slot, so just process as a normal instruction */
8711 break;
8712 case M16_OPC_BNEQZ:
8713 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8714 /* No delay slot, so just process as a normal instruction */
8715 break;
8716 case M16_OPC_SHIFT:
8717 switch (ctx->opcode & 0x3) {
8718 case 0x0:
8719 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8720 break;
8721 case 0x1:
8722 #if defined(TARGET_MIPS64)
8723 check_mips_64(ctx);
8724 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8725 #else
8726 generate_exception(ctx, EXCP_RI);
8727 #endif
8728 break;
8729 case 0x2:
8730 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8731 break;
8732 case 0x3:
8733 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8734 break;
8736 break;
8737 #if defined(TARGET_MIPS64)
8738 case M16_OPC_LD:
8739 check_mips_64(ctx);
8740 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
8741 break;
8742 #endif
8743 case M16_OPC_RRIA:
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)
8750 check_mips_64(ctx);
8751 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8752 #else
8753 generate_exception(ctx, EXCP_RI);
8754 #endif
8755 } else {
8756 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8758 break;
8759 case M16_OPC_ADDIU8:
8760 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8761 break;
8762 case M16_OPC_SLTI:
8763 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8764 break;
8765 case M16_OPC_SLTIU:
8766 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8767 break;
8768 case M16_OPC_I8:
8769 switch (funct) {
8770 case I8_BTEQZ:
8771 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8772 break;
8773 case I8_BTNEZ:
8774 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8775 break;
8776 case I8_SWRASP:
8777 gen_st(ctx, OPC_SW, 31, 29, imm);
8778 break;
8779 case I8_ADJSP:
8780 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8781 break;
8782 case I8_SVRS:
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,
8795 framesize);
8796 } else {
8797 gen_mips16_restore(ctx, xsregs, aregs,
8798 do_ra, do_s0, do_s1,
8799 framesize);
8802 break;
8803 default:
8804 generate_exception(ctx, EXCP_RI);
8805 break;
8807 break;
8808 case M16_OPC_LI:
8809 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8810 break;
8811 case M16_OPC_CMPI:
8812 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8813 break;
8814 #if defined(TARGET_MIPS64)
8815 case M16_OPC_SD:
8816 gen_st(ctx, OPC_SD, ry, rx, offset);
8817 break;
8818 #endif
8819 case M16_OPC_LB:
8820 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8821 break;
8822 case M16_OPC_LH:
8823 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
8824 break;
8825 case M16_OPC_LWSP:
8826 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
8827 break;
8828 case M16_OPC_LW:
8829 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
8830 break;
8831 case M16_OPC_LBU:
8832 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
8833 break;
8834 case M16_OPC_LHU:
8835 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
8836 break;
8837 case M16_OPC_LWPC:
8838 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
8839 break;
8840 #if defined(TARGET_MIPS64)
8841 case M16_OPC_LWU:
8842 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
8843 break;
8844 #endif
8845 case M16_OPC_SB:
8846 gen_st(ctx, OPC_SB, ry, rx, offset);
8847 break;
8848 case M16_OPC_SH:
8849 gen_st(ctx, OPC_SH, ry, rx, offset);
8850 break;
8851 case M16_OPC_SWSP:
8852 gen_st(ctx, OPC_SW, rx, 29, offset);
8853 break;
8854 case M16_OPC_SW:
8855 gen_st(ctx, OPC_SW, ry, rx, offset);
8856 break;
8857 #if defined(TARGET_MIPS64)
8858 case M16_OPC_I64:
8859 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8860 break;
8861 #endif
8862 default:
8863 generate_exception(ctx, EXCP_RI);
8864 break;
8867 return 4;
8870 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
8871 int *is_branch)
8873 int rx, ry;
8874 int sa;
8875 int op, cnvt_op, op1, offset;
8876 int funct;
8877 int n_bytes;
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;
8887 n_bytes = 2;
8889 switch (op) {
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);
8896 break;
8897 case M16_OPC_ADDIUPC:
8898 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8899 break;
8900 case M16_OPC_B:
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 */
8905 break;
8906 case M16_OPC_JAL:
8907 offset = lduw_code(ctx->pc + 2);
8908 offset = (((ctx->opcode & 0x1f) << 21)
8909 | ((ctx->opcode >> 5) & 0x1f) << 16
8910 | offset) << 2;
8911 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8912 gen_compute_branch(ctx, op, 4, rx, ry, offset);
8913 n_bytes = 4;
8914 *is_branch = 1;
8915 break;
8916 case M16_OPC_BEQZ:
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 */
8919 break;
8920 case M16_OPC_BNEQZ:
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 */
8923 break;
8924 case M16_OPC_SHIFT:
8925 switch (ctx->opcode & 0x3) {
8926 case 0x0:
8927 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8928 break;
8929 case 0x1:
8930 #if defined(TARGET_MIPS64)
8931 check_mips_64(ctx);
8932 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8933 #else
8934 generate_exception(ctx, EXCP_RI);
8935 #endif
8936 break;
8937 case 0x2:
8938 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8939 break;
8940 case 0x3:
8941 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8942 break;
8944 break;
8945 #if defined(TARGET_MIPS64)
8946 case M16_OPC_LD:
8947 check_mips_64(ctx);
8948 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
8949 break;
8950 #endif
8951 case M16_OPC_RRIA:
8953 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8955 if ((ctx->opcode >> 4) & 1) {
8956 #if defined(TARGET_MIPS64)
8957 check_mips_64(ctx);
8958 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8959 #else
8960 generate_exception(ctx, EXCP_RI);
8961 #endif
8962 } else {
8963 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8966 break;
8967 case M16_OPC_ADDIU8:
8969 int16_t imm = (int8_t) ctx->opcode;
8971 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8973 break;
8974 case M16_OPC_SLTI:
8976 int16_t imm = (uint8_t) ctx->opcode;
8978 gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8980 break;
8981 case M16_OPC_SLTIU:
8983 int16_t imm = (uint8_t) ctx->opcode;
8985 gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8987 break;
8988 case M16_OPC_I8:
8990 int reg32;
8992 funct = (ctx->opcode >> 8) & 0x7;
8993 switch (funct) {
8994 case I8_BTEQZ:
8995 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8996 ((int8_t)ctx->opcode) << 1);
8997 break;
8998 case I8_BTNEZ:
8999 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9000 ((int8_t)ctx->opcode) << 1);
9001 break;
9002 case I8_SWRASP:
9003 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9004 break;
9005 case I8_ADJSP:
9006 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9007 ((int8_t)ctx->opcode) << 3);
9008 break;
9009 case I8_SVRS:
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) {
9017 framesize = 128;
9018 } else {
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);
9025 } else {
9026 gen_mips16_restore(ctx, 0, 0,
9027 do_ra, do_s0, do_s1, framesize);
9030 break;
9031 case I8_MOV32R:
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);
9039 break;
9040 case I8_MOVR32:
9041 reg32 = ctx->opcode & 0x1f;
9042 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9043 break;
9044 default:
9045 generate_exception(ctx, EXCP_RI);
9046 break;
9049 break;
9050 case M16_OPC_LI:
9052 int16_t imm = (uint8_t) ctx->opcode;
9054 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9056 break;
9057 case M16_OPC_CMPI:
9059 int16_t imm = (uint8_t) ctx->opcode;
9061 gen_logic_imm(env, OPC_XORI, 24, rx, imm);
9063 break;
9064 #if defined(TARGET_MIPS64)
9065 case M16_OPC_SD:
9066 check_mips_64(ctx);
9067 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9068 break;
9069 #endif
9070 case M16_OPC_LB:
9071 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9072 break;
9073 case M16_OPC_LH:
9074 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9075 break;
9076 case M16_OPC_LWSP:
9077 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9078 break;
9079 case M16_OPC_LW:
9080 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
9081 break;
9082 case M16_OPC_LBU:
9083 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9084 break;
9085 case M16_OPC_LHU:
9086 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9087 break;
9088 case M16_OPC_LWPC:
9089 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9090 break;
9091 #if defined (TARGET_MIPS64)
9092 case M16_OPC_LWU:
9093 check_mips_64(ctx);
9094 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
9095 break;
9096 #endif
9097 case M16_OPC_SB:
9098 gen_st(ctx, OPC_SB, ry, rx, offset);
9099 break;
9100 case M16_OPC_SH:
9101 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9102 break;
9103 case M16_OPC_SWSP:
9104 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9105 break;
9106 case M16_OPC_SW:
9107 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9108 break;
9109 case M16_OPC_RRR:
9111 int rz = xlat((ctx->opcode >> 2) & 0x7);
9112 int mips32_op;
9114 switch (ctx->opcode & 0x3) {
9115 case RRR_ADDU:
9116 mips32_op = OPC_ADDU;
9117 break;
9118 case RRR_SUBU:
9119 mips32_op = OPC_SUBU;
9120 break;
9121 #if defined(TARGET_MIPS64)
9122 case RRR_DADDU:
9123 mips32_op = OPC_DADDU;
9124 check_mips_64(ctx);
9125 break;
9126 case RRR_DSUBU:
9127 mips32_op = OPC_DSUBU;
9128 check_mips_64(ctx);
9129 break;
9130 #endif
9131 default:
9132 generate_exception(ctx, EXCP_RI);
9133 goto done;
9136 gen_arith(env, ctx, mips32_op, rz, rx, ry);
9137 done:
9140 break;
9141 case M16_OPC_RR:
9142 switch (op1) {
9143 case RR_JR:
9145 int nd = (ctx->opcode >> 7) & 0x1;
9146 int link = (ctx->opcode >> 6) & 0x1;
9147 int ra = (ctx->opcode >> 5) & 0x1;
9149 if (link) {
9150 op = nd ? OPC_JALRC : OPC_JALRS;
9151 } else {
9152 op = OPC_JR;
9155 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
9156 if (!nd) {
9157 *is_branch = 1;
9160 break;
9161 case RR_SDBBP:
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);
9168 } else {
9169 generate_exception(ctx, EXCP_DBp);
9171 break;
9172 case RR_SLT:
9173 gen_slt(env, OPC_SLT, 24, rx, ry);
9174 break;
9175 case RR_SLTU:
9176 gen_slt(env, OPC_SLTU, 24, rx, ry);
9177 break;
9178 case RR_BREAK:
9179 generate_exception(ctx, EXCP_BREAK);
9180 break;
9181 case RR_SLLV:
9182 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
9183 break;
9184 case RR_SRLV:
9185 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
9186 break;
9187 case RR_SRAV:
9188 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
9189 break;
9190 #if defined (TARGET_MIPS64)
9191 case RR_DSRL:
9192 check_mips_64(ctx);
9193 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
9194 break;
9195 #endif
9196 case RR_CMP:
9197 gen_logic(env, OPC_XOR, 24, rx, ry);
9198 break;
9199 case RR_NEG:
9200 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
9201 break;
9202 case RR_AND:
9203 gen_logic(env, OPC_AND, rx, rx, ry);
9204 break;
9205 case RR_OR:
9206 gen_logic(env, OPC_OR, rx, rx, ry);
9207 break;
9208 case RR_XOR:
9209 gen_logic(env, OPC_XOR, rx, rx, ry);
9210 break;
9211 case RR_NOT:
9212 gen_logic(env, OPC_NOR, rx, ry, 0);
9213 break;
9214 case RR_MFHI:
9215 gen_HILO(ctx, OPC_MFHI, rx);
9216 break;
9217 case RR_CNVT:
9218 switch (cnvt_op) {
9219 case RR_RY_CNVT_ZEB:
9220 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9221 break;
9222 case RR_RY_CNVT_ZEH:
9223 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9224 break;
9225 case RR_RY_CNVT_SEB:
9226 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9227 break;
9228 case RR_RY_CNVT_SEH:
9229 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9230 break;
9231 #if defined (TARGET_MIPS64)
9232 case RR_RY_CNVT_ZEW:
9233 check_mips_64(ctx);
9234 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9235 break;
9236 case RR_RY_CNVT_SEW:
9237 check_mips_64(ctx);
9238 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9239 break;
9240 #endif
9241 default:
9242 generate_exception(ctx, EXCP_RI);
9243 break;
9245 break;
9246 case RR_MFLO:
9247 gen_HILO(ctx, OPC_MFLO, rx);
9248 break;
9249 #if defined (TARGET_MIPS64)
9250 case RR_DSRA:
9251 check_mips_64(ctx);
9252 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
9253 break;
9254 case RR_DSLLV:
9255 check_mips_64(ctx);
9256 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
9257 break;
9258 case RR_DSRLV:
9259 check_mips_64(ctx);
9260 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
9261 break;
9262 case RR_DSRAV:
9263 check_mips_64(ctx);
9264 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
9265 break;
9266 #endif
9267 case RR_MULT:
9268 gen_muldiv(ctx, OPC_MULT, rx, ry);
9269 break;
9270 case RR_MULTU:
9271 gen_muldiv(ctx, OPC_MULTU, rx, ry);
9272 break;
9273 case RR_DIV:
9274 gen_muldiv(ctx, OPC_DIV, rx, ry);
9275 break;
9276 case RR_DIVU:
9277 gen_muldiv(ctx, OPC_DIVU, rx, ry);
9278 break;
9279 #if defined (TARGET_MIPS64)
9280 case RR_DMULT:
9281 check_mips_64(ctx);
9282 gen_muldiv(ctx, OPC_DMULT, rx, ry);
9283 break;
9284 case RR_DMULTU:
9285 check_mips_64(ctx);
9286 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
9287 break;
9288 case RR_DDIV:
9289 check_mips_64(ctx);
9290 gen_muldiv(ctx, OPC_DDIV, rx, ry);
9291 break;
9292 case RR_DDIVU:
9293 check_mips_64(ctx);
9294 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
9295 break;
9296 #endif
9297 default:
9298 generate_exception(ctx, EXCP_RI);
9299 break;
9301 break;
9302 case M16_OPC_EXTEND:
9303 decode_extended_mips16_opc(env, ctx, is_branch);
9304 n_bytes = 4;
9305 break;
9306 #if defined(TARGET_MIPS64)
9307 case M16_OPC_I64:
9308 funct = (ctx->opcode >> 8) & 0x7;
9309 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
9310 break;
9311 #endif
9312 default:
9313 generate_exception(ctx, EXCP_RI);
9314 break;
9317 return n_bytes;
9320 /* microMIPS extension to MIPS32 */
9322 /* microMIPS32 major opcodes */
9324 enum {
9325 POOL32A = 0x00,
9326 POOL16A = 0x01,
9327 LBU16 = 0x02,
9328 MOVE16 = 0x03,
9329 ADDI32 = 0x04,
9330 LBU32 = 0x05,
9331 SB32 = 0x06,
9332 LB32 = 0x07,
9334 POOL32B = 0x08,
9335 POOL16B = 0x09,
9336 LHU16 = 0x0a,
9337 ANDI16 = 0x0b,
9338 ADDIU32 = 0x0c,
9339 LHU32 = 0x0d,
9340 SH32 = 0x0e,
9341 LH32 = 0x0f,
9343 POOL32I = 0x10,
9344 POOL16C = 0x11,
9345 LWSP16 = 0x12,
9346 POOL16D = 0x13,
9347 ORI32 = 0x14,
9348 POOL32F = 0x15,
9349 POOL32S = 0x16,
9350 DADDIU32 = 0x17,
9352 POOL32C = 0x18,
9353 LWGP16 = 0x19,
9354 LW16 = 0x1a,
9355 POOL16E = 0x1b,
9356 XORI32 = 0x1c,
9357 JALS32 = 0x1d,
9358 ADDIUPC = 0x1e,
9359 POOL48A = 0x1f,
9361 /* 0x20 is reserved */
9362 RES_20 = 0x20,
9363 POOL16F = 0x21,
9364 SB16 = 0x22,
9365 BEQZ16 = 0x23,
9366 SLTI32 = 0x24,
9367 BEQ32 = 0x25,
9368 SWC132 = 0x26,
9369 LWC132 = 0x27,
9371 /* 0x28 and 0x29 are reserved */
9372 RES_28 = 0x28,
9373 RES_29 = 0x29,
9374 SH16 = 0x2a,
9375 BNEZ16 = 0x2b,
9376 SLTIU32 = 0x2c,
9377 BNE32 = 0x2d,
9378 SDC132 = 0x2e,
9379 LDC132 = 0x2f,
9381 /* 0x30 and 0x31 are reserved */
9382 RES_30 = 0x30,
9383 RES_31 = 0x31,
9384 SWSP16 = 0x32,
9385 B16 = 0x33,
9386 ANDI32 = 0x34,
9387 J32 = 0x35,
9388 SD32 = 0x36,
9389 LD32 = 0x37,
9391 /* 0x38 and 0x39 are reserved */
9392 RES_38 = 0x38,
9393 RES_39 = 0x39,
9394 SW16 = 0x3a,
9395 LI16 = 0x3b,
9396 JALX32 = 0x3c,
9397 JAL32 = 0x3d,
9398 SW32 = 0x3e,
9399 LW32 = 0x3f
9402 /* POOL32A encoding of minor opcode field */
9404 enum {
9405 /* These opcodes are distinguished only by bits 9..6; those bits are
9406 * what are recorded below. */
9407 SLL32 = 0x0,
9408 SRL32 = 0x1,
9409 SRA = 0x2,
9410 ROTR = 0x3,
9412 SLLV = 0x0,
9413 SRLV = 0x1,
9414 SRAV = 0x2,
9415 ROTRV = 0x3,
9416 ADD = 0x4,
9417 ADDU32 = 0x5,
9418 SUB = 0x6,
9419 SUBU32 = 0x7,
9420 MUL = 0x8,
9421 AND = 0x9,
9422 OR32 = 0xa,
9423 NOR = 0xb,
9424 XOR32 = 0xc,
9425 SLT = 0xd,
9426 SLTU = 0xe,
9428 MOVN = 0x0,
9429 MOVZ = 0x1,
9430 LWXS = 0x4,
9432 /* The following can be distinguished by their lower 6 bits. */
9433 INS = 0x0c,
9434 EXT = 0x2c,
9435 POOL32AXF = 0x3c
9438 /* POOL32AXF encoding of minor opcode field extension */
9440 enum {
9441 /* bits 11..6 */
9442 TEQ = 0x00,
9443 TGE = 0x08,
9444 TGEU = 0x10,
9445 TLT = 0x20,
9446 TLTU = 0x28,
9447 TNE = 0x30,
9449 MFC0 = 0x03,
9450 MTC0 = 0x0b,
9452 /* bits 13..12 for 0x01 */
9453 MFHI_ACC = 0x0,
9454 MFLO_ACC = 0x1,
9455 MTHI_ACC = 0x2,
9456 MTLO_ACC = 0x3,
9458 /* bits 13..12 for 0x2a */
9459 MADD_ACC = 0x0,
9460 MADDU_ACC = 0x1,
9461 MSUB_ACC = 0x2,
9462 MSUBU_ACC = 0x3,
9464 /* bits 13..12 for 0x32 */
9465 MULT_ACC = 0x0,
9466 MULTU_ACC = 0x0,
9468 /* bits 15..12 for 0x2c */
9469 SEB = 0x2,
9470 SEH = 0x3,
9471 CLO = 0x4,
9472 CLZ = 0x5,
9473 RDHWR = 0x6,
9474 WSBH = 0x7,
9475 MULT = 0x8,
9476 MULTU = 0x9,
9477 DIV = 0xa,
9478 DIVU = 0xb,
9479 MADD = 0xc,
9480 MADDU = 0xd,
9481 MSUB = 0xe,
9482 MSUBU = 0xf,
9484 /* bits 15..12 for 0x34 */
9485 MFC2 = 0x4,
9486 MTC2 = 0x5,
9487 MFHC2 = 0x8,
9488 MTHC2 = 0x9,
9489 CFC2 = 0xc,
9490 CTC2 = 0xd,
9492 /* bits 15..12 for 0x3c */
9493 JALR = 0x0,
9494 JR = 0x0, /* alias */
9495 JALR_HB = 0x1,
9496 JALRS = 0x4,
9497 JALRS_HB = 0x5,
9499 /* bits 15..12 for 0x05 */
9500 RDPGPR = 0xe,
9501 WRPGPR = 0xf,
9503 /* bits 15..12 for 0x0d */
9504 TLBP = 0x0,
9505 TLBR = 0x1,
9506 TLBWI = 0x2,
9507 TLBWR = 0x3,
9508 WAIT = 0x9,
9509 IRET = 0xd,
9510 DERET = 0xe,
9511 ERET = 0xf,
9513 /* bits 15..12 for 0x15 */
9514 DMT = 0x0,
9515 DVPE = 0x1,
9516 EMT = 0x2,
9517 EVPE = 0x3,
9519 /* bits 15..12 for 0x1d */
9520 DI = 0x4,
9521 EI = 0x5,
9523 /* bits 15..12 for 0x2d */
9524 SYNC = 0x6,
9525 SYSCALL = 0x8,
9526 SDBBP = 0xd,
9528 /* bits 15..12 for 0x35 */
9529 MFHI32 = 0x0,
9530 MFLO32 = 0x1,
9531 MTHI32 = 0x2,
9532 MTLO32 = 0x3,
9535 /* POOL32B encoding of minor opcode field (bits 15..12) */
9537 enum {
9538 LWC2 = 0x0,
9539 LWP = 0x1,
9540 LDP = 0x4,
9541 LWM32 = 0x5,
9542 CACHE = 0x6,
9543 LDM = 0x7,
9544 SWC2 = 0x8,
9545 SWP = 0x9,
9546 SDP = 0xc,
9547 SWM32 = 0xd,
9548 SDM = 0xf
9551 /* POOL32C encoding of minor opcode field (bits 15..12) */
9553 enum {
9554 LWL = 0x0,
9555 SWL = 0x8,
9556 LWR = 0x1,
9557 SWR = 0x9,
9558 PREF = 0x2,
9559 /* 0xa is reserved */
9560 LL = 0x3,
9561 SC = 0xb,
9562 LDL = 0x4,
9563 SDL = 0xc,
9564 LDR = 0x5,
9565 SDR = 0xd,
9566 /* 0x6 is reserved */
9567 LWU = 0xe,
9568 LLD = 0x7,
9569 SCD = 0xf
9572 /* POOL32F encoding of minor opcode field (bits 5..0) */
9574 enum {
9575 /* These are the bit 7..6 values */
9576 ADD_FMT = 0x0,
9577 MOVN_FMT = 0x0,
9579 SUB_FMT = 0x1,
9580 MOVZ_FMT = 0x1,
9582 MUL_FMT = 0x2,
9584 DIV_FMT = 0x3,
9586 /* These are the bit 8..6 values */
9587 RSQRT2_FMT = 0x0,
9588 MOVF_FMT = 0x0,
9590 LWXC1 = 0x1,
9591 MOVT_FMT = 0x1,
9593 PLL_PS = 0x2,
9594 SWXC1 = 0x2,
9596 PLU_PS = 0x3,
9597 LDXC1 = 0x3,
9599 PUL_PS = 0x4,
9600 SDXC1 = 0x4,
9601 RECIP2_FMT = 0x4,
9603 PUU_PS = 0x5,
9604 LUXC1 = 0x5,
9606 CVT_PS_S = 0x6,
9607 SUXC1 = 0x6,
9608 ADDR_PS = 0x6,
9609 PREFX = 0x6,
9611 MULR_PS = 0x7,
9613 MADD_S = 0x01,
9614 MADD_D = 0x09,
9615 MADD_PS = 0x11,
9616 ALNV_PS = 0x19,
9617 MSUB_S = 0x21,
9618 MSUB_D = 0x29,
9619 MSUB_PS = 0x31,
9621 NMADD_S = 0x02,
9622 NMADD_D = 0x0a,
9623 NMADD_PS = 0x12,
9624 NMSUB_S = 0x22,
9625 NMSUB_D = 0x2a,
9626 NMSUB_PS = 0x32,
9628 POOL32FXF = 0x3b,
9630 CABS_COND_FMT = 0x1c, /* MIPS3D */
9631 C_COND_FMT = 0x3c
9634 /* POOL32Fxf encoding of minor opcode extension field */
9636 enum {
9637 CVT_L = 0x04,
9638 RSQRT_FMT = 0x08,
9639 FLOOR_L = 0x0c,
9640 CVT_PW_PS = 0x1c,
9641 CVT_W = 0x24,
9642 SQRT_FMT = 0x28,
9643 FLOOR_W = 0x2c,
9644 CVT_PS_PW = 0x3c,
9645 CFC1 = 0x40,
9646 RECIP_FMT = 0x48,
9647 CEIL_L = 0x4c,
9648 CTC1 = 0x60,
9649 CEIL_W = 0x6c,
9650 MFC1 = 0x80,
9651 CVT_S_PL = 0x84,
9652 TRUNC_L = 0x8c,
9653 MTC1 = 0xa0,
9654 CVT_S_PU = 0xa4,
9655 TRUNC_W = 0xac,
9656 MFHC1 = 0xc0,
9657 ROUND_L = 0xcc,
9658 MTHC1 = 0xe0,
9659 ROUND_W = 0xec,
9661 MOV_FMT = 0x01,
9662 MOVF = 0x05,
9663 ABS_FMT = 0x0d,
9664 RSQRT1_FMT = 0x1d,
9665 MOVT = 0x25,
9666 NEG_FMT = 0x2d,
9667 CVT_D = 0x4d,
9668 RECIP1_FMT = 0x5d,
9669 CVT_S = 0x6d
9672 /* POOL32I encoding of minor opcode field (bits 25..21) */
9674 enum {
9675 BLTZ = 0x00,
9676 BLTZAL = 0x01,
9677 BGEZ = 0x02,
9678 BGEZAL = 0x03,
9679 BLEZ = 0x04,
9680 BNEZC = 0x05,
9681 BGTZ = 0x06,
9682 BEQZC = 0x07,
9683 TLTI = 0x08,
9684 TGEI = 0x09,
9685 TLTIU = 0x0a,
9686 TGEIU = 0x0b,
9687 TNEI = 0x0c,
9688 LUI = 0x0d,
9689 TEQI = 0x0e,
9690 SYNCI = 0x10,
9691 BLTZALS = 0x11,
9692 BGEZALS = 0x13,
9693 BC2F = 0x14,
9694 BC2T = 0x15,
9695 BPOSGE64 = 0x1a,
9696 BPOSGE32 = 0x1b,
9697 /* These overlap and are distinguished by bit16 of the instruction */
9698 BC1F = 0x1c,
9699 BC1T = 0x1d,
9700 BC1ANY2F = 0x1c,
9701 BC1ANY2T = 0x1d,
9702 BC1ANY4F = 0x1e,
9703 BC1ANY4T = 0x1f
9706 /* POOL16A encoding of minor opcode field */
9708 enum {
9709 ADDU16 = 0x0,
9710 SUBU16 = 0x1
9713 /* POOL16B encoding of minor opcode field */
9715 enum {
9716 SLL16 = 0x0,
9717 SRL16 = 0x1
9720 /* POOL16C encoding of minor opcode field */
9722 enum {
9723 NOT16 = 0x00,
9724 XOR16 = 0x04,
9725 AND16 = 0x08,
9726 OR16 = 0x0c,
9727 LWM16 = 0x10,
9728 SWM16 = 0x14,
9729 JR16 = 0x18,
9730 JRC16 = 0x1a,
9731 JALR16 = 0x1c,
9732 JALR16S = 0x1e,
9733 MFHI16 = 0x20,
9734 MFLO16 = 0x24,
9735 BREAK16 = 0x28,
9736 SDBBP16 = 0x2c,
9737 JRADDIUSP = 0x30
9740 /* POOL16D encoding of minor opcode field */
9742 enum {
9743 ADDIUS5 = 0x0,
9744 ADDIUSP = 0x1
9747 /* POOL16E encoding of minor opcode field */
9749 enum {
9750 ADDIUR2 = 0x0,
9751 ADDIUR1SP = 0x1
9754 static int mmreg (int r)
9756 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9758 return map[r];
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 };
9766 return map[r];
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))) \
9779 << (32-width)) \
9780 >> (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);
9803 int decoded;
9805 if (encoded <= 1) {
9806 decoded = 256 + encoded;
9807 } else if (encoded <= 255) {
9808 decoded = encoded;
9809 } else if (encoded <= 509) {
9810 decoded = encoded - 512;
9811 } else {
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)
9840 TCGv t0, t1;
9841 TCGv_i32 t2;
9843 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9844 generate_exception(ctx, EXCP_RI);
9845 return;
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);
9856 switch (opc) {
9857 case LWM32:
9858 gen_helper_lwm(t0, t1, t2);
9859 break;
9860 case SWM32:
9861 gen_helper_swm(t0, t1, t2);
9862 break;
9863 #ifdef TARGET_MIPS64
9864 case LDM:
9865 gen_helper_ldm(t0, t1, t2);
9866 break;
9867 case SDM:
9868 gen_helper_sdm(t0, t1, t2);
9869 break;
9870 #endif
9872 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9873 tcg_temp_free(t0);
9874 tcg_temp_free(t1);
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);
9883 int opc;
9885 switch (((ctx->opcode) >> 4) & 0x3f) {
9886 case NOT16 + 0:
9887 case NOT16 + 1:
9888 case NOT16 + 2:
9889 case NOT16 + 3:
9890 gen_logic(env, OPC_NOR, rd, rs, 0);
9891 break;
9892 case XOR16 + 0:
9893 case XOR16 + 1:
9894 case XOR16 + 2:
9895 case XOR16 + 3:
9896 gen_logic(env, OPC_XOR, rd, rd, rs);
9897 break;
9898 case AND16 + 0:
9899 case AND16 + 1:
9900 case AND16 + 2:
9901 case AND16 + 3:
9902 gen_logic(env, OPC_AND, rd, rd, rs);
9903 break;
9904 case OR16 + 0:
9905 case OR16 + 1:
9906 case OR16 + 2:
9907 case OR16 + 3:
9908 gen_logic(env, OPC_OR, rd, rd, rs);
9909 break;
9910 case LWM16 + 0:
9911 case LWM16 + 1:
9912 case LWM16 + 2:
9913 case LWM16 + 3:
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],
9919 29, offset << 2);
9921 break;
9922 case SWM16 + 0:
9923 case SWM16 + 1:
9924 case SWM16 + 2:
9925 case SWM16 + 3:
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],
9931 29, offset << 2);
9933 break;
9934 case JR16 + 0:
9935 case JR16 + 1:
9937 int reg = ctx->opcode & 0x1f;
9939 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9941 *is_branch = 1;
9942 break;
9943 case JRC16 + 0:
9944 case JRC16 + 1:
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. */
9952 break;
9953 case JALR16 + 0:
9954 case JALR16 + 1:
9955 opc = OPC_JALR;
9956 goto do_jalr;
9957 case JALR16S + 0:
9958 case JALR16S + 1:
9959 opc = OPC_JALRS;
9960 do_jalr:
9962 int reg = ctx->opcode & 0x1f;
9964 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9966 *is_branch = 1;
9967 break;
9968 case MFHI16 + 0:
9969 case MFHI16 + 1:
9970 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9971 break;
9972 case MFLO16 + 0:
9973 case MFLO16 + 1:
9974 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9975 break;
9976 case BREAK16:
9977 generate_exception(ctx, EXCP_BREAK);
9978 break;
9979 case SDBBP16:
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);
9986 } else {
9987 generate_exception(ctx, EXCP_DBp);
9989 break;
9990 case JRADDIUSP + 0:
9991 case JRADDIUSP + 1:
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. */
10000 break;
10001 default:
10002 generate_exception(ctx, EXCP_RI);
10003 break;
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);
10014 if (index != 0) {
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);
10024 tcg_temp_free(t0);
10025 tcg_temp_free(t1);
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";
10032 TCGv t0, t1;
10034 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10035 generate_exception(ctx, EXCP_RI);
10036 return;
10039 t0 = tcg_temp_new();
10040 t1 = tcg_temp_new();
10042 gen_base_offset_addr(ctx, t0, base, offset);
10044 switch (opc) {
10045 case LWP:
10046 if (rd == base) {
10047 generate_exception(ctx, EXCP_RI);
10048 return;
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);
10057 opn = "lwp";
10058 break;
10059 case SWP:
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);
10067 opn = "swp";
10068 break;
10069 #ifdef TARGET_MIPS64
10070 case LDP:
10071 if (rd == base) {
10072 generate_exception(ctx, EXCP_RI);
10073 return;
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);
10082 opn = "ldp";
10083 break;
10084 case SDP:
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);
10092 opn = "sdp";
10093 break;
10094 #endif
10096 (void)opn; /* avoid a compiler warning */
10097 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
10098 tcg_temp_free(t0);
10099 tcg_temp_free(t1);
10102 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
10103 int *is_branch)
10105 int extension = (ctx->opcode >> 6) & 0x3f;
10106 int minor = (ctx->opcode >> 12) & 0xf;
10107 uint32_t mips32_op;
10109 switch (extension) {
10110 case TEQ:
10111 mips32_op = OPC_TEQ;
10112 goto do_trap;
10113 case TGE:
10114 mips32_op = OPC_TGE;
10115 goto do_trap;
10116 case TGEU:
10117 mips32_op = OPC_TGEU;
10118 goto do_trap;
10119 case TLT:
10120 mips32_op = OPC_TLT;
10121 goto do_trap;
10122 case TLTU:
10123 mips32_op = OPC_TLTU;
10124 goto do_trap;
10125 case TNE:
10126 mips32_op = OPC_TNE;
10127 do_trap:
10128 gen_trap(ctx, mips32_op, rs, rt, -1);
10129 break;
10130 #ifndef CONFIG_USER_ONLY
10131 case MFC0:
10132 case MFC0 + 32:
10133 check_cp0_enabled(ctx);
10134 if (rt == 0) {
10135 /* Treat as NOP. */
10136 break;
10138 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
10139 break;
10140 case MTC0:
10141 case MTC0 + 32:
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);
10148 tcg_temp_free(t0);
10150 break;
10151 #endif
10152 case 0x2c:
10153 switch (minor) {
10154 case SEB:
10155 gen_bshfl(ctx, OPC_SEB, rs, rt);
10156 break;
10157 case SEH:
10158 gen_bshfl(ctx, OPC_SEH, rs, rt);
10159 break;
10160 case CLO:
10161 mips32_op = OPC_CLO;
10162 goto do_cl;
10163 case CLZ:
10164 mips32_op = OPC_CLZ;
10165 do_cl:
10166 check_insn(env, ctx, ISA_MIPS32);
10167 gen_cl(ctx, mips32_op, rt, rs);
10168 break;
10169 case RDHWR:
10170 gen_rdhwr(env, ctx, rt, rs);
10171 break;
10172 case WSBH:
10173 gen_bshfl(ctx, OPC_WSBH, rs, rt);
10174 break;
10175 case MULT:
10176 mips32_op = OPC_MULT;
10177 goto do_muldiv;
10178 case MULTU:
10179 mips32_op = OPC_MULTU;
10180 goto do_muldiv;
10181 case DIV:
10182 mips32_op = OPC_DIV;
10183 goto do_muldiv;
10184 case DIVU:
10185 mips32_op = OPC_DIVU;
10186 goto do_muldiv;
10187 case MADD:
10188 mips32_op = OPC_MADD;
10189 goto do_muldiv;
10190 case MADDU:
10191 mips32_op = OPC_MADDU;
10192 goto do_muldiv;
10193 case MSUB:
10194 mips32_op = OPC_MSUB;
10195 goto do_muldiv;
10196 case MSUBU:
10197 mips32_op = OPC_MSUBU;
10198 do_muldiv:
10199 check_insn(env, ctx, ISA_MIPS32);
10200 gen_muldiv(ctx, mips32_op, rs, rt);
10201 break;
10202 default:
10203 goto pool32axf_invalid;
10205 break;
10206 case 0x34:
10207 switch (minor) {
10208 case MFC2:
10209 case MTC2:
10210 case MFHC2:
10211 case MTHC2:
10212 case CFC2:
10213 case CTC2:
10214 generate_exception_err(ctx, EXCP_CpU, 2);
10215 break;
10216 default:
10217 goto pool32axf_invalid;
10219 break;
10220 case 0x3c:
10221 switch (minor) {
10222 case JALR:
10223 case JALR_HB:
10224 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
10225 *is_branch = 1;
10226 break;
10227 case JALRS:
10228 case JALRS_HB:
10229 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
10230 *is_branch = 1;
10231 break;
10232 default:
10233 goto pool32axf_invalid;
10235 break;
10236 case 0x05:
10237 switch (minor) {
10238 case RDPGPR:
10239 check_cp0_enabled(ctx);
10240 check_insn(env, ctx, ISA_MIPS32R2);
10241 gen_load_srsgpr(rt, rs);
10242 break;
10243 case WRPGPR:
10244 check_cp0_enabled(ctx);
10245 check_insn(env, ctx, ISA_MIPS32R2);
10246 gen_store_srsgpr(rt, rs);
10247 break;
10248 default:
10249 goto pool32axf_invalid;
10251 break;
10252 #ifndef CONFIG_USER_ONLY
10253 case 0x0d:
10254 switch (minor) {
10255 case TLBP:
10256 mips32_op = OPC_TLBP;
10257 goto do_cp0;
10258 case TLBR:
10259 mips32_op = OPC_TLBR;
10260 goto do_cp0;
10261 case TLBWI:
10262 mips32_op = OPC_TLBWI;
10263 goto do_cp0;
10264 case TLBWR:
10265 mips32_op = OPC_TLBWR;
10266 goto do_cp0;
10267 case WAIT:
10268 mips32_op = OPC_WAIT;
10269 goto do_cp0;
10270 case DERET:
10271 mips32_op = OPC_DERET;
10272 goto do_cp0;
10273 case ERET:
10274 mips32_op = OPC_ERET;
10275 do_cp0:
10276 gen_cp0(env, ctx, mips32_op, rt, rs);
10277 break;
10278 default:
10279 goto pool32axf_invalid;
10281 break;
10282 case 0x1d:
10283 switch (minor) {
10284 case DI:
10285 check_cp0_enabled(ctx);
10287 TCGv t0 = tcg_temp_new();
10289 save_cpu_state(ctx, 1);
10290 gen_helper_di(t0);
10291 gen_store_gpr(t0, rs);
10292 /* Stop translation as we may have switched the execution mode */
10293 ctx->bstate = BS_STOP;
10294 tcg_temp_free(t0);
10296 break;
10297 case EI:
10298 check_cp0_enabled(ctx);
10300 TCGv t0 = tcg_temp_new();
10302 save_cpu_state(ctx, 1);
10303 gen_helper_ei(t0);
10304 gen_store_gpr(t0, rs);
10305 /* Stop translation as we may have switched the execution mode */
10306 ctx->bstate = BS_STOP;
10307 tcg_temp_free(t0);
10309 break;
10310 default:
10311 goto pool32axf_invalid;
10313 break;
10314 #endif
10315 case 0x2d:
10316 switch (minor) {
10317 case SYNC:
10318 /* NOP */
10319 break;
10320 case SYSCALL:
10321 generate_exception(ctx, EXCP_SYSCALL);
10322 ctx->bstate = BS_STOP;
10323 break;
10324 case SDBBP:
10325 check_insn(env, ctx, ISA_MIPS32);
10326 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10327 generate_exception(ctx, EXCP_DBp);
10328 } else {
10329 generate_exception(ctx, EXCP_DBp);
10331 break;
10332 default:
10333 goto pool32axf_invalid;
10335 break;
10336 case 0x35:
10337 switch (minor) {
10338 case MFHI32:
10339 gen_HILO(ctx, OPC_MFHI, rs);
10340 break;
10341 case MFLO32:
10342 gen_HILO(ctx, OPC_MFLO, rs);
10343 break;
10344 case MTHI32:
10345 gen_HILO(ctx, OPC_MTHI, rs);
10346 break;
10347 case MTLO32:
10348 gen_HILO(ctx, OPC_MTLO, rs);
10349 break;
10350 default:
10351 goto pool32axf_invalid;
10353 break;
10354 default:
10355 pool32axf_invalid:
10356 MIPS_INVAL("pool32axf");
10357 generate_exception(ctx, EXCP_RI);
10358 break;
10362 /* Values for microMIPS fmt field. Variable-width, depending on which
10363 formats the instruction supports. */
10365 enum {
10366 FMT_SD_S = 0,
10367 FMT_SD_D = 1,
10369 FMT_SDPS_S = 0,
10370 FMT_SDPS_D = 1,
10371 FMT_SDPS_PS = 2,
10373 FMT_SWL_S = 0,
10374 FMT_SWL_W = 1,
10375 FMT_SWL_L = 2,
10377 FMT_DWL_D = 0,
10378 FMT_DWL_W = 1,
10379 FMT_DWL_L = 2
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;
10394 goto do_cp1;
10395 case FLOAT_1BIT_FMT(CTC1, 0):
10396 mips32_op = OPC_CTC1;
10397 goto do_cp1;
10398 case FLOAT_1BIT_FMT(MFC1, 0):
10399 mips32_op = OPC_MFC1;
10400 goto do_cp1;
10401 case FLOAT_1BIT_FMT(MTC1, 0):
10402 mips32_op = OPC_MTC1;
10403 goto do_cp1;
10404 case FLOAT_1BIT_FMT(MFHC1, 0):
10405 mips32_op = OPC_MFHC1;
10406 goto do_cp1;
10407 case FLOAT_1BIT_FMT(MTHC1, 0):
10408 mips32_op = OPC_MTHC1;
10409 do_cp1:
10410 gen_cp1(ctx, mips32_op, rt, rs);
10411 break;
10413 /* Reciprocal square root */
10414 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10415 mips32_op = OPC_RSQRT_S;
10416 goto do_unaryfp;
10417 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10418 mips32_op = OPC_RSQRT_D;
10419 goto do_unaryfp;
10421 /* Square root */
10422 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10423 mips32_op = OPC_SQRT_S;
10424 goto do_unaryfp;
10425 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10426 mips32_op = OPC_SQRT_D;
10427 goto do_unaryfp;
10429 /* Reciprocal */
10430 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10431 mips32_op = OPC_RECIP_S;
10432 goto do_unaryfp;
10433 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10434 mips32_op = OPC_RECIP_D;
10435 goto do_unaryfp;
10437 /* Floor */
10438 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10439 mips32_op = OPC_FLOOR_L_S;
10440 goto do_unaryfp;
10441 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10442 mips32_op = OPC_FLOOR_L_D;
10443 goto do_unaryfp;
10444 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10445 mips32_op = OPC_FLOOR_W_S;
10446 goto do_unaryfp;
10447 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10448 mips32_op = OPC_FLOOR_W_D;
10449 goto do_unaryfp;
10451 /* Ceiling */
10452 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10453 mips32_op = OPC_CEIL_L_S;
10454 goto do_unaryfp;
10455 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10456 mips32_op = OPC_CEIL_L_D;
10457 goto do_unaryfp;
10458 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10459 mips32_op = OPC_CEIL_W_S;
10460 goto do_unaryfp;
10461 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10462 mips32_op = OPC_CEIL_W_D;
10463 goto do_unaryfp;
10465 /* Truncation */
10466 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10467 mips32_op = OPC_TRUNC_L_S;
10468 goto do_unaryfp;
10469 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10470 mips32_op = OPC_TRUNC_L_D;
10471 goto do_unaryfp;
10472 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10473 mips32_op = OPC_TRUNC_W_S;
10474 goto do_unaryfp;
10475 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10476 mips32_op = OPC_TRUNC_W_D;
10477 goto do_unaryfp;
10479 /* Round */
10480 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10481 mips32_op = OPC_ROUND_L_S;
10482 goto do_unaryfp;
10483 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10484 mips32_op = OPC_ROUND_L_D;
10485 goto do_unaryfp;
10486 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10487 mips32_op = OPC_ROUND_W_S;
10488 goto do_unaryfp;
10489 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10490 mips32_op = OPC_ROUND_W_D;
10491 goto do_unaryfp;
10493 /* Integer to floating-point conversion */
10494 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10495 mips32_op = OPC_CVT_L_S;
10496 goto do_unaryfp;
10497 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10498 mips32_op = OPC_CVT_L_D;
10499 goto do_unaryfp;
10500 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10501 mips32_op = OPC_CVT_W_S;
10502 goto do_unaryfp;
10503 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10504 mips32_op = OPC_CVT_W_D;
10505 goto do_unaryfp;
10507 /* Paired-foo conversions */
10508 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10509 mips32_op = OPC_CVT_S_PL;
10510 goto do_unaryfp;
10511 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10512 mips32_op = OPC_CVT_S_PU;
10513 goto do_unaryfp;
10514 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10515 mips32_op = OPC_CVT_PW_PS;
10516 goto do_unaryfp;
10517 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10518 mips32_op = OPC_CVT_PS_PW;
10519 goto do_unaryfp;
10521 /* Floating-point moves */
10522 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10523 mips32_op = OPC_MOV_S;
10524 goto do_unaryfp;
10525 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10526 mips32_op = OPC_MOV_D;
10527 goto do_unaryfp;
10528 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10529 mips32_op = OPC_MOV_PS;
10530 goto do_unaryfp;
10532 /* Absolute value */
10533 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10534 mips32_op = OPC_ABS_S;
10535 goto do_unaryfp;
10536 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10537 mips32_op = OPC_ABS_D;
10538 goto do_unaryfp;
10539 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10540 mips32_op = OPC_ABS_PS;
10541 goto do_unaryfp;
10543 /* Negation */
10544 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10545 mips32_op = OPC_NEG_S;
10546 goto do_unaryfp;
10547 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10548 mips32_op = OPC_NEG_D;
10549 goto do_unaryfp;
10550 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10551 mips32_op = OPC_NEG_PS;
10552 goto do_unaryfp;
10554 /* Reciprocal square root step */
10555 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10556 mips32_op = OPC_RSQRT1_S;
10557 goto do_unaryfp;
10558 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10559 mips32_op = OPC_RSQRT1_D;
10560 goto do_unaryfp;
10561 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10562 mips32_op = OPC_RSQRT1_PS;
10563 goto do_unaryfp;
10565 /* Reciprocal step */
10566 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10567 mips32_op = OPC_RECIP1_S;
10568 goto do_unaryfp;
10569 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10570 mips32_op = OPC_RECIP1_S;
10571 goto do_unaryfp;
10572 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10573 mips32_op = OPC_RECIP1_PS;
10574 goto do_unaryfp;
10576 /* Conversions from double */
10577 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10578 mips32_op = OPC_CVT_D_S;
10579 goto do_unaryfp;
10580 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10581 mips32_op = OPC_CVT_D_W;
10582 goto do_unaryfp;
10583 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10584 mips32_op = OPC_CVT_D_L;
10585 goto do_unaryfp;
10587 /* Conversions from single */
10588 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10589 mips32_op = OPC_CVT_S_D;
10590 goto do_unaryfp;
10591 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10592 mips32_op = OPC_CVT_S_W;
10593 goto do_unaryfp;
10594 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10595 mips32_op = OPC_CVT_S_L;
10596 do_unaryfp:
10597 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10598 break;
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);
10610 break;
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);
10620 break;
10621 default:
10622 MIPS_INVAL("pool32fxf");
10623 generate_exception(ctx, EXCP_RI);
10624 break;
10628 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
10629 uint16_t insn_hw1, int *is_branch)
10631 int32_t offset;
10632 uint16_t insn;
10633 int rt, rs, rd, rr;
10634 int16_t imm;
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;
10648 switch (op) {
10649 case POOL32A:
10650 minor = ctx->opcode & 0x3f;
10651 switch (minor) {
10652 case 0x00:
10653 minor = (ctx->opcode >> 6) & 0xf;
10654 switch (minor) {
10655 case SLL32:
10656 mips32_op = OPC_SLL;
10657 goto do_shifti;
10658 case SRA:
10659 mips32_op = OPC_SRA;
10660 goto do_shifti;
10661 case SRL32:
10662 mips32_op = OPC_SRL;
10663 goto do_shifti;
10664 case ROTR:
10665 mips32_op = OPC_ROTR;
10666 do_shifti:
10667 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10668 break;
10669 default:
10670 goto pool32a_invalid;
10672 break;
10673 case 0x10:
10674 minor = (ctx->opcode >> 6) & 0xf;
10675 switch (minor) {
10676 /* Arithmetic */
10677 case ADD:
10678 mips32_op = OPC_ADD;
10679 goto do_arith;
10680 case ADDU32:
10681 mips32_op = OPC_ADDU;
10682 goto do_arith;
10683 case SUB:
10684 mips32_op = OPC_SUB;
10685 goto do_arith;
10686 case SUBU32:
10687 mips32_op = OPC_SUBU;
10688 goto do_arith;
10689 case MUL:
10690 mips32_op = OPC_MUL;
10691 do_arith:
10692 gen_arith(env, ctx, mips32_op, rd, rs, rt);
10693 break;
10694 /* Shifts */
10695 case SLLV:
10696 mips32_op = OPC_SLLV;
10697 goto do_shift;
10698 case SRLV:
10699 mips32_op = OPC_SRLV;
10700 goto do_shift;
10701 case SRAV:
10702 mips32_op = OPC_SRAV;
10703 goto do_shift;
10704 case ROTRV:
10705 mips32_op = OPC_ROTRV;
10706 do_shift:
10707 gen_shift(env, ctx, mips32_op, rd, rs, rt);
10708 break;
10709 /* Logical operations */
10710 case AND:
10711 mips32_op = OPC_AND;
10712 goto do_logic;
10713 case OR32:
10714 mips32_op = OPC_OR;
10715 goto do_logic;
10716 case NOR:
10717 mips32_op = OPC_NOR;
10718 goto do_logic;
10719 case XOR32:
10720 mips32_op = OPC_XOR;
10721 do_logic:
10722 gen_logic(env, mips32_op, rd, rs, rt);
10723 break;
10724 /* Set less than */
10725 case SLT:
10726 mips32_op = OPC_SLT;
10727 goto do_slt;
10728 case SLTU:
10729 mips32_op = OPC_SLTU;
10730 do_slt:
10731 gen_slt(env, mips32_op, rd, rs, rt);
10732 break;
10733 default:
10734 goto pool32a_invalid;
10736 break;
10737 case 0x18:
10738 minor = (ctx->opcode >> 6) & 0xf;
10739 switch (minor) {
10740 /* Conditional moves */
10741 case MOVN:
10742 mips32_op = OPC_MOVN;
10743 goto do_cmov;
10744 case MOVZ:
10745 mips32_op = OPC_MOVZ;
10746 do_cmov:
10747 gen_cond_move(env, mips32_op, rd, rs, rt);
10748 break;
10749 case LWXS:
10750 gen_ldxs(ctx, rs, rt, rd);
10751 break;
10752 default:
10753 goto pool32a_invalid;
10755 break;
10756 case INS:
10757 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10758 return;
10759 case EXT:
10760 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10761 return;
10762 case POOL32AXF:
10763 gen_pool32axf(env, ctx, rt, rs, is_branch);
10764 break;
10765 case 0x07:
10766 generate_exception(ctx, EXCP_BREAK);
10767 break;
10768 default:
10769 pool32a_invalid:
10770 MIPS_INVAL("pool32a");
10771 generate_exception(ctx, EXCP_RI);
10772 break;
10774 break;
10775 case POOL32B:
10776 minor = (ctx->opcode >> 12) & 0xf;
10777 switch (minor) {
10778 case CACHE:
10779 check_cp0_enabled(ctx);
10780 /* Treat as no-op. */
10781 break;
10782 case LWC2:
10783 case SWC2:
10784 /* COP2: Not implemented. */
10785 generate_exception_err(ctx, EXCP_CpU, 2);
10786 break;
10787 case LWP:
10788 case SWP:
10789 #ifdef TARGET_MIPS64
10790 case LDP:
10791 case SDP:
10792 #endif
10793 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10794 break;
10795 case LWM32:
10796 case SWM32:
10797 #ifdef TARGET_MIPS64
10798 case LDM:
10799 case SDM:
10800 #endif
10801 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10802 break;
10803 default:
10804 MIPS_INVAL("pool32b");
10805 generate_exception(ctx, EXCP_RI);
10806 break;
10808 break;
10809 case POOL32F:
10810 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10811 minor = ctx->opcode & 0x3f;
10812 check_cp1_enabled(ctx);
10813 switch (minor) {
10814 case ALNV_PS:
10815 mips32_op = OPC_ALNV_PS;
10816 goto do_madd;
10817 case MADD_S:
10818 mips32_op = OPC_MADD_S;
10819 goto do_madd;
10820 case MADD_D:
10821 mips32_op = OPC_MADD_D;
10822 goto do_madd;
10823 case MADD_PS:
10824 mips32_op = OPC_MADD_PS;
10825 goto do_madd;
10826 case MSUB_S:
10827 mips32_op = OPC_MSUB_S;
10828 goto do_madd;
10829 case MSUB_D:
10830 mips32_op = OPC_MSUB_D;
10831 goto do_madd;
10832 case MSUB_PS:
10833 mips32_op = OPC_MSUB_PS;
10834 goto do_madd;
10835 case NMADD_S:
10836 mips32_op = OPC_NMADD_S;
10837 goto do_madd;
10838 case NMADD_D:
10839 mips32_op = OPC_NMADD_D;
10840 goto do_madd;
10841 case NMADD_PS:
10842 mips32_op = OPC_NMADD_PS;
10843 goto do_madd;
10844 case NMSUB_S:
10845 mips32_op = OPC_NMSUB_S;
10846 goto do_madd;
10847 case NMSUB_D:
10848 mips32_op = OPC_NMSUB_D;
10849 goto do_madd;
10850 case NMSUB_PS:
10851 mips32_op = OPC_NMSUB_PS;
10852 do_madd:
10853 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10854 break;
10855 case CABS_COND_FMT:
10856 cond = (ctx->opcode >> 6) & 0xf;
10857 cc = (ctx->opcode >> 13) & 0x7;
10858 fmt = (ctx->opcode >> 10) & 0x3;
10859 switch (fmt) {
10860 case 0x0:
10861 gen_cmpabs_s(ctx, cond, rt, rs, cc);
10862 break;
10863 case 0x1:
10864 gen_cmpabs_d(ctx, cond, rt, rs, cc);
10865 break;
10866 case 0x2:
10867 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10868 break;
10869 default:
10870 goto pool32f_invalid;
10872 break;
10873 case C_COND_FMT:
10874 cond = (ctx->opcode >> 6) & 0xf;
10875 cc = (ctx->opcode >> 13) & 0x7;
10876 fmt = (ctx->opcode >> 10) & 0x3;
10877 switch (fmt) {
10878 case 0x0:
10879 gen_cmp_s(ctx, cond, rt, rs, cc);
10880 break;
10881 case 0x1:
10882 gen_cmp_d(ctx, cond, rt, rs, cc);
10883 break;
10884 case 0x2:
10885 gen_cmp_ps(ctx, cond, rt, rs, cc);
10886 break;
10887 default:
10888 goto pool32f_invalid;
10890 break;
10891 case POOL32FXF:
10892 gen_pool32fxf(env, ctx, rt, rs);
10893 break;
10894 case 0x00:
10895 /* PLL foo */
10896 switch ((ctx->opcode >> 6) & 0x7) {
10897 case PLL_PS:
10898 mips32_op = OPC_PLL_PS;
10899 goto do_ps;
10900 case PLU_PS:
10901 mips32_op = OPC_PLU_PS;
10902 goto do_ps;
10903 case PUL_PS:
10904 mips32_op = OPC_PUL_PS;
10905 goto do_ps;
10906 case PUU_PS:
10907 mips32_op = OPC_PUU_PS;
10908 goto do_ps;
10909 case CVT_PS_S:
10910 mips32_op = OPC_CVT_PS_S;
10911 do_ps:
10912 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10913 break;
10914 default:
10915 goto pool32f_invalid;
10917 break;
10918 case 0x08:
10919 /* [LS][WDU]XC1 */
10920 switch ((ctx->opcode >> 6) & 0x7) {
10921 case LWXC1:
10922 mips32_op = OPC_LWXC1;
10923 goto do_ldst_cp1;
10924 case SWXC1:
10925 mips32_op = OPC_SWXC1;
10926 goto do_ldst_cp1;
10927 case LDXC1:
10928 mips32_op = OPC_LDXC1;
10929 goto do_ldst_cp1;
10930 case SDXC1:
10931 mips32_op = OPC_SDXC1;
10932 goto do_ldst_cp1;
10933 case LUXC1:
10934 mips32_op = OPC_LUXC1;
10935 goto do_ldst_cp1;
10936 case SUXC1:
10937 mips32_op = OPC_SUXC1;
10938 do_ldst_cp1:
10939 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10940 break;
10941 default:
10942 goto pool32f_invalid;
10944 break;
10945 case 0x18:
10946 /* 3D insns */
10947 fmt = (ctx->opcode >> 9) & 0x3;
10948 switch ((ctx->opcode >> 6) & 0x7) {
10949 case RSQRT2_FMT:
10950 switch (fmt) {
10951 case FMT_SDPS_S:
10952 mips32_op = OPC_RSQRT2_S;
10953 goto do_3d;
10954 case FMT_SDPS_D:
10955 mips32_op = OPC_RSQRT2_D;
10956 goto do_3d;
10957 case FMT_SDPS_PS:
10958 mips32_op = OPC_RSQRT2_PS;
10959 goto do_3d;
10960 default:
10961 goto pool32f_invalid;
10963 break;
10964 case RECIP2_FMT:
10965 switch (fmt) {
10966 case FMT_SDPS_S:
10967 mips32_op = OPC_RECIP2_S;
10968 goto do_3d;
10969 case FMT_SDPS_D:
10970 mips32_op = OPC_RECIP2_D;
10971 goto do_3d;
10972 case FMT_SDPS_PS:
10973 mips32_op = OPC_RECIP2_PS;
10974 goto do_3d;
10975 default:
10976 goto pool32f_invalid;
10978 break;
10979 case ADDR_PS:
10980 mips32_op = OPC_ADDR_PS;
10981 goto do_3d;
10982 case MULR_PS:
10983 mips32_op = OPC_MULR_PS;
10984 do_3d:
10985 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10986 break;
10987 default:
10988 goto pool32f_invalid;
10990 break;
10991 case 0x20:
10992 /* MOV[FT].fmt and PREFX */
10993 cc = (ctx->opcode >> 13) & 0x7;
10994 fmt = (ctx->opcode >> 9) & 0x3;
10995 switch ((ctx->opcode >> 6) & 0x7) {
10996 case MOVF_FMT:
10997 switch (fmt) {
10998 case FMT_SDPS_S:
10999 gen_movcf_s(rs, rt, cc, 0);
11000 break;
11001 case FMT_SDPS_D:
11002 gen_movcf_d(ctx, rs, rt, cc, 0);
11003 break;
11004 case FMT_SDPS_PS:
11005 gen_movcf_ps(rs, rt, cc, 0);
11006 break;
11007 default:
11008 goto pool32f_invalid;
11010 break;
11011 case MOVT_FMT:
11012 switch (fmt) {
11013 case FMT_SDPS_S:
11014 gen_movcf_s(rs, rt, cc, 1);
11015 break;
11016 case FMT_SDPS_D:
11017 gen_movcf_d(ctx, rs, rt, cc, 1);
11018 break;
11019 case FMT_SDPS_PS:
11020 gen_movcf_ps(rs, rt, cc, 1);
11021 break;
11022 default:
11023 goto pool32f_invalid;
11025 break;
11026 case PREFX:
11027 break;
11028 default:
11029 goto pool32f_invalid;
11031 break;
11032 #define FINSN_3ARG_SDPS(prfx) \
11033 switch ((ctx->opcode >> 8) & 0x3) { \
11034 case FMT_SDPS_S: \
11035 mips32_op = OPC_##prfx##_S; \
11036 goto do_fpop; \
11037 case FMT_SDPS_D: \
11038 mips32_op = OPC_##prfx##_D; \
11039 goto do_fpop; \
11040 case FMT_SDPS_PS: \
11041 mips32_op = OPC_##prfx##_PS; \
11042 goto do_fpop; \
11043 default: \
11044 goto pool32f_invalid; \
11046 case 0x30:
11047 /* regular FP ops */
11048 switch ((ctx->opcode >> 6) & 0x3) {
11049 case ADD_FMT:
11050 FINSN_3ARG_SDPS(ADD);
11051 break;
11052 case SUB_FMT:
11053 FINSN_3ARG_SDPS(SUB);
11054 break;
11055 case MUL_FMT:
11056 FINSN_3ARG_SDPS(MUL);
11057 break;
11058 case DIV_FMT:
11059 fmt = (ctx->opcode >> 8) & 0x3;
11060 if (fmt == 1) {
11061 mips32_op = OPC_DIV_D;
11062 } else if (fmt == 0) {
11063 mips32_op = OPC_DIV_S;
11064 } else {
11065 goto pool32f_invalid;
11067 goto do_fpop;
11068 default:
11069 goto pool32f_invalid;
11071 break;
11072 case 0x38:
11073 /* cmovs */
11074 switch ((ctx->opcode >> 6) & 0x3) {
11075 case MOVN_FMT:
11076 FINSN_3ARG_SDPS(MOVN);
11077 break;
11078 case MOVZ_FMT:
11079 FINSN_3ARG_SDPS(MOVZ);
11080 break;
11081 default:
11082 goto pool32f_invalid;
11084 break;
11085 do_fpop:
11086 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11087 break;
11088 default:
11089 pool32f_invalid:
11090 MIPS_INVAL("pool32f");
11091 generate_exception(ctx, EXCP_RI);
11092 break;
11094 } else {
11095 generate_exception_err(ctx, EXCP_CpU, 1);
11097 break;
11098 case POOL32I:
11099 minor = (ctx->opcode >> 21) & 0x1f;
11100 switch (minor) {
11101 case BLTZ:
11102 mips32_op = OPC_BLTZ;
11103 goto do_branch;
11104 case BLTZAL:
11105 mips32_op = OPC_BLTZAL;
11106 goto do_branch;
11107 case BLTZALS:
11108 mips32_op = OPC_BLTZALS;
11109 goto do_branch;
11110 case BGEZ:
11111 mips32_op = OPC_BGEZ;
11112 goto do_branch;
11113 case BGEZAL:
11114 mips32_op = OPC_BGEZAL;
11115 goto do_branch;
11116 case BGEZALS:
11117 mips32_op = OPC_BGEZALS;
11118 goto do_branch;
11119 case BLEZ:
11120 mips32_op = OPC_BLEZ;
11121 goto do_branch;
11122 case BGTZ:
11123 mips32_op = OPC_BGTZ;
11124 do_branch:
11125 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
11126 *is_branch = 1;
11127 break;
11129 /* Traps */
11130 case TLTI:
11131 mips32_op = OPC_TLTI;
11132 goto do_trapi;
11133 case TGEI:
11134 mips32_op = OPC_TGEI;
11135 goto do_trapi;
11136 case TLTIU:
11137 mips32_op = OPC_TLTIU;
11138 goto do_trapi;
11139 case TGEIU:
11140 mips32_op = OPC_TGEIU;
11141 goto do_trapi;
11142 case TNEI:
11143 mips32_op = OPC_TNEI;
11144 goto do_trapi;
11145 case TEQI:
11146 mips32_op = OPC_TEQI;
11147 do_trapi:
11148 gen_trap(ctx, mips32_op, rs, -1, imm);
11149 break;
11151 case BNEZC:
11152 case BEQZC:
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
11157 target. */
11158 break;
11159 case LUI:
11160 gen_logic_imm(env, OPC_LUI, rs, -1, imm);
11161 break;
11162 case SYNCI:
11163 break;
11164 case BC2F:
11165 case BC2T:
11166 /* COP2: Not implemented. */
11167 generate_exception_err(ctx, EXCP_CpU, 2);
11168 break;
11169 case BC1F:
11170 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
11171 goto do_cp1branch;
11172 case BC1T:
11173 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
11174 goto do_cp1branch;
11175 case BC1ANY4F:
11176 mips32_op = OPC_BC1FANY4;
11177 goto do_cp1mips3d;
11178 case BC1ANY4T:
11179 mips32_op = OPC_BC1TANY4;
11180 do_cp1mips3d:
11181 check_cop1x(ctx);
11182 check_insn(env, ctx, ASE_MIPS3D);
11183 /* Fall through */
11184 do_cp1branch:
11185 gen_compute_branch1(env, ctx, mips32_op,
11186 (ctx->opcode >> 18) & 0x7, imm << 1);
11187 *is_branch = 1;
11188 break;
11189 case BPOSGE64:
11190 case BPOSGE32:
11191 /* MIPS DSP: not implemented */
11192 /* Fall through */
11193 default:
11194 MIPS_INVAL("pool32i");
11195 generate_exception(ctx, EXCP_RI);
11196 break;
11198 break;
11199 case POOL32C:
11200 minor = (ctx->opcode >> 12) & 0xf;
11201 switch (minor) {
11202 case LWL:
11203 mips32_op = OPC_LWL;
11204 goto do_ld_lr;
11205 case SWL:
11206 mips32_op = OPC_SWL;
11207 goto do_st_lr;
11208 case LWR:
11209 mips32_op = OPC_LWR;
11210 goto do_ld_lr;
11211 case SWR:
11212 mips32_op = OPC_SWR;
11213 goto do_st_lr;
11214 #if defined(TARGET_MIPS64)
11215 case LDL:
11216 mips32_op = OPC_LDL;
11217 goto do_ld_lr;
11218 case SDL:
11219 mips32_op = OPC_SDL;
11220 goto do_st_lr;
11221 case LDR:
11222 mips32_op = OPC_LDR;
11223 goto do_ld_lr;
11224 case SDR:
11225 mips32_op = OPC_SDR;
11226 goto do_st_lr;
11227 case LWU:
11228 mips32_op = OPC_LWU;
11229 goto do_ld_lr;
11230 case LLD:
11231 mips32_op = OPC_LLD;
11232 goto do_ld_lr;
11233 #endif
11234 case LL:
11235 mips32_op = OPC_LL;
11236 goto do_ld_lr;
11237 do_ld_lr:
11238 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11239 break;
11240 do_st_lr:
11241 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11242 break;
11243 case SC:
11244 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
11245 break;
11246 #if defined(TARGET_MIPS64)
11247 case SCD:
11248 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
11249 break;
11250 #endif
11251 case PREF:
11252 /* Treat as no-op */
11253 break;
11254 default:
11255 MIPS_INVAL("pool32c");
11256 generate_exception(ctx, EXCP_RI);
11257 break;
11259 break;
11260 case ADDI32:
11261 mips32_op = OPC_ADDI;
11262 goto do_addi;
11263 case ADDIU32:
11264 mips32_op = OPC_ADDIU;
11265 do_addi:
11266 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
11267 break;
11269 /* Logical operations */
11270 case ORI32:
11271 mips32_op = OPC_ORI;
11272 goto do_logici;
11273 case XORI32:
11274 mips32_op = OPC_XORI;
11275 goto do_logici;
11276 case ANDI32:
11277 mips32_op = OPC_ANDI;
11278 do_logici:
11279 gen_logic_imm(env, mips32_op, rt, rs, imm);
11280 break;
11282 /* Set less than immediate */
11283 case SLTI32:
11284 mips32_op = OPC_SLTI;
11285 goto do_slti;
11286 case SLTIU32:
11287 mips32_op = OPC_SLTIU;
11288 do_slti:
11289 gen_slt_imm(env, mips32_op, rt, rs, imm);
11290 break;
11291 case JALX32:
11292 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11293 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
11294 *is_branch = 1;
11295 break;
11296 case JALS32:
11297 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
11298 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
11299 *is_branch = 1;
11300 break;
11301 case BEQ32:
11302 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
11303 *is_branch = 1;
11304 break;
11305 case BNE32:
11306 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
11307 *is_branch = 1;
11308 break;
11309 case J32:
11310 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
11311 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11312 *is_branch = 1;
11313 break;
11314 case JAL32:
11315 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
11316 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11317 *is_branch = 1;
11318 break;
11319 /* Floating point (COP1) */
11320 case LWC132:
11321 mips32_op = OPC_LWC1;
11322 goto do_cop1;
11323 case LDC132:
11324 mips32_op = OPC_LDC1;
11325 goto do_cop1;
11326 case SWC132:
11327 mips32_op = OPC_SWC1;
11328 goto do_cop1;
11329 case SDC132:
11330 mips32_op = OPC_SDC1;
11331 do_cop1:
11332 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
11333 break;
11334 case ADDIUPC:
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);
11341 break;
11342 /* Loads and stores */
11343 case LB32:
11344 mips32_op = OPC_LB;
11345 goto do_ld;
11346 case LBU32:
11347 mips32_op = OPC_LBU;
11348 goto do_ld;
11349 case LH32:
11350 mips32_op = OPC_LH;
11351 goto do_ld;
11352 case LHU32:
11353 mips32_op = OPC_LHU;
11354 goto do_ld;
11355 case LW32:
11356 mips32_op = OPC_LW;
11357 goto do_ld;
11358 #ifdef TARGET_MIPS64
11359 case LD32:
11360 mips32_op = OPC_LD;
11361 goto do_ld;
11362 case SD32:
11363 mips32_op = OPC_SD;
11364 goto do_st;
11365 #endif
11366 case SB32:
11367 mips32_op = OPC_SB;
11368 goto do_st;
11369 case SH32:
11370 mips32_op = OPC_SH;
11371 goto do_st;
11372 case SW32:
11373 mips32_op = OPC_SW;
11374 goto do_st;
11375 do_ld:
11376 gen_ld(env, ctx, mips32_op, rt, rs, imm);
11377 break;
11378 do_st:
11379 gen_st(ctx, mips32_op, rt, rs, imm);
11380 break;
11381 default:
11382 generate_exception(ctx, EXCP_RI);
11383 break;
11387 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
11389 uint32_t op;
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;
11396 return 2;
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;
11404 switch (op) {
11405 case POOL32A:
11406 case POOL32B:
11407 case POOL32I:
11408 case POOL32C:
11409 case ADDI32:
11410 case ADDIU32:
11411 case ORI32:
11412 case XORI32:
11413 case SLTI32:
11414 case SLTIU32:
11415 case ANDI32:
11416 case JALX32:
11417 case LBU32:
11418 case LHU32:
11419 case POOL32F:
11420 case JALS32:
11421 case BEQ32:
11422 case BNE32:
11423 case J32:
11424 case JAL32:
11425 case SB32:
11426 case SH32:
11427 case POOL32S:
11428 case ADDIUPC:
11429 case SWC132:
11430 case SDC132:
11431 case SD32:
11432 case SW32:
11433 case LB32:
11434 case LH32:
11435 case DADDIU32:
11436 case POOL48A: /* ??? */
11437 case LWC132:
11438 case LDC132:
11439 case LD32:
11440 case LW32:
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;
11445 return 2;
11447 break;
11448 case POOL16A:
11449 case POOL16B:
11450 case POOL16C:
11451 case LWGP16:
11452 case POOL16F:
11453 case LBU16:
11454 case LHU16:
11455 case LWSP16:
11456 case LW16:
11457 case SB16:
11458 case SH16:
11459 case SWSP16:
11460 case SW16:
11461 case MOVE16:
11462 case ANDI16:
11463 case POOL16D:
11464 case POOL16E:
11465 case BEQZ16:
11466 case BNEZ16:
11467 case B16:
11468 case LI16:
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;
11473 return 2;
11475 break;
11476 default:
11477 break;
11480 switch (op) {
11481 case POOL16A:
11483 int rd = mmreg(uMIPS_RD(ctx->opcode));
11484 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11485 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11486 uint32_t opc = 0;
11488 switch (ctx->opcode & 0x1) {
11489 case ADDU16:
11490 opc = OPC_ADDU;
11491 break;
11492 case SUBU16:
11493 opc = OPC_SUBU;
11494 break;
11497 gen_arith(env, ctx, opc, rd, rs1, rs2);
11499 break;
11500 case POOL16B:
11502 int rd = mmreg(uMIPS_RD(ctx->opcode));
11503 int rs = mmreg(uMIPS_RS(ctx->opcode));
11504 int amount = (ctx->opcode >> 1) & 0x7;
11505 uint32_t opc = 0;
11506 amount = amount == 0 ? 8 : amount;
11508 switch (ctx->opcode & 0x1) {
11509 case SLL16:
11510 opc = OPC_SLL;
11511 break;
11512 case SRL16:
11513 opc = OPC_SRL;
11514 break;
11517 gen_shift_imm(env, ctx, opc, rd, rs, amount);
11519 break;
11520 case POOL16C:
11521 gen_pool16c_insn(env, ctx, is_branch);
11522 break;
11523 case LWGP16:
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);
11531 break;
11532 case POOL16F:
11533 if (ctx->opcode & 1) {
11534 generate_exception(ctx, EXCP_RI);
11535 } else {
11536 /* MOVEP */
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);
11553 break;
11554 case LBU16:
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);
11563 break;
11564 case LHU16:
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);
11572 break;
11573 case LWSP16:
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);
11581 break;
11582 case LW16:
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);
11590 break;
11591 case SB16:
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);
11599 break;
11600 case SH16:
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);
11608 break;
11609 case SWSP16:
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);
11617 break;
11618 case SW16:
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);
11626 break;
11627 case MOVE16:
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);
11634 break;
11635 case ANDI16:
11636 gen_andi16(env, ctx);
11637 break;
11638 case POOL16D:
11639 switch (ctx->opcode & 0x1) {
11640 case ADDIUS5:
11641 gen_addius5(env, ctx);
11642 break;
11643 case ADDIUSP:
11644 gen_addiusp(env, ctx);
11645 break;
11647 break;
11648 case POOL16E:
11649 switch (ctx->opcode & 0x1) {
11650 case ADDIUR2:
11651 gen_addiur2(env, ctx);
11652 break;
11653 case ADDIUR1SP:
11654 gen_addiur1sp(env, ctx);
11655 break;
11657 break;
11658 case B16:
11659 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11660 SIMM(ctx->opcode, 0, 10) << 1);
11661 *is_branch = 1;
11662 break;
11663 case BNEZ16:
11664 case BEQZ16:
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);
11668 *is_branch = 1;
11669 break;
11670 case LI16:
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);
11678 break;
11679 case RES_20:
11680 case RES_28:
11681 case RES_29:
11682 case RES_30:
11683 case RES_31:
11684 case RES_38:
11685 case RES_39:
11686 generate_exception(ctx, EXCP_RI);
11687 break;
11688 default:
11689 decode_micromips32_opc (env, ctx, op, is_branch);
11690 return 4;
11693 return 2;
11696 /* SmartMIPS extension to MIPS32 */
11698 #if defined(TARGET_MIPS64)
11700 /* MDMX extension to MIPS64 */
11702 #endif
11704 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
11706 int32_t offset;
11707 int rs, rt, rd, sa;
11708 uint32_t op, op1, op2;
11709 int16_t imm;
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);
11715 return;
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);
11726 gen_set_label(l1);
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;
11738 switch (op) {
11739 case OPC_SPECIAL:
11740 op1 = MASK_SPECIAL(ctx->opcode);
11741 switch (op1) {
11742 case OPC_SLL: /* Shift with immediate */
11743 case OPC_SRA:
11744 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11745 break;
11746 case OPC_SRL:
11747 switch ((ctx->opcode >> 21) & 0x1f) {
11748 case 1:
11749 /* rotr is decoded as srl on non-R2 CPUs */
11750 if (env->insn_flags & ISA_MIPS32R2) {
11751 op1 = OPC_ROTR;
11753 /* Fallthrough */
11754 case 0:
11755 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11756 break;
11757 default:
11758 generate_exception(ctx, EXCP_RI);
11759 break;
11761 break;
11762 case OPC_MOVN: /* Conditional move */
11763 case OPC_MOVZ:
11764 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11765 INSN_LOONGSON2E | INSN_LOONGSON2F);
11766 gen_cond_move(env, op1, rd, rs, rt);
11767 break;
11768 case OPC_ADD ... OPC_SUBU:
11769 gen_arith(env, ctx, op1, rd, rs, rt);
11770 break;
11771 case OPC_SLLV: /* Shifts */
11772 case OPC_SRAV:
11773 gen_shift(env, ctx, op1, rd, rs, rt);
11774 break;
11775 case OPC_SRLV:
11776 switch ((ctx->opcode >> 6) & 0x1f) {
11777 case 1:
11778 /* rotrv is decoded as srlv on non-R2 CPUs */
11779 if (env->insn_flags & ISA_MIPS32R2) {
11780 op1 = OPC_ROTRV;
11782 /* Fallthrough */
11783 case 0:
11784 gen_shift(env, ctx, op1, rd, rs, rt);
11785 break;
11786 default:
11787 generate_exception(ctx, EXCP_RI);
11788 break;
11790 break;
11791 case OPC_SLT: /* Set on less than */
11792 case OPC_SLTU:
11793 gen_slt(env, op1, rd, rs, rt);
11794 break;
11795 case OPC_AND: /* Logic*/
11796 case OPC_OR:
11797 case OPC_NOR:
11798 case OPC_XOR:
11799 gen_logic(env, op1, rd, rs, rt);
11800 break;
11801 case OPC_MULT ... OPC_DIVU:
11802 if (sa) {
11803 check_insn(env, ctx, INSN_VR54XX);
11804 op1 = MASK_MUL_VR54XX(ctx->opcode);
11805 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11806 } else
11807 gen_muldiv(ctx, op1, rs, rt);
11808 break;
11809 case OPC_JR ... OPC_JALR:
11810 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11811 *is_branch = 1;
11812 break;
11813 case OPC_TGE ... OPC_TEQ: /* Traps */
11814 case OPC_TNE:
11815 gen_trap(ctx, op1, rs, rt, -1);
11816 break;
11817 case OPC_MFHI: /* Move from HI/LO */
11818 case OPC_MFLO:
11819 gen_HILO(ctx, op1, rd);
11820 break;
11821 case OPC_MTHI:
11822 case OPC_MTLO: /* Move to HI/LO */
11823 gen_HILO(ctx, op1, rs);
11824 break;
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);
11829 #else
11830 gen_helper_0i(pmon, sa);
11831 #endif
11832 break;
11833 case OPC_SYSCALL:
11834 generate_exception(ctx, EXCP_SYSCALL);
11835 ctx->bstate = BS_STOP;
11836 break;
11837 case OPC_BREAK:
11838 generate_exception(ctx, EXCP_BREAK);
11839 break;
11840 case OPC_SPIM:
11841 #ifdef MIPS_STRICT_STANDARD
11842 MIPS_INVAL("SPIM");
11843 generate_exception(ctx, EXCP_RI);
11844 #else
11845 /* Implemented as RI exception for now. */
11846 MIPS_INVAL("spim (unofficial)");
11847 generate_exception(ctx, EXCP_RI);
11848 #endif
11849 break;
11850 case OPC_SYNC:
11851 /* Treat as NOP. */
11852 break;
11854 case OPC_MOVCI:
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);
11860 } else {
11861 generate_exception_err(ctx, EXCP_CpU, 1);
11863 break;
11865 #if defined(TARGET_MIPS64)
11866 /* MIPS64 specific opcodes */
11867 case OPC_DSLL:
11868 case OPC_DSRA:
11869 case OPC_DSLL32:
11870 case OPC_DSRA32:
11871 check_insn(env, ctx, ISA_MIPS3);
11872 check_mips_64(ctx);
11873 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11874 break;
11875 case OPC_DSRL:
11876 switch ((ctx->opcode >> 21) & 0x1f) {
11877 case 1:
11878 /* drotr is decoded as dsrl on non-R2 CPUs */
11879 if (env->insn_flags & ISA_MIPS32R2) {
11880 op1 = OPC_DROTR;
11882 /* Fallthrough */
11883 case 0:
11884 check_insn(env, ctx, ISA_MIPS3);
11885 check_mips_64(ctx);
11886 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11887 break;
11888 default:
11889 generate_exception(ctx, EXCP_RI);
11890 break;
11892 break;
11893 case OPC_DSRL32:
11894 switch ((ctx->opcode >> 21) & 0x1f) {
11895 case 1:
11896 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11897 if (env->insn_flags & ISA_MIPS32R2) {
11898 op1 = OPC_DROTR32;
11900 /* Fallthrough */
11901 case 0:
11902 check_insn(env, ctx, ISA_MIPS3);
11903 check_mips_64(ctx);
11904 gen_shift_imm(env, ctx, op1, rd, rt, sa);
11905 break;
11906 default:
11907 generate_exception(ctx, EXCP_RI);
11908 break;
11910 break;
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);
11915 break;
11916 case OPC_DSLLV:
11917 case OPC_DSRAV:
11918 check_insn(env, ctx, ISA_MIPS3);
11919 check_mips_64(ctx);
11920 gen_shift(env, ctx, op1, rd, rs, rt);
11921 break;
11922 case OPC_DSRLV:
11923 switch ((ctx->opcode >> 6) & 0x1f) {
11924 case 1:
11925 /* drotrv is decoded as dsrlv on non-R2 CPUs */
11926 if (env->insn_flags & ISA_MIPS32R2) {
11927 op1 = OPC_DROTRV;
11929 /* Fallthrough */
11930 case 0:
11931 check_insn(env, ctx, ISA_MIPS3);
11932 check_mips_64(ctx);
11933 gen_shift(env, ctx, op1, rd, rs, rt);
11934 break;
11935 default:
11936 generate_exception(ctx, EXCP_RI);
11937 break;
11939 break;
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);
11944 break;
11945 #endif
11946 default: /* Invalid */
11947 MIPS_INVAL("special");
11948 generate_exception(ctx, EXCP_RI);
11949 break;
11951 break;
11952 case OPC_SPECIAL2:
11953 op1 = MASK_SPECIAL2(ctx->opcode);
11954 switch (op1) {
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);
11959 break;
11960 case OPC_MUL:
11961 gen_arith(env, ctx, op1, rd, rs, rt);
11962 break;
11963 case OPC_CLO:
11964 case OPC_CLZ:
11965 check_insn(env, ctx, ISA_MIPS32);
11966 gen_cl(ctx, op1, rd, rs);
11967 break;
11968 case OPC_SDBBP:
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);
11975 } else {
11976 generate_exception(ctx, EXCP_DBp);
11978 /* Treat as NOP. */
11979 break;
11980 case OPC_DIV_G_2F:
11981 case OPC_DIVU_G_2F:
11982 case OPC_MULT_G_2F:
11983 case OPC_MULTU_G_2F:
11984 case OPC_MOD_G_2F:
11985 case OPC_MODU_G_2F:
11986 check_insn(env, ctx, INSN_LOONGSON2F);
11987 gen_loongson_integer(ctx, op1, rd, rs, rt);
11988 break;
11989 #if defined(TARGET_MIPS64)
11990 case OPC_DCLO:
11991 case OPC_DCLZ:
11992 check_insn(env, ctx, ISA_MIPS64);
11993 check_mips_64(ctx);
11994 gen_cl(ctx, op1, rd, rs);
11995 break;
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);
12004 break;
12005 #endif
12006 default: /* Invalid */
12007 MIPS_INVAL("special2");
12008 generate_exception(ctx, EXCP_RI);
12009 break;
12011 break;
12012 case OPC_SPECIAL3:
12013 op1 = MASK_SPECIAL3(ctx->opcode);
12014 switch (op1) {
12015 case OPC_EXT:
12016 case OPC_INS:
12017 check_insn(env, ctx, ISA_MIPS32R2);
12018 gen_bitops(ctx, op1, rt, rs, sa, rd);
12019 break;
12020 case OPC_BSHFL:
12021 check_insn(env, ctx, ISA_MIPS32R2);
12022 op2 = MASK_BSHFL(ctx->opcode);
12023 gen_bshfl(ctx, op2, rt, rd);
12024 break;
12025 case OPC_RDHWR:
12026 gen_rdhwr(env, ctx, rt, rd);
12027 break;
12028 case OPC_FORK:
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);
12037 tcg_temp_free(t0);
12038 tcg_temp_free(t1);
12040 break;
12041 case OPC_YIELD:
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);
12050 tcg_temp_free(t0);
12052 break;
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);
12058 break;
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);
12065 break;
12066 case OPC_DBSHFL:
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);
12071 break;
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);
12077 break;
12078 #endif
12079 default: /* Invalid */
12080 MIPS_INVAL("special3");
12081 generate_exception(ctx, EXCP_RI);
12082 break;
12084 break;
12085 case OPC_REGIMM:
12086 op1 = MASK_REGIMM(ctx->opcode);
12087 switch (op1) {
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);
12091 *is_branch = 1;
12092 break;
12093 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
12094 case OPC_TNEI:
12095 gen_trap(ctx, op1, rs, -1, imm);
12096 break;
12097 case OPC_SYNCI:
12098 check_insn(env, ctx, ISA_MIPS32R2);
12099 /* Treat as NOP. */
12100 break;
12101 default: /* Invalid */
12102 MIPS_INVAL("regimm");
12103 generate_exception(ctx, EXCP_RI);
12104 break;
12106 break;
12107 case OPC_CP0:
12108 check_cp0_enabled(ctx);
12109 op1 = MASK_CP0(ctx->opcode);
12110 switch (op1) {
12111 case OPC_MFC0:
12112 case OPC_MTC0:
12113 case OPC_MFTR:
12114 case OPC_MTTR:
12115 #if defined(TARGET_MIPS64)
12116 case OPC_DMFC0:
12117 case OPC_DMTC0:
12118 #endif
12119 #ifndef CONFIG_USER_ONLY
12120 gen_cp0(env, ctx, op1, rt, rd);
12121 #endif /* !CONFIG_USER_ONLY */
12122 break;
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 */
12127 break;
12128 case OPC_MFMC0:
12129 #ifndef CONFIG_USER_ONLY
12131 TCGv t0 = tcg_temp_new();
12133 op2 = MASK_MFMC0(ctx->opcode);
12134 switch (op2) {
12135 case OPC_DMT:
12136 check_insn(env, ctx, ASE_MT);
12137 gen_helper_dmt(t0);
12138 gen_store_gpr(t0, rt);
12139 break;
12140 case OPC_EMT:
12141 check_insn(env, ctx, ASE_MT);
12142 gen_helper_emt(t0);
12143 gen_store_gpr(t0, rt);
12144 break;
12145 case OPC_DVPE:
12146 check_insn(env, ctx, ASE_MT);
12147 gen_helper_dvpe(t0);
12148 gen_store_gpr(t0, rt);
12149 break;
12150 case OPC_EVPE:
12151 check_insn(env, ctx, ASE_MT);
12152 gen_helper_evpe(t0);
12153 gen_store_gpr(t0, rt);
12154 break;
12155 case OPC_DI:
12156 check_insn(env, ctx, ISA_MIPS32R2);
12157 save_cpu_state(ctx, 1);
12158 gen_helper_di(t0);
12159 gen_store_gpr(t0, rt);
12160 /* Stop translation as we may have switched the execution mode */
12161 ctx->bstate = BS_STOP;
12162 break;
12163 case OPC_EI:
12164 check_insn(env, ctx, ISA_MIPS32R2);
12165 save_cpu_state(ctx, 1);
12166 gen_helper_ei(t0);
12167 gen_store_gpr(t0, rt);
12168 /* Stop translation as we may have switched the execution mode */
12169 ctx->bstate = BS_STOP;
12170 break;
12171 default: /* Invalid */
12172 MIPS_INVAL("mfmc0");
12173 generate_exception(ctx, EXCP_RI);
12174 break;
12176 tcg_temp_free(t0);
12178 #endif /* !CONFIG_USER_ONLY */
12179 break;
12180 case OPC_RDPGPR:
12181 check_insn(env, ctx, ISA_MIPS32R2);
12182 gen_load_srsgpr(rt, rd);
12183 break;
12184 case OPC_WRPGPR:
12185 check_insn(env, ctx, ISA_MIPS32R2);
12186 gen_store_srsgpr(rt, rd);
12187 break;
12188 default:
12189 MIPS_INVAL("cp0");
12190 generate_exception(ctx, EXCP_RI);
12191 break;
12193 break;
12194 case OPC_ADDI: /* Arithmetic with immediate opcode */
12195 case OPC_ADDIU:
12196 gen_arith_imm(env, ctx, op, rt, rs, imm);
12197 break;
12198 case OPC_SLTI: /* Set on less than with immediate opcode */
12199 case OPC_SLTIU:
12200 gen_slt_imm(env, op, rt, rs, imm);
12201 break;
12202 case OPC_ANDI: /* Arithmetic with immediate opcode */
12203 case OPC_LUI:
12204 case OPC_ORI:
12205 case OPC_XORI:
12206 gen_logic_imm(env, op, rt, rs, imm);
12207 break;
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);
12211 *is_branch = 1;
12212 break;
12213 case OPC_BEQ ... OPC_BGTZ: /* Branch */
12214 case OPC_BEQL ... OPC_BGTZL:
12215 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
12216 *is_branch = 1;
12217 break;
12218 case OPC_LB ... OPC_LWR: /* Load and stores */
12219 case OPC_LL:
12220 gen_ld(env, ctx, op, rt, rs, imm);
12221 break;
12222 case OPC_SB ... OPC_SW:
12223 case OPC_SWR:
12224 gen_st(ctx, op, rt, rs, imm);
12225 break;
12226 case OPC_SC:
12227 gen_st_cond(ctx, op, rt, rs, imm);
12228 break;
12229 case OPC_CACHE:
12230 check_cp0_enabled(ctx);
12231 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
12232 /* Treat as NOP. */
12233 break;
12234 case OPC_PREF:
12235 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12236 /* Treat as NOP. */
12237 break;
12239 /* Floating point (COP1). */
12240 case OPC_LWC1:
12241 case OPC_LDC1:
12242 case OPC_SWC1:
12243 case OPC_SDC1:
12244 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12245 break;
12247 case OPC_CP1:
12248 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12249 check_cp1_enabled(ctx);
12250 op1 = MASK_CP1(ctx->opcode);
12251 switch (op1) {
12252 case OPC_MFHC1:
12253 case OPC_MTHC1:
12254 check_insn(env, ctx, ISA_MIPS32R2);
12255 case OPC_MFC1:
12256 case OPC_CFC1:
12257 case OPC_MTC1:
12258 case OPC_CTC1:
12259 gen_cp1(ctx, op1, rt, rd);
12260 break;
12261 #if defined(TARGET_MIPS64)
12262 case OPC_DMFC1:
12263 case OPC_DMTC1:
12264 check_insn(env, ctx, ISA_MIPS3);
12265 gen_cp1(ctx, op1, rt, rd);
12266 break;
12267 #endif
12268 case OPC_BC1ANY2:
12269 case OPC_BC1ANY4:
12270 check_cop1x(ctx);
12271 check_insn(env, ctx, ASE_MIPS3D);
12272 /* fall through */
12273 case OPC_BC1:
12274 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
12275 (rt >> 2) & 0x7, imm << 2);
12276 *is_branch = 1;
12277 break;
12278 case OPC_S_FMT:
12279 case OPC_D_FMT:
12280 case OPC_W_FMT:
12281 case OPC_L_FMT:
12282 case OPC_PS_FMT:
12283 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
12284 (imm >> 8) & 0x7);
12285 break;
12286 default:
12287 MIPS_INVAL("cp1");
12288 generate_exception (ctx, EXCP_RI);
12289 break;
12291 } else {
12292 generate_exception_err(ctx, EXCP_CpU, 1);
12294 break;
12296 /* COP2. */
12297 case OPC_LWC2:
12298 case OPC_LDC2:
12299 case OPC_SWC2:
12300 case OPC_SDC2:
12301 case OPC_CP2:
12302 /* COP2: Not implemented. */
12303 generate_exception_err(ctx, EXCP_CpU, 2);
12304 break;
12306 case OPC_CP3:
12307 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12308 check_cp1_enabled(ctx);
12309 op1 = MASK_CP3(ctx->opcode);
12310 switch (op1) {
12311 case OPC_LWXC1:
12312 case OPC_LDXC1:
12313 case OPC_LUXC1:
12314 case OPC_SWXC1:
12315 case OPC_SDXC1:
12316 case OPC_SUXC1:
12317 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
12318 break;
12319 case OPC_PREFX:
12320 /* Treat as NOP. */
12321 break;
12322 case OPC_ALNV_PS:
12323 case OPC_MADD_S:
12324 case OPC_MADD_D:
12325 case OPC_MADD_PS:
12326 case OPC_MSUB_S:
12327 case OPC_MSUB_D:
12328 case OPC_MSUB_PS:
12329 case OPC_NMADD_S:
12330 case OPC_NMADD_D:
12331 case OPC_NMADD_PS:
12332 case OPC_NMSUB_S:
12333 case OPC_NMSUB_D:
12334 case OPC_NMSUB_PS:
12335 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
12336 break;
12337 default:
12338 MIPS_INVAL("cp3");
12339 generate_exception (ctx, EXCP_RI);
12340 break;
12342 } else {
12343 generate_exception_err(ctx, EXCP_CpU, 1);
12345 break;
12347 #if defined(TARGET_MIPS64)
12348 /* MIPS64 opcodes */
12349 case OPC_LWU:
12350 case OPC_LDL ... OPC_LDR:
12351 case OPC_LLD:
12352 case OPC_LD:
12353 check_insn(env, ctx, ISA_MIPS3);
12354 check_mips_64(ctx);
12355 gen_ld(env, ctx, op, rt, rs, imm);
12356 break;
12357 case OPC_SDL ... OPC_SDR:
12358 case OPC_SD:
12359 check_insn(env, ctx, ISA_MIPS3);
12360 check_mips_64(ctx);
12361 gen_st(ctx, op, rt, rs, imm);
12362 break;
12363 case OPC_SCD:
12364 check_insn(env, ctx, ISA_MIPS3);
12365 check_mips_64(ctx);
12366 gen_st_cond(ctx, op, rt, rs, imm);
12367 break;
12368 case OPC_DADDI:
12369 case OPC_DADDIU:
12370 check_insn(env, ctx, ISA_MIPS3);
12371 check_mips_64(ctx);
12372 gen_arith_imm(env, ctx, op, rt, rs, imm);
12373 break;
12374 #endif
12375 case OPC_JALX:
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);
12379 *is_branch = 1;
12380 break;
12381 case OPC_MDMX:
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);
12387 break;
12391 static inline void
12392 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
12393 int search_pc)
12395 DisasContext ctx;
12396 target_ulong pc_start;
12397 uint16_t *gen_opc_end;
12398 CPUBreakpoint *bp;
12399 int j, lj = -1;
12400 int num_insns;
12401 int max_insns;
12402 int insn_bytes;
12403 int is_branch;
12405 if (search_pc)
12406 qemu_log("search pc %d\n", search_pc);
12408 pc_start = tb->pc;
12409 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
12410 ctx.pc = pc_start;
12411 ctx.saved_pc = -1;
12412 ctx.singlestep_enabled = env->singlestep_enabled;
12413 ctx.tb = tb;
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;
12420 #else
12421 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
12422 #endif
12423 num_insns = 0;
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. */
12438 ctx.pc += 4;
12439 goto done_generating;
12444 if (search_pc) {
12445 j = gen_opc_ptr - gen_opc_buf;
12446 if (lj < j) {
12447 lj++;
12448 while (lj < j)
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))
12457 gen_io_start();
12459 is_branch = 0;
12460 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12461 ctx.opcode = ldl_code(ctx.pc);
12462 insn_bytes = 4;
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);
12470 } else {
12471 generate_exception(&ctx, EXCP_RI);
12472 ctx.bstate = BS_STOP;
12473 break;
12475 if (!is_branch) {
12476 handle_delay_slot(env, &ctx, insn_bytes);
12478 ctx.pc += insn_bytes;
12480 num_insns++;
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)
12487 break;
12489 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12490 break;
12492 if (gen_opc_ptr >= gen_opc_end)
12493 break;
12495 if (num_insns >= max_insns)
12496 break;
12498 if (singlestep)
12499 break;
12501 if (tb->cflags & CF_LAST_IO)
12502 gen_io_end();
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);
12506 } else {
12507 switch (ctx.bstate) {
12508 case BS_STOP:
12509 gen_goto_tb(&ctx, 0, ctx.pc);
12510 break;
12511 case BS_NONE:
12512 save_cpu_state(&ctx, 0);
12513 gen_goto_tb(&ctx, 0, ctx.pc);
12514 break;
12515 case BS_EXCP:
12516 tcg_gen_exit_tb(0);
12517 break;
12518 case BS_BRANCH:
12519 default:
12520 break;
12523 done_generating:
12524 gen_icount_end(tb, num_insns);
12525 *gen_opc_ptr = INDEX_op_end;
12526 if (search_pc) {
12527 j = gen_opc_ptr - gen_opc_buf;
12528 lj++;
12529 while (lj <= j)
12530 gen_opc_instr_start[lj++] = 0;
12531 } else {
12532 tb->size = ctx.pc - pc_start;
12533 tb->icount = num_insns;
12535 #ifdef DEBUG_DISAS
12536 LOG_DISAS("\n");
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);
12540 qemu_log("\n");
12542 #endif
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,
12556 int flags)
12558 int i;
12559 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12561 #define printfpr(fp) \
12562 do { \
12563 if (is_fpu64) \
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]); \
12570 else { \
12571 fpr_t tmp; \
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, \
12577 (double)tmp.fd, \
12578 (double)tmp.fs[FP_ENDIAN_IDX], \
12579 (double)tmp.fs[!FP_ENDIAN_IDX]); \
12581 } while(0)
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]);
12592 #undef printfpr
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))
12601 static void
12602 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
12603 fprintf_function cpu_fprintf,
12604 int flags)
12606 int i;
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);
12627 #endif
12629 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
12630 int flags)
12632 int i;
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++) {
12640 if ((i & 3) == 0)
12641 cpu_fprintf(f, "GPR%02d:", i);
12642 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12643 if ((i & 3) == 3)
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);
12655 #endif
12658 static void mips_tcg_init(void)
12660 int i;
12661 static int inited;
12663 /* Initialize various static tables. */
12664 if (inited)
12665 return;
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]),
12672 regnames[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]),
12678 regnames_HI[i]);
12679 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12680 offsetof(CPUMIPSState, active_tc.LO[i]),
12681 regnames_LO[i]);
12682 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12683 offsetof(CPUMIPSState, active_tc.ACX[i]),
12684 regnames_ACX[i]);
12686 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12687 offsetof(CPUMIPSState, active_tc.DSPControl),
12688 "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),
12698 "fcr0");
12699 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12700 offsetof(CPUMIPSState, active_fpu.fcr31),
12701 "fcr31");
12703 /* register helpers */
12704 #define GEN_HELPER 2
12705 #include "helper.h"
12707 inited = 1;
12710 #include "translate_init.c"
12712 MIPSCPU *cpu_mips_init(const char *cpu_model)
12714 MIPSCPU *cpu;
12715 CPUMIPSState *env;
12716 const mips_def_t *def;
12718 def = cpu_mips_find_by_name(cpu_model);
12719 if (!def)
12720 return NULL;
12721 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
12722 env = &cpu->env;
12723 env->cpu_model = def;
12724 env->cpu_model_str = cpu_model;
12726 #ifndef CONFIG_USER_ONLY
12727 mmu_init(env, def);
12728 #endif
12729 fpu_init(env, def);
12730 mvp_init(env, def);
12731 mips_tcg_init();
12732 cpu_reset(CPU(cpu));
12733 qemu_init_vcpu(env);
12734 return cpu;
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));
12745 tlb_flush(env, 1);
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);
12752 #endif
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;
12773 #endif
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->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
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->CP0_Status |= (1 << CP0St_CU1);
12797 #else
12798 if (env->hflags & MIPS_HFLAG_BMASK) {
12799 /* If the exception was raised from a delay slot,
12800 come back to the jump. */
12801 env->CP0_ErrorEPC = env->active_tc.PC - 4;
12802 } else {
12803 env->CP0_ErrorEPC = env->active_tc.PC;
12805 env->active_tc.PC = (int32_t)0xBFC00000;
12806 env->CP0_Random = env->tlb->nb_tlb - 1;
12807 env->tlb->tlb_in_use = env->tlb->nb_tlb;
12808 env->CP0_Wired = 0;
12809 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
12810 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12811 /* vectored interrupts not implemented, timer on int 7,
12812 no performance counters. */
12813 env->CP0_IntCtl = 0xe0000000;
12815 int i;
12817 for (i = 0; i < 7; i++) {
12818 env->CP0_WatchLo[i] = 0;
12819 env->CP0_WatchHi[i] = 0x80000000;
12821 env->CP0_WatchLo[7] = 0;
12822 env->CP0_WatchHi[7] = 0;
12824 /* Count register increments in debug mode, EJTAG version 1 */
12825 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12827 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
12828 int i;
12830 /* Only TC0 on VPE 0 starts as active. */
12831 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
12832 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
12833 env->tcs[i].CP0_TCHalt = 1;
12835 env->active_tc.CP0_TCHalt = 1;
12836 env->halted = 1;
12838 if (!env->cpu_index) {
12839 /* VPE0 starts up enabled. */
12840 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
12841 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
12843 /* TC0 starts up unhalted. */
12844 env->halted = 0;
12845 env->active_tc.CP0_TCHalt = 0;
12846 env->tcs[0].CP0_TCHalt = 0;
12847 /* With thread 0 active. */
12848 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
12849 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
12852 #endif
12853 compute_hflags(env);
12854 env->exception_index = EXCP_NONE;
12857 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
12859 env->active_tc.PC = gen_opc_pc[pc_pos];
12860 env->hflags &= ~MIPS_HFLAG_BMASK;
12861 env->hflags |= gen_opc_hflags[pc_pos];