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)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 #include "qemu/osdep.h"
27 #include "disas/disas.h"
28 #include "exec/exec-all.h"
30 #include "exec/cpu_ldst.h"
31 #include "hw/mips/cpudevs.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
35 #include "exec/semihost.h"
37 #include "target/mips/trace.h"
38 #include "trace-tcg.h"
39 #include "exec/translator.h"
42 #define MIPS_DEBUG_DISAS 0
44 /* MIPS major opcodes */
45 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
48 /* indirect opcode tables */
49 OPC_SPECIAL = (0x00 << 26),
50 OPC_REGIMM = (0x01 << 26),
51 OPC_CP0 = (0x10 << 26),
52 OPC_CP1 = (0x11 << 26),
53 OPC_CP2 = (0x12 << 26),
54 OPC_CP3 = (0x13 << 26),
55 OPC_SPECIAL2 = (0x1C << 26),
56 OPC_SPECIAL3 = (0x1F << 26),
57 /* arithmetic with immediate */
58 OPC_ADDI = (0x08 << 26),
59 OPC_ADDIU = (0x09 << 26),
60 OPC_SLTI = (0x0A << 26),
61 OPC_SLTIU = (0x0B << 26),
62 /* logic with immediate */
63 OPC_ANDI = (0x0C << 26),
64 OPC_ORI = (0x0D << 26),
65 OPC_XORI = (0x0E << 26),
66 OPC_LUI = (0x0F << 26),
67 /* arithmetic with immediate */
68 OPC_DADDI = (0x18 << 26),
69 OPC_DADDIU = (0x19 << 26),
70 /* Jump and branches */
72 OPC_JAL = (0x03 << 26),
73 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
74 OPC_BEQL = (0x14 << 26),
75 OPC_BNE = (0x05 << 26),
76 OPC_BNEL = (0x15 << 26),
77 OPC_BLEZ = (0x06 << 26),
78 OPC_BLEZL = (0x16 << 26),
79 OPC_BGTZ = (0x07 << 26),
80 OPC_BGTZL = (0x17 << 26),
81 OPC_JALX = (0x1D << 26),
82 OPC_DAUI = (0x1D << 26),
84 OPC_LDL = (0x1A << 26),
85 OPC_LDR = (0x1B << 26),
86 OPC_LB = (0x20 << 26),
87 OPC_LH = (0x21 << 26),
88 OPC_LWL = (0x22 << 26),
89 OPC_LW = (0x23 << 26),
90 OPC_LWPC = OPC_LW | 0x5,
91 OPC_LBU = (0x24 << 26),
92 OPC_LHU = (0x25 << 26),
93 OPC_LWR = (0x26 << 26),
94 OPC_LWU = (0x27 << 26),
95 OPC_SB = (0x28 << 26),
96 OPC_SH = (0x29 << 26),
97 OPC_SWL = (0x2A << 26),
98 OPC_SW = (0x2B << 26),
99 OPC_SDL = (0x2C << 26),
100 OPC_SDR = (0x2D << 26),
101 OPC_SWR = (0x2E << 26),
102 OPC_LL = (0x30 << 26),
103 OPC_LLD = (0x34 << 26),
104 OPC_LD = (0x37 << 26),
105 OPC_LDPC = OPC_LD | 0x5,
106 OPC_SC = (0x38 << 26),
107 OPC_SCD = (0x3C << 26),
108 OPC_SD = (0x3F << 26),
109 /* Floating point load/store */
110 OPC_LWC1 = (0x31 << 26),
111 OPC_LWC2 = (0x32 << 26),
112 OPC_LDC1 = (0x35 << 26),
113 OPC_LDC2 = (0x36 << 26),
114 OPC_SWC1 = (0x39 << 26),
115 OPC_SWC2 = (0x3A << 26),
116 OPC_SDC1 = (0x3D << 26),
117 OPC_SDC2 = (0x3E << 26),
118 /* Compact Branches */
119 OPC_BLEZALC = (0x06 << 26),
120 OPC_BGEZALC = (0x06 << 26),
121 OPC_BGEUC = (0x06 << 26),
122 OPC_BGTZALC = (0x07 << 26),
123 OPC_BLTZALC = (0x07 << 26),
124 OPC_BLTUC = (0x07 << 26),
125 OPC_BOVC = (0x08 << 26),
126 OPC_BEQZALC = (0x08 << 26),
127 OPC_BEQC = (0x08 << 26),
128 OPC_BLEZC = (0x16 << 26),
129 OPC_BGEZC = (0x16 << 26),
130 OPC_BGEC = (0x16 << 26),
131 OPC_BGTZC = (0x17 << 26),
132 OPC_BLTZC = (0x17 << 26),
133 OPC_BLTC = (0x17 << 26),
134 OPC_BNVC = (0x18 << 26),
135 OPC_BNEZALC = (0x18 << 26),
136 OPC_BNEC = (0x18 << 26),
137 OPC_BC = (0x32 << 26),
138 OPC_BEQZC = (0x36 << 26),
139 OPC_JIC = (0x36 << 26),
140 OPC_BALC = (0x3A << 26),
141 OPC_BNEZC = (0x3E << 26),
142 OPC_JIALC = (0x3E << 26),
143 /* MDMX ASE specific */
144 OPC_MDMX = (0x1E << 26),
145 /* MSA ASE, same as MDMX */
147 /* Cache and prefetch */
148 OPC_CACHE = (0x2F << 26),
149 OPC_PREF = (0x33 << 26),
150 /* PC-relative address computation / loads */
151 OPC_PCREL = (0x3B << 26),
154 /* PC-relative address computation / loads */
155 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
156 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
158 /* Instructions determined by bits 19 and 20 */
159 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
160 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
161 OPC_LWUPC = OPC_PCREL | (2 << 19),
163 /* Instructions determined by bits 16 ... 20 */
164 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
165 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
168 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
171 /* MIPS special opcodes */
172 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
176 OPC_SLL = 0x00 | OPC_SPECIAL,
177 /* NOP is SLL r0, r0, 0 */
178 /* SSNOP is SLL r0, r0, 1 */
179 /* EHB is SLL r0, r0, 3 */
180 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
181 OPC_ROTR = OPC_SRL | (1 << 21),
182 OPC_SRA = 0x03 | OPC_SPECIAL,
183 OPC_SLLV = 0x04 | OPC_SPECIAL,
184 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
185 OPC_ROTRV = OPC_SRLV | (1 << 6),
186 OPC_SRAV = 0x07 | OPC_SPECIAL,
187 OPC_DSLLV = 0x14 | OPC_SPECIAL,
188 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
189 OPC_DROTRV = OPC_DSRLV | (1 << 6),
190 OPC_DSRAV = 0x17 | OPC_SPECIAL,
191 OPC_DSLL = 0x38 | OPC_SPECIAL,
192 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
193 OPC_DROTR = OPC_DSRL | (1 << 21),
194 OPC_DSRA = 0x3B | OPC_SPECIAL,
195 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
196 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
197 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
198 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
199 /* Multiplication / division */
200 OPC_MULT = 0x18 | OPC_SPECIAL,
201 OPC_MULTU = 0x19 | OPC_SPECIAL,
202 OPC_DIV = 0x1A | OPC_SPECIAL,
203 OPC_DIVU = 0x1B | OPC_SPECIAL,
204 OPC_DMULT = 0x1C | OPC_SPECIAL,
205 OPC_DMULTU = 0x1D | OPC_SPECIAL,
206 OPC_DDIV = 0x1E | OPC_SPECIAL,
207 OPC_DDIVU = 0x1F | OPC_SPECIAL,
209 /* 2 registers arithmetic / logic */
210 OPC_ADD = 0x20 | OPC_SPECIAL,
211 OPC_ADDU = 0x21 | OPC_SPECIAL,
212 OPC_SUB = 0x22 | OPC_SPECIAL,
213 OPC_SUBU = 0x23 | OPC_SPECIAL,
214 OPC_AND = 0x24 | OPC_SPECIAL,
215 OPC_OR = 0x25 | OPC_SPECIAL,
216 OPC_XOR = 0x26 | OPC_SPECIAL,
217 OPC_NOR = 0x27 | OPC_SPECIAL,
218 OPC_SLT = 0x2A | OPC_SPECIAL,
219 OPC_SLTU = 0x2B | OPC_SPECIAL,
220 OPC_DADD = 0x2C | OPC_SPECIAL,
221 OPC_DADDU = 0x2D | OPC_SPECIAL,
222 OPC_DSUB = 0x2E | OPC_SPECIAL,
223 OPC_DSUBU = 0x2F | OPC_SPECIAL,
225 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
226 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
228 OPC_TGE = 0x30 | OPC_SPECIAL,
229 OPC_TGEU = 0x31 | OPC_SPECIAL,
230 OPC_TLT = 0x32 | OPC_SPECIAL,
231 OPC_TLTU = 0x33 | OPC_SPECIAL,
232 OPC_TEQ = 0x34 | OPC_SPECIAL,
233 OPC_TNE = 0x36 | OPC_SPECIAL,
234 /* HI / LO registers load & stores */
235 OPC_MFHI = 0x10 | OPC_SPECIAL,
236 OPC_MTHI = 0x11 | OPC_SPECIAL,
237 OPC_MFLO = 0x12 | OPC_SPECIAL,
238 OPC_MTLO = 0x13 | OPC_SPECIAL,
239 /* Conditional moves */
240 OPC_MOVZ = 0x0A | OPC_SPECIAL,
241 OPC_MOVN = 0x0B | OPC_SPECIAL,
243 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
244 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
246 OPC_MOVCI = 0x01 | OPC_SPECIAL,
249 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
250 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
251 OPC_BREAK = 0x0D | OPC_SPECIAL,
252 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
253 OPC_SYNC = 0x0F | OPC_SPECIAL,
255 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
256 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
257 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
258 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
261 /* R6 Multiply and Divide instructions have the same Opcode
262 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
263 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
266 R6_OPC_MUL = OPC_MULT | (2 << 6),
267 R6_OPC_MUH = OPC_MULT | (3 << 6),
268 R6_OPC_MULU = OPC_MULTU | (2 << 6),
269 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
270 R6_OPC_DIV = OPC_DIV | (2 << 6),
271 R6_OPC_MOD = OPC_DIV | (3 << 6),
272 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
273 R6_OPC_MODU = OPC_DIVU | (3 << 6),
275 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
276 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
277 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
278 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
279 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
280 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
281 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
282 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
284 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
285 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
286 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
287 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
288 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
290 OPC_LSA = 0x05 | OPC_SPECIAL,
291 OPC_DLSA = 0x15 | OPC_SPECIAL,
294 /* Multiplication variants of the vr54xx. */
295 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
298 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
299 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
300 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
301 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
302 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
303 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
304 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
305 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
306 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
307 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
308 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
309 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
310 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
311 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
314 /* REGIMM (rt field) opcodes */
315 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
318 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
319 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
320 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
321 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
322 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
323 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
324 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
325 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
326 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
327 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
328 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
329 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
330 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
331 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
332 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
333 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
335 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
336 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
339 /* Special2 opcodes */
340 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
343 /* Multiply & xxx operations */
344 OPC_MADD = 0x00 | OPC_SPECIAL2,
345 OPC_MADDU = 0x01 | OPC_SPECIAL2,
346 OPC_MUL = 0x02 | OPC_SPECIAL2,
347 OPC_MSUB = 0x04 | OPC_SPECIAL2,
348 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
350 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
351 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
352 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
353 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
354 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
355 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
356 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
357 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
358 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
359 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
360 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
361 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
363 OPC_CLZ = 0x20 | OPC_SPECIAL2,
364 OPC_CLO = 0x21 | OPC_SPECIAL2,
365 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
366 OPC_DCLO = 0x25 | OPC_SPECIAL2,
368 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
371 /* Special3 opcodes */
372 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
375 OPC_EXT = 0x00 | OPC_SPECIAL3,
376 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
377 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
378 OPC_DEXT = 0x03 | OPC_SPECIAL3,
379 OPC_INS = 0x04 | OPC_SPECIAL3,
380 OPC_DINSM = 0x05 | OPC_SPECIAL3,
381 OPC_DINSU = 0x06 | OPC_SPECIAL3,
382 OPC_DINS = 0x07 | OPC_SPECIAL3,
383 OPC_FORK = 0x08 | OPC_SPECIAL3,
384 OPC_YIELD = 0x09 | OPC_SPECIAL3,
385 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
386 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
387 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
390 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
391 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
392 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
393 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
394 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
395 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
396 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
397 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
398 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
399 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
400 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
401 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
404 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
405 /* MIPS DSP Arithmetic */
406 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
407 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
408 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
409 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
410 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
411 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
413 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
414 /* MIPS DSP GPR-Based Shift Sub-class */
415 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
416 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
417 /* MIPS DSP Multiply Sub-class insns */
418 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
419 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
420 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
421 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
422 /* DSP Bit/Manipulation Sub-class */
423 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
424 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
425 /* MIPS DSP Append Sub-class */
426 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
427 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
428 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
429 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
430 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
433 OPC_LWLE = 0x19 | OPC_SPECIAL3,
434 OPC_LWRE = 0x1A | OPC_SPECIAL3,
435 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
436 OPC_SBE = 0x1C | OPC_SPECIAL3,
437 OPC_SHE = 0x1D | OPC_SPECIAL3,
438 OPC_SCE = 0x1E | OPC_SPECIAL3,
439 OPC_SWE = 0x1F | OPC_SPECIAL3,
440 OPC_SWLE = 0x21 | OPC_SPECIAL3,
441 OPC_SWRE = 0x22 | OPC_SPECIAL3,
442 OPC_PREFE = 0x23 | OPC_SPECIAL3,
443 OPC_LBUE = 0x28 | OPC_SPECIAL3,
444 OPC_LHUE = 0x29 | OPC_SPECIAL3,
445 OPC_LBE = 0x2C | OPC_SPECIAL3,
446 OPC_LHE = 0x2D | OPC_SPECIAL3,
447 OPC_LLE = 0x2E | OPC_SPECIAL3,
448 OPC_LWE = 0x2F | OPC_SPECIAL3,
451 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
452 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
453 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
454 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
455 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
456 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
460 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
463 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
464 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
465 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
466 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
467 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
468 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
472 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
475 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
476 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
477 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
478 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
479 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
482 /* MIPS DSP REGIMM opcodes */
484 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
485 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
488 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
491 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
492 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
493 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
494 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
497 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
499 /* MIPS DSP Arithmetic Sub-class */
500 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
501 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
502 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
503 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
504 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
505 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
506 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
507 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
508 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
509 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
510 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
511 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
512 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
513 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
515 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
516 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
517 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
518 /* MIPS DSP Multiply Sub-class insns */
519 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
520 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
521 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
522 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
523 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
524 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
527 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
528 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
530 /* MIPS DSP Arithmetic Sub-class */
531 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
532 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
533 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
534 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
535 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
536 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
537 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
538 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
539 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
541 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
542 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
543 /* MIPS DSP Multiply Sub-class insns */
544 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
545 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
546 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
550 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
552 /* MIPS DSP Arithmetic Sub-class */
553 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
554 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
555 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
556 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
557 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
558 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
559 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
560 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
561 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
564 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
566 /* DSP Bit/Manipulation Sub-class */
567 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
574 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
579 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
580 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
581 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
582 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
583 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
584 /* DSP Compare-Pick Sub-class */
585 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
592 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
593 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
602 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604 /* MIPS DSP GPR-Based Shift Sub-class */
605 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
606 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
607 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
608 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
609 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
610 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
611 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
612 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
613 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
629 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
631 /* MIPS DSP Multiply Sub-class insns */
632 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
633 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
634 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
635 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
636 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
637 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
638 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
639 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
640 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
646 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
649 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
652 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
656 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
658 /* DSP Bit/Manipulation Sub-class */
659 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
662 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
664 /* MIPS DSP Append Sub-class */
665 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
666 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
667 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
670 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
672 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
673 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
674 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
675 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
676 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
677 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
678 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
679 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
680 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
681 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
683 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
684 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
685 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
686 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
687 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
688 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
689 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
692 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
694 /* MIPS DSP Arithmetic Sub-class */
695 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
698 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
699 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
700 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
701 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
702 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
703 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
712 /* DSP Bit/Manipulation Sub-class */
713 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
721 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
723 /* MIPS DSP Multiply Sub-class insns */
724 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
725 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
726 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
727 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
728 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
729 /* MIPS DSP Arithmetic Sub-class */
730 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
731 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
732 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
733 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
734 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
735 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
736 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
737 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
738 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
739 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
740 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
741 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
742 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
743 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
744 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
745 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
746 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
747 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
748 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
749 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
750 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
753 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
755 /* DSP Compare-Pick Sub-class */
756 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
763 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
764 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
775 /* MIPS DSP Arithmetic Sub-class */
776 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
783 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
786 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
788 /* DSP Append Sub-class */
789 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
790 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
791 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
792 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
795 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
797 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
798 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
799 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
800 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
801 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
802 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
803 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
804 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
805 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
806 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
807 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
821 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
823 /* DSP Bit/Manipulation Sub-class */
824 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
827 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
829 /* MIPS DSP Multiply Sub-class insns */
830 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
835 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
836 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
837 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
838 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
858 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
860 /* MIPS DSP GPR-Based Shift Sub-class */
861 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
866 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
867 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
868 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
869 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
889 /* Coprocessor 0 (rs field) */
890 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
893 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
894 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
895 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
896 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
897 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
898 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
899 OPC_MFTR = (0x08 << 21) | OPC_CP0,
900 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
901 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
902 OPC_MTTR = (0x0C << 21) | OPC_CP0,
903 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
904 OPC_C0 = (0x10 << 21) | OPC_CP0,
905 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
906 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
907 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
908 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
909 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
910 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
911 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
912 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
913 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
914 OPC_C0_A = (0x1A << 21) | OPC_CP0,
915 OPC_C0_B = (0x1B << 21) | OPC_CP0,
916 OPC_C0_C = (0x1C << 21) | OPC_CP0,
917 OPC_C0_D = (0x1D << 21) | OPC_CP0,
918 OPC_C0_E = (0x1E << 21) | OPC_CP0,
919 OPC_C0_F = (0x1F << 21) | OPC_CP0,
923 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
926 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
927 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
928 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
929 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
930 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
931 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
932 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
933 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
936 /* Coprocessor 0 (with rs == C0) */
937 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
940 OPC_TLBR = 0x01 | OPC_C0,
941 OPC_TLBWI = 0x02 | OPC_C0,
942 OPC_TLBINV = 0x03 | OPC_C0,
943 OPC_TLBINVF = 0x04 | OPC_C0,
944 OPC_TLBWR = 0x06 | OPC_C0,
945 OPC_TLBP = 0x08 | OPC_C0,
946 OPC_RFE = 0x10 | OPC_C0,
947 OPC_ERET = 0x18 | OPC_C0,
948 OPC_DERET = 0x1F | OPC_C0,
949 OPC_WAIT = 0x20 | OPC_C0,
952 /* Coprocessor 1 (rs field) */
953 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
955 /* Values for the fmt field in FP instructions */
957 /* 0 - 15 are reserved */
958 FMT_S = 16, /* single fp */
959 FMT_D = 17, /* double fp */
960 FMT_E = 18, /* extended fp */
961 FMT_Q = 19, /* quad fp */
962 FMT_W = 20, /* 32-bit fixed */
963 FMT_L = 21, /* 64-bit fixed */
964 FMT_PS = 22, /* paired single fp */
965 /* 23 - 31 are reserved */
969 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
970 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
971 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
972 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
973 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
974 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
975 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
976 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
977 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
978 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
979 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
980 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
981 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
982 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
983 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
984 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
985 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
986 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
987 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
988 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
989 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
990 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
991 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
992 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
993 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
994 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
995 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
996 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
997 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
998 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
1001 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1002 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1005 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1006 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1007 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1008 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1012 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1013 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1017 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1018 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1021 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1024 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1025 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1026 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1027 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1028 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1029 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1030 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1031 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1032 OPC_BC2 = (0x08 << 21) | OPC_CP2,
1033 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1034 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1037 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1040 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1041 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1042 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1043 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1044 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1045 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1046 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1047 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1049 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1050 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1051 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1052 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1053 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1054 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1055 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1056 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1058 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1059 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1060 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1061 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1062 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1063 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1064 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1065 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1067 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1068 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1069 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1070 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1071 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1072 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1073 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1074 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1076 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1077 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1078 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1079 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1080 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1081 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1083 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1084 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1085 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1086 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1087 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1088 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1090 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1091 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1092 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1093 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1094 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1095 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1097 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1098 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1099 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1100 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1101 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1102 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1104 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1105 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1106 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1107 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1108 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1109 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1111 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1112 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1113 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1114 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1115 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1116 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1118 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1119 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1120 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1121 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1122 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1123 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1125 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1126 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1127 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1128 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1129 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1130 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1134 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1137 OPC_LWXC1 = 0x00 | OPC_CP3,
1138 OPC_LDXC1 = 0x01 | OPC_CP3,
1139 OPC_LUXC1 = 0x05 | OPC_CP3,
1140 OPC_SWXC1 = 0x08 | OPC_CP3,
1141 OPC_SDXC1 = 0x09 | OPC_CP3,
1142 OPC_SUXC1 = 0x0D | OPC_CP3,
1143 OPC_PREFX = 0x0F | OPC_CP3,
1144 OPC_ALNV_PS = 0x1E | OPC_CP3,
1145 OPC_MADD_S = 0x20 | OPC_CP3,
1146 OPC_MADD_D = 0x21 | OPC_CP3,
1147 OPC_MADD_PS = 0x26 | OPC_CP3,
1148 OPC_MSUB_S = 0x28 | OPC_CP3,
1149 OPC_MSUB_D = 0x29 | OPC_CP3,
1150 OPC_MSUB_PS = 0x2E | OPC_CP3,
1151 OPC_NMADD_S = 0x30 | OPC_CP3,
1152 OPC_NMADD_D = 0x31 | OPC_CP3,
1153 OPC_NMADD_PS= 0x36 | OPC_CP3,
1154 OPC_NMSUB_S = 0x38 | OPC_CP3,
1155 OPC_NMSUB_D = 0x39 | OPC_CP3,
1156 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1160 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1162 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1163 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1164 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1165 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1166 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1167 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1168 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1169 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1170 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1171 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1172 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1173 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1174 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1175 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1176 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1177 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1178 OPC_MSA_ELM = 0x19 | OPC_MSA,
1179 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1180 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1181 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1182 OPC_MSA_VEC = 0x1E | OPC_MSA,
1184 /* MI10 instruction */
1185 OPC_LD_B = (0x20) | OPC_MSA,
1186 OPC_LD_H = (0x21) | OPC_MSA,
1187 OPC_LD_W = (0x22) | OPC_MSA,
1188 OPC_LD_D = (0x23) | OPC_MSA,
1189 OPC_ST_B = (0x24) | OPC_MSA,
1190 OPC_ST_H = (0x25) | OPC_MSA,
1191 OPC_ST_W = (0x26) | OPC_MSA,
1192 OPC_ST_D = (0x27) | OPC_MSA,
1196 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1197 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1198 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1199 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1200 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1201 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1202 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1203 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1204 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1205 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1206 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1207 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1208 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1210 /* I8 instruction */
1211 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1212 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1213 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1214 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1215 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1216 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1217 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1218 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1219 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1220 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1222 /* VEC/2R/2RF instruction */
1223 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1224 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1225 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1226 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1227 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1228 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1229 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1231 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1232 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1234 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1235 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1236 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1237 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1238 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1240 /* 2RF instruction df(bit 16) = _w, _d */
1241 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1242 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1243 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1244 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1245 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1246 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1247 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1248 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1249 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1250 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1251 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1252 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1253 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1254 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1255 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1256 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1258 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1259 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1260 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1261 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1262 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1263 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1264 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1265 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1266 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1267 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1268 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1269 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1270 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1271 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1272 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1273 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1274 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1275 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1276 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1277 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1278 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1279 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1280 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1281 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1282 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1283 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1284 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1285 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1286 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1287 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1288 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1289 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1290 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1291 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1292 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1293 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1294 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1295 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1296 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1297 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1298 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1299 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1300 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1301 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1302 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1303 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1304 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1305 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1306 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1307 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1308 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1309 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1310 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1311 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1312 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1313 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1314 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1315 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1316 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1317 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1318 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1319 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1320 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1321 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1323 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1324 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1325 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1326 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1327 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1328 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1329 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1330 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1331 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1332 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1334 /* 3RF instruction _df(bit 21) = _w, _d */
1335 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1336 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1337 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1338 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1339 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1340 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1341 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1342 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1343 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1345 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1346 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1347 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1348 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1349 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1350 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1351 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1352 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1353 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1356 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1357 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1358 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1359 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1361 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1362 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1363 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1364 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1365 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1366 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1367 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1368 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1369 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1370 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1372 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1373 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1374 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1375 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1377 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1378 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1379 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1380 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1381 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1382 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1383 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1384 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1385 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1386 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1387 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1388 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1389 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1394 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1395 * ============================================
1397 * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
1398 * instructions set. It is designed to fit the needs of signal, graphical and
1399 * video processing applications. MXU instruction set is used in Xburst family
1400 * of microprocessors by Ingenic.
1402 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1403 * the control register.
1405 * The notation used in MXU assembler mnemonics:
1407 * XRa, XRb, XRc, XRd - MXU registers
1408 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1409 * s12 - a subfield of an instruction code
1410 * strd2 - a subfield of an instruction code
1411 * eptn2 - a subfield of an instruction code
1412 * eptn3 - a subfield of an instruction code
1413 * optn2 - a subfield of an instruction code
1414 * optn3 - a subfield of an instruction code
1415 * sft4 - a subfield of an instruction code
1417 * Load/Store instructions Multiplication instructions
1418 * ----------------------- ---------------------------
1420 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1421 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1422 * S32LDDV XRa, Rb, rc, strd2 S32SUB XRa, XRd, Rs, Rt
1423 * S32STDV XRa, Rb, rc, strd2 S32SUBU XRa, XRd, Rs, Rt
1424 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1425 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1426 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1427 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1428 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1429 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1430 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1431 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1432 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1433 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1434 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1435 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1436 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1437 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1438 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1439 * S16SDI XRa, Rb, s10, eptn2
1440 * S8LDD XRa, Rb, s8, eptn3
1441 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1442 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1443 * S8SDI XRa, Rb, s8, eptn3
1444 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1445 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1446 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1447 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1448 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1449 * S32CPS XRa, XRb, XRc
1450 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1451 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1452 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1453 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1454 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1455 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1456 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1457 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1458 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1459 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1460 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1461 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1462 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1463 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1464 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1465 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1466 * Q8SLT XRa, XRb, XRc
1467 * Q8SLTU XRa, XRb, XRc
1468 * Q8MOVZ XRa, XRb, XRc Shift instructions
1469 * Q8MOVN XRa, XRb, XRc ------------------
1471 * D32SLL XRa, XRb, XRc, XRd, sft4
1472 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1473 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1474 * D32SARL XRa, XRb, XRc, sft4
1475 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1476 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1477 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1478 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1479 * Q16SLL XRa, XRb, XRc, XRd, sft4
1480 * Q16SLR XRa, XRb, XRc, XRd, sft4
1481 * Miscelaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1482 * ------------------------- Q16SLLV XRa, XRb, Rb
1483 * Q16SLRV XRa, XRb, Rb
1484 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1485 * S32ALN XRa, XRb, XRc, Rb
1486 * S32ALNI XRa, XRb, XRc, s3
1487 * S32LUI XRa, s8, optn3 Move instructions
1488 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1489 * S32EXTRV XRa, XRb, Rs, Rt
1490 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1491 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1497 * ┌─ 000000 ─ OPC_MXU_S32MADD
1498 * ├─ 000001 ─ OPC_MXU_S32MADDU
1499 * ├─ 000010 ─ <not assigned>
1501 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1502 * │ ├─ 001 ─ OPC_MXU_S32MIN
1503 * │ ├─ 010 ─ OPC_MXU_D16MAX
1504 * │ ├─ 011 ─ OPC_MXU_D16MIN
1505 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1506 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1507 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1508 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1509 * ├─ 000100 ─ OPC_MXU_S32MSUB
1510 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1511 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1512 * │ ├─ 001 ─ OPC_MXU_D16SLT
1513 * │ ├─ 010 ─ OPC_MXU_D16AVG
1514 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1515 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1516 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1517 * │ └─ 111 ─ OPC_MXU_Q8ADD
1520 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1521 * │ ├─ 010 ─ OPC_MXU_D16CPS
1522 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1523 * │ └─ 110 ─ OPC_MXU_Q16SAT
1524 * ├─ 001000 ─ OPC_MXU_D16MUL
1526 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1527 * │ └─ 01 ─ OPC_MXU_D16MULE
1528 * ├─ 001010 ─ OPC_MXU_D16MAC
1529 * ├─ 001011 ─ OPC_MXU_D16MACF
1530 * ├─ 001100 ─ OPC_MXU_D16MADL
1532 * ├─ 001101 ─ OPC_MXU__POOL04 ─┬─ 00 ─ OPC_MXU_S16MAD
1533 * │ └─ 01 ─ OPC_MXU_S16MAD_1
1534 * ├─ 001110 ─ OPC_MXU_Q16ADD
1535 * ├─ 001111 ─ OPC_MXU_D16MACE
1537 * ├─ 010000 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32LDD
1538 * │ └─ 1 ─ OPC_MXU_S32LDDR
1541 * ├─ 010001 ─ OPC_MXU__POOL06 ─┬─ 0 ─ OPC_MXU_S32STD
1542 * │ └─ 1 ─ OPC_MXU_S32STDR
1545 * ├─ 010010 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1546 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1549 * ├─ 010011 ─ OPC_MXU__POOL08 ─┬─ 0000 ─ OPC_MXU_S32STDV
1550 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1553 * ├─ 010100 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32LDI
1554 * │ └─ 1 ─ OPC_MXU_S32LDIR
1557 * ├─ 010101 ─ OPC_MXU__POOL10 ─┬─ 0 ─ OPC_MXU_S32SDI
1558 * │ └─ 1 ─ OPC_MXU_S32SDIR
1561 * ├─ 010110 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1562 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1565 * ├─ 010111 ─ OPC_MXU__POOL12 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1566 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1567 * ├─ 011000 ─ OPC_MXU_D32ADD
1569 * MXU ├─ 011001 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_D32ACC
1570 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1571 * │ └─ 10 ─ OPC_MXU_D32ASUM
1572 * ├─ 011010 ─ <not assigned>
1574 * ├─ 011011 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q16ACC
1575 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1576 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1579 * ├─ 011100 ─ OPC_MXU__POOL15 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1580 * │ ├─ 01 ─ OPC_MXU_D8SUM
1581 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1582 * ├─ 011110 ─ <not assigned>
1583 * ├─ 011111 ─ <not assigned>
1584 * ├─ 100000 ─ <not assigned>
1585 * ├─ 100001 ─ <not assigned>
1586 * ├─ 100010 ─ OPC_MXU_S8LDD
1587 * ├─ 100011 ─ OPC_MXU_S8STD
1588 * ├─ 100100 ─ OPC_MXU_S8LDI
1589 * ├─ 100101 ─ OPC_MXU_S8SDI
1591 * ├─ 100110 ─ OPC_MXU__POOL16 ─┬─ 00 ─ OPC_MXU_S32MUL
1592 * │ ├─ 00 ─ OPC_MXU_S32MULU
1593 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1594 * │ └─ 00 ─ OPC_MXU_S32EXTRV
1597 * ├─ 100111 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_D32SARW
1598 * │ ├─ 001 ─ OPC_MXU_S32ALN
1599 * ├─ 101000 ─ OPC_MXU_LXB ├─ 010 ─ OPC_MXU_S32ALNI
1600 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_S32NOR
1601 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_S32AND
1602 * ├─ 101011 ─ OPC_MXU_S16STD ├─ 101 ─ OPC_MXU_S32OR
1603 * ├─ 101100 ─ OPC_MXU_S16LDI ├─ 110 ─ OPC_MXU_S32XOR
1604 * ├─ 101101 ─ OPC_MXU_S16SDI └─ 111 ─ OPC_MXU_S32LUI
1605 * ├─ 101000 ─ <not assigned>
1606 * ├─ 101001 ─ <not assigned>
1607 * ├─ 101010 ─ <not assigned>
1608 * ├─ 101011 ─ <not assigned>
1609 * ├─ 101100 ─ <not assigned>
1610 * ├─ 101101 ─ <not assigned>
1611 * ├─ 101110 ─ OPC_MXU_S32M2I
1612 * ├─ 101111 ─ OPC_MXU_S32I2M
1613 * ├─ 110000 ─ OPC_MXU_D32SLL
1614 * ├─ 110001 ─ OPC_MXU_D32SLR
1615 * ├─ 110010 ─ OPC_MXU_D32SARL
1616 * ├─ 110011 ─ OPC_MXU_D32SAR
1617 * ├─ 110100 ─ OPC_MXU_Q16SLL
1618 * ├─ 110101 ─ OPC_MXU_Q16SLR 20..18
1619 * ├─ 110110 ─ OPC_MXU__POOL18 ─┬─ 000 ─ OPC_MXU_D32SLLV
1620 * │ ├─ 001 ─ OPC_MXU_D32SLRV
1621 * │ ├─ 010 ─ OPC_MXU_D32SARV
1622 * │ ├─ 011 ─ OPC_MXU_Q16SLLV
1623 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1624 * │ └─ 101 ─ OPC_MXU_Q16SARV
1625 * ├─ 110111 ─ OPC_MXU_Q16SAR
1627 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1628 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1631 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1632 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1633 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1634 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1635 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1636 * │ └─ 101 ─ OPC_MXU_S32MOV
1639 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1640 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1641 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1642 * ├─ 111100 ─ OPC_MXU_Q8MADL
1643 * ├─ 111101 ─ OPC_MXU_S32SFL
1644 * ├─ 111110 ─ OPC_MXU_Q8SAD
1645 * └─ 111111 ─ <not assigned>
1650 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1651 * Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1655 OPC_MXU_S32MADD = 0x00,
1656 OPC_MXU_S32MADDU = 0x01,
1657 /* not assigned 0x02 */
1658 OPC_MXU__POOL00 = 0x03,
1659 OPC_MXU_S32MSUB = 0x04,
1660 OPC_MXU_S32MSUBU = 0x05,
1661 OPC_MXU__POOL01 = 0x06,
1662 OPC_MXU__POOL02 = 0x07,
1663 OPC_MXU_D16MUL = 0x08,
1664 OPC_MXU__POOL03 = 0x09,
1665 OPC_MXU_D16MAC = 0x0A,
1666 OPC_MXU_D16MACF = 0x0B,
1667 OPC_MXU_D16MADL = 0x0C,
1668 OPC_MXU__POOL04 = 0x0D,
1669 OPC_MXU_Q16ADD = 0x0E,
1670 OPC_MXU_D16MACE = 0x0F,
1671 OPC_MXU__POOL05 = 0x10,
1672 OPC_MXU__POOL06 = 0x11,
1673 OPC_MXU__POOL07 = 0x12,
1674 OPC_MXU__POOL08 = 0x13,
1675 OPC_MXU__POOL09 = 0x14,
1676 OPC_MXU__POOL10 = 0x15,
1677 OPC_MXU__POOL11 = 0x16,
1678 OPC_MXU__POOL12 = 0x17,
1679 OPC_MXU_D32ADD = 0x18,
1680 OPC_MXU__POOL13 = 0x19,
1681 /* not assigned 0x1A */
1682 OPC_MXU__POOL14 = 0x1B,
1683 OPC_MXU__POOL15 = 0x1C,
1684 OPC_MXU_Q8ACCE = 0x1D,
1685 /* not assigned 0x1E */
1686 /* not assigned 0x1F */
1687 /* not assigned 0x20 */
1688 /* not assigned 0x21 */
1689 OPC_MXU_S8LDD = 0x22,
1690 OPC_MXU_S8STD = 0x23,
1691 OPC_MXU_S8LDI = 0x24,
1692 OPC_MXU_S8SDI = 0x25,
1693 OPC_MXU__POOL16 = 0x26,
1694 OPC_MXU__POOL17 = 0x27,
1696 /* not assigned 0x29 */
1697 OPC_MXU_S16LDD = 0x2A,
1698 OPC_MXU_S16STD = 0x2B,
1699 OPC_MXU_S16LDI = 0x2C,
1700 OPC_MXU_S16SDI = 0x2D,
1701 OPC_MXU_S32M2I = 0x2E,
1702 OPC_MXU_S32I2M = 0x2F,
1703 OPC_MXU_D32SLL = 0x30,
1704 OPC_MXU_D32SLR = 0x31,
1705 OPC_MXU_D32SARL = 0x32,
1706 OPC_MXU_D32SAR = 0x33,
1707 OPC_MXU_Q16SLL = 0x34,
1708 OPC_MXU_Q16SLR = 0x35,
1709 OPC_MXU__POOL18 = 0x36,
1710 OPC_MXU_Q16SAR = 0x37,
1711 OPC_MXU__POOL19 = 0x38,
1712 OPC_MXU__POOL20 = 0x39,
1713 OPC_MXU__POOL21 = 0x3A,
1714 OPC_MXU_Q16SCOP = 0x3B,
1715 OPC_MXU_Q8MADL = 0x3C,
1716 OPC_MXU_S32SFL = 0x3D,
1717 OPC_MXU_Q8SAD = 0x3E,
1718 /* not assigned 0x3F */
1726 OPC_MXU_S32MAX = 0x00,
1727 OPC_MXU_S32MIN = 0x01,
1728 OPC_MXU_D16MAX = 0x02,
1729 OPC_MXU_D16MIN = 0x03,
1730 OPC_MXU_Q8MAX = 0x04,
1731 OPC_MXU_Q8MIN = 0x05,
1732 OPC_MXU_Q8SLT = 0x06,
1733 OPC_MXU_Q8SLTU = 0x07,
1740 OPC_MXU_S32SLT = 0x00,
1741 OPC_MXU_D16SLT = 0x01,
1742 OPC_MXU_D16AVG = 0x02,
1743 OPC_MXU_D16AVGR = 0x03,
1744 OPC_MXU_Q8AVG = 0x04,
1745 OPC_MXU_Q8AVGR = 0x05,
1746 OPC_MXU_Q8ADD = 0x07,
1753 OPC_MXU_S32CPS = 0x00,
1754 OPC_MXU_D16CPS = 0x02,
1755 OPC_MXU_Q8ABD = 0x04,
1756 OPC_MXU_Q16SAT = 0x06,
1763 OPC_MXU_D16MULF = 0x00,
1764 OPC_MXU_D16MULE = 0x01,
1771 OPC_MXU_S16MAD = 0x00,
1772 OPC_MXU_S16MAD_1 = 0x01,
1779 OPC_MXU_S32LDD = 0x00,
1780 OPC_MXU_S32LDDR = 0x01,
1787 OPC_MXU_S32STD = 0x00,
1788 OPC_MXU_S32STDR = 0x01,
1795 OPC_MXU_S32LDDV = 0x00,
1796 OPC_MXU_S32LDDVR = 0x01,
1803 OPC_MXU_S32STDV = 0x00,
1804 OPC_MXU_S32STDVR = 0x01,
1811 OPC_MXU_S32LDI = 0x00,
1812 OPC_MXU_S32LDIR = 0x01,
1819 OPC_MXU_S32SDI = 0x00,
1820 OPC_MXU_S32SDIR = 0x01,
1827 OPC_MXU_S32LDIV = 0x00,
1828 OPC_MXU_S32LDIVR = 0x01,
1835 OPC_MXU_S32SDIV = 0x00,
1836 OPC_MXU_S32SDIVR = 0x01,
1843 OPC_MXU_D32ACC = 0x00,
1844 OPC_MXU_D32ACCM = 0x01,
1845 OPC_MXU_D32ASUM = 0x02,
1852 OPC_MXU_Q16ACC = 0x00,
1853 OPC_MXU_Q16ACCM = 0x01,
1854 OPC_MXU_Q16ASUM = 0x02,
1861 OPC_MXU_Q8ADDE = 0x00,
1862 OPC_MXU_D8SUM = 0x01,
1863 OPC_MXU_D8SUMC = 0x02,
1870 OPC_MXU_S32MUL = 0x00,
1871 OPC_MXU_S32MULU = 0x01,
1872 OPC_MXU_S32EXTR = 0x02,
1873 OPC_MXU_S32EXTRV = 0x03,
1880 OPC_MXU_D32SARW = 0x00,
1881 OPC_MXU_S32ALN = 0x01,
1882 OPC_MXU_S32ALNI = 0x02,
1883 OPC_MXU_S32NOR = 0x03,
1884 OPC_MXU_S32AND = 0x04,
1885 OPC_MXU_S32OR = 0x05,
1886 OPC_MXU_S32XOR = 0x06,
1887 OPC_MXU_S32LUI = 0x07,
1894 OPC_MXU_D32SLLV = 0x00,
1895 OPC_MXU_D32SLRV = 0x01,
1896 OPC_MXU_D32SARV = 0x03,
1897 OPC_MXU_Q16SLLV = 0x04,
1898 OPC_MXU_Q16SLRV = 0x05,
1899 OPC_MXU_Q16SARV = 0x07,
1906 OPC_MXU_Q8MUL = 0x00,
1907 OPC_MXU_Q8MULSU = 0x01,
1914 OPC_MXU_Q8MOVZ = 0x00,
1915 OPC_MXU_Q8MOVN = 0x01,
1916 OPC_MXU_D16MOVZ = 0x02,
1917 OPC_MXU_D16MOVN = 0x03,
1918 OPC_MXU_S32MOVZ = 0x04,
1919 OPC_MXU_S32MOVN = 0x05,
1926 OPC_MXU_Q8MAC = 0x00,
1927 OPC_MXU_Q8MACSU = 0x01,
1931 /* global register indices */
1932 static TCGv cpu_gpr[32], cpu_PC;
1933 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1934 static TCGv cpu_dspctrl, btarget, bcond;
1935 static TCGv_i32 hflags;
1936 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1937 static TCGv_i64 fpu_f64[32];
1938 static TCGv_i64 msa_wr_d[64];
1940 #include "exec/gen-icount.h"
1942 #define gen_helper_0e0i(name, arg) do { \
1943 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1944 gen_helper_##name(cpu_env, helper_tmp); \
1945 tcg_temp_free_i32(helper_tmp); \
1948 #define gen_helper_0e1i(name, arg1, arg2) do { \
1949 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1950 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1951 tcg_temp_free_i32(helper_tmp); \
1954 #define gen_helper_1e0i(name, ret, arg1) do { \
1955 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1956 gen_helper_##name(ret, cpu_env, helper_tmp); \
1957 tcg_temp_free_i32(helper_tmp); \
1960 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1961 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1962 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1963 tcg_temp_free_i32(helper_tmp); \
1966 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1967 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1968 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1969 tcg_temp_free_i32(helper_tmp); \
1972 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1973 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1974 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1975 tcg_temp_free_i32(helper_tmp); \
1978 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1979 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1980 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1981 tcg_temp_free_i32(helper_tmp); \
1984 typedef struct DisasContext {
1985 DisasContextBase base;
1986 target_ulong saved_pc;
1987 target_ulong page_start;
1989 uint64_t insn_flags;
1990 int32_t CP0_Config1;
1991 int32_t CP0_Config2;
1992 int32_t CP0_Config3;
1993 int32_t CP0_Config5;
1994 /* Routine used to access memory */
1996 TCGMemOp default_tcg_memop_mask;
1997 uint32_t hflags, saved_hflags;
1998 target_ulong btarget;
2009 int CP0_LLAddr_shift;
2018 #define DISAS_STOP DISAS_TARGET_0
2019 #define DISAS_EXIT DISAS_TARGET_1
2021 static const char * const regnames[] = {
2022 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2023 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2024 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2025 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2028 static const char * const regnames_HI[] = {
2029 "HI0", "HI1", "HI2", "HI3",
2032 static const char * const regnames_LO[] = {
2033 "LO0", "LO1", "LO2", "LO3",
2036 static const char * const fregnames[] = {
2037 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2038 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2039 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2040 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2043 static const char * const msaregnames[] = {
2044 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2045 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2046 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2047 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2048 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2049 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2050 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2051 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2052 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2053 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2054 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2055 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2056 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2057 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2058 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2059 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2062 #define LOG_DISAS(...) \
2064 if (MIPS_DEBUG_DISAS) { \
2065 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2069 #define MIPS_INVAL(op) \
2071 if (MIPS_DEBUG_DISAS) { \
2072 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2073 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2074 ctx->base.pc_next, ctx->opcode, op, \
2075 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2076 ((ctx->opcode >> 16) & 0x1F)); \
2080 /* General purpose registers moves. */
2081 static inline void gen_load_gpr (TCGv t, int reg)
2084 tcg_gen_movi_tl(t, 0);
2086 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2089 static inline void gen_store_gpr (TCGv t, int reg)
2092 tcg_gen_mov_tl(cpu_gpr[reg], t);
2095 /* Moves to/from shadow registers. */
2096 static inline void gen_load_srsgpr (int from, int to)
2098 TCGv t0 = tcg_temp_new();
2101 tcg_gen_movi_tl(t0, 0);
2103 TCGv_i32 t2 = tcg_temp_new_i32();
2104 TCGv_ptr addr = tcg_temp_new_ptr();
2106 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2107 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2108 tcg_gen_andi_i32(t2, t2, 0xf);
2109 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2110 tcg_gen_ext_i32_ptr(addr, t2);
2111 tcg_gen_add_ptr(addr, cpu_env, addr);
2113 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2114 tcg_temp_free_ptr(addr);
2115 tcg_temp_free_i32(t2);
2117 gen_store_gpr(t0, to);
2121 static inline void gen_store_srsgpr (int from, int to)
2124 TCGv t0 = tcg_temp_new();
2125 TCGv_i32 t2 = tcg_temp_new_i32();
2126 TCGv_ptr addr = tcg_temp_new_ptr();
2128 gen_load_gpr(t0, from);
2129 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2130 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2131 tcg_gen_andi_i32(t2, t2, 0xf);
2132 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2133 tcg_gen_ext_i32_ptr(addr, t2);
2134 tcg_gen_add_ptr(addr, cpu_env, addr);
2136 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2137 tcg_temp_free_ptr(addr);
2138 tcg_temp_free_i32(t2);
2144 static inline void gen_save_pc(target_ulong pc)
2146 tcg_gen_movi_tl(cpu_PC, pc);
2149 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2151 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2152 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2153 gen_save_pc(ctx->base.pc_next);
2154 ctx->saved_pc = ctx->base.pc_next;
2156 if (ctx->hflags != ctx->saved_hflags) {
2157 tcg_gen_movi_i32(hflags, ctx->hflags);
2158 ctx->saved_hflags = ctx->hflags;
2159 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2165 tcg_gen_movi_tl(btarget, ctx->btarget);
2171 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2173 ctx->saved_hflags = ctx->hflags;
2174 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2180 ctx->btarget = env->btarget;
2185 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2187 TCGv_i32 texcp = tcg_const_i32(excp);
2188 TCGv_i32 terr = tcg_const_i32(err);
2189 save_cpu_state(ctx, 1);
2190 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2191 tcg_temp_free_i32(terr);
2192 tcg_temp_free_i32(texcp);
2193 ctx->base.is_jmp = DISAS_NORETURN;
2196 static inline void generate_exception(DisasContext *ctx, int excp)
2198 gen_helper_0e0i(raise_exception, excp);
2201 static inline void generate_exception_end(DisasContext *ctx, int excp)
2203 generate_exception_err(ctx, excp, 0);
2206 /* Floating point register moves. */
2207 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2209 if (ctx->hflags & MIPS_HFLAG_FRE) {
2210 generate_exception(ctx, EXCP_RI);
2212 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2215 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2218 if (ctx->hflags & MIPS_HFLAG_FRE) {
2219 generate_exception(ctx, EXCP_RI);
2221 t64 = tcg_temp_new_i64();
2222 tcg_gen_extu_i32_i64(t64, t);
2223 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2224 tcg_temp_free_i64(t64);
2227 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2229 if (ctx->hflags & MIPS_HFLAG_F64) {
2230 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2232 gen_load_fpr32(ctx, t, reg | 1);
2236 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2238 if (ctx->hflags & MIPS_HFLAG_F64) {
2239 TCGv_i64 t64 = tcg_temp_new_i64();
2240 tcg_gen_extu_i32_i64(t64, t);
2241 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2242 tcg_temp_free_i64(t64);
2244 gen_store_fpr32(ctx, t, reg | 1);
2248 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2250 if (ctx->hflags & MIPS_HFLAG_F64) {
2251 tcg_gen_mov_i64(t, fpu_f64[reg]);
2253 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2257 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2259 if (ctx->hflags & MIPS_HFLAG_F64) {
2260 tcg_gen_mov_i64(fpu_f64[reg], t);
2263 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2264 t0 = tcg_temp_new_i64();
2265 tcg_gen_shri_i64(t0, t, 32);
2266 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2267 tcg_temp_free_i64(t0);
2271 static inline int get_fp_bit (int cc)
2279 /* Addresses computation */
2280 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2282 tcg_gen_add_tl(ret, arg0, arg1);
2284 #if defined(TARGET_MIPS64)
2285 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2286 tcg_gen_ext32s_i64(ret, ret);
2291 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2294 tcg_gen_addi_tl(ret, base, ofs);
2296 #if defined(TARGET_MIPS64)
2297 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2298 tcg_gen_ext32s_i64(ret, ret);
2303 /* Addresses computation (translation time) */
2304 static target_long addr_add(DisasContext *ctx, target_long base,
2307 target_long sum = base + offset;
2309 #if defined(TARGET_MIPS64)
2310 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2317 /* Sign-extract the low 32-bits to a target_long. */
2318 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2320 #if defined(TARGET_MIPS64)
2321 tcg_gen_ext32s_i64(ret, arg);
2323 tcg_gen_extrl_i64_i32(ret, arg);
2327 /* Sign-extract the high 32-bits to a target_long. */
2328 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2330 #if defined(TARGET_MIPS64)
2331 tcg_gen_sari_i64(ret, arg, 32);
2333 tcg_gen_extrh_i64_i32(ret, arg);
2337 static inline void check_cp0_enabled(DisasContext *ctx)
2339 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2340 generate_exception_err(ctx, EXCP_CpU, 0);
2343 static inline void check_cp1_enabled(DisasContext *ctx)
2345 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2346 generate_exception_err(ctx, EXCP_CpU, 1);
2349 /* Verify that the processor is running with COP1X instructions enabled.
2350 This is associated with the nabla symbol in the MIPS32 and MIPS64
2353 static inline void check_cop1x(DisasContext *ctx)
2355 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2356 generate_exception_end(ctx, EXCP_RI);
2359 /* Verify that the processor is running with 64-bit floating-point
2360 operations enabled. */
2362 static inline void check_cp1_64bitmode(DisasContext *ctx)
2364 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2365 generate_exception_end(ctx, EXCP_RI);
2369 * Verify if floating point register is valid; an operation is not defined
2370 * if bit 0 of any register specification is set and the FR bit in the
2371 * Status register equals zero, since the register numbers specify an
2372 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2373 * in the Status register equals one, both even and odd register numbers
2374 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2376 * Multiple 64 bit wide registers can be checked by calling
2377 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2379 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2381 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2382 generate_exception_end(ctx, EXCP_RI);
2385 /* Verify that the processor is running with DSP instructions enabled.
2386 This is enabled by CP0 Status register MX(24) bit.
2389 static inline void check_dsp(DisasContext *ctx)
2391 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2392 if (ctx->insn_flags & ASE_DSP) {
2393 generate_exception_end(ctx, EXCP_DSPDIS);
2395 generate_exception_end(ctx, EXCP_RI);
2400 static inline void check_dsp_r2(DisasContext *ctx)
2402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2403 if (ctx->insn_flags & ASE_DSP) {
2404 generate_exception_end(ctx, EXCP_DSPDIS);
2406 generate_exception_end(ctx, EXCP_RI);
2411 static inline void check_dsp_r3(DisasContext *ctx)
2413 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2414 if (ctx->insn_flags & ASE_DSP) {
2415 generate_exception_end(ctx, EXCP_DSPDIS);
2417 generate_exception_end(ctx, EXCP_RI);
2422 /* This code generates a "reserved instruction" exception if the
2423 CPU does not support the instruction set corresponding to flags. */
2424 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2426 if (unlikely(!(ctx->insn_flags & flags))) {
2427 generate_exception_end(ctx, EXCP_RI);
2431 /* This code generates a "reserved instruction" exception if the
2432 CPU has corresponding flag set which indicates that the instruction
2433 has been removed. */
2434 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2436 if (unlikely(ctx->insn_flags & flags)) {
2437 generate_exception_end(ctx, EXCP_RI);
2441 /* This code generates a "reserved instruction" exception if the
2442 CPU does not support 64-bit paired-single (PS) floating point data type */
2443 static inline void check_ps(DisasContext *ctx)
2445 if (unlikely(!ctx->ps)) {
2446 generate_exception(ctx, EXCP_RI);
2448 check_cp1_64bitmode(ctx);
2451 #ifdef TARGET_MIPS64
2452 /* This code generates a "reserved instruction" exception if 64-bit
2453 instructions are not enabled. */
2454 static inline void check_mips_64(DisasContext *ctx)
2456 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
2457 generate_exception_end(ctx, EXCP_RI);
2461 #ifndef CONFIG_USER_ONLY
2462 static inline void check_mvh(DisasContext *ctx)
2464 if (unlikely(!ctx->mvh)) {
2465 generate_exception(ctx, EXCP_RI);
2471 * This code generates a "reserved instruction" exception if the
2472 * Config5 XNP bit is set.
2474 static inline void check_xnp(DisasContext *ctx)
2476 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2477 generate_exception_end(ctx, EXCP_RI);
2481 #ifndef CONFIG_USER_ONLY
2483 * This code generates a "reserved instruction" exception if the
2484 * Config3 PW bit is NOT set.
2486 static inline void check_pw(DisasContext *ctx)
2488 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
2489 generate_exception_end(ctx, EXCP_RI);
2495 * This code generates a "reserved instruction" exception if the
2496 * Config3 MT bit is NOT set.
2498 static inline void check_mt(DisasContext *ctx)
2500 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2501 generate_exception_end(ctx, EXCP_RI);
2505 #ifndef CONFIG_USER_ONLY
2507 * This code generates a "coprocessor unusable" exception if CP0 is not
2508 * available, and, if that is not the case, generates a "reserved instruction"
2509 * exception if the Config5 MT bit is NOT set. This is needed for availability
2510 * control of some of MT ASE instructions.
2512 static inline void check_cp0_mt(DisasContext *ctx)
2514 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2515 generate_exception_err(ctx, EXCP_CpU, 0);
2517 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2518 generate_exception_err(ctx, EXCP_RI, 0);
2525 * This code generates a "reserved instruction" exception if the
2526 * Config5 NMS bit is set.
2528 static inline void check_nms(DisasContext *ctx)
2530 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2531 generate_exception_end(ctx, EXCP_RI);
2536 /* Define small wrappers for gen_load_fpr* so that we have a uniform
2537 calling interface for 32 and 64-bit FPRs. No sense in changing
2538 all callers for gen_load_fpr32 when we need the CTX parameter for
2540 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2541 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2542 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2543 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2544 int ft, int fs, int cc) \
2546 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
2547 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
2556 check_cp1_registers(ctx, fs | ft); \
2564 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
2565 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
2567 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
2568 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
2569 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
2570 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
2571 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
2572 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
2573 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
2574 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
2575 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
2576 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
2577 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
2578 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
2579 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
2580 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
2581 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
2582 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
2585 tcg_temp_free_i##bits (fp0); \
2586 tcg_temp_free_i##bits (fp1); \
2589 FOP_CONDS(, 0, d, FMT_D, 64)
2590 FOP_CONDS(abs, 1, d, FMT_D, 64)
2591 FOP_CONDS(, 0, s, FMT_S, 32)
2592 FOP_CONDS(abs, 1, s, FMT_S, 32)
2593 FOP_CONDS(, 0, ps, FMT_PS, 64)
2594 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
2597 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
2598 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
2599 int ft, int fs, int fd) \
2601 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
2602 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
2603 if (ifmt == FMT_D) { \
2604 check_cp1_registers(ctx, fs | ft | fd); \
2606 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
2607 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
2610 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
2613 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
2616 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
2619 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
2622 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
2625 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
2628 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
2631 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2634 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2637 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2640 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2643 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2646 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2649 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2652 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2655 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2658 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2661 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2664 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2667 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2670 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2673 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2679 tcg_temp_free_i ## bits (fp0); \
2680 tcg_temp_free_i ## bits (fp1); \
2683 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2684 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2686 #undef gen_ldcmp_fpr32
2687 #undef gen_ldcmp_fpr64
2689 /* load/store instructions. */
2690 #ifdef CONFIG_USER_ONLY
2691 #define OP_LD_ATOMIC(insn,fname) \
2692 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2693 DisasContext *ctx) \
2695 TCGv t0 = tcg_temp_new(); \
2696 tcg_gen_mov_tl(t0, arg1); \
2697 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2698 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2699 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2700 tcg_temp_free(t0); \
2703 #define OP_LD_ATOMIC(insn,fname) \
2704 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2705 DisasContext *ctx) \
2707 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2710 OP_LD_ATOMIC(ll,ld32s);
2711 #if defined(TARGET_MIPS64)
2712 OP_LD_ATOMIC(lld,ld64);
2716 #ifdef CONFIG_USER_ONLY
2717 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2718 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2719 DisasContext *ctx) \
2721 TCGv t0 = tcg_temp_new(); \
2722 TCGLabel *l1 = gen_new_label(); \
2723 TCGLabel *l2 = gen_new_label(); \
2725 tcg_gen_andi_tl(t0, arg2, almask); \
2726 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2727 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2728 generate_exception(ctx, EXCP_AdES); \
2729 gen_set_label(l1); \
2730 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2731 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2732 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2733 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2734 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2735 generate_exception_end(ctx, EXCP_SC); \
2736 gen_set_label(l2); \
2737 tcg_gen_movi_tl(t0, 0); \
2738 gen_store_gpr(t0, rt); \
2739 tcg_temp_free(t0); \
2742 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2743 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2744 DisasContext *ctx) \
2746 TCGv t0 = tcg_temp_new(); \
2747 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
2748 gen_store_gpr(t0, rt); \
2749 tcg_temp_free(t0); \
2752 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2753 #if defined(TARGET_MIPS64)
2754 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2758 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2759 int base, int offset)
2762 tcg_gen_movi_tl(addr, offset);
2763 } else if (offset == 0) {
2764 gen_load_gpr(addr, base);
2766 tcg_gen_movi_tl(addr, offset);
2767 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2771 static target_ulong pc_relative_pc (DisasContext *ctx)
2773 target_ulong pc = ctx->base.pc_next;
2775 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2776 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2781 pc &= ~(target_ulong)3;
2786 static void gen_ld(DisasContext *ctx, uint32_t opc,
2787 int rt, int base, int offset)
2790 int mem_idx = ctx->mem_idx;
2792 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2793 /* Loongson CPU uses a load to zero register for prefetch.
2794 We emulate it as a NOP. On other CPU we must perform the
2795 actual memory access. */
2799 t0 = tcg_temp_new();
2800 gen_base_offset_addr(ctx, t0, base, offset);
2803 #if defined(TARGET_MIPS64)
2805 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2806 ctx->default_tcg_memop_mask);
2807 gen_store_gpr(t0, rt);
2810 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2811 ctx->default_tcg_memop_mask);
2812 gen_store_gpr(t0, rt);
2816 op_ld_lld(t0, t0, mem_idx, ctx);
2817 gen_store_gpr(t0, rt);
2820 t1 = tcg_temp_new();
2821 /* Do a byte access to possibly trigger a page
2822 fault with the unaligned address. */
2823 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2824 tcg_gen_andi_tl(t1, t0, 7);
2825 #ifndef TARGET_WORDS_BIGENDIAN
2826 tcg_gen_xori_tl(t1, t1, 7);
2828 tcg_gen_shli_tl(t1, t1, 3);
2829 tcg_gen_andi_tl(t0, t0, ~7);
2830 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2831 tcg_gen_shl_tl(t0, t0, t1);
2832 t2 = tcg_const_tl(-1);
2833 tcg_gen_shl_tl(t2, t2, t1);
2834 gen_load_gpr(t1, rt);
2835 tcg_gen_andc_tl(t1, t1, t2);
2837 tcg_gen_or_tl(t0, t0, t1);
2839 gen_store_gpr(t0, rt);
2842 t1 = tcg_temp_new();
2843 /* Do a byte access to possibly trigger a page
2844 fault with the unaligned address. */
2845 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2846 tcg_gen_andi_tl(t1, t0, 7);
2847 #ifdef TARGET_WORDS_BIGENDIAN
2848 tcg_gen_xori_tl(t1, t1, 7);
2850 tcg_gen_shli_tl(t1, t1, 3);
2851 tcg_gen_andi_tl(t0, t0, ~7);
2852 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2853 tcg_gen_shr_tl(t0, t0, t1);
2854 tcg_gen_xori_tl(t1, t1, 63);
2855 t2 = tcg_const_tl(0xfffffffffffffffeull);
2856 tcg_gen_shl_tl(t2, t2, t1);
2857 gen_load_gpr(t1, rt);
2858 tcg_gen_and_tl(t1, t1, t2);
2860 tcg_gen_or_tl(t0, t0, t1);
2862 gen_store_gpr(t0, rt);
2865 t1 = tcg_const_tl(pc_relative_pc(ctx));
2866 gen_op_addr_add(ctx, t0, t0, t1);
2868 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2869 gen_store_gpr(t0, rt);
2873 t1 = tcg_const_tl(pc_relative_pc(ctx));
2874 gen_op_addr_add(ctx, t0, t0, t1);
2876 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2877 gen_store_gpr(t0, rt);
2880 mem_idx = MIPS_HFLAG_UM;
2883 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2884 ctx->default_tcg_memop_mask);
2885 gen_store_gpr(t0, rt);
2888 mem_idx = MIPS_HFLAG_UM;
2891 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2892 ctx->default_tcg_memop_mask);
2893 gen_store_gpr(t0, rt);
2896 mem_idx = MIPS_HFLAG_UM;
2899 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2900 ctx->default_tcg_memop_mask);
2901 gen_store_gpr(t0, rt);
2904 mem_idx = MIPS_HFLAG_UM;
2907 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2908 gen_store_gpr(t0, rt);
2911 mem_idx = MIPS_HFLAG_UM;
2914 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2915 gen_store_gpr(t0, rt);
2918 mem_idx = MIPS_HFLAG_UM;
2921 t1 = tcg_temp_new();
2922 /* Do a byte access to possibly trigger a page
2923 fault with the unaligned address. */
2924 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2925 tcg_gen_andi_tl(t1, t0, 3);
2926 #ifndef TARGET_WORDS_BIGENDIAN
2927 tcg_gen_xori_tl(t1, t1, 3);
2929 tcg_gen_shli_tl(t1, t1, 3);
2930 tcg_gen_andi_tl(t0, t0, ~3);
2931 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2932 tcg_gen_shl_tl(t0, t0, t1);
2933 t2 = tcg_const_tl(-1);
2934 tcg_gen_shl_tl(t2, t2, t1);
2935 gen_load_gpr(t1, rt);
2936 tcg_gen_andc_tl(t1, t1, t2);
2938 tcg_gen_or_tl(t0, t0, t1);
2940 tcg_gen_ext32s_tl(t0, t0);
2941 gen_store_gpr(t0, rt);
2944 mem_idx = MIPS_HFLAG_UM;
2947 t1 = tcg_temp_new();
2948 /* Do a byte access to possibly trigger a page
2949 fault with the unaligned address. */
2950 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2951 tcg_gen_andi_tl(t1, t0, 3);
2952 #ifdef TARGET_WORDS_BIGENDIAN
2953 tcg_gen_xori_tl(t1, t1, 3);
2955 tcg_gen_shli_tl(t1, t1, 3);
2956 tcg_gen_andi_tl(t0, t0, ~3);
2957 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2958 tcg_gen_shr_tl(t0, t0, t1);
2959 tcg_gen_xori_tl(t1, t1, 31);
2960 t2 = tcg_const_tl(0xfffffffeull);
2961 tcg_gen_shl_tl(t2, t2, t1);
2962 gen_load_gpr(t1, rt);
2963 tcg_gen_and_tl(t1, t1, t2);
2965 tcg_gen_or_tl(t0, t0, t1);
2967 tcg_gen_ext32s_tl(t0, t0);
2968 gen_store_gpr(t0, rt);
2971 mem_idx = MIPS_HFLAG_UM;
2975 op_ld_ll(t0, t0, mem_idx, ctx);
2976 gen_store_gpr(t0, rt);
2982 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
2983 uint32_t reg1, uint32_t reg2)
2985 TCGv taddr = tcg_temp_new();
2986 TCGv_i64 tval = tcg_temp_new_i64();
2987 TCGv tmp1 = tcg_temp_new();
2988 TCGv tmp2 = tcg_temp_new();
2990 gen_base_offset_addr(ctx, taddr, base, offset);
2991 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
2992 #ifdef TARGET_WORDS_BIGENDIAN
2993 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
2995 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
2997 gen_store_gpr(tmp1, reg1);
2998 tcg_temp_free(tmp1);
2999 gen_store_gpr(tmp2, reg2);
3000 tcg_temp_free(tmp2);
3001 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3002 tcg_temp_free_i64(tval);
3003 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3004 tcg_temp_free(taddr);
3008 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3009 int base, int offset)
3011 TCGv t0 = tcg_temp_new();
3012 TCGv t1 = tcg_temp_new();
3013 int mem_idx = ctx->mem_idx;
3015 gen_base_offset_addr(ctx, t0, base, offset);
3016 gen_load_gpr(t1, rt);
3018 #if defined(TARGET_MIPS64)
3020 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3021 ctx->default_tcg_memop_mask);
3024 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3027 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3031 mem_idx = MIPS_HFLAG_UM;
3034 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3035 ctx->default_tcg_memop_mask);
3038 mem_idx = MIPS_HFLAG_UM;
3041 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3042 ctx->default_tcg_memop_mask);
3045 mem_idx = MIPS_HFLAG_UM;
3048 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3051 mem_idx = MIPS_HFLAG_UM;
3054 gen_helper_0e2i(swl, t1, t0, mem_idx);
3057 mem_idx = MIPS_HFLAG_UM;
3060 gen_helper_0e2i(swr, t1, t0, mem_idx);
3068 /* Store conditional */
3069 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3070 int base, int16_t offset)
3073 int mem_idx = ctx->mem_idx;
3075 #ifdef CONFIG_USER_ONLY
3076 t0 = tcg_temp_local_new();
3077 t1 = tcg_temp_local_new();
3079 t0 = tcg_temp_new();
3080 t1 = tcg_temp_new();
3082 gen_base_offset_addr(ctx, t0, base, offset);
3083 gen_load_gpr(t1, rt);
3085 #if defined(TARGET_MIPS64)
3088 op_st_scd(t1, t0, rt, mem_idx, ctx);
3092 mem_idx = MIPS_HFLAG_UM;
3096 op_st_sc(t1, t0, rt, mem_idx, ctx);
3103 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3104 uint32_t reg1, uint32_t reg2)
3106 TCGv taddr = tcg_temp_local_new();
3107 TCGv lladdr = tcg_temp_local_new();
3108 TCGv_i64 tval = tcg_temp_new_i64();
3109 TCGv_i64 llval = tcg_temp_new_i64();
3110 TCGv_i64 val = tcg_temp_new_i64();
3111 TCGv tmp1 = tcg_temp_new();
3112 TCGv tmp2 = tcg_temp_new();
3113 TCGLabel *lab_fail = gen_new_label();
3114 TCGLabel *lab_done = gen_new_label();
3116 gen_base_offset_addr(ctx, taddr, base, offset);
3118 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3119 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3121 gen_load_gpr(tmp1, reg1);
3122 gen_load_gpr(tmp2, reg2);
3124 #ifdef TARGET_WORDS_BIGENDIAN
3125 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3127 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3130 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3131 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3132 ctx->mem_idx, MO_64);
3134 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3136 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3138 gen_set_label(lab_fail);
3141 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3143 gen_set_label(lab_done);
3144 tcg_gen_movi_tl(lladdr, -1);
3145 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3148 /* Load and store */
3149 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3152 /* Don't do NOP if destination is zero: we must perform the actual
3157 TCGv_i32 fp0 = tcg_temp_new_i32();
3158 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3159 ctx->default_tcg_memop_mask);
3160 gen_store_fpr32(ctx, fp0, ft);
3161 tcg_temp_free_i32(fp0);
3166 TCGv_i32 fp0 = tcg_temp_new_i32();
3167 gen_load_fpr32(ctx, fp0, ft);
3168 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3169 ctx->default_tcg_memop_mask);
3170 tcg_temp_free_i32(fp0);
3175 TCGv_i64 fp0 = tcg_temp_new_i64();
3176 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3177 ctx->default_tcg_memop_mask);
3178 gen_store_fpr64(ctx, fp0, ft);
3179 tcg_temp_free_i64(fp0);
3184 TCGv_i64 fp0 = tcg_temp_new_i64();
3185 gen_load_fpr64(ctx, fp0, ft);
3186 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3187 ctx->default_tcg_memop_mask);
3188 tcg_temp_free_i64(fp0);
3192 MIPS_INVAL("flt_ldst");
3193 generate_exception_end(ctx, EXCP_RI);
3198 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3199 int rs, int16_t imm)
3201 TCGv t0 = tcg_temp_new();
3203 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3204 check_cp1_enabled(ctx);
3208 check_insn(ctx, ISA_MIPS2);
3211 gen_base_offset_addr(ctx, t0, rs, imm);
3212 gen_flt_ldst(ctx, op, rt, t0);
3215 generate_exception_err(ctx, EXCP_CpU, 1);
3220 /* Arithmetic with immediate operand */
3221 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3222 int rt, int rs, int imm)
3224 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3226 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3227 /* If no destination, treat it as a NOP.
3228 For addi, we must generate the overflow exception when needed. */
3234 TCGv t0 = tcg_temp_local_new();
3235 TCGv t1 = tcg_temp_new();
3236 TCGv t2 = tcg_temp_new();
3237 TCGLabel *l1 = gen_new_label();
3239 gen_load_gpr(t1, rs);
3240 tcg_gen_addi_tl(t0, t1, uimm);
3241 tcg_gen_ext32s_tl(t0, t0);
3243 tcg_gen_xori_tl(t1, t1, ~uimm);
3244 tcg_gen_xori_tl(t2, t0, uimm);
3245 tcg_gen_and_tl(t1, t1, t2);
3247 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3249 /* operands of same sign, result different sign */
3250 generate_exception(ctx, EXCP_OVERFLOW);
3252 tcg_gen_ext32s_tl(t0, t0);
3253 gen_store_gpr(t0, rt);
3259 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3260 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3262 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3265 #if defined(TARGET_MIPS64)
3268 TCGv t0 = tcg_temp_local_new();
3269 TCGv t1 = tcg_temp_new();
3270 TCGv t2 = tcg_temp_new();
3271 TCGLabel *l1 = gen_new_label();
3273 gen_load_gpr(t1, rs);
3274 tcg_gen_addi_tl(t0, t1, uimm);
3276 tcg_gen_xori_tl(t1, t1, ~uimm);
3277 tcg_gen_xori_tl(t2, t0, uimm);
3278 tcg_gen_and_tl(t1, t1, t2);
3280 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3282 /* operands of same sign, result different sign */
3283 generate_exception(ctx, EXCP_OVERFLOW);
3285 gen_store_gpr(t0, rt);
3291 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3293 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3300 /* Logic with immediate operand */
3301 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3302 int rt, int rs, int16_t imm)
3307 /* If no destination, treat it as a NOP. */
3310 uimm = (uint16_t)imm;
3313 if (likely(rs != 0))
3314 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3316 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3320 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3322 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3325 if (likely(rs != 0))
3326 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3328 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3331 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3333 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3334 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3336 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3345 /* Set on less than with immediate operand */
3346 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3347 int rt, int rs, int16_t imm)
3349 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3353 /* If no destination, treat it as a NOP. */
3356 t0 = tcg_temp_new();
3357 gen_load_gpr(t0, rs);
3360 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3363 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3369 /* Shifts with immediate operand */
3370 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3371 int rt, int rs, int16_t imm)
3373 target_ulong uimm = ((uint16_t)imm) & 0x1f;
3377 /* If no destination, treat it as a NOP. */
3381 t0 = tcg_temp_new();
3382 gen_load_gpr(t0, rs);
3385 tcg_gen_shli_tl(t0, t0, uimm);
3386 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3389 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3393 tcg_gen_ext32u_tl(t0, t0);
3394 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3396 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3401 TCGv_i32 t1 = tcg_temp_new_i32();
3403 tcg_gen_trunc_tl_i32(t1, t0);
3404 tcg_gen_rotri_i32(t1, t1, uimm);
3405 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3406 tcg_temp_free_i32(t1);
3408 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3411 #if defined(TARGET_MIPS64)
3413 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3416 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3419 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3423 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3425 tcg_gen_mov_tl(cpu_gpr[rt], t0);
3429 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3432 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
3435 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
3438 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
3446 static void gen_arith(DisasContext *ctx, uint32_t opc,
3447 int rd, int rs, int rt)
3449 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3450 && opc != OPC_DADD && opc != OPC_DSUB) {
3451 /* If no destination, treat it as a NOP.
3452 For add & sub, we must generate the overflow exception when needed. */
3459 TCGv t0 = tcg_temp_local_new();
3460 TCGv t1 = tcg_temp_new();
3461 TCGv t2 = tcg_temp_new();
3462 TCGLabel *l1 = gen_new_label();
3464 gen_load_gpr(t1, rs);
3465 gen_load_gpr(t2, rt);
3466 tcg_gen_add_tl(t0, t1, t2);
3467 tcg_gen_ext32s_tl(t0, t0);
3468 tcg_gen_xor_tl(t1, t1, t2);
3469 tcg_gen_xor_tl(t2, t0, t2);
3470 tcg_gen_andc_tl(t1, t2, t1);
3472 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3474 /* operands of same sign, result different sign */
3475 generate_exception(ctx, EXCP_OVERFLOW);
3477 gen_store_gpr(t0, rd);
3482 if (rs != 0 && rt != 0) {
3483 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3484 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3485 } else if (rs == 0 && rt != 0) {
3486 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3487 } else if (rs != 0 && rt == 0) {
3488 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3490 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3495 TCGv t0 = tcg_temp_local_new();
3496 TCGv t1 = tcg_temp_new();
3497 TCGv t2 = tcg_temp_new();
3498 TCGLabel *l1 = gen_new_label();
3500 gen_load_gpr(t1, rs);
3501 gen_load_gpr(t2, rt);
3502 tcg_gen_sub_tl(t0, t1, t2);
3503 tcg_gen_ext32s_tl(t0, t0);
3504 tcg_gen_xor_tl(t2, t1, t2);
3505 tcg_gen_xor_tl(t1, t0, t1);
3506 tcg_gen_and_tl(t1, t1, t2);
3508 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3510 /* operands of different sign, first operand and result different sign */
3511 generate_exception(ctx, EXCP_OVERFLOW);
3513 gen_store_gpr(t0, rd);
3518 if (rs != 0 && rt != 0) {
3519 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3520 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3521 } else if (rs == 0 && rt != 0) {
3522 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3523 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3524 } else if (rs != 0 && rt == 0) {
3525 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3527 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3530 #if defined(TARGET_MIPS64)
3533 TCGv t0 = tcg_temp_local_new();
3534 TCGv t1 = tcg_temp_new();
3535 TCGv t2 = tcg_temp_new();
3536 TCGLabel *l1 = gen_new_label();
3538 gen_load_gpr(t1, rs);
3539 gen_load_gpr(t2, rt);
3540 tcg_gen_add_tl(t0, t1, t2);
3541 tcg_gen_xor_tl(t1, t1, t2);
3542 tcg_gen_xor_tl(t2, t0, t2);
3543 tcg_gen_andc_tl(t1, t2, t1);
3545 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3547 /* operands of same sign, result different sign */
3548 generate_exception(ctx, EXCP_OVERFLOW);
3550 gen_store_gpr(t0, rd);
3555 if (rs != 0 && rt != 0) {
3556 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3557 } else if (rs == 0 && rt != 0) {
3558 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3559 } else if (rs != 0 && rt == 0) {
3560 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3562 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3567 TCGv t0 = tcg_temp_local_new();
3568 TCGv t1 = tcg_temp_new();
3569 TCGv t2 = tcg_temp_new();
3570 TCGLabel *l1 = gen_new_label();
3572 gen_load_gpr(t1, rs);
3573 gen_load_gpr(t2, rt);
3574 tcg_gen_sub_tl(t0, t1, t2);
3575 tcg_gen_xor_tl(t2, t1, t2);
3576 tcg_gen_xor_tl(t1, t0, t1);
3577 tcg_gen_and_tl(t1, t1, t2);
3579 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3581 /* operands of different sign, first operand and result different sign */
3582 generate_exception(ctx, EXCP_OVERFLOW);
3584 gen_store_gpr(t0, rd);
3589 if (rs != 0 && rt != 0) {
3590 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3591 } else if (rs == 0 && rt != 0) {
3592 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3593 } else if (rs != 0 && rt == 0) {
3594 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3596 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3601 if (likely(rs != 0 && rt != 0)) {
3602 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3603 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3605 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3611 /* Conditional move */
3612 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
3613 int rd, int rs, int rt)
3618 /* If no destination, treat it as a NOP. */
3622 t0 = tcg_temp_new();
3623 gen_load_gpr(t0, rt);
3624 t1 = tcg_const_tl(0);
3625 t2 = tcg_temp_new();
3626 gen_load_gpr(t2, rs);
3629 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
3632 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
3635 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
3638 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
3647 static void gen_logic(DisasContext *ctx, uint32_t opc,
3648 int rd, int rs, int rt)
3651 /* If no destination, treat it as a NOP. */
3657 if (likely(rs != 0 && rt != 0)) {
3658 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3660 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3664 if (rs != 0 && rt != 0) {
3665 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3666 } else if (rs == 0 && rt != 0) {
3667 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
3668 } else if (rs != 0 && rt == 0) {
3669 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
3671 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
3675 if (likely(rs != 0 && rt != 0)) {
3676 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3677 } else if (rs == 0 && rt != 0) {
3678 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3679 } else if (rs != 0 && rt == 0) {
3680 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3682 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3686 if (likely(rs != 0 && rt != 0)) {
3687 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3688 } else if (rs == 0 && rt != 0) {
3689 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3690 } else if (rs != 0 && rt == 0) {
3691 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3693 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3699 /* Set on lower than */
3700 static void gen_slt(DisasContext *ctx, uint32_t opc,
3701 int rd, int rs, int rt)
3706 /* If no destination, treat it as a NOP. */
3710 t0 = tcg_temp_new();
3711 t1 = tcg_temp_new();
3712 gen_load_gpr(t0, rs);
3713 gen_load_gpr(t1, rt);
3716 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
3719 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
3727 static void gen_shift(DisasContext *ctx, uint32_t opc,
3728 int rd, int rs, int rt)
3733 /* If no destination, treat it as a NOP.
3734 For add & sub, we must generate the overflow exception when needed. */
3738 t0 = tcg_temp_new();
3739 t1 = tcg_temp_new();
3740 gen_load_gpr(t0, rs);
3741 gen_load_gpr(t1, rt);
3744 tcg_gen_andi_tl(t0, t0, 0x1f);
3745 tcg_gen_shl_tl(t0, t1, t0);
3746 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3749 tcg_gen_andi_tl(t0, t0, 0x1f);
3750 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3753 tcg_gen_ext32u_tl(t1, t1);
3754 tcg_gen_andi_tl(t0, t0, 0x1f);
3755 tcg_gen_shr_tl(t0, t1, t0);
3756 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3760 TCGv_i32 t2 = tcg_temp_new_i32();
3761 TCGv_i32 t3 = tcg_temp_new_i32();
3763 tcg_gen_trunc_tl_i32(t2, t0);
3764 tcg_gen_trunc_tl_i32(t3, t1);
3765 tcg_gen_andi_i32(t2, t2, 0x1f);
3766 tcg_gen_rotr_i32(t2, t3, t2);
3767 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3768 tcg_temp_free_i32(t2);
3769 tcg_temp_free_i32(t3);
3772 #if defined(TARGET_MIPS64)
3774 tcg_gen_andi_tl(t0, t0, 0x3f);
3775 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
3778 tcg_gen_andi_tl(t0, t0, 0x3f);
3779 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3782 tcg_gen_andi_tl(t0, t0, 0x3f);
3783 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3786 tcg_gen_andi_tl(t0, t0, 0x3f);
3787 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3795 /* Arithmetic on HI/LO registers */
3796 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3798 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3809 #if defined(TARGET_MIPS64)
3811 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3815 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3819 #if defined(TARGET_MIPS64)
3821 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3825 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3830 #if defined(TARGET_MIPS64)
3832 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3836 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3839 tcg_gen_movi_tl(cpu_HI[acc], 0);
3844 #if defined(TARGET_MIPS64)
3846 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3850 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3853 tcg_gen_movi_tl(cpu_LO[acc], 0);
3859 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3862 TCGv t0 = tcg_const_tl(addr);
3863 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3864 gen_store_gpr(t0, reg);
3868 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3874 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3877 offset = sextract32(ctx->opcode << 2, 0, 21);
3878 addr = addr_add(ctx, pc, offset);
3879 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3883 offset = sextract32(ctx->opcode << 2, 0, 21);
3884 addr = addr_add(ctx, pc, offset);
3885 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3887 #if defined(TARGET_MIPS64)
3890 offset = sextract32(ctx->opcode << 2, 0, 21);
3891 addr = addr_add(ctx, pc, offset);
3892 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3896 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3899 offset = sextract32(ctx->opcode, 0, 16) << 16;
3900 addr = addr_add(ctx, pc, offset);
3901 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3906 offset = sextract32(ctx->opcode, 0, 16) << 16;
3907 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3908 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3911 #if defined(TARGET_MIPS64)
3912 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3913 case R6_OPC_LDPC + (1 << 16):
3914 case R6_OPC_LDPC + (2 << 16):
3915 case R6_OPC_LDPC + (3 << 16):
3917 offset = sextract32(ctx->opcode << 3, 0, 21);
3918 addr = addr_add(ctx, (pc & ~0x7), offset);
3919 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3923 MIPS_INVAL("OPC_PCREL");
3924 generate_exception_end(ctx, EXCP_RI);
3931 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3940 t0 = tcg_temp_new();
3941 t1 = tcg_temp_new();
3943 gen_load_gpr(t0, rs);
3944 gen_load_gpr(t1, rt);
3949 TCGv t2 = tcg_temp_new();
3950 TCGv t3 = tcg_temp_new();
3951 tcg_gen_ext32s_tl(t0, t0);
3952 tcg_gen_ext32s_tl(t1, t1);
3953 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3954 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3955 tcg_gen_and_tl(t2, t2, t3);
3956 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3957 tcg_gen_or_tl(t2, t2, t3);
3958 tcg_gen_movi_tl(t3, 0);
3959 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3960 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3961 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3968 TCGv t2 = tcg_temp_new();
3969 TCGv t3 = tcg_temp_new();
3970 tcg_gen_ext32s_tl(t0, t0);
3971 tcg_gen_ext32s_tl(t1, t1);
3972 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3973 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3974 tcg_gen_and_tl(t2, t2, t3);
3975 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3976 tcg_gen_or_tl(t2, t2, t3);
3977 tcg_gen_movi_tl(t3, 0);
3978 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3979 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3980 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3987 TCGv t2 = tcg_const_tl(0);
3988 TCGv t3 = tcg_const_tl(1);
3989 tcg_gen_ext32u_tl(t0, t0);
3990 tcg_gen_ext32u_tl(t1, t1);
3991 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3992 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3993 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4000 TCGv t2 = tcg_const_tl(0);
4001 TCGv t3 = tcg_const_tl(1);
4002 tcg_gen_ext32u_tl(t0, t0);
4003 tcg_gen_ext32u_tl(t1, t1);
4004 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4005 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4006 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4013 TCGv_i32 t2 = tcg_temp_new_i32();
4014 TCGv_i32 t3 = tcg_temp_new_i32();
4015 tcg_gen_trunc_tl_i32(t2, t0);
4016 tcg_gen_trunc_tl_i32(t3, t1);
4017 tcg_gen_mul_i32(t2, t2, t3);
4018 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4019 tcg_temp_free_i32(t2);
4020 tcg_temp_free_i32(t3);
4025 TCGv_i32 t2 = tcg_temp_new_i32();
4026 TCGv_i32 t3 = tcg_temp_new_i32();
4027 tcg_gen_trunc_tl_i32(t2, t0);
4028 tcg_gen_trunc_tl_i32(t3, t1);
4029 tcg_gen_muls2_i32(t2, t3, t2, t3);
4030 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4031 tcg_temp_free_i32(t2);
4032 tcg_temp_free_i32(t3);
4037 TCGv_i32 t2 = tcg_temp_new_i32();
4038 TCGv_i32 t3 = tcg_temp_new_i32();
4039 tcg_gen_trunc_tl_i32(t2, t0);
4040 tcg_gen_trunc_tl_i32(t3, t1);
4041 tcg_gen_mul_i32(t2, t2, t3);
4042 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4043 tcg_temp_free_i32(t2);
4044 tcg_temp_free_i32(t3);
4049 TCGv_i32 t2 = tcg_temp_new_i32();
4050 TCGv_i32 t3 = tcg_temp_new_i32();
4051 tcg_gen_trunc_tl_i32(t2, t0);
4052 tcg_gen_trunc_tl_i32(t3, t1);
4053 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4054 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4055 tcg_temp_free_i32(t2);
4056 tcg_temp_free_i32(t3);
4059 #if defined(TARGET_MIPS64)
4062 TCGv t2 = tcg_temp_new();
4063 TCGv t3 = tcg_temp_new();
4064 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4065 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4066 tcg_gen_and_tl(t2, t2, t3);
4067 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4068 tcg_gen_or_tl(t2, t2, t3);
4069 tcg_gen_movi_tl(t3, 0);
4070 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4071 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4078 TCGv t2 = tcg_temp_new();
4079 TCGv t3 = tcg_temp_new();
4080 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4081 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4082 tcg_gen_and_tl(t2, t2, t3);
4083 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4084 tcg_gen_or_tl(t2, t2, t3);
4085 tcg_gen_movi_tl(t3, 0);
4086 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4087 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4094 TCGv t2 = tcg_const_tl(0);
4095 TCGv t3 = tcg_const_tl(1);
4096 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4097 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4104 TCGv t2 = tcg_const_tl(0);
4105 TCGv t3 = tcg_const_tl(1);
4106 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4107 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4113 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4117 TCGv t2 = tcg_temp_new();
4118 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4123 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4127 TCGv t2 = tcg_temp_new();
4128 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4134 MIPS_INVAL("r6 mul/div");
4135 generate_exception_end(ctx, EXCP_RI);
4143 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4144 int acc, int rs, int rt)
4148 t0 = tcg_temp_new();
4149 t1 = tcg_temp_new();
4151 gen_load_gpr(t0, rs);
4152 gen_load_gpr(t1, rt);
4161 TCGv t2 = tcg_temp_new();
4162 TCGv t3 = tcg_temp_new();
4163 tcg_gen_ext32s_tl(t0, t0);
4164 tcg_gen_ext32s_tl(t1, t1);
4165 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4166 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4167 tcg_gen_and_tl(t2, t2, t3);
4168 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4169 tcg_gen_or_tl(t2, t2, t3);
4170 tcg_gen_movi_tl(t3, 0);
4171 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4172 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4173 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4174 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4175 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4182 TCGv t2 = tcg_const_tl(0);
4183 TCGv t3 = tcg_const_tl(1);
4184 tcg_gen_ext32u_tl(t0, t0);
4185 tcg_gen_ext32u_tl(t1, t1);
4186 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4187 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4188 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4189 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4190 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4197 TCGv_i32 t2 = tcg_temp_new_i32();
4198 TCGv_i32 t3 = tcg_temp_new_i32();
4199 tcg_gen_trunc_tl_i32(t2, t0);
4200 tcg_gen_trunc_tl_i32(t3, t1);
4201 tcg_gen_muls2_i32(t2, t3, t2, t3);
4202 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4203 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4204 tcg_temp_free_i32(t2);
4205 tcg_temp_free_i32(t3);
4210 TCGv_i32 t2 = tcg_temp_new_i32();
4211 TCGv_i32 t3 = tcg_temp_new_i32();
4212 tcg_gen_trunc_tl_i32(t2, t0);
4213 tcg_gen_trunc_tl_i32(t3, t1);
4214 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4215 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4216 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4217 tcg_temp_free_i32(t2);
4218 tcg_temp_free_i32(t3);
4221 #if defined(TARGET_MIPS64)
4224 TCGv t2 = tcg_temp_new();
4225 TCGv t3 = tcg_temp_new();
4226 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4227 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4228 tcg_gen_and_tl(t2, t2, t3);
4229 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4230 tcg_gen_or_tl(t2, t2, t3);
4231 tcg_gen_movi_tl(t3, 0);
4232 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4233 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4234 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4241 TCGv t2 = tcg_const_tl(0);
4242 TCGv t3 = tcg_const_tl(1);
4243 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4244 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4245 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4251 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4254 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4259 TCGv_i64 t2 = tcg_temp_new_i64();
4260 TCGv_i64 t3 = tcg_temp_new_i64();
4262 tcg_gen_ext_tl_i64(t2, t0);
4263 tcg_gen_ext_tl_i64(t3, t1);
4264 tcg_gen_mul_i64(t2, t2, t3);
4265 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4266 tcg_gen_add_i64(t2, t2, t3);
4267 tcg_temp_free_i64(t3);
4268 gen_move_low32(cpu_LO[acc], t2);
4269 gen_move_high32(cpu_HI[acc], t2);
4270 tcg_temp_free_i64(t2);
4275 TCGv_i64 t2 = tcg_temp_new_i64();
4276 TCGv_i64 t3 = tcg_temp_new_i64();
4278 tcg_gen_ext32u_tl(t0, t0);
4279 tcg_gen_ext32u_tl(t1, t1);
4280 tcg_gen_extu_tl_i64(t2, t0);
4281 tcg_gen_extu_tl_i64(t3, t1);
4282 tcg_gen_mul_i64(t2, t2, t3);
4283 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4284 tcg_gen_add_i64(t2, t2, t3);
4285 tcg_temp_free_i64(t3);
4286 gen_move_low32(cpu_LO[acc], t2);
4287 gen_move_high32(cpu_HI[acc], t2);
4288 tcg_temp_free_i64(t2);
4293 TCGv_i64 t2 = tcg_temp_new_i64();
4294 TCGv_i64 t3 = tcg_temp_new_i64();
4296 tcg_gen_ext_tl_i64(t2, t0);
4297 tcg_gen_ext_tl_i64(t3, t1);
4298 tcg_gen_mul_i64(t2, t2, t3);
4299 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4300 tcg_gen_sub_i64(t2, t3, t2);
4301 tcg_temp_free_i64(t3);
4302 gen_move_low32(cpu_LO[acc], t2);
4303 gen_move_high32(cpu_HI[acc], t2);
4304 tcg_temp_free_i64(t2);
4309 TCGv_i64 t2 = tcg_temp_new_i64();
4310 TCGv_i64 t3 = tcg_temp_new_i64();
4312 tcg_gen_ext32u_tl(t0, t0);
4313 tcg_gen_ext32u_tl(t1, t1);
4314 tcg_gen_extu_tl_i64(t2, t0);
4315 tcg_gen_extu_tl_i64(t3, t1);
4316 tcg_gen_mul_i64(t2, t2, t3);
4317 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4318 tcg_gen_sub_i64(t2, t3, t2);
4319 tcg_temp_free_i64(t3);
4320 gen_move_low32(cpu_LO[acc], t2);
4321 gen_move_high32(cpu_HI[acc], t2);
4322 tcg_temp_free_i64(t2);
4326 MIPS_INVAL("mul/div");
4327 generate_exception_end(ctx, EXCP_RI);
4335 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4336 int rd, int rs, int rt)
4338 TCGv t0 = tcg_temp_new();
4339 TCGv t1 = tcg_temp_new();
4341 gen_load_gpr(t0, rs);
4342 gen_load_gpr(t1, rt);
4345 case OPC_VR54XX_MULS:
4346 gen_helper_muls(t0, cpu_env, t0, t1);
4348 case OPC_VR54XX_MULSU:
4349 gen_helper_mulsu(t0, cpu_env, t0, t1);
4351 case OPC_VR54XX_MACC:
4352 gen_helper_macc(t0, cpu_env, t0, t1);
4354 case OPC_VR54XX_MACCU:
4355 gen_helper_maccu(t0, cpu_env, t0, t1);
4357 case OPC_VR54XX_MSAC:
4358 gen_helper_msac(t0, cpu_env, t0, t1);
4360 case OPC_VR54XX_MSACU:
4361 gen_helper_msacu(t0, cpu_env, t0, t1);
4363 case OPC_VR54XX_MULHI:
4364 gen_helper_mulhi(t0, cpu_env, t0, t1);
4366 case OPC_VR54XX_MULHIU:
4367 gen_helper_mulhiu(t0, cpu_env, t0, t1);
4369 case OPC_VR54XX_MULSHI:
4370 gen_helper_mulshi(t0, cpu_env, t0, t1);
4372 case OPC_VR54XX_MULSHIU:
4373 gen_helper_mulshiu(t0, cpu_env, t0, t1);
4375 case OPC_VR54XX_MACCHI:
4376 gen_helper_macchi(t0, cpu_env, t0, t1);
4378 case OPC_VR54XX_MACCHIU:
4379 gen_helper_macchiu(t0, cpu_env, t0, t1);
4381 case OPC_VR54XX_MSACHI:
4382 gen_helper_msachi(t0, cpu_env, t0, t1);
4384 case OPC_VR54XX_MSACHIU:
4385 gen_helper_msachiu(t0, cpu_env, t0, t1);
4388 MIPS_INVAL("mul vr54xx");
4389 generate_exception_end(ctx, EXCP_RI);
4392 gen_store_gpr(t0, rd);
4399 static void gen_cl (DisasContext *ctx, uint32_t opc,
4409 gen_load_gpr(t0, rs);
4414 #if defined(TARGET_MIPS64)
4418 tcg_gen_not_tl(t0, t0);
4427 tcg_gen_ext32u_tl(t0, t0);
4428 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
4429 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
4431 #if defined(TARGET_MIPS64)
4436 tcg_gen_clzi_i64(t0, t0, 64);
4442 /* Godson integer instructions */
4443 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
4444 int rd, int rs, int rt)
4456 case OPC_MULTU_G_2E:
4457 case OPC_MULTU_G_2F:
4458 #if defined(TARGET_MIPS64)
4459 case OPC_DMULT_G_2E:
4460 case OPC_DMULT_G_2F:
4461 case OPC_DMULTU_G_2E:
4462 case OPC_DMULTU_G_2F:
4464 t0 = tcg_temp_new();
4465 t1 = tcg_temp_new();
4468 t0 = tcg_temp_local_new();
4469 t1 = tcg_temp_local_new();
4473 gen_load_gpr(t0, rs);
4474 gen_load_gpr(t1, rt);
4479 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4480 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4482 case OPC_MULTU_G_2E:
4483 case OPC_MULTU_G_2F:
4484 tcg_gen_ext32u_tl(t0, t0);
4485 tcg_gen_ext32u_tl(t1, t1);
4486 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4487 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4492 TCGLabel *l1 = gen_new_label();
4493 TCGLabel *l2 = gen_new_label();
4494 TCGLabel *l3 = gen_new_label();
4495 tcg_gen_ext32s_tl(t0, t0);
4496 tcg_gen_ext32s_tl(t1, t1);
4497 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4498 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4501 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4502 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4503 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4506 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4507 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4514 TCGLabel *l1 = gen_new_label();
4515 TCGLabel *l2 = gen_new_label();
4516 tcg_gen_ext32u_tl(t0, t0);
4517 tcg_gen_ext32u_tl(t1, t1);
4518 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4519 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4522 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4523 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4530 TCGLabel *l1 = gen_new_label();
4531 TCGLabel *l2 = gen_new_label();
4532 TCGLabel *l3 = gen_new_label();
4533 tcg_gen_ext32u_tl(t0, t0);
4534 tcg_gen_ext32u_tl(t1, t1);
4535 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4536 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4537 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4539 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4542 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4543 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4550 TCGLabel *l1 = gen_new_label();
4551 TCGLabel *l2 = gen_new_label();
4552 tcg_gen_ext32u_tl(t0, t0);
4553 tcg_gen_ext32u_tl(t1, t1);
4554 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4555 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4558 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4559 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4563 #if defined(TARGET_MIPS64)
4564 case OPC_DMULT_G_2E:
4565 case OPC_DMULT_G_2F:
4566 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4568 case OPC_DMULTU_G_2E:
4569 case OPC_DMULTU_G_2F:
4570 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4575 TCGLabel *l1 = gen_new_label();
4576 TCGLabel *l2 = gen_new_label();
4577 TCGLabel *l3 = gen_new_label();
4578 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4579 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4582 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4583 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4584 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4587 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4591 case OPC_DDIVU_G_2E:
4592 case OPC_DDIVU_G_2F:
4594 TCGLabel *l1 = gen_new_label();
4595 TCGLabel *l2 = gen_new_label();
4596 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4597 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4600 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4607 TCGLabel *l1 = gen_new_label();
4608 TCGLabel *l2 = gen_new_label();
4609 TCGLabel *l3 = gen_new_label();
4610 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4611 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4612 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4614 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4617 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4621 case OPC_DMODU_G_2E:
4622 case OPC_DMODU_G_2F:
4624 TCGLabel *l1 = gen_new_label();
4625 TCGLabel *l2 = gen_new_label();
4626 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4627 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4630 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4641 /* Loongson multimedia instructions */
4642 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4644 uint32_t opc, shift_max;
4647 opc = MASK_LMI(ctx->opcode);
4653 t0 = tcg_temp_local_new_i64();
4654 t1 = tcg_temp_local_new_i64();
4657 t0 = tcg_temp_new_i64();
4658 t1 = tcg_temp_new_i64();
4662 check_cp1_enabled(ctx);
4663 gen_load_fpr64(ctx, t0, rs);
4664 gen_load_fpr64(ctx, t1, rt);
4666 #define LMI_HELPER(UP, LO) \
4667 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
4668 #define LMI_HELPER_1(UP, LO) \
4669 case OPC_##UP: gen_helper_##LO(t0, t0); break
4670 #define LMI_DIRECT(UP, LO, OP) \
4671 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
4674 LMI_HELPER(PADDSH, paddsh);
4675 LMI_HELPER(PADDUSH, paddush);
4676 LMI_HELPER(PADDH, paddh);
4677 LMI_HELPER(PADDW, paddw);
4678 LMI_HELPER(PADDSB, paddsb);
4679 LMI_HELPER(PADDUSB, paddusb);
4680 LMI_HELPER(PADDB, paddb);
4682 LMI_HELPER(PSUBSH, psubsh);
4683 LMI_HELPER(PSUBUSH, psubush);
4684 LMI_HELPER(PSUBH, psubh);
4685 LMI_HELPER(PSUBW, psubw);
4686 LMI_HELPER(PSUBSB, psubsb);
4687 LMI_HELPER(PSUBUSB, psubusb);
4688 LMI_HELPER(PSUBB, psubb);
4690 LMI_HELPER(PSHUFH, pshufh);
4691 LMI_HELPER(PACKSSWH, packsswh);
4692 LMI_HELPER(PACKSSHB, packsshb);
4693 LMI_HELPER(PACKUSHB, packushb);
4695 LMI_HELPER(PUNPCKLHW, punpcklhw);
4696 LMI_HELPER(PUNPCKHHW, punpckhhw);
4697 LMI_HELPER(PUNPCKLBH, punpcklbh);
4698 LMI_HELPER(PUNPCKHBH, punpckhbh);
4699 LMI_HELPER(PUNPCKLWD, punpcklwd);
4700 LMI_HELPER(PUNPCKHWD, punpckhwd);
4702 LMI_HELPER(PAVGH, pavgh);
4703 LMI_HELPER(PAVGB, pavgb);
4704 LMI_HELPER(PMAXSH, pmaxsh);
4705 LMI_HELPER(PMINSH, pminsh);
4706 LMI_HELPER(PMAXUB, pmaxub);
4707 LMI_HELPER(PMINUB, pminub);
4709 LMI_HELPER(PCMPEQW, pcmpeqw);
4710 LMI_HELPER(PCMPGTW, pcmpgtw);
4711 LMI_HELPER(PCMPEQH, pcmpeqh);
4712 LMI_HELPER(PCMPGTH, pcmpgth);
4713 LMI_HELPER(PCMPEQB, pcmpeqb);
4714 LMI_HELPER(PCMPGTB, pcmpgtb);
4716 LMI_HELPER(PSLLW, psllw);
4717 LMI_HELPER(PSLLH, psllh);
4718 LMI_HELPER(PSRLW, psrlw);
4719 LMI_HELPER(PSRLH, psrlh);
4720 LMI_HELPER(PSRAW, psraw);
4721 LMI_HELPER(PSRAH, psrah);
4723 LMI_HELPER(PMULLH, pmullh);
4724 LMI_HELPER(PMULHH, pmulhh);
4725 LMI_HELPER(PMULHUH, pmulhuh);
4726 LMI_HELPER(PMADDHW, pmaddhw);
4728 LMI_HELPER(PASUBUB, pasubub);
4729 LMI_HELPER_1(BIADD, biadd);
4730 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4732 LMI_DIRECT(PADDD, paddd, add);
4733 LMI_DIRECT(PSUBD, psubd, sub);
4734 LMI_DIRECT(XOR_CP2, xor, xor);
4735 LMI_DIRECT(NOR_CP2, nor, nor);
4736 LMI_DIRECT(AND_CP2, and, and);
4737 LMI_DIRECT(OR_CP2, or, or);
4740 tcg_gen_andc_i64(t0, t1, t0);
4744 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4747 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4750 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4753 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4757 tcg_gen_andi_i64(t1, t1, 3);
4758 tcg_gen_shli_i64(t1, t1, 4);
4759 tcg_gen_shr_i64(t0, t0, t1);
4760 tcg_gen_ext16u_i64(t0, t0);
4764 tcg_gen_add_i64(t0, t0, t1);
4765 tcg_gen_ext32s_i64(t0, t0);
4768 tcg_gen_sub_i64(t0, t0, t1);
4769 tcg_gen_ext32s_i64(t0, t0);
4791 /* Make sure shift count isn't TCG undefined behaviour. */
4792 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4797 tcg_gen_shl_i64(t0, t0, t1);
4801 /* Since SRA is UndefinedResult without sign-extended inputs,
4802 we can treat SRA and DSRA the same. */
4803 tcg_gen_sar_i64(t0, t0, t1);
4806 /* We want to shift in zeros for SRL; zero-extend first. */
4807 tcg_gen_ext32u_i64(t0, t0);
4810 tcg_gen_shr_i64(t0, t0, t1);
4814 if (shift_max == 32) {
4815 tcg_gen_ext32s_i64(t0, t0);
4818 /* Shifts larger than MAX produce zero. */
4819 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4820 tcg_gen_neg_i64(t1, t1);
4821 tcg_gen_and_i64(t0, t0, t1);
4827 TCGv_i64 t2 = tcg_temp_new_i64();
4828 TCGLabel *lab = gen_new_label();
4830 tcg_gen_mov_i64(t2, t0);
4831 tcg_gen_add_i64(t0, t1, t2);
4832 if (opc == OPC_ADD_CP2) {
4833 tcg_gen_ext32s_i64(t0, t0);
4835 tcg_gen_xor_i64(t1, t1, t2);
4836 tcg_gen_xor_i64(t2, t2, t0);
4837 tcg_gen_andc_i64(t1, t2, t1);
4838 tcg_temp_free_i64(t2);
4839 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4840 generate_exception(ctx, EXCP_OVERFLOW);
4848 TCGv_i64 t2 = tcg_temp_new_i64();
4849 TCGLabel *lab = gen_new_label();
4851 tcg_gen_mov_i64(t2, t0);
4852 tcg_gen_sub_i64(t0, t1, t2);
4853 if (opc == OPC_SUB_CP2) {
4854 tcg_gen_ext32s_i64(t0, t0);
4856 tcg_gen_xor_i64(t1, t1, t2);
4857 tcg_gen_xor_i64(t2, t2, t0);
4858 tcg_gen_and_i64(t1, t1, t2);
4859 tcg_temp_free_i64(t2);
4860 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4861 generate_exception(ctx, EXCP_OVERFLOW);
4867 tcg_gen_ext32u_i64(t0, t0);
4868 tcg_gen_ext32u_i64(t1, t1);
4869 tcg_gen_mul_i64(t0, t0, t1);
4878 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4879 FD field is the CC field? */
4881 MIPS_INVAL("loongson_cp2");
4882 generate_exception_end(ctx, EXCP_RI);
4889 gen_store_fpr64(ctx, t0, rd);
4891 tcg_temp_free_i64(t0);
4892 tcg_temp_free_i64(t1);
4896 static void gen_trap (DisasContext *ctx, uint32_t opc,
4897 int rs, int rt, int16_t imm)
4900 TCGv t0 = tcg_temp_new();
4901 TCGv t1 = tcg_temp_new();
4904 /* Load needed operands */
4912 /* Compare two registers */
4914 gen_load_gpr(t0, rs);
4915 gen_load_gpr(t1, rt);
4925 /* Compare register to immediate */
4926 if (rs != 0 || imm != 0) {
4927 gen_load_gpr(t0, rs);
4928 tcg_gen_movi_tl(t1, (int32_t)imm);
4935 case OPC_TEQ: /* rs == rs */
4936 case OPC_TEQI: /* r0 == 0 */
4937 case OPC_TGE: /* rs >= rs */
4938 case OPC_TGEI: /* r0 >= 0 */
4939 case OPC_TGEU: /* rs >= rs unsigned */
4940 case OPC_TGEIU: /* r0 >= 0 unsigned */
4942 generate_exception_end(ctx, EXCP_TRAP);
4944 case OPC_TLT: /* rs < rs */
4945 case OPC_TLTI: /* r0 < 0 */
4946 case OPC_TLTU: /* rs < rs unsigned */
4947 case OPC_TLTIU: /* r0 < 0 unsigned */
4948 case OPC_TNE: /* rs != rs */
4949 case OPC_TNEI: /* r0 != 0 */
4950 /* Never trap: treat as NOP. */
4954 TCGLabel *l1 = gen_new_label();
4959 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4963 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4967 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4971 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4975 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4979 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4982 generate_exception(ctx, EXCP_TRAP);
4989 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4991 if (unlikely(ctx->base.singlestep_enabled)) {
4995 #ifndef CONFIG_USER_ONLY
4996 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5002 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5004 if (use_goto_tb(ctx, dest)) {
5007 tcg_gen_exit_tb(ctx->base.tb, n);
5010 if (ctx->base.singlestep_enabled) {
5011 save_cpu_state(ctx, 0);
5012 gen_helper_raise_exception_debug(cpu_env);
5014 tcg_gen_lookup_and_goto_ptr();
5018 /* Branches (before delay slot) */
5019 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5021 int rs, int rt, int32_t offset,
5024 target_ulong btgt = -1;
5026 int bcond_compute = 0;
5027 TCGv t0 = tcg_temp_new();
5028 TCGv t1 = tcg_temp_new();
5030 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5031 #ifdef MIPS_DEBUG_DISAS
5032 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5033 TARGET_FMT_lx "\n", ctx->base.pc_next);
5035 generate_exception_end(ctx, EXCP_RI);
5039 /* Load needed operands */
5045 /* Compare two registers */
5047 gen_load_gpr(t0, rs);
5048 gen_load_gpr(t1, rt);
5051 btgt = ctx->base.pc_next + insn_bytes + offset;
5065 /* Compare to zero */
5067 gen_load_gpr(t0, rs);
5070 btgt = ctx->base.pc_next + insn_bytes + offset;
5073 #if defined(TARGET_MIPS64)
5075 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5077 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5080 btgt = ctx->base.pc_next + insn_bytes + offset;
5085 /* Jump to immediate */
5086 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5091 /* Jump to register */
5092 if (offset != 0 && offset != 16) {
5093 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5094 others are reserved. */
5095 MIPS_INVAL("jump hint");
5096 generate_exception_end(ctx, EXCP_RI);
5099 gen_load_gpr(btarget, rs);
5102 MIPS_INVAL("branch/jump");
5103 generate_exception_end(ctx, EXCP_RI);
5106 if (bcond_compute == 0) {
5107 /* No condition to be computed */
5109 case OPC_BEQ: /* rx == rx */
5110 case OPC_BEQL: /* rx == rx likely */
5111 case OPC_BGEZ: /* 0 >= 0 */
5112 case OPC_BGEZL: /* 0 >= 0 likely */
5113 case OPC_BLEZ: /* 0 <= 0 */
5114 case OPC_BLEZL: /* 0 <= 0 likely */
5116 ctx->hflags |= MIPS_HFLAG_B;
5118 case OPC_BGEZAL: /* 0 >= 0 */
5119 case OPC_BGEZALL: /* 0 >= 0 likely */
5120 /* Always take and link */
5122 ctx->hflags |= MIPS_HFLAG_B;
5124 case OPC_BNE: /* rx != rx */
5125 case OPC_BGTZ: /* 0 > 0 */
5126 case OPC_BLTZ: /* 0 < 0 */
5129 case OPC_BLTZAL: /* 0 < 0 */
5130 /* Handle as an unconditional branch to get correct delay
5133 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5134 ctx->hflags |= MIPS_HFLAG_B;
5136 case OPC_BLTZALL: /* 0 < 0 likely */
5137 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5138 /* Skip the instruction in the delay slot */
5139 ctx->base.pc_next += 4;
5141 case OPC_BNEL: /* rx != rx likely */
5142 case OPC_BGTZL: /* 0 > 0 likely */
5143 case OPC_BLTZL: /* 0 < 0 likely */
5144 /* Skip the instruction in the delay slot */
5145 ctx->base.pc_next += 4;
5148 ctx->hflags |= MIPS_HFLAG_B;
5151 ctx->hflags |= MIPS_HFLAG_BX;
5155 ctx->hflags |= MIPS_HFLAG_B;
5158 ctx->hflags |= MIPS_HFLAG_BR;
5162 ctx->hflags |= MIPS_HFLAG_BR;
5165 MIPS_INVAL("branch/jump");
5166 generate_exception_end(ctx, EXCP_RI);
5172 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5175 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5178 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5181 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5184 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5187 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5190 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5194 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5198 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5201 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5204 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5207 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5210 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5213 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5216 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5218 #if defined(TARGET_MIPS64)
5220 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5224 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5227 ctx->hflags |= MIPS_HFLAG_BC;
5230 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5233 ctx->hflags |= MIPS_HFLAG_BL;
5236 MIPS_INVAL("conditional branch/jump");
5237 generate_exception_end(ctx, EXCP_RI);
5242 ctx->btarget = btgt;
5244 switch (delayslot_size) {
5246 ctx->hflags |= MIPS_HFLAG_BDS16;
5249 ctx->hflags |= MIPS_HFLAG_BDS32;
5254 int post_delay = insn_bytes + delayslot_size;
5255 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5257 tcg_gen_movi_tl(cpu_gpr[blink],
5258 ctx->base.pc_next + post_delay + lowbit);
5262 if (insn_bytes == 2)
5263 ctx->hflags |= MIPS_HFLAG_B16;
5269 /* nanoMIPS Branches */
5270 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5272 int rs, int rt, int32_t offset)
5274 target_ulong btgt = -1;
5275 int bcond_compute = 0;
5276 TCGv t0 = tcg_temp_new();
5277 TCGv t1 = tcg_temp_new();
5279 /* Load needed operands */
5283 /* Compare two registers */
5285 gen_load_gpr(t0, rs);
5286 gen_load_gpr(t1, rt);
5289 btgt = ctx->base.pc_next + insn_bytes + offset;
5292 /* Compare to zero */
5294 gen_load_gpr(t0, rs);
5297 btgt = ctx->base.pc_next + insn_bytes + offset;
5300 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5302 btgt = ctx->base.pc_next + insn_bytes + offset;
5306 /* Jump to register */
5307 if (offset != 0 && offset != 16) {
5308 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5309 others are reserved. */
5310 MIPS_INVAL("jump hint");
5311 generate_exception_end(ctx, EXCP_RI);
5314 gen_load_gpr(btarget, rs);
5317 MIPS_INVAL("branch/jump");
5318 generate_exception_end(ctx, EXCP_RI);
5321 if (bcond_compute == 0) {
5322 /* No condition to be computed */
5324 case OPC_BEQ: /* rx == rx */
5326 ctx->hflags |= MIPS_HFLAG_B;
5328 case OPC_BGEZAL: /* 0 >= 0 */
5329 /* Always take and link */
5330 tcg_gen_movi_tl(cpu_gpr[31],
5331 ctx->base.pc_next + insn_bytes);
5332 ctx->hflags |= MIPS_HFLAG_B;
5334 case OPC_BNE: /* rx != rx */
5335 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5336 /* Skip the instruction in the delay slot */
5337 ctx->base.pc_next += 4;
5340 ctx->hflags |= MIPS_HFLAG_BR;
5344 tcg_gen_movi_tl(cpu_gpr[rt],
5345 ctx->base.pc_next + insn_bytes);
5347 ctx->hflags |= MIPS_HFLAG_BR;
5350 MIPS_INVAL("branch/jump");
5351 generate_exception_end(ctx, EXCP_RI);
5357 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5360 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5363 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5364 tcg_gen_movi_tl(cpu_gpr[31],
5365 ctx->base.pc_next + insn_bytes);
5368 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5370 ctx->hflags |= MIPS_HFLAG_BC;
5373 MIPS_INVAL("conditional branch/jump");
5374 generate_exception_end(ctx, EXCP_RI);
5379 ctx->btarget = btgt;
5382 if (insn_bytes == 2) {
5383 ctx->hflags |= MIPS_HFLAG_B16;
5390 /* special3 bitfield operations */
5391 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
5392 int rs, int lsb, int msb)
5394 TCGv t0 = tcg_temp_new();
5395 TCGv t1 = tcg_temp_new();
5397 gen_load_gpr(t1, rs);
5400 if (lsb + msb > 31) {
5404 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5406 /* The two checks together imply that lsb == 0,
5407 so this is a simple sign-extension. */
5408 tcg_gen_ext32s_tl(t0, t1);
5411 #if defined(TARGET_MIPS64)
5420 if (lsb + msb > 63) {
5423 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5430 gen_load_gpr(t0, rt);
5431 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5432 tcg_gen_ext32s_tl(t0, t0);
5434 #if defined(TARGET_MIPS64)
5445 gen_load_gpr(t0, rt);
5446 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5451 MIPS_INVAL("bitops");
5452 generate_exception_end(ctx, EXCP_RI);
5457 gen_store_gpr(t0, rt);
5462 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
5467 /* If no destination, treat it as a NOP. */
5471 t0 = tcg_temp_new();
5472 gen_load_gpr(t0, rt);
5476 TCGv t1 = tcg_temp_new();
5477 TCGv t2 = tcg_const_tl(0x00FF00FF);
5479 tcg_gen_shri_tl(t1, t0, 8);
5480 tcg_gen_and_tl(t1, t1, t2);
5481 tcg_gen_and_tl(t0, t0, t2);
5482 tcg_gen_shli_tl(t0, t0, 8);
5483 tcg_gen_or_tl(t0, t0, t1);
5486 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5490 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5493 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5495 #if defined(TARGET_MIPS64)
5498 TCGv t1 = tcg_temp_new();
5499 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5501 tcg_gen_shri_tl(t1, t0, 8);
5502 tcg_gen_and_tl(t1, t1, t2);
5503 tcg_gen_and_tl(t0, t0, t2);
5504 tcg_gen_shli_tl(t0, t0, 8);
5505 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5512 TCGv t1 = tcg_temp_new();
5513 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5515 tcg_gen_shri_tl(t1, t0, 16);
5516 tcg_gen_and_tl(t1, t1, t2);
5517 tcg_gen_and_tl(t0, t0, t2);
5518 tcg_gen_shli_tl(t0, t0, 16);
5519 tcg_gen_or_tl(t0, t0, t1);
5520 tcg_gen_shri_tl(t1, t0, 32);
5521 tcg_gen_shli_tl(t0, t0, 32);
5522 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5529 MIPS_INVAL("bsfhl");
5530 generate_exception_end(ctx, EXCP_RI);
5537 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
5546 t0 = tcg_temp_new();
5547 t1 = tcg_temp_new();
5548 gen_load_gpr(t0, rs);
5549 gen_load_gpr(t1, rt);
5550 tcg_gen_shli_tl(t0, t0, imm2 + 1);
5551 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
5552 if (opc == OPC_LSA) {
5553 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5562 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5570 t0 = tcg_temp_new();
5571 if (bits == 0 || bits == wordsz) {
5573 gen_load_gpr(t0, rt);
5575 gen_load_gpr(t0, rs);
5579 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5581 #if defined(TARGET_MIPS64)
5583 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5588 TCGv t1 = tcg_temp_new();
5589 gen_load_gpr(t0, rt);
5590 gen_load_gpr(t1, rs);
5594 TCGv_i64 t2 = tcg_temp_new_i64();
5595 tcg_gen_concat_tl_i64(t2, t1, t0);
5596 tcg_gen_shri_i64(t2, t2, 32 - bits);
5597 gen_move_low32(cpu_gpr[rd], t2);
5598 tcg_temp_free_i64(t2);
5601 #if defined(TARGET_MIPS64)
5603 tcg_gen_shli_tl(t0, t0, bits);
5604 tcg_gen_shri_tl(t1, t1, 64 - bits);
5605 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5615 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5618 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5621 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5624 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
5627 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5634 t0 = tcg_temp_new();
5635 gen_load_gpr(t0, rt);
5638 gen_helper_bitswap(cpu_gpr[rd], t0);
5640 #if defined(TARGET_MIPS64)
5642 gen_helper_dbitswap(cpu_gpr[rd], t0);
5649 #ifndef CONFIG_USER_ONLY
5650 /* CP0 (MMU and control) */
5651 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5653 TCGv_i64 t0 = tcg_temp_new_i64();
5654 TCGv_i64 t1 = tcg_temp_new_i64();
5656 tcg_gen_ext_tl_i64(t0, arg);
5657 tcg_gen_ld_i64(t1, cpu_env, off);
5658 #if defined(TARGET_MIPS64)
5659 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5661 tcg_gen_concat32_i64(t1, t1, t0);
5663 tcg_gen_st_i64(t1, cpu_env, off);
5664 tcg_temp_free_i64(t1);
5665 tcg_temp_free_i64(t0);
5668 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5670 TCGv_i64 t0 = tcg_temp_new_i64();
5671 TCGv_i64 t1 = tcg_temp_new_i64();
5673 tcg_gen_ext_tl_i64(t0, arg);
5674 tcg_gen_ld_i64(t1, cpu_env, off);
5675 tcg_gen_concat32_i64(t1, t1, t0);
5676 tcg_gen_st_i64(t1, cpu_env, off);
5677 tcg_temp_free_i64(t1);
5678 tcg_temp_free_i64(t0);
5681 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5683 TCGv_i64 t0 = tcg_temp_new_i64();
5685 tcg_gen_ld_i64(t0, cpu_env, off);
5686 #if defined(TARGET_MIPS64)
5687 tcg_gen_shri_i64(t0, t0, 30);
5689 tcg_gen_shri_i64(t0, t0, 32);
5691 gen_move_low32(arg, t0);
5692 tcg_temp_free_i64(t0);
5695 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5697 TCGv_i64 t0 = tcg_temp_new_i64();
5699 tcg_gen_ld_i64(t0, cpu_env, off);
5700 tcg_gen_shri_i64(t0, t0, 32 + shift);
5701 gen_move_low32(arg, t0);
5702 tcg_temp_free_i64(t0);
5705 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
5707 TCGv_i32 t0 = tcg_temp_new_i32();
5709 tcg_gen_ld_i32(t0, cpu_env, off);
5710 tcg_gen_ext_i32_tl(arg, t0);
5711 tcg_temp_free_i32(t0);
5714 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
5716 tcg_gen_ld_tl(arg, cpu_env, off);
5717 tcg_gen_ext32s_tl(arg, arg);
5720 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
5722 TCGv_i32 t0 = tcg_temp_new_i32();
5724 tcg_gen_trunc_tl_i32(t0, arg);
5725 tcg_gen_st_i32(t0, cpu_env, off);
5726 tcg_temp_free_i32(t0);
5729 #define CP0_CHECK(c) \
5732 goto cp0_unimplemented; \
5736 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5738 const char *rn = "invalid";
5744 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5745 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5749 goto cp0_unimplemented;
5755 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5756 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5760 goto cp0_unimplemented;
5766 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
5767 ctx->CP0_LLAddr_shift);
5771 CP0_CHECK(ctx->mrp);
5772 gen_helper_mfhc0_maar(arg, cpu_env);
5776 goto cp0_unimplemented;
5785 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5789 goto cp0_unimplemented;
5793 goto cp0_unimplemented;
5795 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5799 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5800 tcg_gen_movi_tl(arg, 0);
5803 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5805 const char *rn = "invalid";
5806 uint64_t mask = ctx->PAMask >> 36;
5812 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5813 tcg_gen_andi_tl(arg, arg, mask);
5814 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5818 goto cp0_unimplemented;
5824 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5825 tcg_gen_andi_tl(arg, arg, mask);
5826 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5830 goto cp0_unimplemented;
5836 /* LLAddr is read-only (the only exception is bit 0 if LLB is
5837 supported); the CP0_LLAddr_rw_bitmask does not seem to be
5838 relevant for modern MIPS cores supporting MTHC0, therefore
5839 treating MTHC0 to LLAddr as NOP. */
5843 CP0_CHECK(ctx->mrp);
5844 gen_helper_mthc0_maar(cpu_env, arg);
5848 goto cp0_unimplemented;
5857 tcg_gen_andi_tl(arg, arg, mask);
5858 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5862 goto cp0_unimplemented;
5866 goto cp0_unimplemented;
5868 trace_mips_translate_c0("mthc0", rn, reg, sel);
5871 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5874 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5876 if (ctx->insn_flags & ISA_MIPS32R6) {
5877 tcg_gen_movi_tl(arg, 0);
5879 tcg_gen_movi_tl(arg, ~0);
5883 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5885 const char *rn = "invalid";
5888 check_insn(ctx, ISA_MIPS32);
5894 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5898 CP0_CHECK(ctx->insn_flags & ASE_MT);
5899 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5903 CP0_CHECK(ctx->insn_flags & ASE_MT);
5904 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5908 CP0_CHECK(ctx->insn_flags & ASE_MT);
5909 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5918 goto cp0_unimplemented;
5924 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5925 gen_helper_mfc0_random(arg, cpu_env);
5929 CP0_CHECK(ctx->insn_flags & ASE_MT);
5930 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5934 CP0_CHECK(ctx->insn_flags & ASE_MT);
5935 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5939 CP0_CHECK(ctx->insn_flags & ASE_MT);
5940 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5944 CP0_CHECK(ctx->insn_flags & ASE_MT);
5945 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5949 CP0_CHECK(ctx->insn_flags & ASE_MT);
5950 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5954 CP0_CHECK(ctx->insn_flags & ASE_MT);
5955 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5956 rn = "VPEScheFBack";
5959 CP0_CHECK(ctx->insn_flags & ASE_MT);
5960 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5964 goto cp0_unimplemented;
5971 TCGv_i64 tmp = tcg_temp_new_i64();
5972 tcg_gen_ld_i64(tmp, cpu_env,
5973 offsetof(CPUMIPSState, CP0_EntryLo0));
5974 #if defined(TARGET_MIPS64)
5976 /* Move RI/XI fields to bits 31:30 */
5977 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5978 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5981 gen_move_low32(arg, tmp);
5982 tcg_temp_free_i64(tmp);
5987 CP0_CHECK(ctx->insn_flags & ASE_MT);
5988 gen_helper_mfc0_tcstatus(arg, cpu_env);
5992 CP0_CHECK(ctx->insn_flags & ASE_MT);
5993 gen_helper_mfc0_tcbind(arg, cpu_env);
5997 CP0_CHECK(ctx->insn_flags & ASE_MT);
5998 gen_helper_mfc0_tcrestart(arg, cpu_env);
6002 CP0_CHECK(ctx->insn_flags & ASE_MT);
6003 gen_helper_mfc0_tchalt(arg, cpu_env);
6007 CP0_CHECK(ctx->insn_flags & ASE_MT);
6008 gen_helper_mfc0_tccontext(arg, cpu_env);
6012 CP0_CHECK(ctx->insn_flags & ASE_MT);
6013 gen_helper_mfc0_tcschedule(arg, cpu_env);
6017 CP0_CHECK(ctx->insn_flags & ASE_MT);
6018 gen_helper_mfc0_tcschefback(arg, cpu_env);
6022 goto cp0_unimplemented;
6029 TCGv_i64 tmp = tcg_temp_new_i64();
6030 tcg_gen_ld_i64(tmp, cpu_env,
6031 offsetof(CPUMIPSState, CP0_EntryLo1));
6032 #if defined(TARGET_MIPS64)
6034 /* Move RI/XI fields to bits 31:30 */
6035 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6036 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6039 gen_move_low32(arg, tmp);
6040 tcg_temp_free_i64(tmp);
6046 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6047 rn = "GlobalNumber";
6050 goto cp0_unimplemented;
6056 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6057 tcg_gen_ext32s_tl(arg, arg);
6061 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6062 rn = "ContextConfig";
6063 goto cp0_unimplemented;
6065 CP0_CHECK(ctx->ulri);
6066 tcg_gen_ld_tl(arg, cpu_env,
6067 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6068 tcg_gen_ext32s_tl(arg, arg);
6072 goto cp0_unimplemented;
6078 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6082 check_insn(ctx, ISA_MIPS32R2);
6083 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6088 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6089 tcg_gen_ext32s_tl(arg, arg);
6094 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6095 tcg_gen_ext32s_tl(arg, arg);
6100 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6101 tcg_gen_ext32s_tl(arg, arg);
6106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6120 goto cp0_unimplemented;
6126 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6130 check_insn(ctx, ISA_MIPS32R2);
6131 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6135 check_insn(ctx, ISA_MIPS32R2);
6136 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6140 check_insn(ctx, ISA_MIPS32R2);
6141 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6145 check_insn(ctx, ISA_MIPS32R2);
6146 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6150 check_insn(ctx, ISA_MIPS32R2);
6151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6156 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6160 goto cp0_unimplemented;
6166 check_insn(ctx, ISA_MIPS32R2);
6167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6171 goto cp0_unimplemented;
6177 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6178 tcg_gen_ext32s_tl(arg, arg);
6183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6188 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6193 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6194 tcg_gen_andi_tl(arg, arg, ~0xffff);
6198 goto cp0_unimplemented;
6204 /* Mark as an IO operation because we read the time. */
6205 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6208 gen_helper_mfc0_count(arg, cpu_env);
6209 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6212 /* Break the TB to be able to take timer interrupts immediately
6213 after reading count. DISAS_STOP isn't sufficient, we need to
6214 ensure we break completely out of translated code. */
6215 gen_save_pc(ctx->base.pc_next + 4);
6216 ctx->base.is_jmp = DISAS_EXIT;
6219 /* 6,7 are implementation dependent */
6221 goto cp0_unimplemented;
6227 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6228 tcg_gen_ext32s_tl(arg, arg);
6232 goto cp0_unimplemented;
6238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6241 /* 6,7 are implementation dependent */
6243 goto cp0_unimplemented;
6249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6253 check_insn(ctx, ISA_MIPS32R2);
6254 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6258 check_insn(ctx, ISA_MIPS32R2);
6259 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6263 check_insn(ctx, ISA_MIPS32R2);
6264 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6268 goto cp0_unimplemented;
6274 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6278 goto cp0_unimplemented;
6284 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6285 tcg_gen_ext32s_tl(arg, arg);
6289 goto cp0_unimplemented;
6295 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6299 check_insn(ctx, ISA_MIPS32R2);
6300 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6301 tcg_gen_ext32s_tl(arg, arg);
6305 check_insn(ctx, ISA_MIPS32R2);
6306 CP0_CHECK(ctx->cmgcr);
6307 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6308 tcg_gen_ext32s_tl(arg, arg);
6312 goto cp0_unimplemented;
6318 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6322 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6326 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6338 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6341 /* 6,7 are implementation dependent */
6343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6351 goto cp0_unimplemented;
6357 gen_helper_mfc0_lladdr(arg, cpu_env);
6361 CP0_CHECK(ctx->mrp);
6362 gen_helper_mfc0_maar(arg, cpu_env);
6366 CP0_CHECK(ctx->mrp);
6367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6371 goto cp0_unimplemented;
6384 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6385 gen_helper_1e0i(mfc0_watchlo, arg, sel);
6389 goto cp0_unimplemented;
6402 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6403 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6407 goto cp0_unimplemented;
6413 #if defined(TARGET_MIPS64)
6414 check_insn(ctx, ISA_MIPS3);
6415 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6416 tcg_gen_ext32s_tl(arg, arg);
6421 goto cp0_unimplemented;
6425 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6426 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6433 goto cp0_unimplemented;
6437 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6438 rn = "'Diagnostic"; /* implementation dependent */
6443 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6447 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
6448 rn = "TraceControl";
6449 goto cp0_unimplemented;
6451 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
6452 rn = "TraceControl2";
6453 goto cp0_unimplemented;
6455 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
6456 rn = "UserTraceData";
6457 goto cp0_unimplemented;
6459 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
6461 goto cp0_unimplemented;
6463 goto cp0_unimplemented;
6470 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6471 tcg_gen_ext32s_tl(arg, arg);
6475 goto cp0_unimplemented;
6481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6482 rn = "Performance0";
6485 // gen_helper_mfc0_performance1(arg);
6486 rn = "Performance1";
6487 goto cp0_unimplemented;
6489 // gen_helper_mfc0_performance2(arg);
6490 rn = "Performance2";
6491 goto cp0_unimplemented;
6493 // gen_helper_mfc0_performance3(arg);
6494 rn = "Performance3";
6495 goto cp0_unimplemented;
6497 // gen_helper_mfc0_performance4(arg);
6498 rn = "Performance4";
6499 goto cp0_unimplemented;
6501 // gen_helper_mfc0_performance5(arg);
6502 rn = "Performance5";
6503 goto cp0_unimplemented;
6505 // gen_helper_mfc0_performance6(arg);
6506 rn = "Performance6";
6507 goto cp0_unimplemented;
6509 // gen_helper_mfc0_performance7(arg);
6510 rn = "Performance7";
6511 goto cp0_unimplemented;
6513 goto cp0_unimplemented;
6519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6523 goto cp0_unimplemented;
6532 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6536 goto cp0_unimplemented;
6546 TCGv_i64 tmp = tcg_temp_new_i64();
6547 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6548 gen_move_low32(arg, tmp);
6549 tcg_temp_free_i64(tmp);
6557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6561 goto cp0_unimplemented;
6570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6577 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6581 goto cp0_unimplemented;
6587 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6588 tcg_gen_ext32s_tl(arg, arg);
6592 goto cp0_unimplemented;
6599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6608 CP0_CHECK(ctx->kscrexist & (1 << sel));
6609 tcg_gen_ld_tl(arg, cpu_env,
6610 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6611 tcg_gen_ext32s_tl(arg, arg);
6615 goto cp0_unimplemented;
6619 goto cp0_unimplemented;
6621 trace_mips_translate_c0("mfc0", rn, reg, sel);
6625 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6626 gen_mfc0_unimplemented(ctx, arg);
6629 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6631 const char *rn = "invalid";
6634 check_insn(ctx, ISA_MIPS32);
6636 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6644 gen_helper_mtc0_index(cpu_env, arg);
6648 CP0_CHECK(ctx->insn_flags & ASE_MT);
6649 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6653 CP0_CHECK(ctx->insn_flags & ASE_MT);
6658 CP0_CHECK(ctx->insn_flags & ASE_MT);
6668 goto cp0_unimplemented;
6678 CP0_CHECK(ctx->insn_flags & ASE_MT);
6679 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6683 CP0_CHECK(ctx->insn_flags & ASE_MT);
6684 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6688 CP0_CHECK(ctx->insn_flags & ASE_MT);
6689 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6693 CP0_CHECK(ctx->insn_flags & ASE_MT);
6694 gen_helper_mtc0_yqmask(cpu_env, arg);
6698 CP0_CHECK(ctx->insn_flags & ASE_MT);
6699 tcg_gen_st_tl(arg, cpu_env,
6700 offsetof(CPUMIPSState, CP0_VPESchedule));
6704 CP0_CHECK(ctx->insn_flags & ASE_MT);
6705 tcg_gen_st_tl(arg, cpu_env,
6706 offsetof(CPUMIPSState, CP0_VPEScheFBack));
6707 rn = "VPEScheFBack";
6710 CP0_CHECK(ctx->insn_flags & ASE_MT);
6711 gen_helper_mtc0_vpeopt(cpu_env, arg);
6715 goto cp0_unimplemented;
6721 gen_helper_mtc0_entrylo0(cpu_env, arg);
6725 CP0_CHECK(ctx->insn_flags & ASE_MT);
6726 gen_helper_mtc0_tcstatus(cpu_env, arg);
6730 CP0_CHECK(ctx->insn_flags & ASE_MT);
6731 gen_helper_mtc0_tcbind(cpu_env, arg);
6735 CP0_CHECK(ctx->insn_flags & ASE_MT);
6736 gen_helper_mtc0_tcrestart(cpu_env, arg);
6740 CP0_CHECK(ctx->insn_flags & ASE_MT);
6741 gen_helper_mtc0_tchalt(cpu_env, arg);
6745 CP0_CHECK(ctx->insn_flags & ASE_MT);
6746 gen_helper_mtc0_tccontext(cpu_env, arg);
6750 CP0_CHECK(ctx->insn_flags & ASE_MT);
6751 gen_helper_mtc0_tcschedule(cpu_env, arg);
6755 CP0_CHECK(ctx->insn_flags & ASE_MT);
6756 gen_helper_mtc0_tcschefback(cpu_env, arg);
6760 goto cp0_unimplemented;
6766 gen_helper_mtc0_entrylo1(cpu_env, arg);
6772 rn = "GlobalNumber";
6775 goto cp0_unimplemented;
6781 gen_helper_mtc0_context(cpu_env, arg);
6785 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6786 rn = "ContextConfig";
6787 goto cp0_unimplemented;
6789 CP0_CHECK(ctx->ulri);
6790 tcg_gen_st_tl(arg, cpu_env,
6791 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6795 goto cp0_unimplemented;
6801 gen_helper_mtc0_pagemask(cpu_env, arg);
6805 check_insn(ctx, ISA_MIPS32R2);
6806 gen_helper_mtc0_pagegrain(cpu_env, arg);
6808 ctx->base.is_jmp = DISAS_STOP;
6812 gen_helper_mtc0_segctl0(cpu_env, arg);
6817 gen_helper_mtc0_segctl1(cpu_env, arg);
6822 gen_helper_mtc0_segctl2(cpu_env, arg);
6827 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6832 gen_helper_mtc0_pwfield(cpu_env, arg);
6837 gen_helper_mtc0_pwsize(cpu_env, arg);
6841 goto cp0_unimplemented;
6847 gen_helper_mtc0_wired(cpu_env, arg);
6851 check_insn(ctx, ISA_MIPS32R2);
6852 gen_helper_mtc0_srsconf0(cpu_env, arg);
6856 check_insn(ctx, ISA_MIPS32R2);
6857 gen_helper_mtc0_srsconf1(cpu_env, arg);
6861 check_insn(ctx, ISA_MIPS32R2);
6862 gen_helper_mtc0_srsconf2(cpu_env, arg);
6866 check_insn(ctx, ISA_MIPS32R2);
6867 gen_helper_mtc0_srsconf3(cpu_env, arg);
6871 check_insn(ctx, ISA_MIPS32R2);
6872 gen_helper_mtc0_srsconf4(cpu_env, arg);
6877 gen_helper_mtc0_pwctl(cpu_env, arg);
6881 goto cp0_unimplemented;
6887 check_insn(ctx, ISA_MIPS32R2);
6888 gen_helper_mtc0_hwrena(cpu_env, arg);
6889 ctx->base.is_jmp = DISAS_STOP;
6893 goto cp0_unimplemented;
6915 goto cp0_unimplemented;
6921 gen_helper_mtc0_count(cpu_env, arg);
6924 /* 6,7 are implementation dependent */
6926 goto cp0_unimplemented;
6932 gen_helper_mtc0_entryhi(cpu_env, arg);
6936 goto cp0_unimplemented;
6942 gen_helper_mtc0_compare(cpu_env, arg);
6945 /* 6,7 are implementation dependent */
6947 goto cp0_unimplemented;
6953 save_cpu_state(ctx, 1);
6954 gen_helper_mtc0_status(cpu_env, arg);
6955 /* DISAS_STOP isn't good enough here, hflags may have changed. */
6956 gen_save_pc(ctx->base.pc_next + 4);
6957 ctx->base.is_jmp = DISAS_EXIT;
6961 check_insn(ctx, ISA_MIPS32R2);
6962 gen_helper_mtc0_intctl(cpu_env, arg);
6963 /* Stop translation as we may have switched the execution mode */
6964 ctx->base.is_jmp = DISAS_STOP;
6968 check_insn(ctx, ISA_MIPS32R2);
6969 gen_helper_mtc0_srsctl(cpu_env, arg);
6970 /* Stop translation as we may have switched the execution mode */
6971 ctx->base.is_jmp = DISAS_STOP;
6975 check_insn(ctx, ISA_MIPS32R2);
6976 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6977 /* Stop translation as we may have switched the execution mode */
6978 ctx->base.is_jmp = DISAS_STOP;
6982 goto cp0_unimplemented;
6988 save_cpu_state(ctx, 1);
6989 gen_helper_mtc0_cause(cpu_env, arg);
6990 /* Stop translation as we may have triggered an interrupt.
6991 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6992 * translated code to check for pending interrupts. */
6993 gen_save_pc(ctx->base.pc_next + 4);
6994 ctx->base.is_jmp = DISAS_EXIT;
6998 goto cp0_unimplemented;
7004 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7008 goto cp0_unimplemented;
7018 check_insn(ctx, ISA_MIPS32R2);
7019 gen_helper_mtc0_ebase(cpu_env, arg);
7023 goto cp0_unimplemented;
7029 gen_helper_mtc0_config0(cpu_env, arg);
7031 /* Stop translation as we may have switched the execution mode */
7032 ctx->base.is_jmp = DISAS_STOP;
7035 /* ignored, read only */
7039 gen_helper_mtc0_config2(cpu_env, arg);
7041 /* Stop translation as we may have switched the execution mode */
7042 ctx->base.is_jmp = DISAS_STOP;
7045 gen_helper_mtc0_config3(cpu_env, arg);
7047 /* Stop translation as we may have switched the execution mode */
7048 ctx->base.is_jmp = DISAS_STOP;
7051 gen_helper_mtc0_config4(cpu_env, arg);
7053 ctx->base.is_jmp = DISAS_STOP;
7056 gen_helper_mtc0_config5(cpu_env, arg);
7058 /* Stop translation as we may have switched the execution mode */
7059 ctx->base.is_jmp = DISAS_STOP;
7061 /* 6,7 are implementation dependent */
7071 rn = "Invalid config selector";
7072 goto cp0_unimplemented;
7078 gen_helper_mtc0_lladdr(cpu_env, arg);
7082 CP0_CHECK(ctx->mrp);
7083 gen_helper_mtc0_maar(cpu_env, arg);
7087 CP0_CHECK(ctx->mrp);
7088 gen_helper_mtc0_maari(cpu_env, arg);
7092 goto cp0_unimplemented;
7105 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7106 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7110 goto cp0_unimplemented;
7123 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7124 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7128 goto cp0_unimplemented;
7134 #if defined(TARGET_MIPS64)
7135 check_insn(ctx, ISA_MIPS3);
7136 gen_helper_mtc0_xcontext(cpu_env, arg);
7141 goto cp0_unimplemented;
7145 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7146 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7149 gen_helper_mtc0_framemask(cpu_env, arg);
7153 goto cp0_unimplemented;
7158 rn = "Diagnostic"; /* implementation dependent */
7163 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7164 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7165 gen_save_pc(ctx->base.pc_next + 4);
7166 ctx->base.is_jmp = DISAS_EXIT;
7170 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7171 rn = "TraceControl";
7172 /* Stop translation as we may have switched the execution mode */
7173 ctx->base.is_jmp = DISAS_STOP;
7174 goto cp0_unimplemented;
7176 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7177 rn = "TraceControl2";
7178 /* Stop translation as we may have switched the execution mode */
7179 ctx->base.is_jmp = DISAS_STOP;
7180 goto cp0_unimplemented;
7182 /* Stop translation as we may have switched the execution mode */
7183 ctx->base.is_jmp = DISAS_STOP;
7184 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7185 rn = "UserTraceData";
7186 /* Stop translation as we may have switched the execution mode */
7187 ctx->base.is_jmp = DISAS_STOP;
7188 goto cp0_unimplemented;
7190 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7191 /* Stop translation as we may have switched the execution mode */
7192 ctx->base.is_jmp = DISAS_STOP;
7194 goto cp0_unimplemented;
7196 goto cp0_unimplemented;
7203 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7207 goto cp0_unimplemented;
7213 gen_helper_mtc0_performance0(cpu_env, arg);
7214 rn = "Performance0";
7217 // gen_helper_mtc0_performance1(arg);
7218 rn = "Performance1";
7219 goto cp0_unimplemented;
7221 // gen_helper_mtc0_performance2(arg);
7222 rn = "Performance2";
7223 goto cp0_unimplemented;
7225 // gen_helper_mtc0_performance3(arg);
7226 rn = "Performance3";
7227 goto cp0_unimplemented;
7229 // gen_helper_mtc0_performance4(arg);
7230 rn = "Performance4";
7231 goto cp0_unimplemented;
7233 // gen_helper_mtc0_performance5(arg);
7234 rn = "Performance5";
7235 goto cp0_unimplemented;
7237 // gen_helper_mtc0_performance6(arg);
7238 rn = "Performance6";
7239 goto cp0_unimplemented;
7241 // gen_helper_mtc0_performance7(arg);
7242 rn = "Performance7";
7243 goto cp0_unimplemented;
7245 goto cp0_unimplemented;
7251 gen_helper_mtc0_errctl(cpu_env, arg);
7252 ctx->base.is_jmp = DISAS_STOP;
7256 goto cp0_unimplemented;
7269 goto cp0_unimplemented;
7278 gen_helper_mtc0_taglo(cpu_env, arg);
7285 gen_helper_mtc0_datalo(cpu_env, arg);
7289 goto cp0_unimplemented;
7298 gen_helper_mtc0_taghi(cpu_env, arg);
7305 gen_helper_mtc0_datahi(cpu_env, arg);
7310 goto cp0_unimplemented;
7316 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7320 goto cp0_unimplemented;
7327 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7336 CP0_CHECK(ctx->kscrexist & (1 << sel));
7337 tcg_gen_st_tl(arg, cpu_env,
7338 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7342 goto cp0_unimplemented;
7346 goto cp0_unimplemented;
7348 trace_mips_translate_c0("mtc0", rn, reg, sel);
7350 /* For simplicity assume that all writes can cause interrupts. */
7351 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7353 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
7354 * translated code to check for pending interrupts. */
7355 gen_save_pc(ctx->base.pc_next + 4);
7356 ctx->base.is_jmp = DISAS_EXIT;
7361 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7364 #if defined(TARGET_MIPS64)
7365 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7367 const char *rn = "invalid";
7370 check_insn(ctx, ISA_MIPS64);
7376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7380 CP0_CHECK(ctx->insn_flags & ASE_MT);
7381 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7385 CP0_CHECK(ctx->insn_flags & ASE_MT);
7386 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7390 CP0_CHECK(ctx->insn_flags & ASE_MT);
7391 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7396 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7400 goto cp0_unimplemented;
7406 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7407 gen_helper_mfc0_random(arg, cpu_env);
7411 CP0_CHECK(ctx->insn_flags & ASE_MT);
7412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7416 CP0_CHECK(ctx->insn_flags & ASE_MT);
7417 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7421 CP0_CHECK(ctx->insn_flags & ASE_MT);
7422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7426 CP0_CHECK(ctx->insn_flags & ASE_MT);
7427 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
7431 CP0_CHECK(ctx->insn_flags & ASE_MT);
7432 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7436 CP0_CHECK(ctx->insn_flags & ASE_MT);
7437 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7438 rn = "VPEScheFBack";
7441 CP0_CHECK(ctx->insn_flags & ASE_MT);
7442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7446 goto cp0_unimplemented;
7452 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7456 CP0_CHECK(ctx->insn_flags & ASE_MT);
7457 gen_helper_mfc0_tcstatus(arg, cpu_env);
7461 CP0_CHECK(ctx->insn_flags & ASE_MT);
7462 gen_helper_mfc0_tcbind(arg, cpu_env);
7466 CP0_CHECK(ctx->insn_flags & ASE_MT);
7467 gen_helper_dmfc0_tcrestart(arg, cpu_env);
7471 CP0_CHECK(ctx->insn_flags & ASE_MT);
7472 gen_helper_dmfc0_tchalt(arg, cpu_env);
7476 CP0_CHECK(ctx->insn_flags & ASE_MT);
7477 gen_helper_dmfc0_tccontext(arg, cpu_env);
7481 CP0_CHECK(ctx->insn_flags & ASE_MT);
7482 gen_helper_dmfc0_tcschedule(arg, cpu_env);
7486 CP0_CHECK(ctx->insn_flags & ASE_MT);
7487 gen_helper_dmfc0_tcschefback(arg, cpu_env);
7491 goto cp0_unimplemented;
7497 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7503 rn = "GlobalNumber";
7506 goto cp0_unimplemented;
7512 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7516 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
7517 rn = "ContextConfig";
7518 goto cp0_unimplemented;
7520 CP0_CHECK(ctx->ulri);
7521 tcg_gen_ld_tl(arg, cpu_env,
7522 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7526 goto cp0_unimplemented;
7532 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7536 check_insn(ctx, ISA_MIPS32R2);
7537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7542 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7547 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7552 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7557 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7562 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7567 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7571 goto cp0_unimplemented;
7577 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7581 check_insn(ctx, ISA_MIPS32R2);
7582 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7586 check_insn(ctx, ISA_MIPS32R2);
7587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7591 check_insn(ctx, ISA_MIPS32R2);
7592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7596 check_insn(ctx, ISA_MIPS32R2);
7597 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7601 check_insn(ctx, ISA_MIPS32R2);
7602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7611 goto cp0_unimplemented;
7617 check_insn(ctx, ISA_MIPS32R2);
7618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7622 goto cp0_unimplemented;
7628 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7633 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7643 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7644 tcg_gen_andi_tl(arg, arg, ~0xffff);
7648 goto cp0_unimplemented;
7654 /* Mark as an IO operation because we read the time. */
7655 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7658 gen_helper_mfc0_count(arg, cpu_env);
7659 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7662 /* Break the TB to be able to take timer interrupts immediately
7663 after reading count. DISAS_STOP isn't sufficient, we need to
7664 ensure we break completely out of translated code. */
7665 gen_save_pc(ctx->base.pc_next + 4);
7666 ctx->base.is_jmp = DISAS_EXIT;
7669 /* 6,7 are implementation dependent */
7671 goto cp0_unimplemented;
7677 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7681 goto cp0_unimplemented;
7687 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7690 /* 6,7 are implementation dependent */
7692 goto cp0_unimplemented;
7698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7702 check_insn(ctx, ISA_MIPS32R2);
7703 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7707 check_insn(ctx, ISA_MIPS32R2);
7708 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7712 check_insn(ctx, ISA_MIPS32R2);
7713 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7717 goto cp0_unimplemented;
7723 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7727 goto cp0_unimplemented;
7733 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7737 goto cp0_unimplemented;
7743 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7747 check_insn(ctx, ISA_MIPS32R2);
7748 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7752 check_insn(ctx, ISA_MIPS32R2);
7753 CP0_CHECK(ctx->cmgcr);
7754 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7758 goto cp0_unimplemented;
7764 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7772 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7776 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7780 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7784 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7787 /* 6,7 are implementation dependent */
7789 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7793 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7797 goto cp0_unimplemented;
7803 gen_helper_dmfc0_lladdr(arg, cpu_env);
7807 CP0_CHECK(ctx->mrp);
7808 gen_helper_dmfc0_maar(arg, cpu_env);
7812 CP0_CHECK(ctx->mrp);
7813 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7817 goto cp0_unimplemented;
7830 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7831 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7835 goto cp0_unimplemented;
7848 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7849 gen_helper_1e0i(mfc0_watchhi, arg, sel);
7853 goto cp0_unimplemented;
7859 check_insn(ctx, ISA_MIPS3);
7860 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7864 goto cp0_unimplemented;
7868 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7869 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7872 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7876 goto cp0_unimplemented;
7880 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7881 rn = "'Diagnostic"; /* implementation dependent */
7886 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7890 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
7891 rn = "TraceControl";
7892 goto cp0_unimplemented;
7894 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
7895 rn = "TraceControl2";
7896 goto cp0_unimplemented;
7898 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
7899 rn = "UserTraceData";
7900 goto cp0_unimplemented;
7902 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
7904 goto cp0_unimplemented;
7906 goto cp0_unimplemented;
7913 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7917 goto cp0_unimplemented;
7923 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7924 rn = "Performance0";
7927 // gen_helper_dmfc0_performance1(arg);
7928 rn = "Performance1";
7929 goto cp0_unimplemented;
7931 // gen_helper_dmfc0_performance2(arg);
7932 rn = "Performance2";
7933 goto cp0_unimplemented;
7935 // gen_helper_dmfc0_performance3(arg);
7936 rn = "Performance3";
7937 goto cp0_unimplemented;
7939 // gen_helper_dmfc0_performance4(arg);
7940 rn = "Performance4";
7941 goto cp0_unimplemented;
7943 // gen_helper_dmfc0_performance5(arg);
7944 rn = "Performance5";
7945 goto cp0_unimplemented;
7947 // gen_helper_dmfc0_performance6(arg);
7948 rn = "Performance6";
7949 goto cp0_unimplemented;
7951 // gen_helper_dmfc0_performance7(arg);
7952 rn = "Performance7";
7953 goto cp0_unimplemented;
7955 goto cp0_unimplemented;
7961 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7965 goto cp0_unimplemented;
7975 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7979 goto cp0_unimplemented;
7988 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7995 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7999 goto cp0_unimplemented;
8008 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8015 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8019 goto cp0_unimplemented;
8025 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8029 goto cp0_unimplemented;
8036 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8045 CP0_CHECK(ctx->kscrexist & (1 << sel));
8046 tcg_gen_ld_tl(arg, cpu_env,
8047 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8051 goto cp0_unimplemented;
8055 goto cp0_unimplemented;
8057 trace_mips_translate_c0("dmfc0", rn, reg, sel);
8061 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
8062 gen_mfc0_unimplemented(ctx, arg);
8065 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8067 const char *rn = "invalid";
8070 check_insn(ctx, ISA_MIPS64);
8072 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8080 gen_helper_mtc0_index(cpu_env, arg);
8084 CP0_CHECK(ctx->insn_flags & ASE_MT);
8085 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8089 CP0_CHECK(ctx->insn_flags & ASE_MT);
8094 CP0_CHECK(ctx->insn_flags & ASE_MT);
8104 goto cp0_unimplemented;
8114 CP0_CHECK(ctx->insn_flags & ASE_MT);
8115 gen_helper_mtc0_vpecontrol(cpu_env, arg);
8119 CP0_CHECK(ctx->insn_flags & ASE_MT);
8120 gen_helper_mtc0_vpeconf0(cpu_env, arg);
8124 CP0_CHECK(ctx->insn_flags & ASE_MT);
8125 gen_helper_mtc0_vpeconf1(cpu_env, arg);
8129 CP0_CHECK(ctx->insn_flags & ASE_MT);
8130 gen_helper_mtc0_yqmask(cpu_env, arg);
8134 CP0_CHECK(ctx->insn_flags & ASE_MT);
8135 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8139 CP0_CHECK(ctx->insn_flags & ASE_MT);
8140 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8141 rn = "VPEScheFBack";
8144 CP0_CHECK(ctx->insn_flags & ASE_MT);
8145 gen_helper_mtc0_vpeopt(cpu_env, arg);
8149 goto cp0_unimplemented;
8155 gen_helper_dmtc0_entrylo0(cpu_env, arg);
8159 CP0_CHECK(ctx->insn_flags & ASE_MT);
8160 gen_helper_mtc0_tcstatus(cpu_env, arg);
8164 CP0_CHECK(ctx->insn_flags & ASE_MT);
8165 gen_helper_mtc0_tcbind(cpu_env, arg);
8169 CP0_CHECK(ctx->insn_flags & ASE_MT);
8170 gen_helper_mtc0_tcrestart(cpu_env, arg);
8174 CP0_CHECK(ctx->insn_flags & ASE_MT);
8175 gen_helper_mtc0_tchalt(cpu_env, arg);
8179 CP0_CHECK(ctx->insn_flags & ASE_MT);
8180 gen_helper_mtc0_tccontext(cpu_env, arg);
8184 CP0_CHECK(ctx->insn_flags & ASE_MT);
8185 gen_helper_mtc0_tcschedule(cpu_env, arg);
8189 CP0_CHECK(ctx->insn_flags & ASE_MT);
8190 gen_helper_mtc0_tcschefback(cpu_env, arg);
8194 goto cp0_unimplemented;
8200 gen_helper_dmtc0_entrylo1(cpu_env, arg);
8206 rn = "GlobalNumber";
8209 goto cp0_unimplemented;
8215 gen_helper_mtc0_context(cpu_env, arg);
8219 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8220 rn = "ContextConfig";
8221 goto cp0_unimplemented;
8223 CP0_CHECK(ctx->ulri);
8224 tcg_gen_st_tl(arg, cpu_env,
8225 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8229 goto cp0_unimplemented;
8235 gen_helper_mtc0_pagemask(cpu_env, arg);
8239 check_insn(ctx, ISA_MIPS32R2);
8240 gen_helper_mtc0_pagegrain(cpu_env, arg);
8245 gen_helper_mtc0_segctl0(cpu_env, arg);
8250 gen_helper_mtc0_segctl1(cpu_env, arg);
8255 gen_helper_mtc0_segctl2(cpu_env, arg);
8260 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8265 gen_helper_mtc0_pwfield(cpu_env, arg);
8270 gen_helper_mtc0_pwsize(cpu_env, arg);
8274 goto cp0_unimplemented;
8280 gen_helper_mtc0_wired(cpu_env, arg);
8284 check_insn(ctx, ISA_MIPS32R2);
8285 gen_helper_mtc0_srsconf0(cpu_env, arg);
8289 check_insn(ctx, ISA_MIPS32R2);
8290 gen_helper_mtc0_srsconf1(cpu_env, arg);
8294 check_insn(ctx, ISA_MIPS32R2);
8295 gen_helper_mtc0_srsconf2(cpu_env, arg);
8299 check_insn(ctx, ISA_MIPS32R2);
8300 gen_helper_mtc0_srsconf3(cpu_env, arg);
8304 check_insn(ctx, ISA_MIPS32R2);
8305 gen_helper_mtc0_srsconf4(cpu_env, arg);
8310 gen_helper_mtc0_pwctl(cpu_env, arg);
8314 goto cp0_unimplemented;
8320 check_insn(ctx, ISA_MIPS32R2);
8321 gen_helper_mtc0_hwrena(cpu_env, arg);
8322 ctx->base.is_jmp = DISAS_STOP;
8326 goto cp0_unimplemented;
8348 goto cp0_unimplemented;
8354 gen_helper_mtc0_count(cpu_env, arg);
8357 /* 6,7 are implementation dependent */
8359 goto cp0_unimplemented;
8361 /* Stop translation as we may have switched the execution mode */
8362 ctx->base.is_jmp = DISAS_STOP;
8367 gen_helper_mtc0_entryhi(cpu_env, arg);
8371 goto cp0_unimplemented;
8377 gen_helper_mtc0_compare(cpu_env, arg);
8380 /* 6,7 are implementation dependent */
8382 goto cp0_unimplemented;
8384 /* Stop translation as we may have switched the execution mode */
8385 ctx->base.is_jmp = DISAS_STOP;
8390 save_cpu_state(ctx, 1);
8391 gen_helper_mtc0_status(cpu_env, arg);
8392 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8393 gen_save_pc(ctx->base.pc_next + 4);
8394 ctx->base.is_jmp = DISAS_EXIT;
8398 check_insn(ctx, ISA_MIPS32R2);
8399 gen_helper_mtc0_intctl(cpu_env, arg);
8400 /* Stop translation as we may have switched the execution mode */
8401 ctx->base.is_jmp = DISAS_STOP;
8405 check_insn(ctx, ISA_MIPS32R2);
8406 gen_helper_mtc0_srsctl(cpu_env, arg);
8407 /* Stop translation as we may have switched the execution mode */
8408 ctx->base.is_jmp = DISAS_STOP;
8412 check_insn(ctx, ISA_MIPS32R2);
8413 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8414 /* Stop translation as we may have switched the execution mode */
8415 ctx->base.is_jmp = DISAS_STOP;
8419 goto cp0_unimplemented;
8425 save_cpu_state(ctx, 1);
8426 gen_helper_mtc0_cause(cpu_env, arg);
8427 /* Stop translation as we may have triggered an interrupt.
8428 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8429 * translated code to check for pending interrupts. */
8430 gen_save_pc(ctx->base.pc_next + 4);
8431 ctx->base.is_jmp = DISAS_EXIT;
8435 goto cp0_unimplemented;
8441 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8445 goto cp0_unimplemented;
8455 check_insn(ctx, ISA_MIPS32R2);
8456 gen_helper_mtc0_ebase(cpu_env, arg);
8460 goto cp0_unimplemented;
8466 gen_helper_mtc0_config0(cpu_env, arg);
8468 /* Stop translation as we may have switched the execution mode */
8469 ctx->base.is_jmp = DISAS_STOP;
8472 /* ignored, read only */
8476 gen_helper_mtc0_config2(cpu_env, arg);
8478 /* Stop translation as we may have switched the execution mode */
8479 ctx->base.is_jmp = DISAS_STOP;
8482 gen_helper_mtc0_config3(cpu_env, arg);
8484 /* Stop translation as we may have switched the execution mode */
8485 ctx->base.is_jmp = DISAS_STOP;
8488 /* currently ignored */
8492 gen_helper_mtc0_config5(cpu_env, arg);
8494 /* Stop translation as we may have switched the execution mode */
8495 ctx->base.is_jmp = DISAS_STOP;
8497 /* 6,7 are implementation dependent */
8499 rn = "Invalid config selector";
8500 goto cp0_unimplemented;
8506 gen_helper_mtc0_lladdr(cpu_env, arg);
8510 CP0_CHECK(ctx->mrp);
8511 gen_helper_mtc0_maar(cpu_env, arg);
8515 CP0_CHECK(ctx->mrp);
8516 gen_helper_mtc0_maari(cpu_env, arg);
8520 goto cp0_unimplemented;
8533 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8534 gen_helper_0e1i(mtc0_watchlo, arg, sel);
8538 goto cp0_unimplemented;
8551 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8552 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8556 goto cp0_unimplemented;
8562 check_insn(ctx, ISA_MIPS3);
8563 gen_helper_mtc0_xcontext(cpu_env, arg);
8567 goto cp0_unimplemented;
8571 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8572 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8575 gen_helper_mtc0_framemask(cpu_env, arg);
8579 goto cp0_unimplemented;
8584 rn = "Diagnostic"; /* implementation dependent */
8589 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8590 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8591 gen_save_pc(ctx->base.pc_next + 4);
8592 ctx->base.is_jmp = DISAS_EXIT;
8596 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8597 /* Stop translation as we may have switched the execution mode */
8598 ctx->base.is_jmp = DISAS_STOP;
8599 rn = "TraceControl";
8600 goto cp0_unimplemented;
8602 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8603 /* Stop translation as we may have switched the execution mode */
8604 ctx->base.is_jmp = DISAS_STOP;
8605 rn = "TraceControl2";
8606 goto cp0_unimplemented;
8608 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8609 /* Stop translation as we may have switched the execution mode */
8610 ctx->base.is_jmp = DISAS_STOP;
8611 rn = "UserTraceData";
8612 goto cp0_unimplemented;
8614 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8615 /* Stop translation as we may have switched the execution mode */
8616 ctx->base.is_jmp = DISAS_STOP;
8618 goto cp0_unimplemented;
8620 goto cp0_unimplemented;
8627 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8631 goto cp0_unimplemented;
8637 gen_helper_mtc0_performance0(cpu_env, arg);
8638 rn = "Performance0";
8641 // gen_helper_mtc0_performance1(cpu_env, arg);
8642 rn = "Performance1";
8643 goto cp0_unimplemented;
8645 // gen_helper_mtc0_performance2(cpu_env, arg);
8646 rn = "Performance2";
8647 goto cp0_unimplemented;
8649 // gen_helper_mtc0_performance3(cpu_env, arg);
8650 rn = "Performance3";
8651 goto cp0_unimplemented;
8653 // gen_helper_mtc0_performance4(cpu_env, arg);
8654 rn = "Performance4";
8655 goto cp0_unimplemented;
8657 // gen_helper_mtc0_performance5(cpu_env, arg);
8658 rn = "Performance5";
8659 goto cp0_unimplemented;
8661 // gen_helper_mtc0_performance6(cpu_env, arg);
8662 rn = "Performance6";
8663 goto cp0_unimplemented;
8665 // gen_helper_mtc0_performance7(cpu_env, arg);
8666 rn = "Performance7";
8667 goto cp0_unimplemented;
8669 goto cp0_unimplemented;
8675 gen_helper_mtc0_errctl(cpu_env, arg);
8676 ctx->base.is_jmp = DISAS_STOP;
8680 goto cp0_unimplemented;
8693 goto cp0_unimplemented;
8702 gen_helper_mtc0_taglo(cpu_env, arg);
8709 gen_helper_mtc0_datalo(cpu_env, arg);
8713 goto cp0_unimplemented;
8722 gen_helper_mtc0_taghi(cpu_env, arg);
8729 gen_helper_mtc0_datahi(cpu_env, arg);
8734 goto cp0_unimplemented;
8740 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8744 goto cp0_unimplemented;
8751 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8760 CP0_CHECK(ctx->kscrexist & (1 << sel));
8761 tcg_gen_st_tl(arg, cpu_env,
8762 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8766 goto cp0_unimplemented;
8770 goto cp0_unimplemented;
8772 trace_mips_translate_c0("dmtc0", rn, reg, sel);
8774 /* For simplicity assume that all writes can cause interrupts. */
8775 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8777 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8778 * translated code to check for pending interrupts. */
8779 gen_save_pc(ctx->base.pc_next + 4);
8780 ctx->base.is_jmp = DISAS_EXIT;
8785 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8787 #endif /* TARGET_MIPS64 */
8789 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8790 int u, int sel, int h)
8792 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8793 TCGv t0 = tcg_temp_local_new();
8795 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8796 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8797 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
8798 tcg_gen_movi_tl(t0, -1);
8799 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8800 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8801 tcg_gen_movi_tl(t0, -1);
8807 gen_helper_mftc0_vpecontrol(t0, cpu_env);
8810 gen_helper_mftc0_vpeconf0(t0, cpu_env);
8820 gen_helper_mftc0_tcstatus(t0, cpu_env);
8823 gen_helper_mftc0_tcbind(t0, cpu_env);
8826 gen_helper_mftc0_tcrestart(t0, cpu_env);
8829 gen_helper_mftc0_tchalt(t0, cpu_env);
8832 gen_helper_mftc0_tccontext(t0, cpu_env);
8835 gen_helper_mftc0_tcschedule(t0, cpu_env);
8838 gen_helper_mftc0_tcschefback(t0, cpu_env);
8841 gen_mfc0(ctx, t0, rt, sel);
8848 gen_helper_mftc0_entryhi(t0, cpu_env);
8851 gen_mfc0(ctx, t0, rt, sel);
8857 gen_helper_mftc0_status(t0, cpu_env);
8860 gen_mfc0(ctx, t0, rt, sel);
8866 gen_helper_mftc0_cause(t0, cpu_env);
8876 gen_helper_mftc0_epc(t0, cpu_env);
8886 gen_helper_mftc0_ebase(t0, cpu_env);
8903 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8913 gen_helper_mftc0_debug(t0, cpu_env);
8916 gen_mfc0(ctx, t0, rt, sel);
8921 gen_mfc0(ctx, t0, rt, sel);
8923 } else switch (sel) {
8924 /* GPR registers. */
8926 gen_helper_1e0i(mftgpr, t0, rt);
8928 /* Auxiliary CPU registers */
8932 gen_helper_1e0i(mftlo, t0, 0);
8935 gen_helper_1e0i(mfthi, t0, 0);
8938 gen_helper_1e0i(mftacx, t0, 0);
8941 gen_helper_1e0i(mftlo, t0, 1);
8944 gen_helper_1e0i(mfthi, t0, 1);
8947 gen_helper_1e0i(mftacx, t0, 1);
8950 gen_helper_1e0i(mftlo, t0, 2);
8953 gen_helper_1e0i(mfthi, t0, 2);
8956 gen_helper_1e0i(mftacx, t0, 2);
8959 gen_helper_1e0i(mftlo, t0, 3);
8962 gen_helper_1e0i(mfthi, t0, 3);
8965 gen_helper_1e0i(mftacx, t0, 3);
8968 gen_helper_mftdsp(t0, cpu_env);
8974 /* Floating point (COP1). */
8976 /* XXX: For now we support only a single FPU context. */
8978 TCGv_i32 fp0 = tcg_temp_new_i32();
8980 gen_load_fpr32(ctx, fp0, rt);
8981 tcg_gen_ext_i32_tl(t0, fp0);
8982 tcg_temp_free_i32(fp0);
8984 TCGv_i32 fp0 = tcg_temp_new_i32();
8986 gen_load_fpr32h(ctx, fp0, rt);
8987 tcg_gen_ext_i32_tl(t0, fp0);
8988 tcg_temp_free_i32(fp0);
8992 /* XXX: For now we support only a single FPU context. */
8993 gen_helper_1e0i(cfc1, t0, rt);
8995 /* COP2: Not implemented. */
9002 trace_mips_translate_tr("mftr", rt, u, sel, h);
9003 gen_store_gpr(t0, rd);
9009 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9010 generate_exception_end(ctx, EXCP_RI);
9013 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9014 int u, int sel, int h)
9016 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9017 TCGv t0 = tcg_temp_local_new();
9019 gen_load_gpr(t0, rt);
9020 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9021 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9022 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9024 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9025 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9032 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9035 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9045 gen_helper_mttc0_tcstatus(cpu_env, t0);
9048 gen_helper_mttc0_tcbind(cpu_env, t0);
9051 gen_helper_mttc0_tcrestart(cpu_env, t0);
9054 gen_helper_mttc0_tchalt(cpu_env, t0);
9057 gen_helper_mttc0_tccontext(cpu_env, t0);
9060 gen_helper_mttc0_tcschedule(cpu_env, t0);
9063 gen_helper_mttc0_tcschefback(cpu_env, t0);
9066 gen_mtc0(ctx, t0, rd, sel);
9073 gen_helper_mttc0_entryhi(cpu_env, t0);
9076 gen_mtc0(ctx, t0, rd, sel);
9082 gen_helper_mttc0_status(cpu_env, t0);
9085 gen_mtc0(ctx, t0, rd, sel);
9091 gen_helper_mttc0_cause(cpu_env, t0);
9101 gen_helper_mttc0_ebase(cpu_env, t0);
9111 gen_helper_mttc0_debug(cpu_env, t0);
9114 gen_mtc0(ctx, t0, rd, sel);
9119 gen_mtc0(ctx, t0, rd, sel);
9121 } else switch (sel) {
9122 /* GPR registers. */
9124 gen_helper_0e1i(mttgpr, t0, rd);
9126 /* Auxiliary CPU registers */
9130 gen_helper_0e1i(mttlo, t0, 0);
9133 gen_helper_0e1i(mtthi, t0, 0);
9136 gen_helper_0e1i(mttacx, t0, 0);
9139 gen_helper_0e1i(mttlo, t0, 1);
9142 gen_helper_0e1i(mtthi, t0, 1);
9145 gen_helper_0e1i(mttacx, t0, 1);
9148 gen_helper_0e1i(mttlo, t0, 2);
9151 gen_helper_0e1i(mtthi, t0, 2);
9154 gen_helper_0e1i(mttacx, t0, 2);
9157 gen_helper_0e1i(mttlo, t0, 3);
9160 gen_helper_0e1i(mtthi, t0, 3);
9163 gen_helper_0e1i(mttacx, t0, 3);
9166 gen_helper_mttdsp(cpu_env, t0);
9172 /* Floating point (COP1). */
9174 /* XXX: For now we support only a single FPU context. */
9176 TCGv_i32 fp0 = tcg_temp_new_i32();
9178 tcg_gen_trunc_tl_i32(fp0, t0);
9179 gen_store_fpr32(ctx, fp0, rd);
9180 tcg_temp_free_i32(fp0);
9182 TCGv_i32 fp0 = tcg_temp_new_i32();
9184 tcg_gen_trunc_tl_i32(fp0, t0);
9185 gen_store_fpr32h(ctx, fp0, rd);
9186 tcg_temp_free_i32(fp0);
9190 /* XXX: For now we support only a single FPU context. */
9192 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9194 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9195 tcg_temp_free_i32(fs_tmp);
9197 /* Stop translation as we may have changed hflags */
9198 ctx->base.is_jmp = DISAS_STOP;
9200 /* COP2: Not implemented. */
9207 trace_mips_translate_tr("mttr", rd, u, sel, h);
9213 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9214 generate_exception_end(ctx, EXCP_RI);
9217 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9219 const char *opn = "ldst";
9221 check_cp0_enabled(ctx);
9228 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9233 TCGv t0 = tcg_temp_new();
9235 gen_load_gpr(t0, rt);
9236 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9241 #if defined(TARGET_MIPS64)
9243 check_insn(ctx, ISA_MIPS3);
9248 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9252 check_insn(ctx, ISA_MIPS3);
9254 TCGv t0 = tcg_temp_new();
9256 gen_load_gpr(t0, rt);
9257 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9269 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9275 TCGv t0 = tcg_temp_new();
9276 gen_load_gpr(t0, rt);
9277 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9283 check_cp0_enabled(ctx);
9288 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9289 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9293 check_cp0_enabled(ctx);
9294 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9295 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9300 if (!env->tlb->helper_tlbwi)
9302 gen_helper_tlbwi(cpu_env);
9307 if (!env->tlb->helper_tlbinv) {
9310 gen_helper_tlbinv(cpu_env);
9311 } /* treat as nop if TLBINV not supported */
9316 if (!env->tlb->helper_tlbinvf) {
9319 gen_helper_tlbinvf(cpu_env);
9320 } /* treat as nop if TLBINV not supported */
9324 if (!env->tlb->helper_tlbwr)
9326 gen_helper_tlbwr(cpu_env);
9330 if (!env->tlb->helper_tlbp)
9332 gen_helper_tlbp(cpu_env);
9336 if (!env->tlb->helper_tlbr)
9338 gen_helper_tlbr(cpu_env);
9340 case OPC_ERET: /* OPC_ERETNC */
9341 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9342 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9345 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9346 if (ctx->opcode & (1 << bit_shift)) {
9349 check_insn(ctx, ISA_MIPS32R5);
9350 gen_helper_eretnc(cpu_env);
9354 check_insn(ctx, ISA_MIPS2);
9355 gen_helper_eret(cpu_env);
9357 ctx->base.is_jmp = DISAS_EXIT;
9362 check_insn(ctx, ISA_MIPS32);
9363 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9364 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9367 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9369 generate_exception_end(ctx, EXCP_RI);
9371 gen_helper_deret(cpu_env);
9372 ctx->base.is_jmp = DISAS_EXIT;
9377 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
9378 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9379 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9382 /* If we get an exception, we want to restart at next instruction */
9383 ctx->base.pc_next += 4;
9384 save_cpu_state(ctx, 1);
9385 ctx->base.pc_next -= 4;
9386 gen_helper_wait(cpu_env);
9387 ctx->base.is_jmp = DISAS_NORETURN;
9392 generate_exception_end(ctx, EXCP_RI);
9395 (void)opn; /* avoid a compiler warning */
9397 #endif /* !CONFIG_USER_ONLY */
9399 /* CP1 Branches (before delay slot) */
9400 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9401 int32_t cc, int32_t offset)
9403 target_ulong btarget;
9404 TCGv_i32 t0 = tcg_temp_new_i32();
9406 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9407 generate_exception_end(ctx, EXCP_RI);
9412 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
9414 btarget = ctx->base.pc_next + 4 + offset;
9418 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9419 tcg_gen_not_i32(t0, t0);
9420 tcg_gen_andi_i32(t0, t0, 1);
9421 tcg_gen_extu_i32_tl(bcond, t0);
9424 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9425 tcg_gen_not_i32(t0, t0);
9426 tcg_gen_andi_i32(t0, t0, 1);
9427 tcg_gen_extu_i32_tl(bcond, t0);
9430 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9431 tcg_gen_andi_i32(t0, t0, 1);
9432 tcg_gen_extu_i32_tl(bcond, t0);
9435 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9436 tcg_gen_andi_i32(t0, t0, 1);
9437 tcg_gen_extu_i32_tl(bcond, t0);
9439 ctx->hflags |= MIPS_HFLAG_BL;
9443 TCGv_i32 t1 = tcg_temp_new_i32();
9444 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9445 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9446 tcg_gen_nand_i32(t0, t0, t1);
9447 tcg_temp_free_i32(t1);
9448 tcg_gen_andi_i32(t0, t0, 1);
9449 tcg_gen_extu_i32_tl(bcond, t0);
9454 TCGv_i32 t1 = tcg_temp_new_i32();
9455 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9456 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9457 tcg_gen_or_i32(t0, t0, t1);
9458 tcg_temp_free_i32(t1);
9459 tcg_gen_andi_i32(t0, t0, 1);
9460 tcg_gen_extu_i32_tl(bcond, t0);
9465 TCGv_i32 t1 = tcg_temp_new_i32();
9466 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9467 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9468 tcg_gen_and_i32(t0, t0, t1);
9469 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9470 tcg_gen_and_i32(t0, t0, t1);
9471 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9472 tcg_gen_nand_i32(t0, t0, t1);
9473 tcg_temp_free_i32(t1);
9474 tcg_gen_andi_i32(t0, t0, 1);
9475 tcg_gen_extu_i32_tl(bcond, t0);
9480 TCGv_i32 t1 = tcg_temp_new_i32();
9481 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9482 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9483 tcg_gen_or_i32(t0, t0, t1);
9484 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9485 tcg_gen_or_i32(t0, t0, t1);
9486 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9487 tcg_gen_or_i32(t0, t0, t1);
9488 tcg_temp_free_i32(t1);
9489 tcg_gen_andi_i32(t0, t0, 1);
9490 tcg_gen_extu_i32_tl(bcond, t0);
9493 ctx->hflags |= MIPS_HFLAG_BC;
9496 MIPS_INVAL("cp1 cond branch");
9497 generate_exception_end(ctx, EXCP_RI);
9500 ctx->btarget = btarget;
9501 ctx->hflags |= MIPS_HFLAG_BDS32;
9503 tcg_temp_free_i32(t0);
9506 /* R6 CP1 Branches */
9507 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9508 int32_t ft, int32_t offset,
9511 target_ulong btarget;
9512 TCGv_i64 t0 = tcg_temp_new_i64();
9514 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9515 #ifdef MIPS_DEBUG_DISAS
9516 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9517 "\n", ctx->base.pc_next);
9519 generate_exception_end(ctx, EXCP_RI);
9523 gen_load_fpr64(ctx, t0, ft);
9524 tcg_gen_andi_i64(t0, t0, 1);
9526 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9530 tcg_gen_xori_i64(t0, t0, 1);
9531 ctx->hflags |= MIPS_HFLAG_BC;
9534 /* t0 already set */
9535 ctx->hflags |= MIPS_HFLAG_BC;
9538 MIPS_INVAL("cp1 cond branch");
9539 generate_exception_end(ctx, EXCP_RI);
9543 tcg_gen_trunc_i64_tl(bcond, t0);
9545 ctx->btarget = btarget;
9547 switch (delayslot_size) {
9549 ctx->hflags |= MIPS_HFLAG_BDS16;
9552 ctx->hflags |= MIPS_HFLAG_BDS32;
9557 tcg_temp_free_i64(t0);
9560 /* Coprocessor 1 (FPU) */
9562 #define FOP(func, fmt) (((fmt) << 21) | (func))
9565 OPC_ADD_S = FOP(0, FMT_S),
9566 OPC_SUB_S = FOP(1, FMT_S),
9567 OPC_MUL_S = FOP(2, FMT_S),
9568 OPC_DIV_S = FOP(3, FMT_S),
9569 OPC_SQRT_S = FOP(4, FMT_S),
9570 OPC_ABS_S = FOP(5, FMT_S),
9571 OPC_MOV_S = FOP(6, FMT_S),
9572 OPC_NEG_S = FOP(7, FMT_S),
9573 OPC_ROUND_L_S = FOP(8, FMT_S),
9574 OPC_TRUNC_L_S = FOP(9, FMT_S),
9575 OPC_CEIL_L_S = FOP(10, FMT_S),
9576 OPC_FLOOR_L_S = FOP(11, FMT_S),
9577 OPC_ROUND_W_S = FOP(12, FMT_S),
9578 OPC_TRUNC_W_S = FOP(13, FMT_S),
9579 OPC_CEIL_W_S = FOP(14, FMT_S),
9580 OPC_FLOOR_W_S = FOP(15, FMT_S),
9581 OPC_SEL_S = FOP(16, FMT_S),
9582 OPC_MOVCF_S = FOP(17, FMT_S),
9583 OPC_MOVZ_S = FOP(18, FMT_S),
9584 OPC_MOVN_S = FOP(19, FMT_S),
9585 OPC_SELEQZ_S = FOP(20, FMT_S),
9586 OPC_RECIP_S = FOP(21, FMT_S),
9587 OPC_RSQRT_S = FOP(22, FMT_S),
9588 OPC_SELNEZ_S = FOP(23, FMT_S),
9589 OPC_MADDF_S = FOP(24, FMT_S),
9590 OPC_MSUBF_S = FOP(25, FMT_S),
9591 OPC_RINT_S = FOP(26, FMT_S),
9592 OPC_CLASS_S = FOP(27, FMT_S),
9593 OPC_MIN_S = FOP(28, FMT_S),
9594 OPC_RECIP2_S = FOP(28, FMT_S),
9595 OPC_MINA_S = FOP(29, FMT_S),
9596 OPC_RECIP1_S = FOP(29, FMT_S),
9597 OPC_MAX_S = FOP(30, FMT_S),
9598 OPC_RSQRT1_S = FOP(30, FMT_S),
9599 OPC_MAXA_S = FOP(31, FMT_S),
9600 OPC_RSQRT2_S = FOP(31, FMT_S),
9601 OPC_CVT_D_S = FOP(33, FMT_S),
9602 OPC_CVT_W_S = FOP(36, FMT_S),
9603 OPC_CVT_L_S = FOP(37, FMT_S),
9604 OPC_CVT_PS_S = FOP(38, FMT_S),
9605 OPC_CMP_F_S = FOP (48, FMT_S),
9606 OPC_CMP_UN_S = FOP (49, FMT_S),
9607 OPC_CMP_EQ_S = FOP (50, FMT_S),
9608 OPC_CMP_UEQ_S = FOP (51, FMT_S),
9609 OPC_CMP_OLT_S = FOP (52, FMT_S),
9610 OPC_CMP_ULT_S = FOP (53, FMT_S),
9611 OPC_CMP_OLE_S = FOP (54, FMT_S),
9612 OPC_CMP_ULE_S = FOP (55, FMT_S),
9613 OPC_CMP_SF_S = FOP (56, FMT_S),
9614 OPC_CMP_NGLE_S = FOP (57, FMT_S),
9615 OPC_CMP_SEQ_S = FOP (58, FMT_S),
9616 OPC_CMP_NGL_S = FOP (59, FMT_S),
9617 OPC_CMP_LT_S = FOP (60, FMT_S),
9618 OPC_CMP_NGE_S = FOP (61, FMT_S),
9619 OPC_CMP_LE_S = FOP (62, FMT_S),
9620 OPC_CMP_NGT_S = FOP (63, FMT_S),
9622 OPC_ADD_D = FOP(0, FMT_D),
9623 OPC_SUB_D = FOP(1, FMT_D),
9624 OPC_MUL_D = FOP(2, FMT_D),
9625 OPC_DIV_D = FOP(3, FMT_D),
9626 OPC_SQRT_D = FOP(4, FMT_D),
9627 OPC_ABS_D = FOP(5, FMT_D),
9628 OPC_MOV_D = FOP(6, FMT_D),
9629 OPC_NEG_D = FOP(7, FMT_D),
9630 OPC_ROUND_L_D = FOP(8, FMT_D),
9631 OPC_TRUNC_L_D = FOP(9, FMT_D),
9632 OPC_CEIL_L_D = FOP(10, FMT_D),
9633 OPC_FLOOR_L_D = FOP(11, FMT_D),
9634 OPC_ROUND_W_D = FOP(12, FMT_D),
9635 OPC_TRUNC_W_D = FOP(13, FMT_D),
9636 OPC_CEIL_W_D = FOP(14, FMT_D),
9637 OPC_FLOOR_W_D = FOP(15, FMT_D),
9638 OPC_SEL_D = FOP(16, FMT_D),
9639 OPC_MOVCF_D = FOP(17, FMT_D),
9640 OPC_MOVZ_D = FOP(18, FMT_D),
9641 OPC_MOVN_D = FOP(19, FMT_D),
9642 OPC_SELEQZ_D = FOP(20, FMT_D),
9643 OPC_RECIP_D = FOP(21, FMT_D),
9644 OPC_RSQRT_D = FOP(22, FMT_D),
9645 OPC_SELNEZ_D = FOP(23, FMT_D),
9646 OPC_MADDF_D = FOP(24, FMT_D),
9647 OPC_MSUBF_D = FOP(25, FMT_D),
9648 OPC_RINT_D = FOP(26, FMT_D),
9649 OPC_CLASS_D = FOP(27, FMT_D),
9650 OPC_MIN_D = FOP(28, FMT_D),
9651 OPC_RECIP2_D = FOP(28, FMT_D),
9652 OPC_MINA_D = FOP(29, FMT_D),
9653 OPC_RECIP1_D = FOP(29, FMT_D),
9654 OPC_MAX_D = FOP(30, FMT_D),
9655 OPC_RSQRT1_D = FOP(30, FMT_D),
9656 OPC_MAXA_D = FOP(31, FMT_D),
9657 OPC_RSQRT2_D = FOP(31, FMT_D),
9658 OPC_CVT_S_D = FOP(32, FMT_D),
9659 OPC_CVT_W_D = FOP(36, FMT_D),
9660 OPC_CVT_L_D = FOP(37, FMT_D),
9661 OPC_CMP_F_D = FOP (48, FMT_D),
9662 OPC_CMP_UN_D = FOP (49, FMT_D),
9663 OPC_CMP_EQ_D = FOP (50, FMT_D),
9664 OPC_CMP_UEQ_D = FOP (51, FMT_D),
9665 OPC_CMP_OLT_D = FOP (52, FMT_D),
9666 OPC_CMP_ULT_D = FOP (53, FMT_D),
9667 OPC_CMP_OLE_D = FOP (54, FMT_D),
9668 OPC_CMP_ULE_D = FOP (55, FMT_D),
9669 OPC_CMP_SF_D = FOP (56, FMT_D),
9670 OPC_CMP_NGLE_D = FOP (57, FMT_D),
9671 OPC_CMP_SEQ_D = FOP (58, FMT_D),
9672 OPC_CMP_NGL_D = FOP (59, FMT_D),
9673 OPC_CMP_LT_D = FOP (60, FMT_D),
9674 OPC_CMP_NGE_D = FOP (61, FMT_D),
9675 OPC_CMP_LE_D = FOP (62, FMT_D),
9676 OPC_CMP_NGT_D = FOP (63, FMT_D),
9678 OPC_CVT_S_W = FOP(32, FMT_W),
9679 OPC_CVT_D_W = FOP(33, FMT_W),
9680 OPC_CVT_S_L = FOP(32, FMT_L),
9681 OPC_CVT_D_L = FOP(33, FMT_L),
9682 OPC_CVT_PS_PW = FOP(38, FMT_W),
9684 OPC_ADD_PS = FOP(0, FMT_PS),
9685 OPC_SUB_PS = FOP(1, FMT_PS),
9686 OPC_MUL_PS = FOP(2, FMT_PS),
9687 OPC_DIV_PS = FOP(3, FMT_PS),
9688 OPC_ABS_PS = FOP(5, FMT_PS),
9689 OPC_MOV_PS = FOP(6, FMT_PS),
9690 OPC_NEG_PS = FOP(7, FMT_PS),
9691 OPC_MOVCF_PS = FOP(17, FMT_PS),
9692 OPC_MOVZ_PS = FOP(18, FMT_PS),
9693 OPC_MOVN_PS = FOP(19, FMT_PS),
9694 OPC_ADDR_PS = FOP(24, FMT_PS),
9695 OPC_MULR_PS = FOP(26, FMT_PS),
9696 OPC_RECIP2_PS = FOP(28, FMT_PS),
9697 OPC_RECIP1_PS = FOP(29, FMT_PS),
9698 OPC_RSQRT1_PS = FOP(30, FMT_PS),
9699 OPC_RSQRT2_PS = FOP(31, FMT_PS),
9701 OPC_CVT_S_PU = FOP(32, FMT_PS),
9702 OPC_CVT_PW_PS = FOP(36, FMT_PS),
9703 OPC_CVT_S_PL = FOP(40, FMT_PS),
9704 OPC_PLL_PS = FOP(44, FMT_PS),
9705 OPC_PLU_PS = FOP(45, FMT_PS),
9706 OPC_PUL_PS = FOP(46, FMT_PS),
9707 OPC_PUU_PS = FOP(47, FMT_PS),
9708 OPC_CMP_F_PS = FOP (48, FMT_PS),
9709 OPC_CMP_UN_PS = FOP (49, FMT_PS),
9710 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
9711 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
9712 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
9713 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
9714 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
9715 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
9716 OPC_CMP_SF_PS = FOP (56, FMT_PS),
9717 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
9718 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
9719 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
9720 OPC_CMP_LT_PS = FOP (60, FMT_PS),
9721 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
9722 OPC_CMP_LE_PS = FOP (62, FMT_PS),
9723 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
9727 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
9728 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
9729 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
9730 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
9731 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
9732 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
9733 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
9734 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
9735 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
9736 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
9737 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
9738 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9739 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
9740 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9741 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
9742 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9743 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
9744 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
9745 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
9746 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
9747 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9748 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
9750 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
9751 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
9752 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
9753 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
9754 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
9755 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
9756 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
9757 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
9758 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
9759 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
9760 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
9761 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9762 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
9763 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9764 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
9765 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9766 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
9767 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
9768 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
9769 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
9770 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9771 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
9773 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
9775 TCGv t0 = tcg_temp_new();
9780 TCGv_i32 fp0 = tcg_temp_new_i32();
9782 gen_load_fpr32(ctx, fp0, fs);
9783 tcg_gen_ext_i32_tl(t0, fp0);
9784 tcg_temp_free_i32(fp0);
9786 gen_store_gpr(t0, rt);
9789 gen_load_gpr(t0, rt);
9791 TCGv_i32 fp0 = tcg_temp_new_i32();
9793 tcg_gen_trunc_tl_i32(fp0, t0);
9794 gen_store_fpr32(ctx, fp0, fs);
9795 tcg_temp_free_i32(fp0);
9799 gen_helper_1e0i(cfc1, t0, fs);
9800 gen_store_gpr(t0, rt);
9803 gen_load_gpr(t0, rt);
9804 save_cpu_state(ctx, 0);
9806 TCGv_i32 fs_tmp = tcg_const_i32(fs);
9808 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9809 tcg_temp_free_i32(fs_tmp);
9811 /* Stop translation as we may have changed hflags */
9812 ctx->base.is_jmp = DISAS_STOP;
9814 #if defined(TARGET_MIPS64)
9816 gen_load_fpr64(ctx, t0, fs);
9817 gen_store_gpr(t0, rt);
9820 gen_load_gpr(t0, rt);
9821 gen_store_fpr64(ctx, t0, fs);
9826 TCGv_i32 fp0 = tcg_temp_new_i32();
9828 gen_load_fpr32h(ctx, fp0, fs);
9829 tcg_gen_ext_i32_tl(t0, fp0);
9830 tcg_temp_free_i32(fp0);
9832 gen_store_gpr(t0, rt);
9835 gen_load_gpr(t0, rt);
9837 TCGv_i32 fp0 = tcg_temp_new_i32();
9839 tcg_gen_trunc_tl_i32(fp0, t0);
9840 gen_store_fpr32h(ctx, fp0, fs);
9841 tcg_temp_free_i32(fp0);
9845 MIPS_INVAL("cp1 move");
9846 generate_exception_end(ctx, EXCP_RI);
9854 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
9870 l1 = gen_new_label();
9871 t0 = tcg_temp_new_i32();
9872 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9873 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9874 tcg_temp_free_i32(t0);
9876 tcg_gen_movi_tl(cpu_gpr[rd], 0);
9878 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
9883 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9887 TCGv_i32 t0 = tcg_temp_new_i32();
9888 TCGLabel *l1 = gen_new_label();
9895 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9896 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9897 gen_load_fpr32(ctx, t0, fs);
9898 gen_store_fpr32(ctx, t0, fd);
9900 tcg_temp_free_i32(t0);
9903 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
9906 TCGv_i32 t0 = tcg_temp_new_i32();
9908 TCGLabel *l1 = gen_new_label();
9915 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9916 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9917 tcg_temp_free_i32(t0);
9918 fp0 = tcg_temp_new_i64();
9919 gen_load_fpr64(ctx, fp0, fs);
9920 gen_store_fpr64(ctx, fp0, fd);
9921 tcg_temp_free_i64(fp0);
9925 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9929 TCGv_i32 t0 = tcg_temp_new_i32();
9930 TCGLabel *l1 = gen_new_label();
9931 TCGLabel *l2 = gen_new_label();
9938 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9939 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9940 gen_load_fpr32(ctx, t0, fs);
9941 gen_store_fpr32(ctx, t0, fd);
9944 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
9945 tcg_gen_brcondi_i32(cond, t0, 0, l2);
9946 gen_load_fpr32h(ctx, t0, fs);
9947 gen_store_fpr32h(ctx, t0, fd);
9948 tcg_temp_free_i32(t0);
9952 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9955 TCGv_i32 t1 = tcg_const_i32(0);
9956 TCGv_i32 fp0 = tcg_temp_new_i32();
9957 TCGv_i32 fp1 = tcg_temp_new_i32();
9958 TCGv_i32 fp2 = tcg_temp_new_i32();
9959 gen_load_fpr32(ctx, fp0, fd);
9960 gen_load_fpr32(ctx, fp1, ft);
9961 gen_load_fpr32(ctx, fp2, fs);
9965 tcg_gen_andi_i32(fp0, fp0, 1);
9966 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9969 tcg_gen_andi_i32(fp1, fp1, 1);
9970 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9973 tcg_gen_andi_i32(fp1, fp1, 1);
9974 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9977 MIPS_INVAL("gen_sel_s");
9978 generate_exception_end(ctx, EXCP_RI);
9982 gen_store_fpr32(ctx, fp0, fd);
9983 tcg_temp_free_i32(fp2);
9984 tcg_temp_free_i32(fp1);
9985 tcg_temp_free_i32(fp0);
9986 tcg_temp_free_i32(t1);
9989 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9992 TCGv_i64 t1 = tcg_const_i64(0);
9993 TCGv_i64 fp0 = tcg_temp_new_i64();
9994 TCGv_i64 fp1 = tcg_temp_new_i64();
9995 TCGv_i64 fp2 = tcg_temp_new_i64();
9996 gen_load_fpr64(ctx, fp0, fd);
9997 gen_load_fpr64(ctx, fp1, ft);
9998 gen_load_fpr64(ctx, fp2, fs);
10002 tcg_gen_andi_i64(fp0, fp0, 1);
10003 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10006 tcg_gen_andi_i64(fp1, fp1, 1);
10007 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10010 tcg_gen_andi_i64(fp1, fp1, 1);
10011 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10014 MIPS_INVAL("gen_sel_d");
10015 generate_exception_end(ctx, EXCP_RI);
10019 gen_store_fpr64(ctx, fp0, fd);
10020 tcg_temp_free_i64(fp2);
10021 tcg_temp_free_i64(fp1);
10022 tcg_temp_free_i64(fp0);
10023 tcg_temp_free_i64(t1);
10026 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10027 int ft, int fs, int fd, int cc)
10029 uint32_t func = ctx->opcode & 0x3f;
10033 TCGv_i32 fp0 = tcg_temp_new_i32();
10034 TCGv_i32 fp1 = tcg_temp_new_i32();
10036 gen_load_fpr32(ctx, fp0, fs);
10037 gen_load_fpr32(ctx, fp1, ft);
10038 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10039 tcg_temp_free_i32(fp1);
10040 gen_store_fpr32(ctx, fp0, fd);
10041 tcg_temp_free_i32(fp0);
10046 TCGv_i32 fp0 = tcg_temp_new_i32();
10047 TCGv_i32 fp1 = tcg_temp_new_i32();
10049 gen_load_fpr32(ctx, fp0, fs);
10050 gen_load_fpr32(ctx, fp1, ft);
10051 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10052 tcg_temp_free_i32(fp1);
10053 gen_store_fpr32(ctx, fp0, fd);
10054 tcg_temp_free_i32(fp0);
10059 TCGv_i32 fp0 = tcg_temp_new_i32();
10060 TCGv_i32 fp1 = tcg_temp_new_i32();
10062 gen_load_fpr32(ctx, fp0, fs);
10063 gen_load_fpr32(ctx, fp1, ft);
10064 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10065 tcg_temp_free_i32(fp1);
10066 gen_store_fpr32(ctx, fp0, fd);
10067 tcg_temp_free_i32(fp0);
10072 TCGv_i32 fp0 = tcg_temp_new_i32();
10073 TCGv_i32 fp1 = tcg_temp_new_i32();
10075 gen_load_fpr32(ctx, fp0, fs);
10076 gen_load_fpr32(ctx, fp1, ft);
10077 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10078 tcg_temp_free_i32(fp1);
10079 gen_store_fpr32(ctx, fp0, fd);
10080 tcg_temp_free_i32(fp0);
10085 TCGv_i32 fp0 = tcg_temp_new_i32();
10087 gen_load_fpr32(ctx, fp0, fs);
10088 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10089 gen_store_fpr32(ctx, fp0, fd);
10090 tcg_temp_free_i32(fp0);
10095 TCGv_i32 fp0 = tcg_temp_new_i32();
10097 gen_load_fpr32(ctx, fp0, fs);
10098 if (ctx->abs2008) {
10099 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10101 gen_helper_float_abs_s(fp0, fp0);
10103 gen_store_fpr32(ctx, fp0, fd);
10104 tcg_temp_free_i32(fp0);
10109 TCGv_i32 fp0 = tcg_temp_new_i32();
10111 gen_load_fpr32(ctx, fp0, fs);
10112 gen_store_fpr32(ctx, fp0, fd);
10113 tcg_temp_free_i32(fp0);
10118 TCGv_i32 fp0 = tcg_temp_new_i32();
10120 gen_load_fpr32(ctx, fp0, fs);
10121 if (ctx->abs2008) {
10122 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10124 gen_helper_float_chs_s(fp0, fp0);
10126 gen_store_fpr32(ctx, fp0, fd);
10127 tcg_temp_free_i32(fp0);
10130 case OPC_ROUND_L_S:
10131 check_cp1_64bitmode(ctx);
10133 TCGv_i32 fp32 = tcg_temp_new_i32();
10134 TCGv_i64 fp64 = tcg_temp_new_i64();
10136 gen_load_fpr32(ctx, fp32, fs);
10137 if (ctx->nan2008) {
10138 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10140 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10142 tcg_temp_free_i32(fp32);
10143 gen_store_fpr64(ctx, fp64, fd);
10144 tcg_temp_free_i64(fp64);
10147 case OPC_TRUNC_L_S:
10148 check_cp1_64bitmode(ctx);
10150 TCGv_i32 fp32 = tcg_temp_new_i32();
10151 TCGv_i64 fp64 = tcg_temp_new_i64();
10153 gen_load_fpr32(ctx, fp32, fs);
10154 if (ctx->nan2008) {
10155 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10157 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10159 tcg_temp_free_i32(fp32);
10160 gen_store_fpr64(ctx, fp64, fd);
10161 tcg_temp_free_i64(fp64);
10165 check_cp1_64bitmode(ctx);
10167 TCGv_i32 fp32 = tcg_temp_new_i32();
10168 TCGv_i64 fp64 = tcg_temp_new_i64();
10170 gen_load_fpr32(ctx, fp32, fs);
10171 if (ctx->nan2008) {
10172 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10174 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10176 tcg_temp_free_i32(fp32);
10177 gen_store_fpr64(ctx, fp64, fd);
10178 tcg_temp_free_i64(fp64);
10181 case OPC_FLOOR_L_S:
10182 check_cp1_64bitmode(ctx);
10184 TCGv_i32 fp32 = tcg_temp_new_i32();
10185 TCGv_i64 fp64 = tcg_temp_new_i64();
10187 gen_load_fpr32(ctx, fp32, fs);
10188 if (ctx->nan2008) {
10189 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10191 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10193 tcg_temp_free_i32(fp32);
10194 gen_store_fpr64(ctx, fp64, fd);
10195 tcg_temp_free_i64(fp64);
10198 case OPC_ROUND_W_S:
10200 TCGv_i32 fp0 = tcg_temp_new_i32();
10202 gen_load_fpr32(ctx, fp0, fs);
10203 if (ctx->nan2008) {
10204 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10206 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10208 gen_store_fpr32(ctx, fp0, fd);
10209 tcg_temp_free_i32(fp0);
10212 case OPC_TRUNC_W_S:
10214 TCGv_i32 fp0 = tcg_temp_new_i32();
10216 gen_load_fpr32(ctx, fp0, fs);
10217 if (ctx->nan2008) {
10218 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10220 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10222 gen_store_fpr32(ctx, fp0, fd);
10223 tcg_temp_free_i32(fp0);
10228 TCGv_i32 fp0 = tcg_temp_new_i32();
10230 gen_load_fpr32(ctx, fp0, fs);
10231 if (ctx->nan2008) {
10232 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10234 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10236 gen_store_fpr32(ctx, fp0, fd);
10237 tcg_temp_free_i32(fp0);
10240 case OPC_FLOOR_W_S:
10242 TCGv_i32 fp0 = tcg_temp_new_i32();
10244 gen_load_fpr32(ctx, fp0, fs);
10245 if (ctx->nan2008) {
10246 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10248 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10250 gen_store_fpr32(ctx, fp0, fd);
10251 tcg_temp_free_i32(fp0);
10255 check_insn(ctx, ISA_MIPS32R6);
10256 gen_sel_s(ctx, op1, fd, ft, fs);
10259 check_insn(ctx, ISA_MIPS32R6);
10260 gen_sel_s(ctx, op1, fd, ft, fs);
10263 check_insn(ctx, ISA_MIPS32R6);
10264 gen_sel_s(ctx, op1, fd, ft, fs);
10267 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10268 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10271 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10273 TCGLabel *l1 = gen_new_label();
10277 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10279 fp0 = tcg_temp_new_i32();
10280 gen_load_fpr32(ctx, fp0, fs);
10281 gen_store_fpr32(ctx, fp0, fd);
10282 tcg_temp_free_i32(fp0);
10287 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10289 TCGLabel *l1 = gen_new_label();
10293 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10294 fp0 = tcg_temp_new_i32();
10295 gen_load_fpr32(ctx, fp0, fs);
10296 gen_store_fpr32(ctx, fp0, fd);
10297 tcg_temp_free_i32(fp0);
10304 TCGv_i32 fp0 = tcg_temp_new_i32();
10306 gen_load_fpr32(ctx, fp0, fs);
10307 gen_helper_float_recip_s(fp0, cpu_env, fp0);
10308 gen_store_fpr32(ctx, fp0, fd);
10309 tcg_temp_free_i32(fp0);
10314 TCGv_i32 fp0 = tcg_temp_new_i32();
10316 gen_load_fpr32(ctx, fp0, fs);
10317 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10318 gen_store_fpr32(ctx, fp0, fd);
10319 tcg_temp_free_i32(fp0);
10323 check_insn(ctx, ISA_MIPS32R6);
10325 TCGv_i32 fp0 = tcg_temp_new_i32();
10326 TCGv_i32 fp1 = tcg_temp_new_i32();
10327 TCGv_i32 fp2 = tcg_temp_new_i32();
10328 gen_load_fpr32(ctx, fp0, fs);
10329 gen_load_fpr32(ctx, fp1, ft);
10330 gen_load_fpr32(ctx, fp2, fd);
10331 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10332 gen_store_fpr32(ctx, fp2, fd);
10333 tcg_temp_free_i32(fp2);
10334 tcg_temp_free_i32(fp1);
10335 tcg_temp_free_i32(fp0);
10339 check_insn(ctx, ISA_MIPS32R6);
10341 TCGv_i32 fp0 = tcg_temp_new_i32();
10342 TCGv_i32 fp1 = tcg_temp_new_i32();
10343 TCGv_i32 fp2 = tcg_temp_new_i32();
10344 gen_load_fpr32(ctx, fp0, fs);
10345 gen_load_fpr32(ctx, fp1, ft);
10346 gen_load_fpr32(ctx, fp2, fd);
10347 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10348 gen_store_fpr32(ctx, fp2, fd);
10349 tcg_temp_free_i32(fp2);
10350 tcg_temp_free_i32(fp1);
10351 tcg_temp_free_i32(fp0);
10355 check_insn(ctx, ISA_MIPS32R6);
10357 TCGv_i32 fp0 = tcg_temp_new_i32();
10358 gen_load_fpr32(ctx, fp0, fs);
10359 gen_helper_float_rint_s(fp0, cpu_env, fp0);
10360 gen_store_fpr32(ctx, fp0, fd);
10361 tcg_temp_free_i32(fp0);
10365 check_insn(ctx, ISA_MIPS32R6);
10367 TCGv_i32 fp0 = tcg_temp_new_i32();
10368 gen_load_fpr32(ctx, fp0, fs);
10369 gen_helper_float_class_s(fp0, cpu_env, fp0);
10370 gen_store_fpr32(ctx, fp0, fd);
10371 tcg_temp_free_i32(fp0);
10374 case OPC_MIN_S: /* OPC_RECIP2_S */
10375 if (ctx->insn_flags & ISA_MIPS32R6) {
10377 TCGv_i32 fp0 = tcg_temp_new_i32();
10378 TCGv_i32 fp1 = tcg_temp_new_i32();
10379 TCGv_i32 fp2 = tcg_temp_new_i32();
10380 gen_load_fpr32(ctx, fp0, fs);
10381 gen_load_fpr32(ctx, fp1, ft);
10382 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10383 gen_store_fpr32(ctx, fp2, fd);
10384 tcg_temp_free_i32(fp2);
10385 tcg_temp_free_i32(fp1);
10386 tcg_temp_free_i32(fp0);
10389 check_cp1_64bitmode(ctx);
10391 TCGv_i32 fp0 = tcg_temp_new_i32();
10392 TCGv_i32 fp1 = tcg_temp_new_i32();
10394 gen_load_fpr32(ctx, fp0, fs);
10395 gen_load_fpr32(ctx, fp1, ft);
10396 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10397 tcg_temp_free_i32(fp1);
10398 gen_store_fpr32(ctx, fp0, fd);
10399 tcg_temp_free_i32(fp0);
10403 case OPC_MINA_S: /* OPC_RECIP1_S */
10404 if (ctx->insn_flags & ISA_MIPS32R6) {
10406 TCGv_i32 fp0 = tcg_temp_new_i32();
10407 TCGv_i32 fp1 = tcg_temp_new_i32();
10408 TCGv_i32 fp2 = tcg_temp_new_i32();
10409 gen_load_fpr32(ctx, fp0, fs);
10410 gen_load_fpr32(ctx, fp1, ft);
10411 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10412 gen_store_fpr32(ctx, fp2, fd);
10413 tcg_temp_free_i32(fp2);
10414 tcg_temp_free_i32(fp1);
10415 tcg_temp_free_i32(fp0);
10418 check_cp1_64bitmode(ctx);
10420 TCGv_i32 fp0 = tcg_temp_new_i32();
10422 gen_load_fpr32(ctx, fp0, fs);
10423 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10424 gen_store_fpr32(ctx, fp0, fd);
10425 tcg_temp_free_i32(fp0);
10429 case OPC_MAX_S: /* OPC_RSQRT1_S */
10430 if (ctx->insn_flags & ISA_MIPS32R6) {
10432 TCGv_i32 fp0 = tcg_temp_new_i32();
10433 TCGv_i32 fp1 = tcg_temp_new_i32();
10434 gen_load_fpr32(ctx, fp0, fs);
10435 gen_load_fpr32(ctx, fp1, ft);
10436 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10437 gen_store_fpr32(ctx, fp1, fd);
10438 tcg_temp_free_i32(fp1);
10439 tcg_temp_free_i32(fp0);
10442 check_cp1_64bitmode(ctx);
10444 TCGv_i32 fp0 = tcg_temp_new_i32();
10446 gen_load_fpr32(ctx, fp0, fs);
10447 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10448 gen_store_fpr32(ctx, fp0, fd);
10449 tcg_temp_free_i32(fp0);
10453 case OPC_MAXA_S: /* OPC_RSQRT2_S */
10454 if (ctx->insn_flags & ISA_MIPS32R6) {
10456 TCGv_i32 fp0 = tcg_temp_new_i32();
10457 TCGv_i32 fp1 = tcg_temp_new_i32();
10458 gen_load_fpr32(ctx, fp0, fs);
10459 gen_load_fpr32(ctx, fp1, ft);
10460 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10461 gen_store_fpr32(ctx, fp1, fd);
10462 tcg_temp_free_i32(fp1);
10463 tcg_temp_free_i32(fp0);
10466 check_cp1_64bitmode(ctx);
10468 TCGv_i32 fp0 = tcg_temp_new_i32();
10469 TCGv_i32 fp1 = tcg_temp_new_i32();
10471 gen_load_fpr32(ctx, fp0, fs);
10472 gen_load_fpr32(ctx, fp1, ft);
10473 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10474 tcg_temp_free_i32(fp1);
10475 gen_store_fpr32(ctx, fp0, fd);
10476 tcg_temp_free_i32(fp0);
10481 check_cp1_registers(ctx, fd);
10483 TCGv_i32 fp32 = tcg_temp_new_i32();
10484 TCGv_i64 fp64 = tcg_temp_new_i64();
10486 gen_load_fpr32(ctx, fp32, fs);
10487 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10488 tcg_temp_free_i32(fp32);
10489 gen_store_fpr64(ctx, fp64, fd);
10490 tcg_temp_free_i64(fp64);
10495 TCGv_i32 fp0 = tcg_temp_new_i32();
10497 gen_load_fpr32(ctx, fp0, fs);
10498 if (ctx->nan2008) {
10499 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10501 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10503 gen_store_fpr32(ctx, fp0, fd);
10504 tcg_temp_free_i32(fp0);
10508 check_cp1_64bitmode(ctx);
10510 TCGv_i32 fp32 = tcg_temp_new_i32();
10511 TCGv_i64 fp64 = tcg_temp_new_i64();
10513 gen_load_fpr32(ctx, fp32, fs);
10514 if (ctx->nan2008) {
10515 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10517 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10519 tcg_temp_free_i32(fp32);
10520 gen_store_fpr64(ctx, fp64, fd);
10521 tcg_temp_free_i64(fp64);
10527 TCGv_i64 fp64 = tcg_temp_new_i64();
10528 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10529 TCGv_i32 fp32_1 = tcg_temp_new_i32();
10531 gen_load_fpr32(ctx, fp32_0, fs);
10532 gen_load_fpr32(ctx, fp32_1, ft);
10533 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10534 tcg_temp_free_i32(fp32_1);
10535 tcg_temp_free_i32(fp32_0);
10536 gen_store_fpr64(ctx, fp64, fd);
10537 tcg_temp_free_i64(fp64);
10543 case OPC_CMP_UEQ_S:
10544 case OPC_CMP_OLT_S:
10545 case OPC_CMP_ULT_S:
10546 case OPC_CMP_OLE_S:
10547 case OPC_CMP_ULE_S:
10549 case OPC_CMP_NGLE_S:
10550 case OPC_CMP_SEQ_S:
10551 case OPC_CMP_NGL_S:
10553 case OPC_CMP_NGE_S:
10555 case OPC_CMP_NGT_S:
10556 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10557 if (ctx->opcode & (1 << 6)) {
10558 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
10560 gen_cmp_s(ctx, func-48, ft, fs, cc);
10564 check_cp1_registers(ctx, fs | ft | fd);
10566 TCGv_i64 fp0 = tcg_temp_new_i64();
10567 TCGv_i64 fp1 = tcg_temp_new_i64();
10569 gen_load_fpr64(ctx, fp0, fs);
10570 gen_load_fpr64(ctx, fp1, ft);
10571 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10572 tcg_temp_free_i64(fp1);
10573 gen_store_fpr64(ctx, fp0, fd);
10574 tcg_temp_free_i64(fp0);
10578 check_cp1_registers(ctx, fs | ft | fd);
10580 TCGv_i64 fp0 = tcg_temp_new_i64();
10581 TCGv_i64 fp1 = tcg_temp_new_i64();
10583 gen_load_fpr64(ctx, fp0, fs);
10584 gen_load_fpr64(ctx, fp1, ft);
10585 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10586 tcg_temp_free_i64(fp1);
10587 gen_store_fpr64(ctx, fp0, fd);
10588 tcg_temp_free_i64(fp0);
10592 check_cp1_registers(ctx, fs | ft | fd);
10594 TCGv_i64 fp0 = tcg_temp_new_i64();
10595 TCGv_i64 fp1 = tcg_temp_new_i64();
10597 gen_load_fpr64(ctx, fp0, fs);
10598 gen_load_fpr64(ctx, fp1, ft);
10599 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10600 tcg_temp_free_i64(fp1);
10601 gen_store_fpr64(ctx, fp0, fd);
10602 tcg_temp_free_i64(fp0);
10606 check_cp1_registers(ctx, fs | ft | fd);
10608 TCGv_i64 fp0 = tcg_temp_new_i64();
10609 TCGv_i64 fp1 = tcg_temp_new_i64();
10611 gen_load_fpr64(ctx, fp0, fs);
10612 gen_load_fpr64(ctx, fp1, ft);
10613 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10614 tcg_temp_free_i64(fp1);
10615 gen_store_fpr64(ctx, fp0, fd);
10616 tcg_temp_free_i64(fp0);
10620 check_cp1_registers(ctx, fs | fd);
10622 TCGv_i64 fp0 = tcg_temp_new_i64();
10624 gen_load_fpr64(ctx, fp0, fs);
10625 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10626 gen_store_fpr64(ctx, fp0, fd);
10627 tcg_temp_free_i64(fp0);
10631 check_cp1_registers(ctx, fs | fd);
10633 TCGv_i64 fp0 = tcg_temp_new_i64();
10635 gen_load_fpr64(ctx, fp0, fs);
10636 if (ctx->abs2008) {
10637 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10639 gen_helper_float_abs_d(fp0, fp0);
10641 gen_store_fpr64(ctx, fp0, fd);
10642 tcg_temp_free_i64(fp0);
10646 check_cp1_registers(ctx, fs | fd);
10648 TCGv_i64 fp0 = tcg_temp_new_i64();
10650 gen_load_fpr64(ctx, fp0, fs);
10651 gen_store_fpr64(ctx, fp0, fd);
10652 tcg_temp_free_i64(fp0);
10656 check_cp1_registers(ctx, fs | fd);
10658 TCGv_i64 fp0 = tcg_temp_new_i64();
10660 gen_load_fpr64(ctx, fp0, fs);
10661 if (ctx->abs2008) {
10662 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10664 gen_helper_float_chs_d(fp0, fp0);
10666 gen_store_fpr64(ctx, fp0, fd);
10667 tcg_temp_free_i64(fp0);
10670 case OPC_ROUND_L_D:
10671 check_cp1_64bitmode(ctx);
10673 TCGv_i64 fp0 = tcg_temp_new_i64();
10675 gen_load_fpr64(ctx, fp0, fs);
10676 if (ctx->nan2008) {
10677 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10679 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10681 gen_store_fpr64(ctx, fp0, fd);
10682 tcg_temp_free_i64(fp0);
10685 case OPC_TRUNC_L_D:
10686 check_cp1_64bitmode(ctx);
10688 TCGv_i64 fp0 = tcg_temp_new_i64();
10690 gen_load_fpr64(ctx, fp0, fs);
10691 if (ctx->nan2008) {
10692 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10694 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10696 gen_store_fpr64(ctx, fp0, fd);
10697 tcg_temp_free_i64(fp0);
10701 check_cp1_64bitmode(ctx);
10703 TCGv_i64 fp0 = tcg_temp_new_i64();
10705 gen_load_fpr64(ctx, fp0, fs);
10706 if (ctx->nan2008) {
10707 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10709 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10711 gen_store_fpr64(ctx, fp0, fd);
10712 tcg_temp_free_i64(fp0);
10715 case OPC_FLOOR_L_D:
10716 check_cp1_64bitmode(ctx);
10718 TCGv_i64 fp0 = tcg_temp_new_i64();
10720 gen_load_fpr64(ctx, fp0, fs);
10721 if (ctx->nan2008) {
10722 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10724 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10726 gen_store_fpr64(ctx, fp0, fd);
10727 tcg_temp_free_i64(fp0);
10730 case OPC_ROUND_W_D:
10731 check_cp1_registers(ctx, fs);
10733 TCGv_i32 fp32 = tcg_temp_new_i32();
10734 TCGv_i64 fp64 = tcg_temp_new_i64();
10736 gen_load_fpr64(ctx, fp64, fs);
10737 if (ctx->nan2008) {
10738 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10740 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10742 tcg_temp_free_i64(fp64);
10743 gen_store_fpr32(ctx, fp32, fd);
10744 tcg_temp_free_i32(fp32);
10747 case OPC_TRUNC_W_D:
10748 check_cp1_registers(ctx, fs);
10750 TCGv_i32 fp32 = tcg_temp_new_i32();
10751 TCGv_i64 fp64 = tcg_temp_new_i64();
10753 gen_load_fpr64(ctx, fp64, fs);
10754 if (ctx->nan2008) {
10755 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10757 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10759 tcg_temp_free_i64(fp64);
10760 gen_store_fpr32(ctx, fp32, fd);
10761 tcg_temp_free_i32(fp32);
10765 check_cp1_registers(ctx, fs);
10767 TCGv_i32 fp32 = tcg_temp_new_i32();
10768 TCGv_i64 fp64 = tcg_temp_new_i64();
10770 gen_load_fpr64(ctx, fp64, fs);
10771 if (ctx->nan2008) {
10772 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10774 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10776 tcg_temp_free_i64(fp64);
10777 gen_store_fpr32(ctx, fp32, fd);
10778 tcg_temp_free_i32(fp32);
10781 case OPC_FLOOR_W_D:
10782 check_cp1_registers(ctx, fs);
10784 TCGv_i32 fp32 = tcg_temp_new_i32();
10785 TCGv_i64 fp64 = tcg_temp_new_i64();
10787 gen_load_fpr64(ctx, fp64, fs);
10788 if (ctx->nan2008) {
10789 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10791 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10793 tcg_temp_free_i64(fp64);
10794 gen_store_fpr32(ctx, fp32, fd);
10795 tcg_temp_free_i32(fp32);
10799 check_insn(ctx, ISA_MIPS32R6);
10800 gen_sel_d(ctx, op1, fd, ft, fs);
10803 check_insn(ctx, ISA_MIPS32R6);
10804 gen_sel_d(ctx, op1, fd, ft, fs);
10807 check_insn(ctx, ISA_MIPS32R6);
10808 gen_sel_d(ctx, op1, fd, ft, fs);
10811 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10812 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10815 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10817 TCGLabel *l1 = gen_new_label();
10821 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10823 fp0 = tcg_temp_new_i64();
10824 gen_load_fpr64(ctx, fp0, fs);
10825 gen_store_fpr64(ctx, fp0, fd);
10826 tcg_temp_free_i64(fp0);
10831 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10833 TCGLabel *l1 = gen_new_label();
10837 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10838 fp0 = tcg_temp_new_i64();
10839 gen_load_fpr64(ctx, fp0, fs);
10840 gen_store_fpr64(ctx, fp0, fd);
10841 tcg_temp_free_i64(fp0);
10847 check_cp1_registers(ctx, fs | fd);
10849 TCGv_i64 fp0 = tcg_temp_new_i64();
10851 gen_load_fpr64(ctx, fp0, fs);
10852 gen_helper_float_recip_d(fp0, cpu_env, fp0);
10853 gen_store_fpr64(ctx, fp0, fd);
10854 tcg_temp_free_i64(fp0);
10858 check_cp1_registers(ctx, fs | fd);
10860 TCGv_i64 fp0 = tcg_temp_new_i64();
10862 gen_load_fpr64(ctx, fp0, fs);
10863 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10864 gen_store_fpr64(ctx, fp0, fd);
10865 tcg_temp_free_i64(fp0);
10869 check_insn(ctx, ISA_MIPS32R6);
10871 TCGv_i64 fp0 = tcg_temp_new_i64();
10872 TCGv_i64 fp1 = tcg_temp_new_i64();
10873 TCGv_i64 fp2 = tcg_temp_new_i64();
10874 gen_load_fpr64(ctx, fp0, fs);
10875 gen_load_fpr64(ctx, fp1, ft);
10876 gen_load_fpr64(ctx, fp2, fd);
10877 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10878 gen_store_fpr64(ctx, fp2, fd);
10879 tcg_temp_free_i64(fp2);
10880 tcg_temp_free_i64(fp1);
10881 tcg_temp_free_i64(fp0);
10885 check_insn(ctx, ISA_MIPS32R6);
10887 TCGv_i64 fp0 = tcg_temp_new_i64();
10888 TCGv_i64 fp1 = tcg_temp_new_i64();
10889 TCGv_i64 fp2 = tcg_temp_new_i64();
10890 gen_load_fpr64(ctx, fp0, fs);
10891 gen_load_fpr64(ctx, fp1, ft);
10892 gen_load_fpr64(ctx, fp2, fd);
10893 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10894 gen_store_fpr64(ctx, fp2, fd);
10895 tcg_temp_free_i64(fp2);
10896 tcg_temp_free_i64(fp1);
10897 tcg_temp_free_i64(fp0);
10901 check_insn(ctx, ISA_MIPS32R6);
10903 TCGv_i64 fp0 = tcg_temp_new_i64();
10904 gen_load_fpr64(ctx, fp0, fs);
10905 gen_helper_float_rint_d(fp0, cpu_env, fp0);
10906 gen_store_fpr64(ctx, fp0, fd);
10907 tcg_temp_free_i64(fp0);
10911 check_insn(ctx, ISA_MIPS32R6);
10913 TCGv_i64 fp0 = tcg_temp_new_i64();
10914 gen_load_fpr64(ctx, fp0, fs);
10915 gen_helper_float_class_d(fp0, cpu_env, fp0);
10916 gen_store_fpr64(ctx, fp0, fd);
10917 tcg_temp_free_i64(fp0);
10920 case OPC_MIN_D: /* OPC_RECIP2_D */
10921 if (ctx->insn_flags & ISA_MIPS32R6) {
10923 TCGv_i64 fp0 = tcg_temp_new_i64();
10924 TCGv_i64 fp1 = tcg_temp_new_i64();
10925 gen_load_fpr64(ctx, fp0, fs);
10926 gen_load_fpr64(ctx, fp1, ft);
10927 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10928 gen_store_fpr64(ctx, fp1, fd);
10929 tcg_temp_free_i64(fp1);
10930 tcg_temp_free_i64(fp0);
10933 check_cp1_64bitmode(ctx);
10935 TCGv_i64 fp0 = tcg_temp_new_i64();
10936 TCGv_i64 fp1 = tcg_temp_new_i64();
10938 gen_load_fpr64(ctx, fp0, fs);
10939 gen_load_fpr64(ctx, fp1, ft);
10940 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10941 tcg_temp_free_i64(fp1);
10942 gen_store_fpr64(ctx, fp0, fd);
10943 tcg_temp_free_i64(fp0);
10947 case OPC_MINA_D: /* OPC_RECIP1_D */
10948 if (ctx->insn_flags & ISA_MIPS32R6) {
10950 TCGv_i64 fp0 = tcg_temp_new_i64();
10951 TCGv_i64 fp1 = tcg_temp_new_i64();
10952 gen_load_fpr64(ctx, fp0, fs);
10953 gen_load_fpr64(ctx, fp1, ft);
10954 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10955 gen_store_fpr64(ctx, fp1, fd);
10956 tcg_temp_free_i64(fp1);
10957 tcg_temp_free_i64(fp0);
10960 check_cp1_64bitmode(ctx);
10962 TCGv_i64 fp0 = tcg_temp_new_i64();
10964 gen_load_fpr64(ctx, fp0, fs);
10965 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10966 gen_store_fpr64(ctx, fp0, fd);
10967 tcg_temp_free_i64(fp0);
10971 case OPC_MAX_D: /* OPC_RSQRT1_D */
10972 if (ctx->insn_flags & ISA_MIPS32R6) {
10974 TCGv_i64 fp0 = tcg_temp_new_i64();
10975 TCGv_i64 fp1 = tcg_temp_new_i64();
10976 gen_load_fpr64(ctx, fp0, fs);
10977 gen_load_fpr64(ctx, fp1, ft);
10978 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10979 gen_store_fpr64(ctx, fp1, fd);
10980 tcg_temp_free_i64(fp1);
10981 tcg_temp_free_i64(fp0);
10984 check_cp1_64bitmode(ctx);
10986 TCGv_i64 fp0 = tcg_temp_new_i64();
10988 gen_load_fpr64(ctx, fp0, fs);
10989 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10990 gen_store_fpr64(ctx, fp0, fd);
10991 tcg_temp_free_i64(fp0);
10995 case OPC_MAXA_D: /* OPC_RSQRT2_D */
10996 if (ctx->insn_flags & ISA_MIPS32R6) {
10998 TCGv_i64 fp0 = tcg_temp_new_i64();
10999 TCGv_i64 fp1 = tcg_temp_new_i64();
11000 gen_load_fpr64(ctx, fp0, fs);
11001 gen_load_fpr64(ctx, fp1, ft);
11002 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11003 gen_store_fpr64(ctx, fp1, fd);
11004 tcg_temp_free_i64(fp1);
11005 tcg_temp_free_i64(fp0);
11008 check_cp1_64bitmode(ctx);
11010 TCGv_i64 fp0 = tcg_temp_new_i64();
11011 TCGv_i64 fp1 = tcg_temp_new_i64();
11013 gen_load_fpr64(ctx, fp0, fs);
11014 gen_load_fpr64(ctx, fp1, ft);
11015 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11016 tcg_temp_free_i64(fp1);
11017 gen_store_fpr64(ctx, fp0, fd);
11018 tcg_temp_free_i64(fp0);
11025 case OPC_CMP_UEQ_D:
11026 case OPC_CMP_OLT_D:
11027 case OPC_CMP_ULT_D:
11028 case OPC_CMP_OLE_D:
11029 case OPC_CMP_ULE_D:
11031 case OPC_CMP_NGLE_D:
11032 case OPC_CMP_SEQ_D:
11033 case OPC_CMP_NGL_D:
11035 case OPC_CMP_NGE_D:
11037 case OPC_CMP_NGT_D:
11038 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11039 if (ctx->opcode & (1 << 6)) {
11040 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11042 gen_cmp_d(ctx, func-48, ft, fs, cc);
11046 check_cp1_registers(ctx, fs);
11048 TCGv_i32 fp32 = tcg_temp_new_i32();
11049 TCGv_i64 fp64 = tcg_temp_new_i64();
11051 gen_load_fpr64(ctx, fp64, fs);
11052 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11053 tcg_temp_free_i64(fp64);
11054 gen_store_fpr32(ctx, fp32, fd);
11055 tcg_temp_free_i32(fp32);
11059 check_cp1_registers(ctx, fs);
11061 TCGv_i32 fp32 = tcg_temp_new_i32();
11062 TCGv_i64 fp64 = tcg_temp_new_i64();
11064 gen_load_fpr64(ctx, fp64, fs);
11065 if (ctx->nan2008) {
11066 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11068 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11070 tcg_temp_free_i64(fp64);
11071 gen_store_fpr32(ctx, fp32, fd);
11072 tcg_temp_free_i32(fp32);
11076 check_cp1_64bitmode(ctx);
11078 TCGv_i64 fp0 = tcg_temp_new_i64();
11080 gen_load_fpr64(ctx, fp0, fs);
11081 if (ctx->nan2008) {
11082 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11084 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11086 gen_store_fpr64(ctx, fp0, fd);
11087 tcg_temp_free_i64(fp0);
11092 TCGv_i32 fp0 = tcg_temp_new_i32();
11094 gen_load_fpr32(ctx, fp0, fs);
11095 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11096 gen_store_fpr32(ctx, fp0, fd);
11097 tcg_temp_free_i32(fp0);
11101 check_cp1_registers(ctx, fd);
11103 TCGv_i32 fp32 = tcg_temp_new_i32();
11104 TCGv_i64 fp64 = tcg_temp_new_i64();
11106 gen_load_fpr32(ctx, fp32, fs);
11107 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11108 tcg_temp_free_i32(fp32);
11109 gen_store_fpr64(ctx, fp64, fd);
11110 tcg_temp_free_i64(fp64);
11114 check_cp1_64bitmode(ctx);
11116 TCGv_i32 fp32 = tcg_temp_new_i32();
11117 TCGv_i64 fp64 = tcg_temp_new_i64();
11119 gen_load_fpr64(ctx, fp64, fs);
11120 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11121 tcg_temp_free_i64(fp64);
11122 gen_store_fpr32(ctx, fp32, fd);
11123 tcg_temp_free_i32(fp32);
11127 check_cp1_64bitmode(ctx);
11129 TCGv_i64 fp0 = tcg_temp_new_i64();
11131 gen_load_fpr64(ctx, fp0, fs);
11132 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11133 gen_store_fpr64(ctx, fp0, fd);
11134 tcg_temp_free_i64(fp0);
11137 case OPC_CVT_PS_PW:
11140 TCGv_i64 fp0 = tcg_temp_new_i64();
11142 gen_load_fpr64(ctx, fp0, fs);
11143 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11144 gen_store_fpr64(ctx, fp0, fd);
11145 tcg_temp_free_i64(fp0);
11151 TCGv_i64 fp0 = tcg_temp_new_i64();
11152 TCGv_i64 fp1 = tcg_temp_new_i64();
11154 gen_load_fpr64(ctx, fp0, fs);
11155 gen_load_fpr64(ctx, fp1, ft);
11156 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11157 tcg_temp_free_i64(fp1);
11158 gen_store_fpr64(ctx, fp0, fd);
11159 tcg_temp_free_i64(fp0);
11165 TCGv_i64 fp0 = tcg_temp_new_i64();
11166 TCGv_i64 fp1 = tcg_temp_new_i64();
11168 gen_load_fpr64(ctx, fp0, fs);
11169 gen_load_fpr64(ctx, fp1, ft);
11170 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11171 tcg_temp_free_i64(fp1);
11172 gen_store_fpr64(ctx, fp0, fd);
11173 tcg_temp_free_i64(fp0);
11179 TCGv_i64 fp0 = tcg_temp_new_i64();
11180 TCGv_i64 fp1 = tcg_temp_new_i64();
11182 gen_load_fpr64(ctx, fp0, fs);
11183 gen_load_fpr64(ctx, fp1, ft);
11184 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11185 tcg_temp_free_i64(fp1);
11186 gen_store_fpr64(ctx, fp0, fd);
11187 tcg_temp_free_i64(fp0);
11193 TCGv_i64 fp0 = tcg_temp_new_i64();
11195 gen_load_fpr64(ctx, fp0, fs);
11196 gen_helper_float_abs_ps(fp0, fp0);
11197 gen_store_fpr64(ctx, fp0, fd);
11198 tcg_temp_free_i64(fp0);
11204 TCGv_i64 fp0 = tcg_temp_new_i64();
11206 gen_load_fpr64(ctx, fp0, fs);
11207 gen_store_fpr64(ctx, fp0, fd);
11208 tcg_temp_free_i64(fp0);
11214 TCGv_i64 fp0 = tcg_temp_new_i64();
11216 gen_load_fpr64(ctx, fp0, fs);
11217 gen_helper_float_chs_ps(fp0, fp0);
11218 gen_store_fpr64(ctx, fp0, fd);
11219 tcg_temp_free_i64(fp0);
11224 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11229 TCGLabel *l1 = gen_new_label();
11233 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11234 fp0 = tcg_temp_new_i64();
11235 gen_load_fpr64(ctx, fp0, fs);
11236 gen_store_fpr64(ctx, fp0, fd);
11237 tcg_temp_free_i64(fp0);
11244 TCGLabel *l1 = gen_new_label();
11248 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11249 fp0 = tcg_temp_new_i64();
11250 gen_load_fpr64(ctx, fp0, fs);
11251 gen_store_fpr64(ctx, fp0, fd);
11252 tcg_temp_free_i64(fp0);
11260 TCGv_i64 fp0 = tcg_temp_new_i64();
11261 TCGv_i64 fp1 = tcg_temp_new_i64();
11263 gen_load_fpr64(ctx, fp0, ft);
11264 gen_load_fpr64(ctx, fp1, fs);
11265 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11266 tcg_temp_free_i64(fp1);
11267 gen_store_fpr64(ctx, fp0, fd);
11268 tcg_temp_free_i64(fp0);
11274 TCGv_i64 fp0 = tcg_temp_new_i64();
11275 TCGv_i64 fp1 = tcg_temp_new_i64();
11277 gen_load_fpr64(ctx, fp0, ft);
11278 gen_load_fpr64(ctx, fp1, fs);
11279 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11280 tcg_temp_free_i64(fp1);
11281 gen_store_fpr64(ctx, fp0, fd);
11282 tcg_temp_free_i64(fp0);
11285 case OPC_RECIP2_PS:
11288 TCGv_i64 fp0 = tcg_temp_new_i64();
11289 TCGv_i64 fp1 = tcg_temp_new_i64();
11291 gen_load_fpr64(ctx, fp0, fs);
11292 gen_load_fpr64(ctx, fp1, ft);
11293 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11294 tcg_temp_free_i64(fp1);
11295 gen_store_fpr64(ctx, fp0, fd);
11296 tcg_temp_free_i64(fp0);
11299 case OPC_RECIP1_PS:
11302 TCGv_i64 fp0 = tcg_temp_new_i64();
11304 gen_load_fpr64(ctx, fp0, fs);
11305 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11306 gen_store_fpr64(ctx, fp0, fd);
11307 tcg_temp_free_i64(fp0);
11310 case OPC_RSQRT1_PS:
11313 TCGv_i64 fp0 = tcg_temp_new_i64();
11315 gen_load_fpr64(ctx, fp0, fs);
11316 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11317 gen_store_fpr64(ctx, fp0, fd);
11318 tcg_temp_free_i64(fp0);
11321 case OPC_RSQRT2_PS:
11324 TCGv_i64 fp0 = tcg_temp_new_i64();
11325 TCGv_i64 fp1 = tcg_temp_new_i64();
11327 gen_load_fpr64(ctx, fp0, fs);
11328 gen_load_fpr64(ctx, fp1, ft);
11329 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11330 tcg_temp_free_i64(fp1);
11331 gen_store_fpr64(ctx, fp0, fd);
11332 tcg_temp_free_i64(fp0);
11336 check_cp1_64bitmode(ctx);
11338 TCGv_i32 fp0 = tcg_temp_new_i32();
11340 gen_load_fpr32h(ctx, fp0, fs);
11341 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11342 gen_store_fpr32(ctx, fp0, fd);
11343 tcg_temp_free_i32(fp0);
11346 case OPC_CVT_PW_PS:
11349 TCGv_i64 fp0 = tcg_temp_new_i64();
11351 gen_load_fpr64(ctx, fp0, fs);
11352 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11353 gen_store_fpr64(ctx, fp0, fd);
11354 tcg_temp_free_i64(fp0);
11358 check_cp1_64bitmode(ctx);
11360 TCGv_i32 fp0 = tcg_temp_new_i32();
11362 gen_load_fpr32(ctx, fp0, fs);
11363 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11364 gen_store_fpr32(ctx, fp0, fd);
11365 tcg_temp_free_i32(fp0);
11371 TCGv_i32 fp0 = tcg_temp_new_i32();
11372 TCGv_i32 fp1 = tcg_temp_new_i32();
11374 gen_load_fpr32(ctx, fp0, fs);
11375 gen_load_fpr32(ctx, fp1, ft);
11376 gen_store_fpr32h(ctx, fp0, fd);
11377 gen_store_fpr32(ctx, fp1, fd);
11378 tcg_temp_free_i32(fp0);
11379 tcg_temp_free_i32(fp1);
11385 TCGv_i32 fp0 = tcg_temp_new_i32();
11386 TCGv_i32 fp1 = tcg_temp_new_i32();
11388 gen_load_fpr32(ctx, fp0, fs);
11389 gen_load_fpr32h(ctx, fp1, ft);
11390 gen_store_fpr32(ctx, fp1, fd);
11391 gen_store_fpr32h(ctx, fp0, fd);
11392 tcg_temp_free_i32(fp0);
11393 tcg_temp_free_i32(fp1);
11399 TCGv_i32 fp0 = tcg_temp_new_i32();
11400 TCGv_i32 fp1 = tcg_temp_new_i32();
11402 gen_load_fpr32h(ctx, fp0, fs);
11403 gen_load_fpr32(ctx, fp1, ft);
11404 gen_store_fpr32(ctx, fp1, fd);
11405 gen_store_fpr32h(ctx, fp0, fd);
11406 tcg_temp_free_i32(fp0);
11407 tcg_temp_free_i32(fp1);
11413 TCGv_i32 fp0 = tcg_temp_new_i32();
11414 TCGv_i32 fp1 = tcg_temp_new_i32();
11416 gen_load_fpr32h(ctx, fp0, fs);
11417 gen_load_fpr32h(ctx, fp1, ft);
11418 gen_store_fpr32(ctx, fp1, fd);
11419 gen_store_fpr32h(ctx, fp0, fd);
11420 tcg_temp_free_i32(fp0);
11421 tcg_temp_free_i32(fp1);
11425 case OPC_CMP_UN_PS:
11426 case OPC_CMP_EQ_PS:
11427 case OPC_CMP_UEQ_PS:
11428 case OPC_CMP_OLT_PS:
11429 case OPC_CMP_ULT_PS:
11430 case OPC_CMP_OLE_PS:
11431 case OPC_CMP_ULE_PS:
11432 case OPC_CMP_SF_PS:
11433 case OPC_CMP_NGLE_PS:
11434 case OPC_CMP_SEQ_PS:
11435 case OPC_CMP_NGL_PS:
11436 case OPC_CMP_LT_PS:
11437 case OPC_CMP_NGE_PS:
11438 case OPC_CMP_LE_PS:
11439 case OPC_CMP_NGT_PS:
11440 if (ctx->opcode & (1 << 6)) {
11441 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
11443 gen_cmp_ps(ctx, func-48, ft, fs, cc);
11447 MIPS_INVAL("farith");
11448 generate_exception_end(ctx, EXCP_RI);
11453 /* Coprocessor 3 (FPU) */
11454 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
11455 int fd, int fs, int base, int index)
11457 TCGv t0 = tcg_temp_new();
11460 gen_load_gpr(t0, index);
11461 } else if (index == 0) {
11462 gen_load_gpr(t0, base);
11464 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11466 /* Don't do NOP if destination is zero: we must perform the actual
11472 TCGv_i32 fp0 = tcg_temp_new_i32();
11474 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11475 tcg_gen_trunc_tl_i32(fp0, t0);
11476 gen_store_fpr32(ctx, fp0, fd);
11477 tcg_temp_free_i32(fp0);
11482 check_cp1_registers(ctx, fd);
11484 TCGv_i64 fp0 = tcg_temp_new_i64();
11485 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11486 gen_store_fpr64(ctx, fp0, fd);
11487 tcg_temp_free_i64(fp0);
11491 check_cp1_64bitmode(ctx);
11492 tcg_gen_andi_tl(t0, t0, ~0x7);
11494 TCGv_i64 fp0 = tcg_temp_new_i64();
11496 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11497 gen_store_fpr64(ctx, fp0, fd);
11498 tcg_temp_free_i64(fp0);
11504 TCGv_i32 fp0 = tcg_temp_new_i32();
11505 gen_load_fpr32(ctx, fp0, fs);
11506 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11507 tcg_temp_free_i32(fp0);
11512 check_cp1_registers(ctx, fs);
11514 TCGv_i64 fp0 = tcg_temp_new_i64();
11515 gen_load_fpr64(ctx, fp0, fs);
11516 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11517 tcg_temp_free_i64(fp0);
11521 check_cp1_64bitmode(ctx);
11522 tcg_gen_andi_tl(t0, t0, ~0x7);
11524 TCGv_i64 fp0 = tcg_temp_new_i64();
11525 gen_load_fpr64(ctx, fp0, fs);
11526 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11527 tcg_temp_free_i64(fp0);
11534 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
11535 int fd, int fr, int fs, int ft)
11541 TCGv t0 = tcg_temp_local_new();
11542 TCGv_i32 fp = tcg_temp_new_i32();
11543 TCGv_i32 fph = tcg_temp_new_i32();
11544 TCGLabel *l1 = gen_new_label();
11545 TCGLabel *l2 = gen_new_label();
11547 gen_load_gpr(t0, fr);
11548 tcg_gen_andi_tl(t0, t0, 0x7);
11550 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11551 gen_load_fpr32(ctx, fp, fs);
11552 gen_load_fpr32h(ctx, fph, fs);
11553 gen_store_fpr32(ctx, fp, fd);
11554 gen_store_fpr32h(ctx, fph, fd);
11557 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11559 #ifdef TARGET_WORDS_BIGENDIAN
11560 gen_load_fpr32(ctx, fp, fs);
11561 gen_load_fpr32h(ctx, fph, ft);
11562 gen_store_fpr32h(ctx, fp, fd);
11563 gen_store_fpr32(ctx, fph, fd);
11565 gen_load_fpr32h(ctx, fph, fs);
11566 gen_load_fpr32(ctx, fp, ft);
11567 gen_store_fpr32(ctx, fph, fd);
11568 gen_store_fpr32h(ctx, fp, fd);
11571 tcg_temp_free_i32(fp);
11572 tcg_temp_free_i32(fph);
11578 TCGv_i32 fp0 = tcg_temp_new_i32();
11579 TCGv_i32 fp1 = tcg_temp_new_i32();
11580 TCGv_i32 fp2 = tcg_temp_new_i32();
11582 gen_load_fpr32(ctx, fp0, fs);
11583 gen_load_fpr32(ctx, fp1, ft);
11584 gen_load_fpr32(ctx, fp2, fr);
11585 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11586 tcg_temp_free_i32(fp0);
11587 tcg_temp_free_i32(fp1);
11588 gen_store_fpr32(ctx, fp2, fd);
11589 tcg_temp_free_i32(fp2);
11594 check_cp1_registers(ctx, fd | fs | ft | fr);
11596 TCGv_i64 fp0 = tcg_temp_new_i64();
11597 TCGv_i64 fp1 = tcg_temp_new_i64();
11598 TCGv_i64 fp2 = tcg_temp_new_i64();
11600 gen_load_fpr64(ctx, fp0, fs);
11601 gen_load_fpr64(ctx, fp1, ft);
11602 gen_load_fpr64(ctx, fp2, fr);
11603 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11604 tcg_temp_free_i64(fp0);
11605 tcg_temp_free_i64(fp1);
11606 gen_store_fpr64(ctx, fp2, fd);
11607 tcg_temp_free_i64(fp2);
11613 TCGv_i64 fp0 = tcg_temp_new_i64();
11614 TCGv_i64 fp1 = tcg_temp_new_i64();
11615 TCGv_i64 fp2 = tcg_temp_new_i64();
11617 gen_load_fpr64(ctx, fp0, fs);
11618 gen_load_fpr64(ctx, fp1, ft);
11619 gen_load_fpr64(ctx, fp2, fr);
11620 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11621 tcg_temp_free_i64(fp0);
11622 tcg_temp_free_i64(fp1);
11623 gen_store_fpr64(ctx, fp2, fd);
11624 tcg_temp_free_i64(fp2);
11630 TCGv_i32 fp0 = tcg_temp_new_i32();
11631 TCGv_i32 fp1 = tcg_temp_new_i32();
11632 TCGv_i32 fp2 = tcg_temp_new_i32();
11634 gen_load_fpr32(ctx, fp0, fs);
11635 gen_load_fpr32(ctx, fp1, ft);
11636 gen_load_fpr32(ctx, fp2, fr);
11637 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11638 tcg_temp_free_i32(fp0);
11639 tcg_temp_free_i32(fp1);
11640 gen_store_fpr32(ctx, fp2, fd);
11641 tcg_temp_free_i32(fp2);
11646 check_cp1_registers(ctx, fd | fs | ft | fr);
11648 TCGv_i64 fp0 = tcg_temp_new_i64();
11649 TCGv_i64 fp1 = tcg_temp_new_i64();
11650 TCGv_i64 fp2 = tcg_temp_new_i64();
11652 gen_load_fpr64(ctx, fp0, fs);
11653 gen_load_fpr64(ctx, fp1, ft);
11654 gen_load_fpr64(ctx, fp2, fr);
11655 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11656 tcg_temp_free_i64(fp0);
11657 tcg_temp_free_i64(fp1);
11658 gen_store_fpr64(ctx, fp2, fd);
11659 tcg_temp_free_i64(fp2);
11665 TCGv_i64 fp0 = tcg_temp_new_i64();
11666 TCGv_i64 fp1 = tcg_temp_new_i64();
11667 TCGv_i64 fp2 = tcg_temp_new_i64();
11669 gen_load_fpr64(ctx, fp0, fs);
11670 gen_load_fpr64(ctx, fp1, ft);
11671 gen_load_fpr64(ctx, fp2, fr);
11672 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11673 tcg_temp_free_i64(fp0);
11674 tcg_temp_free_i64(fp1);
11675 gen_store_fpr64(ctx, fp2, fd);
11676 tcg_temp_free_i64(fp2);
11682 TCGv_i32 fp0 = tcg_temp_new_i32();
11683 TCGv_i32 fp1 = tcg_temp_new_i32();
11684 TCGv_i32 fp2 = tcg_temp_new_i32();
11686 gen_load_fpr32(ctx, fp0, fs);
11687 gen_load_fpr32(ctx, fp1, ft);
11688 gen_load_fpr32(ctx, fp2, fr);
11689 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11690 tcg_temp_free_i32(fp0);
11691 tcg_temp_free_i32(fp1);
11692 gen_store_fpr32(ctx, fp2, fd);
11693 tcg_temp_free_i32(fp2);
11698 check_cp1_registers(ctx, fd | fs | ft | fr);
11700 TCGv_i64 fp0 = tcg_temp_new_i64();
11701 TCGv_i64 fp1 = tcg_temp_new_i64();
11702 TCGv_i64 fp2 = tcg_temp_new_i64();
11704 gen_load_fpr64(ctx, fp0, fs);
11705 gen_load_fpr64(ctx, fp1, ft);
11706 gen_load_fpr64(ctx, fp2, fr);
11707 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11708 tcg_temp_free_i64(fp0);
11709 tcg_temp_free_i64(fp1);
11710 gen_store_fpr64(ctx, fp2, fd);
11711 tcg_temp_free_i64(fp2);
11717 TCGv_i64 fp0 = tcg_temp_new_i64();
11718 TCGv_i64 fp1 = tcg_temp_new_i64();
11719 TCGv_i64 fp2 = tcg_temp_new_i64();
11721 gen_load_fpr64(ctx, fp0, fs);
11722 gen_load_fpr64(ctx, fp1, ft);
11723 gen_load_fpr64(ctx, fp2, fr);
11724 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11725 tcg_temp_free_i64(fp0);
11726 tcg_temp_free_i64(fp1);
11727 gen_store_fpr64(ctx, fp2, fd);
11728 tcg_temp_free_i64(fp2);
11734 TCGv_i32 fp0 = tcg_temp_new_i32();
11735 TCGv_i32 fp1 = tcg_temp_new_i32();
11736 TCGv_i32 fp2 = tcg_temp_new_i32();
11738 gen_load_fpr32(ctx, fp0, fs);
11739 gen_load_fpr32(ctx, fp1, ft);
11740 gen_load_fpr32(ctx, fp2, fr);
11741 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11742 tcg_temp_free_i32(fp0);
11743 tcg_temp_free_i32(fp1);
11744 gen_store_fpr32(ctx, fp2, fd);
11745 tcg_temp_free_i32(fp2);
11750 check_cp1_registers(ctx, fd | fs | ft | fr);
11752 TCGv_i64 fp0 = tcg_temp_new_i64();
11753 TCGv_i64 fp1 = tcg_temp_new_i64();
11754 TCGv_i64 fp2 = tcg_temp_new_i64();
11756 gen_load_fpr64(ctx, fp0, fs);
11757 gen_load_fpr64(ctx, fp1, ft);
11758 gen_load_fpr64(ctx, fp2, fr);
11759 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11760 tcg_temp_free_i64(fp0);
11761 tcg_temp_free_i64(fp1);
11762 gen_store_fpr64(ctx, fp2, fd);
11763 tcg_temp_free_i64(fp2);
11769 TCGv_i64 fp0 = tcg_temp_new_i64();
11770 TCGv_i64 fp1 = tcg_temp_new_i64();
11771 TCGv_i64 fp2 = tcg_temp_new_i64();
11773 gen_load_fpr64(ctx, fp0, fs);
11774 gen_load_fpr64(ctx, fp1, ft);
11775 gen_load_fpr64(ctx, fp2, fr);
11776 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11777 tcg_temp_free_i64(fp0);
11778 tcg_temp_free_i64(fp1);
11779 gen_store_fpr64(ctx, fp2, fd);
11780 tcg_temp_free_i64(fp2);
11784 MIPS_INVAL("flt3_arith");
11785 generate_exception_end(ctx, EXCP_RI);
11790 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11794 #if !defined(CONFIG_USER_ONLY)
11795 /* The Linux kernel will emulate rdhwr if it's not supported natively.
11796 Therefore only check the ISA in system mode. */
11797 check_insn(ctx, ISA_MIPS32R2);
11799 t0 = tcg_temp_new();
11803 gen_helper_rdhwr_cpunum(t0, cpu_env);
11804 gen_store_gpr(t0, rt);
11807 gen_helper_rdhwr_synci_step(t0, cpu_env);
11808 gen_store_gpr(t0, rt);
11811 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11814 gen_helper_rdhwr_cc(t0, cpu_env);
11815 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11818 gen_store_gpr(t0, rt);
11819 /* Break the TB to be able to take timer interrupts immediately
11820 after reading count. DISAS_STOP isn't sufficient, we need to ensure
11821 we break completely out of translated code. */
11822 gen_save_pc(ctx->base.pc_next + 4);
11823 ctx->base.is_jmp = DISAS_EXIT;
11826 gen_helper_rdhwr_ccres(t0, cpu_env);
11827 gen_store_gpr(t0, rt);
11830 check_insn(ctx, ISA_MIPS32R6);
11832 /* Performance counter registers are not implemented other than
11833 * control register 0.
11835 generate_exception(ctx, EXCP_RI);
11837 gen_helper_rdhwr_performance(t0, cpu_env);
11838 gen_store_gpr(t0, rt);
11841 check_insn(ctx, ISA_MIPS32R6);
11842 gen_helper_rdhwr_xnp(t0, cpu_env);
11843 gen_store_gpr(t0, rt);
11846 #if defined(CONFIG_USER_ONLY)
11847 tcg_gen_ld_tl(t0, cpu_env,
11848 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11849 gen_store_gpr(t0, rt);
11852 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11853 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11854 tcg_gen_ld_tl(t0, cpu_env,
11855 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11856 gen_store_gpr(t0, rt);
11858 generate_exception_end(ctx, EXCP_RI);
11862 default: /* Invalid */
11863 MIPS_INVAL("rdhwr");
11864 generate_exception_end(ctx, EXCP_RI);
11870 static inline void clear_branch_hflags(DisasContext *ctx)
11872 ctx->hflags &= ~MIPS_HFLAG_BMASK;
11873 if (ctx->base.is_jmp == DISAS_NEXT) {
11874 save_cpu_state(ctx, 0);
11876 /* it is not safe to save ctx->hflags as hflags may be changed
11877 in execution time by the instruction in delay / forbidden slot. */
11878 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11882 static void gen_branch(DisasContext *ctx, int insn_bytes)
11884 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11885 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11886 /* Branches completion */
11887 clear_branch_hflags(ctx);
11888 ctx->base.is_jmp = DISAS_NORETURN;
11889 /* FIXME: Need to clear can_do_io. */
11890 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11891 case MIPS_HFLAG_FBNSLOT:
11892 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11895 /* unconditional branch */
11896 if (proc_hflags & MIPS_HFLAG_BX) {
11897 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11899 gen_goto_tb(ctx, 0, ctx->btarget);
11901 case MIPS_HFLAG_BL:
11902 /* blikely taken case */
11903 gen_goto_tb(ctx, 0, ctx->btarget);
11905 case MIPS_HFLAG_BC:
11906 /* Conditional branch */
11908 TCGLabel *l1 = gen_new_label();
11910 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11911 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11913 gen_goto_tb(ctx, 0, ctx->btarget);
11916 case MIPS_HFLAG_BR:
11917 /* unconditional branch to register */
11918 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11919 TCGv t0 = tcg_temp_new();
11920 TCGv_i32 t1 = tcg_temp_new_i32();
11922 tcg_gen_andi_tl(t0, btarget, 0x1);
11923 tcg_gen_trunc_tl_i32(t1, t0);
11925 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11926 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11927 tcg_gen_or_i32(hflags, hflags, t1);
11928 tcg_temp_free_i32(t1);
11930 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11932 tcg_gen_mov_tl(cpu_PC, btarget);
11934 if (ctx->base.singlestep_enabled) {
11935 save_cpu_state(ctx, 0);
11936 gen_helper_raise_exception_debug(cpu_env);
11938 tcg_gen_lookup_and_goto_ptr();
11941 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
11947 /* Compact Branches */
11948 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11949 int rs, int rt, int32_t offset)
11951 int bcond_compute = 0;
11952 TCGv t0 = tcg_temp_new();
11953 TCGv t1 = tcg_temp_new();
11954 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11956 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11957 #ifdef MIPS_DEBUG_DISAS
11958 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11959 "\n", ctx->base.pc_next);
11961 generate_exception_end(ctx, EXCP_RI);
11965 /* Load needed operands and calculate btarget */
11967 /* compact branch */
11968 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11969 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11970 gen_load_gpr(t0, rs);
11971 gen_load_gpr(t1, rt);
11973 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11974 if (rs <= rt && rs == 0) {
11975 /* OPC_BEQZALC, OPC_BNEZALC */
11976 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11979 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11980 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11981 gen_load_gpr(t0, rs);
11982 gen_load_gpr(t1, rt);
11984 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11986 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11987 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11988 if (rs == 0 || rs == rt) {
11989 /* OPC_BLEZALC, OPC_BGEZALC */
11990 /* OPC_BGTZALC, OPC_BLTZALC */
11991 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11993 gen_load_gpr(t0, rs);
11994 gen_load_gpr(t1, rt);
11996 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12000 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12005 /* OPC_BEQZC, OPC_BNEZC */
12006 gen_load_gpr(t0, rs);
12008 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12010 /* OPC_JIC, OPC_JIALC */
12011 TCGv tbase = tcg_temp_new();
12012 TCGv toffset = tcg_temp_new();
12014 gen_load_gpr(tbase, rt);
12015 tcg_gen_movi_tl(toffset, offset);
12016 gen_op_addr_add(ctx, btarget, tbase, toffset);
12017 tcg_temp_free(tbase);
12018 tcg_temp_free(toffset);
12022 MIPS_INVAL("Compact branch/jump");
12023 generate_exception_end(ctx, EXCP_RI);
12027 if (bcond_compute == 0) {
12028 /* Uncoditional compact branch */
12031 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12034 ctx->hflags |= MIPS_HFLAG_BR;
12037 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12040 ctx->hflags |= MIPS_HFLAG_B;
12043 MIPS_INVAL("Compact branch/jump");
12044 generate_exception_end(ctx, EXCP_RI);
12048 /* Generating branch here as compact branches don't have delay slot */
12049 gen_branch(ctx, 4);
12051 /* Conditional compact branch */
12052 TCGLabel *fs = gen_new_label();
12053 save_cpu_state(ctx, 0);
12056 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12057 if (rs == 0 && rt != 0) {
12059 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12060 } else if (rs != 0 && rt != 0 && rs == rt) {
12062 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12065 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12068 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12069 if (rs == 0 && rt != 0) {
12071 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12072 } else if (rs != 0 && rt != 0 && rs == rt) {
12074 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12077 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12080 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12081 if (rs == 0 && rt != 0) {
12083 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12084 } else if (rs != 0 && rt != 0 && rs == rt) {
12086 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12089 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12092 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12093 if (rs == 0 && rt != 0) {
12095 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12096 } else if (rs != 0 && rt != 0 && rs == rt) {
12098 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12101 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12104 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12105 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12107 /* OPC_BOVC, OPC_BNVC */
12108 TCGv t2 = tcg_temp_new();
12109 TCGv t3 = tcg_temp_new();
12110 TCGv t4 = tcg_temp_new();
12111 TCGv input_overflow = tcg_temp_new();
12113 gen_load_gpr(t0, rs);
12114 gen_load_gpr(t1, rt);
12115 tcg_gen_ext32s_tl(t2, t0);
12116 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12117 tcg_gen_ext32s_tl(t3, t1);
12118 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12119 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12121 tcg_gen_add_tl(t4, t2, t3);
12122 tcg_gen_ext32s_tl(t4, t4);
12123 tcg_gen_xor_tl(t2, t2, t3);
12124 tcg_gen_xor_tl(t3, t4, t3);
12125 tcg_gen_andc_tl(t2, t3, t2);
12126 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12127 tcg_gen_or_tl(t4, t4, input_overflow);
12128 if (opc == OPC_BOVC) {
12130 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12133 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12135 tcg_temp_free(input_overflow);
12139 } else if (rs < rt && rs == 0) {
12140 /* OPC_BEQZALC, OPC_BNEZALC */
12141 if (opc == OPC_BEQZALC) {
12143 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12146 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12149 /* OPC_BEQC, OPC_BNEC */
12150 if (opc == OPC_BEQC) {
12152 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12155 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12160 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12163 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12166 MIPS_INVAL("Compact conditional branch/jump");
12167 generate_exception_end(ctx, EXCP_RI);
12171 /* Generating branch here as compact branches don't have delay slot */
12172 gen_goto_tb(ctx, 1, ctx->btarget);
12175 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12183 /* ISA extensions (ASEs) */
12184 /* MIPS16 extension to MIPS32 */
12186 /* MIPS16 major opcodes */
12188 M16_OPC_ADDIUSP = 0x00,
12189 M16_OPC_ADDIUPC = 0x01,
12191 M16_OPC_JAL = 0x03,
12192 M16_OPC_BEQZ = 0x04,
12193 M16_OPC_BNEQZ = 0x05,
12194 M16_OPC_SHIFT = 0x06,
12196 M16_OPC_RRIA = 0x08,
12197 M16_OPC_ADDIU8 = 0x09,
12198 M16_OPC_SLTI = 0x0a,
12199 M16_OPC_SLTIU = 0x0b,
12202 M16_OPC_CMPI = 0x0e,
12206 M16_OPC_LWSP = 0x12,
12208 M16_OPC_LBU = 0x14,
12209 M16_OPC_LHU = 0x15,
12210 M16_OPC_LWPC = 0x16,
12211 M16_OPC_LWU = 0x17,
12214 M16_OPC_SWSP = 0x1a,
12216 M16_OPC_RRR = 0x1c,
12218 M16_OPC_EXTEND = 0x1e,
12222 /* I8 funct field */
12241 /* RR funct field */
12275 /* I64 funct field */
12283 I64_DADDIUPC = 0x6,
12287 /* RR ry field for CNVT */
12289 RR_RY_CNVT_ZEB = 0x0,
12290 RR_RY_CNVT_ZEH = 0x1,
12291 RR_RY_CNVT_ZEW = 0x2,
12292 RR_RY_CNVT_SEB = 0x4,
12293 RR_RY_CNVT_SEH = 0x5,
12294 RR_RY_CNVT_SEW = 0x6,
12297 static int xlat (int r)
12299 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12304 static void gen_mips16_save (DisasContext *ctx,
12305 int xsregs, int aregs,
12306 int do_ra, int do_s0, int do_s1,
12309 TCGv t0 = tcg_temp_new();
12310 TCGv t1 = tcg_temp_new();
12311 TCGv t2 = tcg_temp_new();
12341 generate_exception_end(ctx, EXCP_RI);
12347 gen_base_offset_addr(ctx, t0, 29, 12);
12348 gen_load_gpr(t1, 7);
12349 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12352 gen_base_offset_addr(ctx, t0, 29, 8);
12353 gen_load_gpr(t1, 6);
12354 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12357 gen_base_offset_addr(ctx, t0, 29, 4);
12358 gen_load_gpr(t1, 5);
12359 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12362 gen_base_offset_addr(ctx, t0, 29, 0);
12363 gen_load_gpr(t1, 4);
12364 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12367 gen_load_gpr(t0, 29);
12369 #define DECR_AND_STORE(reg) do { \
12370 tcg_gen_movi_tl(t2, -4); \
12371 gen_op_addr_add(ctx, t0, t0, t2); \
12372 gen_load_gpr(t1, reg); \
12373 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12377 DECR_AND_STORE(31);
12382 DECR_AND_STORE(30);
12385 DECR_AND_STORE(23);
12388 DECR_AND_STORE(22);
12391 DECR_AND_STORE(21);
12394 DECR_AND_STORE(20);
12397 DECR_AND_STORE(19);
12400 DECR_AND_STORE(18);
12404 DECR_AND_STORE(17);
12407 DECR_AND_STORE(16);
12437 generate_exception_end(ctx, EXCP_RI);
12453 #undef DECR_AND_STORE
12455 tcg_gen_movi_tl(t2, -framesize);
12456 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12462 static void gen_mips16_restore (DisasContext *ctx,
12463 int xsregs, int aregs,
12464 int do_ra, int do_s0, int do_s1,
12468 TCGv t0 = tcg_temp_new();
12469 TCGv t1 = tcg_temp_new();
12470 TCGv t2 = tcg_temp_new();
12472 tcg_gen_movi_tl(t2, framesize);
12473 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
12475 #define DECR_AND_LOAD(reg) do { \
12476 tcg_gen_movi_tl(t2, -4); \
12477 gen_op_addr_add(ctx, t0, t0, t2); \
12478 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12479 gen_store_gpr(t1, reg); \
12543 generate_exception_end(ctx, EXCP_RI);
12559 #undef DECR_AND_LOAD
12561 tcg_gen_movi_tl(t2, framesize);
12562 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12568 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
12569 int is_64_bit, int extended)
12573 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12574 generate_exception_end(ctx, EXCP_RI);
12578 t0 = tcg_temp_new();
12580 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12581 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12583 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12589 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12592 TCGv_i32 t0 = tcg_const_i32(op);
12593 TCGv t1 = tcg_temp_new();
12594 gen_base_offset_addr(ctx, t1, base, offset);
12595 gen_helper_cache(cpu_env, t1, t0);
12598 #if defined(TARGET_MIPS64)
12599 static void decode_i64_mips16 (DisasContext *ctx,
12600 int ry, int funct, int16_t offset,
12605 check_insn(ctx, ISA_MIPS3);
12606 check_mips_64(ctx);
12607 offset = extended ? offset : offset << 3;
12608 gen_ld(ctx, OPC_LD, ry, 29, offset);
12611 check_insn(ctx, ISA_MIPS3);
12612 check_mips_64(ctx);
12613 offset = extended ? offset : offset << 3;
12614 gen_st(ctx, OPC_SD, ry, 29, offset);
12617 check_insn(ctx, ISA_MIPS3);
12618 check_mips_64(ctx);
12619 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
12620 gen_st(ctx, OPC_SD, 31, 29, offset);
12623 check_insn(ctx, ISA_MIPS3);
12624 check_mips_64(ctx);
12625 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
12626 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
12629 check_insn(ctx, ISA_MIPS3);
12630 check_mips_64(ctx);
12631 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12632 generate_exception_end(ctx, EXCP_RI);
12634 offset = extended ? offset : offset << 3;
12635 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
12639 check_insn(ctx, ISA_MIPS3);
12640 check_mips_64(ctx);
12641 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
12642 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
12645 check_insn(ctx, ISA_MIPS3);
12646 check_mips_64(ctx);
12647 offset = extended ? offset : offset << 2;
12648 gen_addiupc(ctx, ry, offset, 1, extended);
12651 check_insn(ctx, ISA_MIPS3);
12652 check_mips_64(ctx);
12653 offset = extended ? offset : offset << 2;
12654 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
12660 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
12662 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
12663 int op, rx, ry, funct, sa;
12664 int16_t imm, offset;
12666 ctx->opcode = (ctx->opcode << 16) | extend;
12667 op = (ctx->opcode >> 11) & 0x1f;
12668 sa = (ctx->opcode >> 22) & 0x1f;
12669 funct = (ctx->opcode >> 8) & 0x7;
12670 rx = xlat((ctx->opcode >> 8) & 0x7);
12671 ry = xlat((ctx->opcode >> 5) & 0x7);
12672 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
12673 | ((ctx->opcode >> 21) & 0x3f) << 5
12674 | (ctx->opcode & 0x1f));
12676 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
12679 case M16_OPC_ADDIUSP:
12680 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12682 case M16_OPC_ADDIUPC:
12683 gen_addiupc(ctx, rx, imm, 0, 1);
12686 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
12687 /* No delay slot, so just process as a normal instruction */
12690 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
12691 /* No delay slot, so just process as a normal instruction */
12693 case M16_OPC_BNEQZ:
12694 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
12695 /* No delay slot, so just process as a normal instruction */
12697 case M16_OPC_SHIFT:
12698 switch (ctx->opcode & 0x3) {
12700 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12703 #if defined(TARGET_MIPS64)
12704 check_mips_64(ctx);
12705 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12707 generate_exception_end(ctx, EXCP_RI);
12711 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12714 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12718 #if defined(TARGET_MIPS64)
12720 check_insn(ctx, ISA_MIPS3);
12721 check_mips_64(ctx);
12722 gen_ld(ctx, OPC_LD, ry, rx, offset);
12726 imm = ctx->opcode & 0xf;
12727 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
12728 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
12729 imm = (int16_t) (imm << 1) >> 1;
12730 if ((ctx->opcode >> 4) & 0x1) {
12731 #if defined(TARGET_MIPS64)
12732 check_mips_64(ctx);
12733 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12735 generate_exception_end(ctx, EXCP_RI);
12738 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12741 case M16_OPC_ADDIU8:
12742 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12745 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12747 case M16_OPC_SLTIU:
12748 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12753 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
12756 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
12759 gen_st(ctx, OPC_SW, 31, 29, imm);
12762 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
12765 check_insn(ctx, ISA_MIPS32);
12767 int xsregs = (ctx->opcode >> 24) & 0x7;
12768 int aregs = (ctx->opcode >> 16) & 0xf;
12769 int do_ra = (ctx->opcode >> 6) & 0x1;
12770 int do_s0 = (ctx->opcode >> 5) & 0x1;
12771 int do_s1 = (ctx->opcode >> 4) & 0x1;
12772 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
12773 | (ctx->opcode & 0xf)) << 3;
12775 if (ctx->opcode & (1 << 7)) {
12776 gen_mips16_save(ctx, xsregs, aregs,
12777 do_ra, do_s0, do_s1,
12780 gen_mips16_restore(ctx, xsregs, aregs,
12781 do_ra, do_s0, do_s1,
12787 generate_exception_end(ctx, EXCP_RI);
12792 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
12795 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
12797 #if defined(TARGET_MIPS64)
12799 check_insn(ctx, ISA_MIPS3);
12800 check_mips_64(ctx);
12801 gen_st(ctx, OPC_SD, ry, rx, offset);
12805 gen_ld(ctx, OPC_LB, ry, rx, offset);
12808 gen_ld(ctx, OPC_LH, ry, rx, offset);
12811 gen_ld(ctx, OPC_LW, rx, 29, offset);
12814 gen_ld(ctx, OPC_LW, ry, rx, offset);
12817 gen_ld(ctx, OPC_LBU, ry, rx, offset);
12820 gen_ld(ctx, OPC_LHU, ry, rx, offset);
12823 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
12825 #if defined(TARGET_MIPS64)
12827 check_insn(ctx, ISA_MIPS3);
12828 check_mips_64(ctx);
12829 gen_ld(ctx, OPC_LWU, ry, rx, offset);
12833 gen_st(ctx, OPC_SB, ry, rx, offset);
12836 gen_st(ctx, OPC_SH, ry, rx, offset);
12839 gen_st(ctx, OPC_SW, rx, 29, offset);
12842 gen_st(ctx, OPC_SW, ry, rx, offset);
12844 #if defined(TARGET_MIPS64)
12846 decode_i64_mips16(ctx, ry, funct, offset, 1);
12850 generate_exception_end(ctx, EXCP_RI);
12857 static inline bool is_uhi(int sdbbp_code)
12859 #ifdef CONFIG_USER_ONLY
12862 return semihosting_enabled() && sdbbp_code == 1;
12866 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
12870 int op, cnvt_op, op1, offset;
12874 op = (ctx->opcode >> 11) & 0x1f;
12875 sa = (ctx->opcode >> 2) & 0x7;
12876 sa = sa == 0 ? 8 : sa;
12877 rx = xlat((ctx->opcode >> 8) & 0x7);
12878 cnvt_op = (ctx->opcode >> 5) & 0x7;
12879 ry = xlat((ctx->opcode >> 5) & 0x7);
12880 op1 = offset = ctx->opcode & 0x1f;
12885 case M16_OPC_ADDIUSP:
12887 int16_t imm = ((uint8_t) ctx->opcode) << 2;
12889 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12892 case M16_OPC_ADDIUPC:
12893 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
12896 offset = (ctx->opcode & 0x7ff) << 1;
12897 offset = (int16_t)(offset << 4) >> 4;
12898 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
12899 /* No delay slot, so just process as a normal instruction */
12902 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
12903 offset = (((ctx->opcode & 0x1f) << 21)
12904 | ((ctx->opcode >> 5) & 0x1f) << 16
12906 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
12907 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
12911 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
12912 ((int8_t)ctx->opcode) << 1, 0);
12913 /* No delay slot, so just process as a normal instruction */
12915 case M16_OPC_BNEQZ:
12916 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
12917 ((int8_t)ctx->opcode) << 1, 0);
12918 /* No delay slot, so just process as a normal instruction */
12920 case M16_OPC_SHIFT:
12921 switch (ctx->opcode & 0x3) {
12923 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12926 #if defined(TARGET_MIPS64)
12927 check_insn(ctx, ISA_MIPS3);
12928 check_mips_64(ctx);
12929 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12931 generate_exception_end(ctx, EXCP_RI);
12935 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12938 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12942 #if defined(TARGET_MIPS64)
12944 check_insn(ctx, ISA_MIPS3);
12945 check_mips_64(ctx);
12946 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
12951 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
12953 if ((ctx->opcode >> 4) & 1) {
12954 #if defined(TARGET_MIPS64)
12955 check_insn(ctx, ISA_MIPS3);
12956 check_mips_64(ctx);
12957 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12959 generate_exception_end(ctx, EXCP_RI);
12962 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12966 case M16_OPC_ADDIU8:
12968 int16_t imm = (int8_t) ctx->opcode;
12970 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12975 int16_t imm = (uint8_t) ctx->opcode;
12976 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12979 case M16_OPC_SLTIU:
12981 int16_t imm = (uint8_t) ctx->opcode;
12982 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12989 funct = (ctx->opcode >> 8) & 0x7;
12992 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
12993 ((int8_t)ctx->opcode) << 1, 0);
12996 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
12997 ((int8_t)ctx->opcode) << 1, 0);
13000 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13003 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13004 ((int8_t)ctx->opcode) << 3);
13007 check_insn(ctx, ISA_MIPS32);
13009 int do_ra = ctx->opcode & (1 << 6);
13010 int do_s0 = ctx->opcode & (1 << 5);
13011 int do_s1 = ctx->opcode & (1 << 4);
13012 int framesize = ctx->opcode & 0xf;
13014 if (framesize == 0) {
13017 framesize = framesize << 3;
13020 if (ctx->opcode & (1 << 7)) {
13021 gen_mips16_save(ctx, 0, 0,
13022 do_ra, do_s0, do_s1, framesize);
13024 gen_mips16_restore(ctx, 0, 0,
13025 do_ra, do_s0, do_s1, framesize);
13031 int rz = xlat(ctx->opcode & 0x7);
13033 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13034 ((ctx->opcode >> 5) & 0x7);
13035 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13039 reg32 = ctx->opcode & 0x1f;
13040 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13043 generate_exception_end(ctx, EXCP_RI);
13050 int16_t imm = (uint8_t) ctx->opcode;
13052 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13057 int16_t imm = (uint8_t) ctx->opcode;
13058 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13061 #if defined(TARGET_MIPS64)
13063 check_insn(ctx, ISA_MIPS3);
13064 check_mips_64(ctx);
13065 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13069 gen_ld(ctx, OPC_LB, ry, rx, offset);
13072 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13075 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13078 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13081 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13084 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13087 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13089 #if defined (TARGET_MIPS64)
13091 check_insn(ctx, ISA_MIPS3);
13092 check_mips_64(ctx);
13093 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13097 gen_st(ctx, OPC_SB, ry, rx, offset);
13100 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13103 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13106 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13110 int rz = xlat((ctx->opcode >> 2) & 0x7);
13113 switch (ctx->opcode & 0x3) {
13115 mips32_op = OPC_ADDU;
13118 mips32_op = OPC_SUBU;
13120 #if defined(TARGET_MIPS64)
13122 mips32_op = OPC_DADDU;
13123 check_insn(ctx, ISA_MIPS3);
13124 check_mips_64(ctx);
13127 mips32_op = OPC_DSUBU;
13128 check_insn(ctx, ISA_MIPS3);
13129 check_mips_64(ctx);
13133 generate_exception_end(ctx, EXCP_RI);
13137 gen_arith(ctx, mips32_op, rz, rx, ry);
13146 int nd = (ctx->opcode >> 7) & 0x1;
13147 int link = (ctx->opcode >> 6) & 0x1;
13148 int ra = (ctx->opcode >> 5) & 0x1;
13151 check_insn(ctx, ISA_MIPS32);
13160 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13165 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13166 gen_helper_do_semihosting(cpu_env);
13168 /* XXX: not clear which exception should be raised
13169 * when in debug mode...
13171 check_insn(ctx, ISA_MIPS32);
13172 generate_exception_end(ctx, EXCP_DBp);
13176 gen_slt(ctx, OPC_SLT, 24, rx, ry);
13179 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13182 generate_exception_end(ctx, EXCP_BREAK);
13185 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13188 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13191 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13193 #if defined (TARGET_MIPS64)
13195 check_insn(ctx, ISA_MIPS3);
13196 check_mips_64(ctx);
13197 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13201 gen_logic(ctx, OPC_XOR, 24, rx, ry);
13204 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13207 gen_logic(ctx, OPC_AND, rx, rx, ry);
13210 gen_logic(ctx, OPC_OR, rx, rx, ry);
13213 gen_logic(ctx, OPC_XOR, rx, rx, ry);
13216 gen_logic(ctx, OPC_NOR, rx, ry, 0);
13219 gen_HILO(ctx, OPC_MFHI, 0, rx);
13222 check_insn(ctx, ISA_MIPS32);
13224 case RR_RY_CNVT_ZEB:
13225 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13227 case RR_RY_CNVT_ZEH:
13228 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13230 case RR_RY_CNVT_SEB:
13231 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13233 case RR_RY_CNVT_SEH:
13234 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13236 #if defined (TARGET_MIPS64)
13237 case RR_RY_CNVT_ZEW:
13238 check_insn(ctx, ISA_MIPS64);
13239 check_mips_64(ctx);
13240 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13242 case RR_RY_CNVT_SEW:
13243 check_insn(ctx, ISA_MIPS64);
13244 check_mips_64(ctx);
13245 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13249 generate_exception_end(ctx, EXCP_RI);
13254 gen_HILO(ctx, OPC_MFLO, 0, rx);
13256 #if defined (TARGET_MIPS64)
13258 check_insn(ctx, ISA_MIPS3);
13259 check_mips_64(ctx);
13260 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13263 check_insn(ctx, ISA_MIPS3);
13264 check_mips_64(ctx);
13265 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
13268 check_insn(ctx, ISA_MIPS3);
13269 check_mips_64(ctx);
13270 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
13273 check_insn(ctx, ISA_MIPS3);
13274 check_mips_64(ctx);
13275 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
13279 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
13282 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
13285 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
13288 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
13290 #if defined (TARGET_MIPS64)
13292 check_insn(ctx, ISA_MIPS3);
13293 check_mips_64(ctx);
13294 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
13297 check_insn(ctx, ISA_MIPS3);
13298 check_mips_64(ctx);
13299 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
13302 check_insn(ctx, ISA_MIPS3);
13303 check_mips_64(ctx);
13304 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
13307 check_insn(ctx, ISA_MIPS3);
13308 check_mips_64(ctx);
13309 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
13313 generate_exception_end(ctx, EXCP_RI);
13317 case M16_OPC_EXTEND:
13318 decode_extended_mips16_opc(env, ctx);
13321 #if defined(TARGET_MIPS64)
13323 funct = (ctx->opcode >> 8) & 0x7;
13324 decode_i64_mips16(ctx, ry, funct, offset, 0);
13328 generate_exception_end(ctx, EXCP_RI);
13335 /* microMIPS extension to MIPS32/MIPS64 */
13338 * microMIPS32/microMIPS64 major opcodes
13340 * 1. MIPS Architecture for Programmers Volume II-B:
13341 * The microMIPS32 Instruction Set (Revision 3.05)
13343 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13345 * 2. MIPS Architecture For Programmers Volume II-A:
13346 * The MIPS64 Instruction Set (Revision 3.51)
13376 POOL32S = 0x16, /* MIPS64 */
13377 DADDIU32 = 0x17, /* MIPS64 */
13406 /* 0x29 is reserved */
13419 /* 0x31 is reserved */
13432 SD32 = 0x36, /* MIPS64 */
13433 LD32 = 0x37, /* MIPS64 */
13435 /* 0x39 is reserved */
13451 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13473 /* POOL32A encoding of minor opcode field */
13476 /* These opcodes are distinguished only by bits 9..6; those bits are
13477 * what are recorded below. */
13514 /* The following can be distinguished by their lower 6 bits. */
13524 /* POOL32AXF encoding of minor opcode field extension */
13527 * 1. MIPS Architecture for Programmers Volume II-B:
13528 * The microMIPS32 Instruction Set (Revision 3.05)
13530 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13532 * 2. MIPS Architecture for Programmers VolumeIV-e:
13533 * The MIPS DSP Application-Specific Extension
13534 * to the microMIPS32 Architecture (Revision 2.34)
13536 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13551 /* begin of microMIPS32 DSP */
13553 /* bits 13..12 for 0x01 */
13559 /* bits 13..12 for 0x2a */
13565 /* bits 13..12 for 0x32 */
13569 /* end of microMIPS32 DSP */
13571 /* bits 15..12 for 0x2c */
13588 /* bits 15..12 for 0x34 */
13596 /* bits 15..12 for 0x3c */
13598 JR = 0x0, /* alias */
13606 /* bits 15..12 for 0x05 */
13610 /* bits 15..12 for 0x0d */
13622 /* bits 15..12 for 0x15 */
13628 /* bits 15..12 for 0x1d */
13632 /* bits 15..12 for 0x2d */
13637 /* bits 15..12 for 0x35 */
13644 /* POOL32B encoding of minor opcode field (bits 15..12) */
13660 /* POOL32C encoding of minor opcode field (bits 15..12) */
13681 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13694 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13707 /* POOL32F encoding of minor opcode field (bits 5..0) */
13710 /* These are the bit 7..6 values */
13719 /* These are the bit 8..6 values */
13744 MOVZ_FMT_05 = 0x05,
13778 CABS_COND_FMT = 0x1c, /* MIPS3D */
13785 /* POOL32Fxf encoding of minor opcode extension field */
13823 /* POOL32I encoding of minor opcode field (bits 25..21) */
13853 /* These overlap and are distinguished by bit16 of the instruction */
13862 /* POOL16A encoding of minor opcode field */
13869 /* POOL16B encoding of minor opcode field */
13876 /* POOL16C encoding of minor opcode field */
13896 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
13920 /* POOL16D encoding of minor opcode field */
13927 /* POOL16E encoding of minor opcode field */
13934 static int mmreg (int r)
13936 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13941 /* Used for 16-bit store instructions. */
13942 static int mmreg2 (int r)
13944 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
13949 #define uMIPS_RD(op) ((op >> 7) & 0x7)
13950 #define uMIPS_RS(op) ((op >> 4) & 0x7)
13951 #define uMIPS_RS2(op) uMIPS_RS(op)
13952 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
13953 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
13954 #define uMIPS_RS5(op) (op & 0x1f)
13956 /* Signed immediate */
13957 #define SIMM(op, start, width) \
13958 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
13961 /* Zero-extended immediate */
13962 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
13964 static void gen_addiur1sp(DisasContext *ctx)
13966 int rd = mmreg(uMIPS_RD(ctx->opcode));
13968 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
13971 static void gen_addiur2(DisasContext *ctx)
13973 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
13974 int rd = mmreg(uMIPS_RD(ctx->opcode));
13975 int rs = mmreg(uMIPS_RS(ctx->opcode));
13977 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
13980 static void gen_addiusp(DisasContext *ctx)
13982 int encoded = ZIMM(ctx->opcode, 1, 9);
13985 if (encoded <= 1) {
13986 decoded = 256 + encoded;
13987 } else if (encoded <= 255) {
13989 } else if (encoded <= 509) {
13990 decoded = encoded - 512;
13992 decoded = encoded - 768;
13995 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
13998 static void gen_addius5(DisasContext *ctx)
14000 int imm = SIMM(ctx->opcode, 1, 4);
14001 int rd = (ctx->opcode >> 5) & 0x1f;
14003 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14006 static void gen_andi16(DisasContext *ctx)
14008 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14009 31, 32, 63, 64, 255, 32768, 65535 };
14010 int rd = mmreg(uMIPS_RD(ctx->opcode));
14011 int rs = mmreg(uMIPS_RS(ctx->opcode));
14012 int encoded = ZIMM(ctx->opcode, 0, 4);
14014 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14017 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14018 int base, int16_t offset)
14023 if (ctx->hflags & MIPS_HFLAG_BMASK) {
14024 generate_exception_end(ctx, EXCP_RI);
14028 t0 = tcg_temp_new();
14030 gen_base_offset_addr(ctx, t0, base, offset);
14032 t1 = tcg_const_tl(reglist);
14033 t2 = tcg_const_i32(ctx->mem_idx);
14035 save_cpu_state(ctx, 1);
14038 gen_helper_lwm(cpu_env, t0, t1, t2);
14041 gen_helper_swm(cpu_env, t0, t1, t2);
14043 #ifdef TARGET_MIPS64
14045 gen_helper_ldm(cpu_env, t0, t1, t2);
14048 gen_helper_sdm(cpu_env, t0, t1, t2);
14054 tcg_temp_free_i32(t2);
14058 static void gen_pool16c_insn(DisasContext *ctx)
14060 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14061 int rs = mmreg(ctx->opcode & 0x7);
14063 switch (((ctx->opcode) >> 4) & 0x3f) {
14068 gen_logic(ctx, OPC_NOR, rd, rs, 0);
14074 gen_logic(ctx, OPC_XOR, rd, rd, rs);
14080 gen_logic(ctx, OPC_AND, rd, rd, rs);
14086 gen_logic(ctx, OPC_OR, rd, rd, rs);
14093 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14094 int offset = ZIMM(ctx->opcode, 0, 4);
14096 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14105 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14106 int offset = ZIMM(ctx->opcode, 0, 4);
14108 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14115 int reg = ctx->opcode & 0x1f;
14117 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14123 int reg = ctx->opcode & 0x1f;
14124 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14125 /* Let normal delay slot handling in our caller take us
14126 to the branch target. */
14131 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14132 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14136 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14137 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14141 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14145 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14148 generate_exception_end(ctx, EXCP_BREAK);
14151 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14152 gen_helper_do_semihosting(cpu_env);
14154 /* XXX: not clear which exception should be raised
14155 * when in debug mode...
14157 check_insn(ctx, ISA_MIPS32);
14158 generate_exception_end(ctx, EXCP_DBp);
14161 case JRADDIUSP + 0:
14162 case JRADDIUSP + 1:
14164 int imm = ZIMM(ctx->opcode, 0, 5);
14165 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14166 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14167 /* Let normal delay slot handling in our caller take us
14168 to the branch target. */
14172 generate_exception_end(ctx, EXCP_RI);
14177 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14180 int rd, rs, re, rt;
14181 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14182 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14183 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14184 rd = rd_enc[enc_dest];
14185 re = re_enc[enc_dest];
14186 rs = rs_rt_enc[enc_rs];
14187 rt = rs_rt_enc[enc_rt];
14189 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14191 tcg_gen_movi_tl(cpu_gpr[rd], 0);
14194 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14196 tcg_gen_movi_tl(cpu_gpr[re], 0);
14200 static void gen_pool16c_r6_insn(DisasContext *ctx)
14202 int rt = mmreg((ctx->opcode >> 7) & 0x7);
14203 int rs = mmreg((ctx->opcode >> 4) & 0x7);
14205 switch (ctx->opcode & 0xf) {
14207 gen_logic(ctx, OPC_NOR, rt, rs, 0);
14210 gen_logic(ctx, OPC_AND, rt, rt, rs);
14214 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14215 int offset = extract32(ctx->opcode, 4, 4);
14216 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14219 case R6_JRC16: /* JRCADDIUSP */
14220 if ((ctx->opcode >> 4) & 1) {
14222 int imm = extract32(ctx->opcode, 5, 5);
14223 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14224 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14227 rs = extract32(ctx->opcode, 5, 5);
14228 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14240 int enc_dest = uMIPS_RD(ctx->opcode);
14241 int enc_rt = uMIPS_RS2(ctx->opcode);
14242 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14243 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14247 gen_logic(ctx, OPC_XOR, rt, rt, rs);
14250 gen_logic(ctx, OPC_OR, rt, rt, rs);
14254 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14255 int offset = extract32(ctx->opcode, 4, 4);
14256 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14259 case JALRC16: /* BREAK16, SDBBP16 */
14260 switch (ctx->opcode & 0x3f) {
14262 case JALRC16 + 0x20:
14264 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14269 generate_exception(ctx, EXCP_BREAK);
14273 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14274 gen_helper_do_semihosting(cpu_env);
14276 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14277 generate_exception(ctx, EXCP_RI);
14279 generate_exception(ctx, EXCP_DBp);
14286 generate_exception(ctx, EXCP_RI);
14291 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14293 TCGv t0 = tcg_temp_new();
14294 TCGv t1 = tcg_temp_new();
14296 gen_load_gpr(t0, base);
14299 gen_load_gpr(t1, index);
14300 tcg_gen_shli_tl(t1, t1, 2);
14301 gen_op_addr_add(ctx, t0, t1, t0);
14304 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14305 gen_store_gpr(t1, rd);
14311 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14312 int base, int16_t offset)
14316 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
14317 generate_exception_end(ctx, EXCP_RI);
14321 t0 = tcg_temp_new();
14322 t1 = tcg_temp_new();
14324 gen_base_offset_addr(ctx, t0, base, offset);
14329 generate_exception_end(ctx, EXCP_RI);
14332 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14333 gen_store_gpr(t1, rd);
14334 tcg_gen_movi_tl(t1, 4);
14335 gen_op_addr_add(ctx, t0, t0, t1);
14336 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14337 gen_store_gpr(t1, rd+1);
14340 gen_load_gpr(t1, rd);
14341 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14342 tcg_gen_movi_tl(t1, 4);
14343 gen_op_addr_add(ctx, t0, t0, t1);
14344 gen_load_gpr(t1, rd+1);
14345 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14347 #ifdef TARGET_MIPS64
14350 generate_exception_end(ctx, EXCP_RI);
14353 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14354 gen_store_gpr(t1, rd);
14355 tcg_gen_movi_tl(t1, 8);
14356 gen_op_addr_add(ctx, t0, t0, t1);
14357 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14358 gen_store_gpr(t1, rd+1);
14361 gen_load_gpr(t1, rd);
14362 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14363 tcg_gen_movi_tl(t1, 8);
14364 gen_op_addr_add(ctx, t0, t0, t1);
14365 gen_load_gpr(t1, rd+1);
14366 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14374 static void gen_sync(int stype)
14376 TCGBar tcg_mo = TCG_BAR_SC;
14379 case 0x4: /* SYNC_WMB */
14380 tcg_mo |= TCG_MO_ST_ST;
14382 case 0x10: /* SYNC_MB */
14383 tcg_mo |= TCG_MO_ALL;
14385 case 0x11: /* SYNC_ACQUIRE */
14386 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14388 case 0x12: /* SYNC_RELEASE */
14389 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14391 case 0x13: /* SYNC_RMB */
14392 tcg_mo |= TCG_MO_LD_LD;
14395 tcg_mo |= TCG_MO_ALL;
14399 tcg_gen_mb(tcg_mo);
14402 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
14404 int extension = (ctx->opcode >> 6) & 0x3f;
14405 int minor = (ctx->opcode >> 12) & 0xf;
14406 uint32_t mips32_op;
14408 switch (extension) {
14410 mips32_op = OPC_TEQ;
14413 mips32_op = OPC_TGE;
14416 mips32_op = OPC_TGEU;
14419 mips32_op = OPC_TLT;
14422 mips32_op = OPC_TLTU;
14425 mips32_op = OPC_TNE;
14427 gen_trap(ctx, mips32_op, rs, rt, -1);
14429 #ifndef CONFIG_USER_ONLY
14432 check_cp0_enabled(ctx);
14434 /* Treat as NOP. */
14437 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
14441 check_cp0_enabled(ctx);
14443 TCGv t0 = tcg_temp_new();
14445 gen_load_gpr(t0, rt);
14446 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
14452 switch (minor & 3) {
14454 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
14457 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
14460 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
14463 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
14466 goto pool32axf_invalid;
14470 switch (minor & 3) {
14472 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
14475 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
14478 goto pool32axf_invalid;
14484 check_insn(ctx, ISA_MIPS32R6);
14485 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
14488 gen_bshfl(ctx, OPC_SEB, rs, rt);
14491 gen_bshfl(ctx, OPC_SEH, rs, rt);
14494 mips32_op = OPC_CLO;
14497 mips32_op = OPC_CLZ;
14499 check_insn(ctx, ISA_MIPS32);
14500 gen_cl(ctx, mips32_op, rt, rs);
14503 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14504 gen_rdhwr(ctx, rt, rs, 0);
14507 gen_bshfl(ctx, OPC_WSBH, rs, rt);
14510 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14511 mips32_op = OPC_MULT;
14514 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14515 mips32_op = OPC_MULTU;
14518 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14519 mips32_op = OPC_DIV;
14522 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14523 mips32_op = OPC_DIVU;
14526 check_insn(ctx, ISA_MIPS32);
14527 gen_muldiv(ctx, mips32_op, 0, rs, rt);
14530 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14531 mips32_op = OPC_MADD;
14534 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14535 mips32_op = OPC_MADDU;
14538 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14539 mips32_op = OPC_MSUB;
14542 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14543 mips32_op = OPC_MSUBU;
14545 check_insn(ctx, ISA_MIPS32);
14546 gen_muldiv(ctx, mips32_op, 0, rs, rt);
14549 goto pool32axf_invalid;
14560 generate_exception_err(ctx, EXCP_CpU, 2);
14563 goto pool32axf_invalid;
14568 case JALR: /* JALRC */
14569 case JALR_HB: /* JALRC_HB */
14570 if (ctx->insn_flags & ISA_MIPS32R6) {
14571 /* JALRC, JALRC_HB */
14572 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
14574 /* JALR, JALR_HB */
14575 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
14576 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14581 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14582 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
14583 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14586 goto pool32axf_invalid;
14592 check_cp0_enabled(ctx);
14593 check_insn(ctx, ISA_MIPS32R2);
14594 gen_load_srsgpr(rs, rt);
14597 check_cp0_enabled(ctx);
14598 check_insn(ctx, ISA_MIPS32R2);
14599 gen_store_srsgpr(rs, rt);
14602 goto pool32axf_invalid;
14605 #ifndef CONFIG_USER_ONLY
14609 mips32_op = OPC_TLBP;
14612 mips32_op = OPC_TLBR;
14615 mips32_op = OPC_TLBWI;
14618 mips32_op = OPC_TLBWR;
14621 mips32_op = OPC_TLBINV;
14624 mips32_op = OPC_TLBINVF;
14627 mips32_op = OPC_WAIT;
14630 mips32_op = OPC_DERET;
14633 mips32_op = OPC_ERET;
14635 gen_cp0(env, ctx, mips32_op, rt, rs);
14638 goto pool32axf_invalid;
14644 check_cp0_enabled(ctx);
14646 TCGv t0 = tcg_temp_new();
14648 save_cpu_state(ctx, 1);
14649 gen_helper_di(t0, cpu_env);
14650 gen_store_gpr(t0, rs);
14651 /* Stop translation as we may have switched the execution mode */
14652 ctx->base.is_jmp = DISAS_STOP;
14657 check_cp0_enabled(ctx);
14659 TCGv t0 = tcg_temp_new();
14661 save_cpu_state(ctx, 1);
14662 gen_helper_ei(t0, cpu_env);
14663 gen_store_gpr(t0, rs);
14664 /* DISAS_STOP isn't sufficient, we need to ensure we break out
14665 of translated code to check for pending interrupts. */
14666 gen_save_pc(ctx->base.pc_next + 4);
14667 ctx->base.is_jmp = DISAS_EXIT;
14672 goto pool32axf_invalid;
14679 gen_sync(extract32(ctx->opcode, 16, 5));
14682 generate_exception_end(ctx, EXCP_SYSCALL);
14685 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
14686 gen_helper_do_semihosting(cpu_env);
14688 check_insn(ctx, ISA_MIPS32);
14689 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14690 generate_exception_end(ctx, EXCP_RI);
14692 generate_exception_end(ctx, EXCP_DBp);
14697 goto pool32axf_invalid;
14701 switch (minor & 3) {
14703 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
14706 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
14709 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
14712 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
14715 goto pool32axf_invalid;
14719 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14722 gen_HILO(ctx, OPC_MFHI, 0, rs);
14725 gen_HILO(ctx, OPC_MFLO, 0, rs);
14728 gen_HILO(ctx, OPC_MTHI, 0, rs);
14731 gen_HILO(ctx, OPC_MTLO, 0, rs);
14734 goto pool32axf_invalid;
14739 MIPS_INVAL("pool32axf");
14740 generate_exception_end(ctx, EXCP_RI);
14745 /* Values for microMIPS fmt field. Variable-width, depending on which
14746 formats the instruction supports. */
14765 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
14767 int extension = (ctx->opcode >> 6) & 0x3ff;
14768 uint32_t mips32_op;
14770 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
14771 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
14772 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
14774 switch (extension) {
14775 case FLOAT_1BIT_FMT(CFC1, 0):
14776 mips32_op = OPC_CFC1;
14778 case FLOAT_1BIT_FMT(CTC1, 0):
14779 mips32_op = OPC_CTC1;
14781 case FLOAT_1BIT_FMT(MFC1, 0):
14782 mips32_op = OPC_MFC1;
14784 case FLOAT_1BIT_FMT(MTC1, 0):
14785 mips32_op = OPC_MTC1;
14787 case FLOAT_1BIT_FMT(MFHC1, 0):
14788 mips32_op = OPC_MFHC1;
14790 case FLOAT_1BIT_FMT(MTHC1, 0):
14791 mips32_op = OPC_MTHC1;
14793 gen_cp1(ctx, mips32_op, rt, rs);
14796 /* Reciprocal square root */
14797 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
14798 mips32_op = OPC_RSQRT_S;
14800 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
14801 mips32_op = OPC_RSQRT_D;
14805 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
14806 mips32_op = OPC_SQRT_S;
14808 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
14809 mips32_op = OPC_SQRT_D;
14813 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
14814 mips32_op = OPC_RECIP_S;
14816 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
14817 mips32_op = OPC_RECIP_D;
14821 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
14822 mips32_op = OPC_FLOOR_L_S;
14824 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
14825 mips32_op = OPC_FLOOR_L_D;
14827 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
14828 mips32_op = OPC_FLOOR_W_S;
14830 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
14831 mips32_op = OPC_FLOOR_W_D;
14835 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
14836 mips32_op = OPC_CEIL_L_S;
14838 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
14839 mips32_op = OPC_CEIL_L_D;
14841 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
14842 mips32_op = OPC_CEIL_W_S;
14844 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
14845 mips32_op = OPC_CEIL_W_D;
14849 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
14850 mips32_op = OPC_TRUNC_L_S;
14852 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
14853 mips32_op = OPC_TRUNC_L_D;
14855 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
14856 mips32_op = OPC_TRUNC_W_S;
14858 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
14859 mips32_op = OPC_TRUNC_W_D;
14863 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
14864 mips32_op = OPC_ROUND_L_S;
14866 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
14867 mips32_op = OPC_ROUND_L_D;
14869 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
14870 mips32_op = OPC_ROUND_W_S;
14872 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
14873 mips32_op = OPC_ROUND_W_D;
14876 /* Integer to floating-point conversion */
14877 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
14878 mips32_op = OPC_CVT_L_S;
14880 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
14881 mips32_op = OPC_CVT_L_D;
14883 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
14884 mips32_op = OPC_CVT_W_S;
14886 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
14887 mips32_op = OPC_CVT_W_D;
14890 /* Paired-foo conversions */
14891 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
14892 mips32_op = OPC_CVT_S_PL;
14894 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
14895 mips32_op = OPC_CVT_S_PU;
14897 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
14898 mips32_op = OPC_CVT_PW_PS;
14900 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
14901 mips32_op = OPC_CVT_PS_PW;
14904 /* Floating-point moves */
14905 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
14906 mips32_op = OPC_MOV_S;
14908 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
14909 mips32_op = OPC_MOV_D;
14911 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
14912 mips32_op = OPC_MOV_PS;
14915 /* Absolute value */
14916 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
14917 mips32_op = OPC_ABS_S;
14919 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
14920 mips32_op = OPC_ABS_D;
14922 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
14923 mips32_op = OPC_ABS_PS;
14927 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
14928 mips32_op = OPC_NEG_S;
14930 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
14931 mips32_op = OPC_NEG_D;
14933 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
14934 mips32_op = OPC_NEG_PS;
14937 /* Reciprocal square root step */
14938 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
14939 mips32_op = OPC_RSQRT1_S;
14941 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
14942 mips32_op = OPC_RSQRT1_D;
14944 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
14945 mips32_op = OPC_RSQRT1_PS;
14948 /* Reciprocal step */
14949 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
14950 mips32_op = OPC_RECIP1_S;
14952 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
14953 mips32_op = OPC_RECIP1_S;
14955 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
14956 mips32_op = OPC_RECIP1_PS;
14959 /* Conversions from double */
14960 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
14961 mips32_op = OPC_CVT_D_S;
14963 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
14964 mips32_op = OPC_CVT_D_W;
14966 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
14967 mips32_op = OPC_CVT_D_L;
14970 /* Conversions from single */
14971 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
14972 mips32_op = OPC_CVT_S_D;
14974 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
14975 mips32_op = OPC_CVT_S_W;
14977 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
14978 mips32_op = OPC_CVT_S_L;
14980 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
14983 /* Conditional moves on floating-point codes */
14984 case COND_FLOAT_MOV(MOVT, 0):
14985 case COND_FLOAT_MOV(MOVT, 1):
14986 case COND_FLOAT_MOV(MOVT, 2):
14987 case COND_FLOAT_MOV(MOVT, 3):
14988 case COND_FLOAT_MOV(MOVT, 4):
14989 case COND_FLOAT_MOV(MOVT, 5):
14990 case COND_FLOAT_MOV(MOVT, 6):
14991 case COND_FLOAT_MOV(MOVT, 7):
14992 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14993 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
14995 case COND_FLOAT_MOV(MOVF, 0):
14996 case COND_FLOAT_MOV(MOVF, 1):
14997 case COND_FLOAT_MOV(MOVF, 2):
14998 case COND_FLOAT_MOV(MOVF, 3):
14999 case COND_FLOAT_MOV(MOVF, 4):
15000 case COND_FLOAT_MOV(MOVF, 5):
15001 case COND_FLOAT_MOV(MOVF, 6):
15002 case COND_FLOAT_MOV(MOVF, 7):
15003 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15004 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15007 MIPS_INVAL("pool32fxf");
15008 generate_exception_end(ctx, EXCP_RI);
15013 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15017 int rt, rs, rd, rr;
15019 uint32_t op, minor, minor2, mips32_op;
15020 uint32_t cond, fmt, cc;
15022 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15023 ctx->opcode = (ctx->opcode << 16) | insn;
15025 rt = (ctx->opcode >> 21) & 0x1f;
15026 rs = (ctx->opcode >> 16) & 0x1f;
15027 rd = (ctx->opcode >> 11) & 0x1f;
15028 rr = (ctx->opcode >> 6) & 0x1f;
15029 imm = (int16_t) ctx->opcode;
15031 op = (ctx->opcode >> 26) & 0x3f;
15034 minor = ctx->opcode & 0x3f;
15037 minor = (ctx->opcode >> 6) & 0xf;
15040 mips32_op = OPC_SLL;
15043 mips32_op = OPC_SRA;
15046 mips32_op = OPC_SRL;
15049 mips32_op = OPC_ROTR;
15051 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15054 check_insn(ctx, ISA_MIPS32R6);
15055 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15058 check_insn(ctx, ISA_MIPS32R6);
15059 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15062 check_insn(ctx, ISA_MIPS32R6);
15063 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15066 goto pool32a_invalid;
15070 minor = (ctx->opcode >> 6) & 0xf;
15074 mips32_op = OPC_ADD;
15077 mips32_op = OPC_ADDU;
15080 mips32_op = OPC_SUB;
15083 mips32_op = OPC_SUBU;
15086 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15087 mips32_op = OPC_MUL;
15089 gen_arith(ctx, mips32_op, rd, rs, rt);
15093 mips32_op = OPC_SLLV;
15096 mips32_op = OPC_SRLV;
15099 mips32_op = OPC_SRAV;
15102 mips32_op = OPC_ROTRV;
15104 gen_shift(ctx, mips32_op, rd, rs, rt);
15106 /* Logical operations */
15108 mips32_op = OPC_AND;
15111 mips32_op = OPC_OR;
15114 mips32_op = OPC_NOR;
15117 mips32_op = OPC_XOR;
15119 gen_logic(ctx, mips32_op, rd, rs, rt);
15121 /* Set less than */
15123 mips32_op = OPC_SLT;
15126 mips32_op = OPC_SLTU;
15128 gen_slt(ctx, mips32_op, rd, rs, rt);
15131 goto pool32a_invalid;
15135 minor = (ctx->opcode >> 6) & 0xf;
15137 /* Conditional moves */
15138 case MOVN: /* MUL */
15139 if (ctx->insn_flags & ISA_MIPS32R6) {
15141 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15144 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15147 case MOVZ: /* MUH */
15148 if (ctx->insn_flags & ISA_MIPS32R6) {
15150 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15153 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15157 check_insn(ctx, ISA_MIPS32R6);
15158 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15161 check_insn(ctx, ISA_MIPS32R6);
15162 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15164 case LWXS: /* DIV */
15165 if (ctx->insn_flags & ISA_MIPS32R6) {
15167 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15170 gen_ldxs(ctx, rs, rt, rd);
15174 check_insn(ctx, ISA_MIPS32R6);
15175 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15178 check_insn(ctx, ISA_MIPS32R6);
15179 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15182 check_insn(ctx, ISA_MIPS32R6);
15183 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15186 goto pool32a_invalid;
15190 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15193 check_insn(ctx, ISA_MIPS32R6);
15194 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15195 extract32(ctx->opcode, 9, 2));
15198 check_insn(ctx, ISA_MIPS32R6);
15199 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15202 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15205 gen_pool32axf(env, ctx, rt, rs);
15208 generate_exception_end(ctx, EXCP_BREAK);
15211 check_insn(ctx, ISA_MIPS32R6);
15212 generate_exception_end(ctx, EXCP_RI);
15216 MIPS_INVAL("pool32a");
15217 generate_exception_end(ctx, EXCP_RI);
15222 minor = (ctx->opcode >> 12) & 0xf;
15225 check_cp0_enabled(ctx);
15226 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15227 gen_cache_operation(ctx, rt, rs, imm);
15232 /* COP2: Not implemented. */
15233 generate_exception_err(ctx, EXCP_CpU, 2);
15235 #ifdef TARGET_MIPS64
15238 check_insn(ctx, ISA_MIPS3);
15239 check_mips_64(ctx);
15244 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15246 #ifdef TARGET_MIPS64
15249 check_insn(ctx, ISA_MIPS3);
15250 check_mips_64(ctx);
15255 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15258 MIPS_INVAL("pool32b");
15259 generate_exception_end(ctx, EXCP_RI);
15264 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15265 minor = ctx->opcode & 0x3f;
15266 check_cp1_enabled(ctx);
15269 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15270 mips32_op = OPC_ALNV_PS;
15273 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15274 mips32_op = OPC_MADD_S;
15277 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15278 mips32_op = OPC_MADD_D;
15281 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15282 mips32_op = OPC_MADD_PS;
15285 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15286 mips32_op = OPC_MSUB_S;
15289 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15290 mips32_op = OPC_MSUB_D;
15293 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15294 mips32_op = OPC_MSUB_PS;
15297 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15298 mips32_op = OPC_NMADD_S;
15301 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15302 mips32_op = OPC_NMADD_D;
15305 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15306 mips32_op = OPC_NMADD_PS;
15309 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15310 mips32_op = OPC_NMSUB_S;
15313 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15314 mips32_op = OPC_NMSUB_D;
15317 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15318 mips32_op = OPC_NMSUB_PS;
15320 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15322 case CABS_COND_FMT:
15323 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15324 cond = (ctx->opcode >> 6) & 0xf;
15325 cc = (ctx->opcode >> 13) & 0x7;
15326 fmt = (ctx->opcode >> 10) & 0x3;
15329 gen_cmpabs_s(ctx, cond, rt, rs, cc);
15332 gen_cmpabs_d(ctx, cond, rt, rs, cc);
15335 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15338 goto pool32f_invalid;
15342 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15343 cond = (ctx->opcode >> 6) & 0xf;
15344 cc = (ctx->opcode >> 13) & 0x7;
15345 fmt = (ctx->opcode >> 10) & 0x3;
15348 gen_cmp_s(ctx, cond, rt, rs, cc);
15351 gen_cmp_d(ctx, cond, rt, rs, cc);
15354 gen_cmp_ps(ctx, cond, rt, rs, cc);
15357 goto pool32f_invalid;
15361 check_insn(ctx, ISA_MIPS32R6);
15362 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15365 check_insn(ctx, ISA_MIPS32R6);
15366 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15369 gen_pool32fxf(ctx, rt, rs);
15373 switch ((ctx->opcode >> 6) & 0x7) {
15375 mips32_op = OPC_PLL_PS;
15378 mips32_op = OPC_PLU_PS;
15381 mips32_op = OPC_PUL_PS;
15384 mips32_op = OPC_PUU_PS;
15387 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15388 mips32_op = OPC_CVT_PS_S;
15390 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15393 goto pool32f_invalid;
15397 check_insn(ctx, ISA_MIPS32R6);
15398 switch ((ctx->opcode >> 9) & 0x3) {
15400 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15403 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15406 goto pool32f_invalid;
15411 switch ((ctx->opcode >> 6) & 0x7) {
15413 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15414 mips32_op = OPC_LWXC1;
15417 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15418 mips32_op = OPC_SWXC1;
15421 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15422 mips32_op = OPC_LDXC1;
15425 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15426 mips32_op = OPC_SDXC1;
15429 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15430 mips32_op = OPC_LUXC1;
15433 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15434 mips32_op = OPC_SUXC1;
15436 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
15439 goto pool32f_invalid;
15443 check_insn(ctx, ISA_MIPS32R6);
15444 switch ((ctx->opcode >> 9) & 0x3) {
15446 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
15449 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
15452 goto pool32f_invalid;
15457 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15458 fmt = (ctx->opcode >> 9) & 0x3;
15459 switch ((ctx->opcode >> 6) & 0x7) {
15463 mips32_op = OPC_RSQRT2_S;
15466 mips32_op = OPC_RSQRT2_D;
15469 mips32_op = OPC_RSQRT2_PS;
15472 goto pool32f_invalid;
15478 mips32_op = OPC_RECIP2_S;
15481 mips32_op = OPC_RECIP2_D;
15484 mips32_op = OPC_RECIP2_PS;
15487 goto pool32f_invalid;
15491 mips32_op = OPC_ADDR_PS;
15494 mips32_op = OPC_MULR_PS;
15496 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15499 goto pool32f_invalid;
15503 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15504 cc = (ctx->opcode >> 13) & 0x7;
15505 fmt = (ctx->opcode >> 9) & 0x3;
15506 switch ((ctx->opcode >> 6) & 0x7) {
15507 case MOVF_FMT: /* RINT_FMT */
15508 if (ctx->insn_flags & ISA_MIPS32R6) {
15512 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
15515 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
15518 goto pool32f_invalid;
15524 gen_movcf_s(ctx, rs, rt, cc, 0);
15527 gen_movcf_d(ctx, rs, rt, cc, 0);
15531 gen_movcf_ps(ctx, rs, rt, cc, 0);
15534 goto pool32f_invalid;
15538 case MOVT_FMT: /* CLASS_FMT */
15539 if (ctx->insn_flags & ISA_MIPS32R6) {
15543 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
15546 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
15549 goto pool32f_invalid;
15555 gen_movcf_s(ctx, rs, rt, cc, 1);
15558 gen_movcf_d(ctx, rs, rt, cc, 1);
15562 gen_movcf_ps(ctx, rs, rt, cc, 1);
15565 goto pool32f_invalid;
15570 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15573 goto pool32f_invalid;
15576 #define FINSN_3ARG_SDPS(prfx) \
15577 switch ((ctx->opcode >> 8) & 0x3) { \
15579 mips32_op = OPC_##prfx##_S; \
15582 mips32_op = OPC_##prfx##_D; \
15584 case FMT_SDPS_PS: \
15586 mips32_op = OPC_##prfx##_PS; \
15589 goto pool32f_invalid; \
15592 check_insn(ctx, ISA_MIPS32R6);
15593 switch ((ctx->opcode >> 9) & 0x3) {
15595 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
15598 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
15601 goto pool32f_invalid;
15605 check_insn(ctx, ISA_MIPS32R6);
15606 switch ((ctx->opcode >> 9) & 0x3) {
15608 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
15611 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
15614 goto pool32f_invalid;
15618 /* regular FP ops */
15619 switch ((ctx->opcode >> 6) & 0x3) {
15621 FINSN_3ARG_SDPS(ADD);
15624 FINSN_3ARG_SDPS(SUB);
15627 FINSN_3ARG_SDPS(MUL);
15630 fmt = (ctx->opcode >> 8) & 0x3;
15632 mips32_op = OPC_DIV_D;
15633 } else if (fmt == 0) {
15634 mips32_op = OPC_DIV_S;
15636 goto pool32f_invalid;
15640 goto pool32f_invalid;
15645 switch ((ctx->opcode >> 6) & 0x7) {
15646 case MOVN_FMT: /* SELEQZ_FMT */
15647 if (ctx->insn_flags & ISA_MIPS32R6) {
15649 switch ((ctx->opcode >> 9) & 0x3) {
15651 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
15654 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
15657 goto pool32f_invalid;
15661 FINSN_3ARG_SDPS(MOVN);
15665 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15666 FINSN_3ARG_SDPS(MOVN);
15668 case MOVZ_FMT: /* SELNEZ_FMT */
15669 if (ctx->insn_flags & ISA_MIPS32R6) {
15671 switch ((ctx->opcode >> 9) & 0x3) {
15673 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
15676 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
15679 goto pool32f_invalid;
15683 FINSN_3ARG_SDPS(MOVZ);
15687 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15688 FINSN_3ARG_SDPS(MOVZ);
15691 check_insn(ctx, ISA_MIPS32R6);
15692 switch ((ctx->opcode >> 9) & 0x3) {
15694 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
15697 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
15700 goto pool32f_invalid;
15704 check_insn(ctx, ISA_MIPS32R6);
15705 switch ((ctx->opcode >> 9) & 0x3) {
15707 mips32_op = OPC_MADDF_S;
15710 mips32_op = OPC_MADDF_D;
15713 goto pool32f_invalid;
15717 check_insn(ctx, ISA_MIPS32R6);
15718 switch ((ctx->opcode >> 9) & 0x3) {
15720 mips32_op = OPC_MSUBF_S;
15723 mips32_op = OPC_MSUBF_D;
15726 goto pool32f_invalid;
15730 goto pool32f_invalid;
15734 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15738 MIPS_INVAL("pool32f");
15739 generate_exception_end(ctx, EXCP_RI);
15743 generate_exception_err(ctx, EXCP_CpU, 1);
15747 minor = (ctx->opcode >> 21) & 0x1f;
15750 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15751 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
15754 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15755 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
15756 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15759 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15760 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
15761 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15764 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15765 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
15768 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15769 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
15770 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15773 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15774 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
15775 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15778 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15779 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
15782 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15783 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
15787 case TLTI: /* BC1EQZC */
15788 if (ctx->insn_flags & ISA_MIPS32R6) {
15790 check_cp1_enabled(ctx);
15791 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
15794 mips32_op = OPC_TLTI;
15798 case TGEI: /* BC1NEZC */
15799 if (ctx->insn_flags & ISA_MIPS32R6) {
15801 check_cp1_enabled(ctx);
15802 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
15805 mips32_op = OPC_TGEI;
15810 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15811 mips32_op = OPC_TLTIU;
15814 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15815 mips32_op = OPC_TGEIU;
15817 case TNEI: /* SYNCI */
15818 if (ctx->insn_flags & ISA_MIPS32R6) {
15820 /* Break the TB to be able to sync copied instructions
15822 ctx->base.is_jmp = DISAS_STOP;
15825 mips32_op = OPC_TNEI;
15830 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15831 mips32_op = OPC_TEQI;
15833 gen_trap(ctx, mips32_op, rs, -1, imm);
15838 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15839 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
15840 4, rs, 0, imm << 1, 0);
15841 /* Compact branches don't have a delay slot, so just let
15842 the normal delay slot handling take us to the branch
15846 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15847 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
15850 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15851 /* Break the TB to be able to sync copied instructions
15853 ctx->base.is_jmp = DISAS_STOP;
15857 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15858 /* COP2: Not implemented. */
15859 generate_exception_err(ctx, EXCP_CpU, 2);
15862 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15863 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
15866 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15867 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
15870 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15871 mips32_op = OPC_BC1FANY4;
15874 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15875 mips32_op = OPC_BC1TANY4;
15878 check_insn(ctx, ASE_MIPS3D);
15881 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15882 check_cp1_enabled(ctx);
15883 gen_compute_branch1(ctx, mips32_op,
15884 (ctx->opcode >> 18) & 0x7, imm << 1);
15886 generate_exception_err(ctx, EXCP_CpU, 1);
15891 /* MIPS DSP: not implemented */
15894 MIPS_INVAL("pool32i");
15895 generate_exception_end(ctx, EXCP_RI);
15900 minor = (ctx->opcode >> 12) & 0xf;
15901 offset = sextract32(ctx->opcode, 0,
15902 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
15905 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15906 mips32_op = OPC_LWL;
15909 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15910 mips32_op = OPC_SWL;
15913 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15914 mips32_op = OPC_LWR;
15917 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15918 mips32_op = OPC_SWR;
15920 #if defined(TARGET_MIPS64)
15922 check_insn(ctx, ISA_MIPS3);
15923 check_mips_64(ctx);
15924 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15925 mips32_op = OPC_LDL;
15928 check_insn(ctx, ISA_MIPS3);
15929 check_mips_64(ctx);
15930 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15931 mips32_op = OPC_SDL;
15934 check_insn(ctx, ISA_MIPS3);
15935 check_mips_64(ctx);
15936 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15937 mips32_op = OPC_LDR;
15940 check_insn(ctx, ISA_MIPS3);
15941 check_mips_64(ctx);
15942 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15943 mips32_op = OPC_SDR;
15946 check_insn(ctx, ISA_MIPS3);
15947 check_mips_64(ctx);
15948 mips32_op = OPC_LWU;
15951 check_insn(ctx, ISA_MIPS3);
15952 check_mips_64(ctx);
15953 mips32_op = OPC_LLD;
15957 mips32_op = OPC_LL;
15960 gen_ld(ctx, mips32_op, rt, rs, offset);
15963 gen_st(ctx, mips32_op, rt, rs, offset);
15966 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
15968 #if defined(TARGET_MIPS64)
15970 check_insn(ctx, ISA_MIPS3);
15971 check_mips_64(ctx);
15972 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
15977 MIPS_INVAL("pool32c ld-eva");
15978 generate_exception_end(ctx, EXCP_RI);
15981 check_cp0_enabled(ctx);
15983 minor2 = (ctx->opcode >> 9) & 0x7;
15984 offset = sextract32(ctx->opcode, 0, 9);
15987 mips32_op = OPC_LBUE;
15990 mips32_op = OPC_LHUE;
15993 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15994 mips32_op = OPC_LWLE;
15997 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15998 mips32_op = OPC_LWRE;
16001 mips32_op = OPC_LBE;
16004 mips32_op = OPC_LHE;
16007 mips32_op = OPC_LLE;
16010 mips32_op = OPC_LWE;
16016 MIPS_INVAL("pool32c st-eva");
16017 generate_exception_end(ctx, EXCP_RI);
16020 check_cp0_enabled(ctx);
16022 minor2 = (ctx->opcode >> 9) & 0x7;
16023 offset = sextract32(ctx->opcode, 0, 9);
16026 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16027 mips32_op = OPC_SWLE;
16030 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16031 mips32_op = OPC_SWRE;
16034 /* Treat as no-op */
16035 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16036 /* hint codes 24-31 are reserved and signal RI */
16037 generate_exception(ctx, EXCP_RI);
16041 /* Treat as no-op */
16042 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16043 gen_cache_operation(ctx, rt, rs, offset);
16047 mips32_op = OPC_SBE;
16050 mips32_op = OPC_SHE;
16053 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16056 mips32_op = OPC_SWE;
16061 /* Treat as no-op */
16062 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16063 /* hint codes 24-31 are reserved and signal RI */
16064 generate_exception(ctx, EXCP_RI);
16068 MIPS_INVAL("pool32c");
16069 generate_exception_end(ctx, EXCP_RI);
16073 case ADDI32: /* AUI, LUI */
16074 if (ctx->insn_flags & ISA_MIPS32R6) {
16076 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16079 mips32_op = OPC_ADDI;
16084 mips32_op = OPC_ADDIU;
16086 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16089 /* Logical operations */
16091 mips32_op = OPC_ORI;
16094 mips32_op = OPC_XORI;
16097 mips32_op = OPC_ANDI;
16099 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16102 /* Set less than immediate */
16104 mips32_op = OPC_SLTI;
16107 mips32_op = OPC_SLTIU;
16109 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16112 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16113 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16114 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16115 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16117 case JALS32: /* BOVC, BEQC, BEQZALC */
16118 if (ctx->insn_flags & ISA_MIPS32R6) {
16121 mips32_op = OPC_BOVC;
16122 } else if (rs < rt && rs == 0) {
16124 mips32_op = OPC_BEQZALC;
16127 mips32_op = OPC_BEQC;
16129 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16132 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16133 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16134 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16137 case BEQ32: /* BC */
16138 if (ctx->insn_flags & ISA_MIPS32R6) {
16140 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16141 sextract32(ctx->opcode << 1, 0, 27));
16144 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16147 case BNE32: /* BALC */
16148 if (ctx->insn_flags & ISA_MIPS32R6) {
16150 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16151 sextract32(ctx->opcode << 1, 0, 27));
16154 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16157 case J32: /* BGTZC, BLTZC, BLTC */
16158 if (ctx->insn_flags & ISA_MIPS32R6) {
16159 if (rs == 0 && rt != 0) {
16161 mips32_op = OPC_BGTZC;
16162 } else if (rs != 0 && rt != 0 && rs == rt) {
16164 mips32_op = OPC_BLTZC;
16167 mips32_op = OPC_BLTC;
16169 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16172 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16173 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16176 case JAL32: /* BLEZC, BGEZC, BGEC */
16177 if (ctx->insn_flags & ISA_MIPS32R6) {
16178 if (rs == 0 && rt != 0) {
16180 mips32_op = OPC_BLEZC;
16181 } else if (rs != 0 && rt != 0 && rs == rt) {
16183 mips32_op = OPC_BGEZC;
16186 mips32_op = OPC_BGEC;
16188 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16191 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16192 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16193 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16196 /* Floating point (COP1) */
16198 mips32_op = OPC_LWC1;
16201 mips32_op = OPC_LDC1;
16204 mips32_op = OPC_SWC1;
16207 mips32_op = OPC_SDC1;
16209 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16211 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16212 if (ctx->insn_flags & ISA_MIPS32R6) {
16213 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16214 switch ((ctx->opcode >> 16) & 0x1f) {
16223 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16226 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16229 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16239 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16242 generate_exception(ctx, EXCP_RI);
16247 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16248 offset = SIMM(ctx->opcode, 0, 23) << 2;
16250 gen_addiupc(ctx, reg, offset, 0, 0);
16253 case BNVC: /* BNEC, BNEZALC */
16254 check_insn(ctx, ISA_MIPS32R6);
16257 mips32_op = OPC_BNVC;
16258 } else if (rs < rt && rs == 0) {
16260 mips32_op = OPC_BNEZALC;
16263 mips32_op = OPC_BNEC;
16265 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16267 case R6_BNEZC: /* JIALC */
16268 check_insn(ctx, ISA_MIPS32R6);
16271 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16272 sextract32(ctx->opcode << 1, 0, 22));
16275 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16278 case R6_BEQZC: /* JIC */
16279 check_insn(ctx, ISA_MIPS32R6);
16282 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16283 sextract32(ctx->opcode << 1, 0, 22));
16286 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16289 case BLEZALC: /* BGEZALC, BGEUC */
16290 check_insn(ctx, ISA_MIPS32R6);
16291 if (rs == 0 && rt != 0) {
16293 mips32_op = OPC_BLEZALC;
16294 } else if (rs != 0 && rt != 0 && rs == rt) {
16296 mips32_op = OPC_BGEZALC;
16299 mips32_op = OPC_BGEUC;
16301 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16303 case BGTZALC: /* BLTZALC, BLTUC */
16304 check_insn(ctx, ISA_MIPS32R6);
16305 if (rs == 0 && rt != 0) {
16307 mips32_op = OPC_BGTZALC;
16308 } else if (rs != 0 && rt != 0 && rs == rt) {
16310 mips32_op = OPC_BLTZALC;
16313 mips32_op = OPC_BLTUC;
16315 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16317 /* Loads and stores */
16319 mips32_op = OPC_LB;
16322 mips32_op = OPC_LBU;
16325 mips32_op = OPC_LH;
16328 mips32_op = OPC_LHU;
16331 mips32_op = OPC_LW;
16333 #ifdef TARGET_MIPS64
16335 check_insn(ctx, ISA_MIPS3);
16336 check_mips_64(ctx);
16337 mips32_op = OPC_LD;
16340 check_insn(ctx, ISA_MIPS3);
16341 check_mips_64(ctx);
16342 mips32_op = OPC_SD;
16346 mips32_op = OPC_SB;
16349 mips32_op = OPC_SH;
16352 mips32_op = OPC_SW;
16355 gen_ld(ctx, mips32_op, rt, rs, imm);
16358 gen_st(ctx, mips32_op, rt, rs, imm);
16361 generate_exception_end(ctx, EXCP_RI);
16366 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
16370 /* make sure instructions are on a halfword boundary */
16371 if (ctx->base.pc_next & 0x1) {
16372 env->CP0_BadVAddr = ctx->base.pc_next;
16373 generate_exception_end(ctx, EXCP_AdEL);
16377 op = (ctx->opcode >> 10) & 0x3f;
16378 /* Enforce properly-sized instructions in a delay slot */
16379 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16380 switch (op & 0x7) { /* MSB-3..MSB-5 */
16382 /* POOL32A, POOL32B, POOL32I, POOL32C */
16384 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16386 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16388 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16390 /* LB32, LH32, LWC132, LDC132, LW32 */
16391 if (ctx->hflags & MIPS_HFLAG_BDS16) {
16392 generate_exception_end(ctx, EXCP_RI);
16397 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16399 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16401 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16402 if (ctx->hflags & MIPS_HFLAG_BDS32) {
16403 generate_exception_end(ctx, EXCP_RI);
16413 int rd = mmreg(uMIPS_RD(ctx->opcode));
16414 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16415 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16418 switch (ctx->opcode & 0x1) {
16426 if (ctx->insn_flags & ISA_MIPS32R6) {
16427 /* In the Release 6 the register number location in
16428 * the instruction encoding has changed.
16430 gen_arith(ctx, opc, rs1, rd, rs2);
16432 gen_arith(ctx, opc, rd, rs1, rs2);
16438 int rd = mmreg(uMIPS_RD(ctx->opcode));
16439 int rs = mmreg(uMIPS_RS(ctx->opcode));
16440 int amount = (ctx->opcode >> 1) & 0x7;
16442 amount = amount == 0 ? 8 : amount;
16444 switch (ctx->opcode & 0x1) {
16453 gen_shift_imm(ctx, opc, rd, rs, amount);
16457 if (ctx->insn_flags & ISA_MIPS32R6) {
16458 gen_pool16c_r6_insn(ctx);
16460 gen_pool16c_insn(ctx);
16465 int rd = mmreg(uMIPS_RD(ctx->opcode));
16466 int rb = 28; /* GP */
16467 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
16469 gen_ld(ctx, OPC_LW, rd, rb, offset);
16473 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16474 if (ctx->opcode & 1) {
16475 generate_exception_end(ctx, EXCP_RI);
16478 int enc_dest = uMIPS_RD(ctx->opcode);
16479 int enc_rt = uMIPS_RS2(ctx->opcode);
16480 int enc_rs = uMIPS_RS1(ctx->opcode);
16481 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
16486 int rd = mmreg(uMIPS_RD(ctx->opcode));
16487 int rb = mmreg(uMIPS_RS(ctx->opcode));
16488 int16_t offset = ZIMM(ctx->opcode, 0, 4);
16489 offset = (offset == 0xf ? -1 : offset);
16491 gen_ld(ctx, OPC_LBU, rd, rb, offset);
16496 int rd = mmreg(uMIPS_RD(ctx->opcode));
16497 int rb = mmreg(uMIPS_RS(ctx->opcode));
16498 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16500 gen_ld(ctx, OPC_LHU, rd, rb, offset);
16505 int rd = (ctx->opcode >> 5) & 0x1f;
16506 int rb = 29; /* SP */
16507 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16509 gen_ld(ctx, OPC_LW, rd, rb, offset);
16514 int rd = mmreg(uMIPS_RD(ctx->opcode));
16515 int rb = mmreg(uMIPS_RS(ctx->opcode));
16516 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16518 gen_ld(ctx, OPC_LW, rd, rb, offset);
16523 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16524 int rb = mmreg(uMIPS_RS(ctx->opcode));
16525 int16_t offset = ZIMM(ctx->opcode, 0, 4);
16527 gen_st(ctx, OPC_SB, rd, rb, offset);
16532 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16533 int rb = mmreg(uMIPS_RS(ctx->opcode));
16534 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16536 gen_st(ctx, OPC_SH, rd, rb, offset);
16541 int rd = (ctx->opcode >> 5) & 0x1f;
16542 int rb = 29; /* SP */
16543 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16545 gen_st(ctx, OPC_SW, rd, rb, offset);
16550 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16551 int rb = mmreg(uMIPS_RS(ctx->opcode));
16552 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16554 gen_st(ctx, OPC_SW, rd, rb, offset);
16559 int rd = uMIPS_RD5(ctx->opcode);
16560 int rs = uMIPS_RS5(ctx->opcode);
16562 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
16569 switch (ctx->opcode & 0x1) {
16579 switch (ctx->opcode & 0x1) {
16584 gen_addiur1sp(ctx);
16588 case B16: /* BC16 */
16589 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
16590 sextract32(ctx->opcode, 0, 10) << 1,
16591 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16593 case BNEZ16: /* BNEZC16 */
16594 case BEQZ16: /* BEQZC16 */
16595 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
16596 mmreg(uMIPS_RD(ctx->opcode)),
16597 0, sextract32(ctx->opcode, 0, 7) << 1,
16598 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16603 int reg = mmreg(uMIPS_RD(ctx->opcode));
16604 int imm = ZIMM(ctx->opcode, 0, 7);
16606 imm = (imm == 0x7f ? -1 : imm);
16607 tcg_gen_movi_tl(cpu_gpr[reg], imm);
16613 generate_exception_end(ctx, EXCP_RI);
16616 decode_micromips32_opc(env, ctx);
16629 /* MAJOR, P16, and P32 pools opcodes */
16633 NM_MOVE_BALC = 0x02,
16641 NM_P16_SHIFT = 0x0c,
16659 NM_P_LS_U12 = 0x21,
16669 NM_P16_ADDU = 0x2c,
16683 NM_MOVEPREV = 0x3f,
16686 /* POOL32A instruction pool */
16688 NM_POOL32A0 = 0x00,
16689 NM_SPECIAL2 = 0x01,
16692 NM_POOL32A5 = 0x05,
16693 NM_POOL32A7 = 0x07,
16696 /* P.GP.W instruction pool */
16698 NM_ADDIUGP_W = 0x00,
16703 /* P48I instruction pool */
16707 NM_ADDIUGP48 = 0x02,
16708 NM_ADDIUPC48 = 0x03,
16713 /* P.U12 instruction pool */
16722 NM_ADDIUNEG = 0x08,
16729 /* POOL32F instruction pool */
16731 NM_POOL32F_0 = 0x00,
16732 NM_POOL32F_3 = 0x03,
16733 NM_POOL32F_5 = 0x05,
16736 /* POOL32S instruction pool */
16738 NM_POOL32S_0 = 0x00,
16739 NM_POOL32S_4 = 0x04,
16742 /* P.LUI instruction pool */
16748 /* P.GP.BH instruction pool */
16753 NM_ADDIUGP_B = 0x03,
16756 NM_P_GP_CP1 = 0x06,
16759 /* P.LS.U12 instruction pool */
16764 NM_P_PREFU12 = 0x03,
16777 /* P.LS.S9 instruction pool */
16783 NM_P_LS_UAWM = 0x05,
16786 /* P.BAL instruction pool */
16792 /* P.J instruction pool */
16795 NM_JALRC_HB = 0x01,
16796 NM_P_BALRSC = 0x08,
16799 /* P.BR1 instruction pool */
16807 /* P.BR2 instruction pool */
16814 /* P.BRI instruction pool */
16826 /* P16.SHIFT instruction pool */
16832 /* POOL16C instruction pool */
16834 NM_POOL16C_0 = 0x00,
16838 /* P16.A1 instruction pool */
16840 NM_ADDIUR1SP = 0x01,
16843 /* P16.A2 instruction pool */
16846 NM_P_ADDIURS5 = 0x01,
16849 /* P16.ADDU instruction pool */
16855 /* P16.SR instruction pool */
16858 NM_RESTORE_JRC16 = 0x01,
16861 /* P16.4X4 instruction pool */
16867 /* P16.LB instruction pool */
16874 /* P16.LH instruction pool */
16881 /* P.RI instruction pool */
16884 NM_P_SYSCALL = 0x01,
16889 /* POOL32A0 instruction pool */
16924 NM_D_E_MT_VPE = 0x56,
16932 /* POOL32A5 instruction pool */
16934 NM_CMP_EQ_PH = 0x00,
16935 NM_CMP_LT_PH = 0x08,
16936 NM_CMP_LE_PH = 0x10,
16937 NM_CMPGU_EQ_QB = 0x18,
16938 NM_CMPGU_LT_QB = 0x20,
16939 NM_CMPGU_LE_QB = 0x28,
16940 NM_CMPGDU_EQ_QB = 0x30,
16941 NM_CMPGDU_LT_QB = 0x38,
16942 NM_CMPGDU_LE_QB = 0x40,
16943 NM_CMPU_EQ_QB = 0x48,
16944 NM_CMPU_LT_QB = 0x50,
16945 NM_CMPU_LE_QB = 0x58,
16946 NM_ADDQ_S_W = 0x60,
16947 NM_SUBQ_S_W = 0x68,
16951 NM_ADDQ_S_PH = 0x01,
16952 NM_ADDQH_R_PH = 0x09,
16953 NM_ADDQH_R_W = 0x11,
16954 NM_ADDU_S_QB = 0x19,
16955 NM_ADDU_S_PH = 0x21,
16956 NM_ADDUH_R_QB = 0x29,
16957 NM_SHRAV_R_PH = 0x31,
16958 NM_SHRAV_R_QB = 0x39,
16959 NM_SUBQ_S_PH = 0x41,
16960 NM_SUBQH_R_PH = 0x49,
16961 NM_SUBQH_R_W = 0x51,
16962 NM_SUBU_S_QB = 0x59,
16963 NM_SUBU_S_PH = 0x61,
16964 NM_SUBUH_R_QB = 0x69,
16965 NM_SHLLV_S_PH = 0x71,
16966 NM_PRECR_SRA_R_PH_W = 0x79,
16968 NM_MULEU_S_PH_QBL = 0x12,
16969 NM_MULEU_S_PH_QBR = 0x1a,
16970 NM_MULQ_RS_PH = 0x22,
16971 NM_MULQ_S_PH = 0x2a,
16972 NM_MULQ_RS_W = 0x32,
16973 NM_MULQ_S_W = 0x3a,
16976 NM_SHRAV_R_W = 0x5a,
16977 NM_SHRLV_PH = 0x62,
16978 NM_SHRLV_QB = 0x6a,
16979 NM_SHLLV_QB = 0x72,
16980 NM_SHLLV_S_W = 0x7a,
16984 NM_MULEQ_S_W_PHL = 0x04,
16985 NM_MULEQ_S_W_PHR = 0x0c,
16987 NM_MUL_S_PH = 0x05,
16988 NM_PRECR_QB_PH = 0x0d,
16989 NM_PRECRQ_QB_PH = 0x15,
16990 NM_PRECRQ_PH_W = 0x1d,
16991 NM_PRECRQ_RS_PH_W = 0x25,
16992 NM_PRECRQU_S_QB_PH = 0x2d,
16993 NM_PACKRL_PH = 0x35,
16997 NM_SHRA_R_W = 0x5e,
16998 NM_SHRA_R_PH = 0x66,
16999 NM_SHLL_S_PH = 0x76,
17000 NM_SHLL_S_W = 0x7e,
17005 /* POOL32A7 instruction pool */
17010 NM_POOL32AXF = 0x07,
17013 /* P.SR instruction pool */
17019 /* P.SHIFT instruction pool */
17027 /* P.ROTX instruction pool */
17032 /* P.INS instruction pool */
17037 /* P.EXT instruction pool */
17042 /* POOL32F_0 (fmt) instruction pool */
17047 NM_SELEQZ_S = 0x07,
17048 NM_SELEQZ_D = 0x47,
17052 NM_SELNEZ_S = 0x0f,
17053 NM_SELNEZ_D = 0x4f,
17068 /* POOL32F_3 instruction pool */
17072 NM_MINA_FMT = 0x04,
17073 NM_MAXA_FMT = 0x05,
17074 NM_POOL32FXF = 0x07,
17077 /* POOL32F_5 instruction pool */
17079 NM_CMP_CONDN_S = 0x00,
17080 NM_CMP_CONDN_D = 0x02,
17083 /* P.GP.LH instruction pool */
17089 /* P.GP.SH instruction pool */
17094 /* P.GP.CP1 instruction pool */
17102 /* P.LS.S0 instruction pool */
17119 NM_P_PREFS9 = 0x03,
17125 /* P.LS.S1 instruction pool */
17127 NM_ASET_ACLR = 0x02,
17135 /* P.LS.WM instruction pool */
17141 /* P.LS.UAWM instruction pool */
17147 /* P.BR3A instruction pool */
17153 NM_BPOSGE32C = 0x04,
17156 /* P16.RI instruction pool */
17158 NM_P16_SYSCALL = 0x01,
17163 /* POOL16C_0 instruction pool */
17165 NM_POOL16C_00 = 0x00,
17168 /* P16.JRC instruction pool */
17174 /* P.SYSCALL instruction pool */
17180 /* P.TRAP instruction pool */
17186 /* P.CMOVE instruction pool */
17192 /* POOL32Axf instruction pool */
17194 NM_POOL32AXF_1 = 0x01,
17195 NM_POOL32AXF_2 = 0x02,
17196 NM_POOL32AXF_4 = 0x04,
17197 NM_POOL32AXF_5 = 0x05,
17198 NM_POOL32AXF_7 = 0x07,
17201 /* POOL32Axf_1 instruction pool */
17203 NM_POOL32AXF_1_0 = 0x00,
17204 NM_POOL32AXF_1_1 = 0x01,
17205 NM_POOL32AXF_1_3 = 0x03,
17206 NM_POOL32AXF_1_4 = 0x04,
17207 NM_POOL32AXF_1_5 = 0x05,
17208 NM_POOL32AXF_1_7 = 0x07,
17211 /* POOL32Axf_2 instruction pool */
17213 NM_POOL32AXF_2_0_7 = 0x00,
17214 NM_POOL32AXF_2_8_15 = 0x01,
17215 NM_POOL32AXF_2_16_23 = 0x02,
17216 NM_POOL32AXF_2_24_31 = 0x03,
17219 /* POOL32Axf_7 instruction pool */
17221 NM_SHRA_R_QB = 0x0,
17226 /* POOL32Axf_1_0 instruction pool */
17234 /* POOL32Axf_1_1 instruction pool */
17240 /* POOL32Axf_1_3 instruction pool */
17248 /* POOL32Axf_1_4 instruction pool */
17254 /* POOL32Axf_1_5 instruction pool */
17256 NM_MAQ_S_W_PHR = 0x0,
17257 NM_MAQ_S_W_PHL = 0x1,
17258 NM_MAQ_SA_W_PHR = 0x2,
17259 NM_MAQ_SA_W_PHL = 0x3,
17262 /* POOL32Axf_1_7 instruction pool */
17266 NM_EXTR_RS_W = 0x2,
17270 /* POOL32Axf_2_0_7 instruction pool */
17273 NM_DPAQ_S_W_PH = 0x1,
17275 NM_DPSQ_S_W_PH = 0x3,
17282 /* POOL32Axf_2_8_15 instruction pool */
17284 NM_DPAX_W_PH = 0x0,
17285 NM_DPAQ_SA_L_W = 0x1,
17286 NM_DPSX_W_PH = 0x2,
17287 NM_DPSQ_SA_L_W = 0x3,
17290 NM_EXTRV_R_W = 0x7,
17293 /* POOL32Axf_2_16_23 instruction pool */
17295 NM_DPAU_H_QBL = 0x0,
17296 NM_DPAQX_S_W_PH = 0x1,
17297 NM_DPSU_H_QBL = 0x2,
17298 NM_DPSQX_S_W_PH = 0x3,
17301 NM_MULSA_W_PH = 0x6,
17302 NM_EXTRV_RS_W = 0x7,
17305 /* POOL32Axf_2_24_31 instruction pool */
17307 NM_DPAU_H_QBR = 0x0,
17308 NM_DPAQX_SA_W_PH = 0x1,
17309 NM_DPSU_H_QBR = 0x2,
17310 NM_DPSQX_SA_W_PH = 0x3,
17313 NM_MULSAQ_S_W_PH = 0x6,
17314 NM_EXTRV_S_H = 0x7,
17317 /* POOL32Axf_{4, 5} instruction pool */
17336 /* nanoMIPS DSP instructions */
17337 NM_ABSQ_S_QB = 0x00,
17338 NM_ABSQ_S_PH = 0x08,
17339 NM_ABSQ_S_W = 0x10,
17340 NM_PRECEQ_W_PHL = 0x28,
17341 NM_PRECEQ_W_PHR = 0x30,
17342 NM_PRECEQU_PH_QBL = 0x38,
17343 NM_PRECEQU_PH_QBR = 0x48,
17344 NM_PRECEU_PH_QBL = 0x58,
17345 NM_PRECEU_PH_QBR = 0x68,
17346 NM_PRECEQU_PH_QBLA = 0x39,
17347 NM_PRECEQU_PH_QBRA = 0x49,
17348 NM_PRECEU_PH_QBLA = 0x59,
17349 NM_PRECEU_PH_QBRA = 0x69,
17350 NM_REPLV_PH = 0x01,
17351 NM_REPLV_QB = 0x09,
17354 NM_RADDU_W_QB = 0x78,
17360 /* PP.SR instruction pool */
17364 NM_RESTORE_JRC = 0x03,
17367 /* P.SR.F instruction pool */
17370 NM_RESTOREF = 0x01,
17373 /* P16.SYSCALL instruction pool */
17375 NM_SYSCALL16 = 0x00,
17376 NM_HYPCALL16 = 0x01,
17379 /* POOL16C_00 instruction pool */
17387 /* PP.LSX and PP.LSXS instruction pool */
17425 /* ERETx instruction pool */
17431 /* POOL32FxF_{0, 1} insturction pool */
17440 NM_CVT_S_PL = 0x84,
17441 NM_CVT_S_PU = 0xa4,
17443 NM_CVT_L_S = 0x004,
17444 NM_CVT_L_D = 0x104,
17445 NM_CVT_W_S = 0x024,
17446 NM_CVT_W_D = 0x124,
17448 NM_RSQRT_S = 0x008,
17449 NM_RSQRT_D = 0x108,
17454 NM_RECIP_S = 0x048,
17455 NM_RECIP_D = 0x148,
17457 NM_FLOOR_L_S = 0x00c,
17458 NM_FLOOR_L_D = 0x10c,
17460 NM_FLOOR_W_S = 0x02c,
17461 NM_FLOOR_W_D = 0x12c,
17463 NM_CEIL_L_S = 0x04c,
17464 NM_CEIL_L_D = 0x14c,
17465 NM_CEIL_W_S = 0x06c,
17466 NM_CEIL_W_D = 0x16c,
17467 NM_TRUNC_L_S = 0x08c,
17468 NM_TRUNC_L_D = 0x18c,
17469 NM_TRUNC_W_S = 0x0ac,
17470 NM_TRUNC_W_D = 0x1ac,
17471 NM_ROUND_L_S = 0x0cc,
17472 NM_ROUND_L_D = 0x1cc,
17473 NM_ROUND_W_S = 0x0ec,
17474 NM_ROUND_W_D = 0x1ec,
17482 NM_CVT_D_S = 0x04d,
17483 NM_CVT_D_W = 0x0cd,
17484 NM_CVT_D_L = 0x14d,
17485 NM_CVT_S_D = 0x06d,
17486 NM_CVT_S_W = 0x0ed,
17487 NM_CVT_S_L = 0x16d,
17490 /* P.LL instruction pool */
17496 /* P.SC instruction pool */
17502 /* P.DVP instruction pool */
17511 * nanoMIPS decoding engine
17516 /* extraction utilities */
17518 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17519 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17520 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17521 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17522 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17523 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17525 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17526 static inline int decode_gpr_gpr3(int r)
17528 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17530 return map[r & 0x7];
17533 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17534 static inline int decode_gpr_gpr3_src_store(int r)
17536 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
17538 return map[r & 0x7];
17541 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17542 static inline int decode_gpr_gpr4(int r)
17544 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
17545 16, 17, 18, 19, 20, 21, 22, 23 };
17547 return map[r & 0xf];
17550 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17551 static inline int decode_gpr_gpr4_zero(int r)
17553 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
17554 16, 17, 18, 19, 20, 21, 22, 23 };
17556 return map[r & 0xf];
17560 /* extraction utilities */
17562 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17563 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17564 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17565 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17566 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17567 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17570 static void gen_adjust_sp(DisasContext *ctx, int u)
17572 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
17575 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
17576 uint8_t gp, uint16_t u)
17579 TCGv va = tcg_temp_new();
17580 TCGv t0 = tcg_temp_new();
17582 while (counter != count) {
17583 bool use_gp = gp && (counter == count - 1);
17584 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17585 int this_offset = -((counter + 1) << 2);
17586 gen_base_offset_addr(ctx, va, 29, this_offset);
17587 gen_load_gpr(t0, this_rt);
17588 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
17589 (MO_TEUL | ctx->default_tcg_memop_mask));
17593 /* adjust stack pointer */
17594 gen_adjust_sp(ctx, -u);
17600 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
17601 uint8_t gp, uint16_t u)
17604 TCGv va = tcg_temp_new();
17605 TCGv t0 = tcg_temp_new();
17607 while (counter != count) {
17608 bool use_gp = gp && (counter == count - 1);
17609 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17610 int this_offset = u - ((counter + 1) << 2);
17611 gen_base_offset_addr(ctx, va, 29, this_offset);
17612 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
17613 ctx->default_tcg_memop_mask);
17614 tcg_gen_ext32s_tl(t0, t0);
17615 gen_store_gpr(t0, this_rt);
17619 /* adjust stack pointer */
17620 gen_adjust_sp(ctx, u);
17626 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
17628 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
17629 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
17631 switch (extract32(ctx->opcode, 2, 2)) {
17633 gen_logic(ctx, OPC_NOR, rt, rs, 0);
17636 gen_logic(ctx, OPC_AND, rt, rt, rs);
17639 gen_logic(ctx, OPC_XOR, rt, rt, rs);
17642 gen_logic(ctx, OPC_OR, rt, rt, rs);
17647 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
17649 int rt = extract32(ctx->opcode, 21, 5);
17650 int rs = extract32(ctx->opcode, 16, 5);
17651 int rd = extract32(ctx->opcode, 11, 5);
17653 switch (extract32(ctx->opcode, 3, 7)) {
17655 switch (extract32(ctx->opcode, 10, 1)) {
17658 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
17662 gen_trap(ctx, OPC_TNE, rs, rt, -1);
17668 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
17672 gen_bshfl(ctx, OPC_SEB, rs, rt);
17675 gen_bshfl(ctx, OPC_SEH, rs, rt);
17678 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
17681 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
17684 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
17687 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
17690 gen_arith(ctx, OPC_ADD, rd, rs, rt);
17693 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
17697 gen_arith(ctx, OPC_SUB, rd, rs, rt);
17700 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
17703 switch (extract32(ctx->opcode, 10, 1)) {
17705 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
17708 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
17713 gen_logic(ctx, OPC_AND, rd, rs, rt);
17716 gen_logic(ctx, OPC_OR, rd, rs, rt);
17719 gen_logic(ctx, OPC_NOR, rd, rs, rt);
17722 gen_logic(ctx, OPC_XOR, rd, rs, rt);
17725 gen_slt(ctx, OPC_SLT, rd, rs, rt);
17730 #ifndef CONFIG_USER_ONLY
17731 TCGv t0 = tcg_temp_new();
17732 switch (extract32(ctx->opcode, 10, 1)) {
17735 check_cp0_enabled(ctx);
17736 gen_helper_dvp(t0, cpu_env);
17737 gen_store_gpr(t0, rt);
17742 check_cp0_enabled(ctx);
17743 gen_helper_evp(t0, cpu_env);
17744 gen_store_gpr(t0, rt);
17751 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
17756 TCGv t0 = tcg_temp_new();
17757 TCGv t1 = tcg_temp_new();
17758 TCGv t2 = tcg_temp_new();
17760 gen_load_gpr(t1, rs);
17761 gen_load_gpr(t2, rt);
17762 tcg_gen_add_tl(t0, t1, t2);
17763 tcg_gen_ext32s_tl(t0, t0);
17764 tcg_gen_xor_tl(t1, t1, t2);
17765 tcg_gen_xor_tl(t2, t0, t2);
17766 tcg_gen_andc_tl(t1, t2, t1);
17768 /* operands of same sign, result different sign */
17769 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
17770 gen_store_gpr(t0, rd);
17778 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
17781 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
17784 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
17787 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
17790 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
17793 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
17796 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
17799 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
17801 #ifndef CONFIG_USER_ONLY
17803 check_cp0_enabled(ctx);
17805 /* Treat as NOP. */
17808 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
17811 check_cp0_enabled(ctx);
17813 TCGv t0 = tcg_temp_new();
17815 gen_load_gpr(t0, rt);
17816 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
17820 case NM_D_E_MT_VPE:
17822 uint8_t sc = extract32(ctx->opcode, 10, 1);
17823 TCGv t0 = tcg_temp_new();
17830 gen_helper_dmt(t0);
17831 gen_store_gpr(t0, rt);
17832 } else if (rs == 0) {
17835 gen_helper_dvpe(t0, cpu_env);
17836 gen_store_gpr(t0, rt);
17838 generate_exception_end(ctx, EXCP_RI);
17845 gen_helper_emt(t0);
17846 gen_store_gpr(t0, rt);
17847 } else if (rs == 0) {
17850 gen_helper_evpe(t0, cpu_env);
17851 gen_store_gpr(t0, rt);
17853 generate_exception_end(ctx, EXCP_RI);
17864 TCGv t0 = tcg_temp_new();
17865 TCGv t1 = tcg_temp_new();
17867 gen_load_gpr(t0, rt);
17868 gen_load_gpr(t1, rs);
17869 gen_helper_fork(t0, t1);
17876 check_cp0_enabled(ctx);
17878 /* Treat as NOP. */
17881 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17882 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17886 check_cp0_enabled(ctx);
17887 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17888 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17893 TCGv t0 = tcg_temp_new();
17895 gen_load_gpr(t0, rs);
17896 gen_helper_yield(t0, cpu_env, t0);
17897 gen_store_gpr(t0, rt);
17903 generate_exception_end(ctx, EXCP_RI);
17909 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
17910 int ret, int v1, int v2)
17916 t0 = tcg_temp_new_i32();
17918 v0_t = tcg_temp_new();
17919 v1_t = tcg_temp_new();
17921 tcg_gen_movi_i32(t0, v2 >> 3);
17923 gen_load_gpr(v0_t, ret);
17924 gen_load_gpr(v1_t, v1);
17927 case NM_MAQ_S_W_PHR:
17929 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
17931 case NM_MAQ_S_W_PHL:
17933 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
17935 case NM_MAQ_SA_W_PHR:
17937 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
17939 case NM_MAQ_SA_W_PHL:
17941 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
17944 generate_exception_end(ctx, EXCP_RI);
17948 tcg_temp_free_i32(t0);
17950 tcg_temp_free(v0_t);
17951 tcg_temp_free(v1_t);
17955 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
17956 int ret, int v1, int v2)
17959 TCGv t0 = tcg_temp_new();
17960 TCGv t1 = tcg_temp_new();
17961 TCGv v0_t = tcg_temp_new();
17963 gen_load_gpr(v0_t, v1);
17966 case NM_POOL32AXF_1_0:
17968 switch (extract32(ctx->opcode, 12, 2)) {
17970 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
17973 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
17976 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
17979 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
17983 case NM_POOL32AXF_1_1:
17985 switch (extract32(ctx->opcode, 12, 2)) {
17987 tcg_gen_movi_tl(t0, v2);
17988 gen_helper_mthlip(t0, v0_t, cpu_env);
17991 tcg_gen_movi_tl(t0, v2 >> 3);
17992 gen_helper_shilo(t0, v0_t, cpu_env);
17995 generate_exception_end(ctx, EXCP_RI);
17999 case NM_POOL32AXF_1_3:
18001 imm = extract32(ctx->opcode, 14, 7);
18002 switch (extract32(ctx->opcode, 12, 2)) {
18004 tcg_gen_movi_tl(t0, imm);
18005 gen_helper_rddsp(t0, t0, cpu_env);
18006 gen_store_gpr(t0, ret);
18009 gen_load_gpr(t0, ret);
18010 tcg_gen_movi_tl(t1, imm);
18011 gen_helper_wrdsp(t0, t1, cpu_env);
18014 tcg_gen_movi_tl(t0, v2 >> 3);
18015 tcg_gen_movi_tl(t1, v1);
18016 gen_helper_extp(t0, t0, t1, cpu_env);
18017 gen_store_gpr(t0, ret);
18020 tcg_gen_movi_tl(t0, v2 >> 3);
18021 tcg_gen_movi_tl(t1, v1);
18022 gen_helper_extpdp(t0, t0, t1, cpu_env);
18023 gen_store_gpr(t0, ret);
18027 case NM_POOL32AXF_1_4:
18029 tcg_gen_movi_tl(t0, v2 >> 2);
18030 switch (extract32(ctx->opcode, 12, 1)) {
18032 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18033 gen_store_gpr(t0, ret);
18036 gen_helper_shrl_qb(t0, t0, v0_t);
18037 gen_store_gpr(t0, ret);
18041 case NM_POOL32AXF_1_5:
18042 opc = extract32(ctx->opcode, 12, 2);
18043 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18045 case NM_POOL32AXF_1_7:
18047 tcg_gen_movi_tl(t0, v2 >> 3);
18048 tcg_gen_movi_tl(t1, v1);
18049 switch (extract32(ctx->opcode, 12, 2)) {
18051 gen_helper_extr_w(t0, t0, t1, cpu_env);
18052 gen_store_gpr(t0, ret);
18055 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18056 gen_store_gpr(t0, ret);
18059 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18060 gen_store_gpr(t0, ret);
18063 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18064 gen_store_gpr(t0, ret);
18069 generate_exception_end(ctx, EXCP_RI);
18075 tcg_temp_free(v0_t);
18078 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18079 TCGv v0, TCGv v1, int rd)
18083 t0 = tcg_temp_new_i32();
18085 tcg_gen_movi_i32(t0, rd >> 3);
18088 case NM_POOL32AXF_2_0_7:
18089 switch (extract32(ctx->opcode, 9, 3)) {
18092 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18094 case NM_DPAQ_S_W_PH:
18096 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18100 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18102 case NM_DPSQ_S_W_PH:
18104 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18107 generate_exception_end(ctx, EXCP_RI);
18111 case NM_POOL32AXF_2_8_15:
18112 switch (extract32(ctx->opcode, 9, 3)) {
18115 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18117 case NM_DPAQ_SA_L_W:
18119 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18123 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18125 case NM_DPSQ_SA_L_W:
18127 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18130 generate_exception_end(ctx, EXCP_RI);
18134 case NM_POOL32AXF_2_16_23:
18135 switch (extract32(ctx->opcode, 9, 3)) {
18136 case NM_DPAU_H_QBL:
18138 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18140 case NM_DPAQX_S_W_PH:
18142 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18144 case NM_DPSU_H_QBL:
18146 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18148 case NM_DPSQX_S_W_PH:
18150 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18152 case NM_MULSA_W_PH:
18154 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18157 generate_exception_end(ctx, EXCP_RI);
18161 case NM_POOL32AXF_2_24_31:
18162 switch (extract32(ctx->opcode, 9, 3)) {
18163 case NM_DPAU_H_QBR:
18165 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18167 case NM_DPAQX_SA_W_PH:
18169 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18171 case NM_DPSU_H_QBR:
18173 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18175 case NM_DPSQX_SA_W_PH:
18177 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18179 case NM_MULSAQ_S_W_PH:
18181 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18184 generate_exception_end(ctx, EXCP_RI);
18189 generate_exception_end(ctx, EXCP_RI);
18193 tcg_temp_free_i32(t0);
18196 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18197 int rt, int rs, int rd)
18200 TCGv t0 = tcg_temp_new();
18201 TCGv t1 = tcg_temp_new();
18202 TCGv v0_t = tcg_temp_new();
18203 TCGv v1_t = tcg_temp_new();
18205 gen_load_gpr(v0_t, rt);
18206 gen_load_gpr(v1_t, rs);
18209 case NM_POOL32AXF_2_0_7:
18210 switch (extract32(ctx->opcode, 9, 3)) {
18212 case NM_DPAQ_S_W_PH:
18214 case NM_DPSQ_S_W_PH:
18215 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18220 gen_load_gpr(t0, rs);
18222 if (rd != 0 && rd != 2) {
18223 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18224 tcg_gen_ext32u_tl(t0, t0);
18225 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18226 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18228 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18234 int acc = extract32(ctx->opcode, 14, 2);
18235 TCGv_i64 t2 = tcg_temp_new_i64();
18236 TCGv_i64 t3 = tcg_temp_new_i64();
18238 gen_load_gpr(t0, rt);
18239 gen_load_gpr(t1, rs);
18240 tcg_gen_ext_tl_i64(t2, t0);
18241 tcg_gen_ext_tl_i64(t3, t1);
18242 tcg_gen_mul_i64(t2, t2, t3);
18243 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18244 tcg_gen_add_i64(t2, t2, t3);
18245 tcg_temp_free_i64(t3);
18246 gen_move_low32(cpu_LO[acc], t2);
18247 gen_move_high32(cpu_HI[acc], t2);
18248 tcg_temp_free_i64(t2);
18254 int acc = extract32(ctx->opcode, 14, 2);
18255 TCGv_i32 t2 = tcg_temp_new_i32();
18256 TCGv_i32 t3 = tcg_temp_new_i32();
18258 gen_load_gpr(t0, rs);
18259 gen_load_gpr(t1, rt);
18260 tcg_gen_trunc_tl_i32(t2, t0);
18261 tcg_gen_trunc_tl_i32(t3, t1);
18262 tcg_gen_muls2_i32(t2, t3, t2, t3);
18263 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18264 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18265 tcg_temp_free_i32(t2);
18266 tcg_temp_free_i32(t3);
18271 gen_load_gpr(v1_t, rs);
18272 tcg_gen_movi_tl(t0, rd >> 3);
18273 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18274 gen_store_gpr(t0, ret);
18278 case NM_POOL32AXF_2_8_15:
18279 switch (extract32(ctx->opcode, 9, 3)) {
18281 case NM_DPAQ_SA_L_W:
18283 case NM_DPSQ_SA_L_W:
18284 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18289 int acc = extract32(ctx->opcode, 14, 2);
18290 TCGv_i64 t2 = tcg_temp_new_i64();
18291 TCGv_i64 t3 = tcg_temp_new_i64();
18293 gen_load_gpr(t0, rs);
18294 gen_load_gpr(t1, rt);
18295 tcg_gen_ext32u_tl(t0, t0);
18296 tcg_gen_ext32u_tl(t1, t1);
18297 tcg_gen_extu_tl_i64(t2, t0);
18298 tcg_gen_extu_tl_i64(t3, t1);
18299 tcg_gen_mul_i64(t2, t2, t3);
18300 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18301 tcg_gen_add_i64(t2, t2, t3);
18302 tcg_temp_free_i64(t3);
18303 gen_move_low32(cpu_LO[acc], t2);
18304 gen_move_high32(cpu_HI[acc], t2);
18305 tcg_temp_free_i64(t2);
18311 int acc = extract32(ctx->opcode, 14, 2);
18312 TCGv_i32 t2 = tcg_temp_new_i32();
18313 TCGv_i32 t3 = tcg_temp_new_i32();
18315 gen_load_gpr(t0, rs);
18316 gen_load_gpr(t1, rt);
18317 tcg_gen_trunc_tl_i32(t2, t0);
18318 tcg_gen_trunc_tl_i32(t3, t1);
18319 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18320 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18321 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18322 tcg_temp_free_i32(t2);
18323 tcg_temp_free_i32(t3);
18328 tcg_gen_movi_tl(t0, rd >> 3);
18329 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18330 gen_store_gpr(t0, ret);
18333 generate_exception_end(ctx, EXCP_RI);
18337 case NM_POOL32AXF_2_16_23:
18338 switch (extract32(ctx->opcode, 9, 3)) {
18339 case NM_DPAU_H_QBL:
18340 case NM_DPAQX_S_W_PH:
18341 case NM_DPSU_H_QBL:
18342 case NM_DPSQX_S_W_PH:
18343 case NM_MULSA_W_PH:
18344 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18348 tcg_gen_movi_tl(t0, rd >> 3);
18349 gen_helper_extp(t0, t0, v1_t, cpu_env);
18350 gen_store_gpr(t0, ret);
18355 int acc = extract32(ctx->opcode, 14, 2);
18356 TCGv_i64 t2 = tcg_temp_new_i64();
18357 TCGv_i64 t3 = tcg_temp_new_i64();
18359 gen_load_gpr(t0, rs);
18360 gen_load_gpr(t1, rt);
18361 tcg_gen_ext_tl_i64(t2, t0);
18362 tcg_gen_ext_tl_i64(t3, t1);
18363 tcg_gen_mul_i64(t2, t2, t3);
18364 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18365 tcg_gen_sub_i64(t2, t3, t2);
18366 tcg_temp_free_i64(t3);
18367 gen_move_low32(cpu_LO[acc], t2);
18368 gen_move_high32(cpu_HI[acc], t2);
18369 tcg_temp_free_i64(t2);
18372 case NM_EXTRV_RS_W:
18374 tcg_gen_movi_tl(t0, rd >> 3);
18375 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18376 gen_store_gpr(t0, ret);
18380 case NM_POOL32AXF_2_24_31:
18381 switch (extract32(ctx->opcode, 9, 3)) {
18382 case NM_DPAU_H_QBR:
18383 case NM_DPAQX_SA_W_PH:
18384 case NM_DPSU_H_QBR:
18385 case NM_DPSQX_SA_W_PH:
18386 case NM_MULSAQ_S_W_PH:
18387 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18391 tcg_gen_movi_tl(t0, rd >> 3);
18392 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
18393 gen_store_gpr(t0, ret);
18398 int acc = extract32(ctx->opcode, 14, 2);
18399 TCGv_i64 t2 = tcg_temp_new_i64();
18400 TCGv_i64 t3 = tcg_temp_new_i64();
18402 gen_load_gpr(t0, rs);
18403 gen_load_gpr(t1, rt);
18404 tcg_gen_ext32u_tl(t0, t0);
18405 tcg_gen_ext32u_tl(t1, t1);
18406 tcg_gen_extu_tl_i64(t2, t0);
18407 tcg_gen_extu_tl_i64(t3, t1);
18408 tcg_gen_mul_i64(t2, t2, t3);
18409 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18410 tcg_gen_sub_i64(t2, t3, t2);
18411 tcg_temp_free_i64(t3);
18412 gen_move_low32(cpu_LO[acc], t2);
18413 gen_move_high32(cpu_HI[acc], t2);
18414 tcg_temp_free_i64(t2);
18419 tcg_gen_movi_tl(t0, rd >> 3);
18420 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
18421 gen_store_gpr(t0, ret);
18426 generate_exception_end(ctx, EXCP_RI);
18433 tcg_temp_free(v0_t);
18434 tcg_temp_free(v1_t);
18437 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
18441 TCGv t0 = tcg_temp_new();
18442 TCGv v0_t = tcg_temp_new();
18444 gen_load_gpr(v0_t, rs);
18449 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
18450 gen_store_gpr(v0_t, ret);
18454 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
18455 gen_store_gpr(v0_t, ret);
18459 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
18460 gen_store_gpr(v0_t, ret);
18462 case NM_PRECEQ_W_PHL:
18464 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
18465 tcg_gen_ext32s_tl(v0_t, v0_t);
18466 gen_store_gpr(v0_t, ret);
18468 case NM_PRECEQ_W_PHR:
18470 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
18471 tcg_gen_shli_tl(v0_t, v0_t, 16);
18472 tcg_gen_ext32s_tl(v0_t, v0_t);
18473 gen_store_gpr(v0_t, ret);
18475 case NM_PRECEQU_PH_QBL:
18477 gen_helper_precequ_ph_qbl(v0_t, v0_t);
18478 gen_store_gpr(v0_t, ret);
18480 case NM_PRECEQU_PH_QBR:
18482 gen_helper_precequ_ph_qbr(v0_t, v0_t);
18483 gen_store_gpr(v0_t, ret);
18485 case NM_PRECEQU_PH_QBLA:
18487 gen_helper_precequ_ph_qbla(v0_t, v0_t);
18488 gen_store_gpr(v0_t, ret);
18490 case NM_PRECEQU_PH_QBRA:
18492 gen_helper_precequ_ph_qbra(v0_t, v0_t);
18493 gen_store_gpr(v0_t, ret);
18495 case NM_PRECEU_PH_QBL:
18497 gen_helper_preceu_ph_qbl(v0_t, v0_t);
18498 gen_store_gpr(v0_t, ret);
18500 case NM_PRECEU_PH_QBR:
18502 gen_helper_preceu_ph_qbr(v0_t, v0_t);
18503 gen_store_gpr(v0_t, ret);
18505 case NM_PRECEU_PH_QBLA:
18507 gen_helper_preceu_ph_qbla(v0_t, v0_t);
18508 gen_store_gpr(v0_t, ret);
18510 case NM_PRECEU_PH_QBRA:
18512 gen_helper_preceu_ph_qbra(v0_t, v0_t);
18513 gen_store_gpr(v0_t, ret);
18517 tcg_gen_ext16u_tl(v0_t, v0_t);
18518 tcg_gen_shli_tl(t0, v0_t, 16);
18519 tcg_gen_or_tl(v0_t, v0_t, t0);
18520 tcg_gen_ext32s_tl(v0_t, v0_t);
18521 gen_store_gpr(v0_t, ret);
18525 tcg_gen_ext8u_tl(v0_t, v0_t);
18526 tcg_gen_shli_tl(t0, v0_t, 8);
18527 tcg_gen_or_tl(v0_t, v0_t, t0);
18528 tcg_gen_shli_tl(t0, v0_t, 16);
18529 tcg_gen_or_tl(v0_t, v0_t, t0);
18530 tcg_gen_ext32s_tl(v0_t, v0_t);
18531 gen_store_gpr(v0_t, ret);
18535 gen_helper_bitrev(v0_t, v0_t);
18536 gen_store_gpr(v0_t, ret);
18541 TCGv tv0 = tcg_temp_new();
18543 gen_load_gpr(tv0, rt);
18544 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
18545 gen_store_gpr(v0_t, ret);
18546 tcg_temp_free(tv0);
18549 case NM_RADDU_W_QB:
18551 gen_helper_raddu_w_qb(v0_t, v0_t);
18552 gen_store_gpr(v0_t, ret);
18555 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
18559 gen_cl(ctx, OPC_CLO, ret, rs);
18563 gen_cl(ctx, OPC_CLZ, ret, rs);
18566 gen_bshfl(ctx, OPC_WSBH, ret, rs);
18569 generate_exception_end(ctx, EXCP_RI);
18573 tcg_temp_free(v0_t);
18577 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
18578 int rt, int rs, int rd)
18580 TCGv t0 = tcg_temp_new();
18581 TCGv rs_t = tcg_temp_new();
18583 gen_load_gpr(rs_t, rs);
18588 tcg_gen_movi_tl(t0, rd >> 2);
18589 switch (extract32(ctx->opcode, 12, 1)) {
18592 gen_helper_shra_qb(t0, t0, rs_t);
18593 gen_store_gpr(t0, rt);
18597 gen_helper_shra_r_qb(t0, t0, rs_t);
18598 gen_store_gpr(t0, rt);
18604 tcg_gen_movi_tl(t0, rd >> 1);
18605 gen_helper_shrl_ph(t0, t0, rs_t);
18606 gen_store_gpr(t0, rt);
18612 target_long result;
18613 imm = extract32(ctx->opcode, 13, 8);
18614 result = (uint32_t)imm << 24 |
18615 (uint32_t)imm << 16 |
18616 (uint32_t)imm << 8 |
18618 result = (int32_t)result;
18619 tcg_gen_movi_tl(t0, result);
18620 gen_store_gpr(t0, rt);
18624 generate_exception_end(ctx, EXCP_RI);
18628 tcg_temp_free(rs_t);
18632 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18634 int rt = extract32(ctx->opcode, 21, 5);
18635 int rs = extract32(ctx->opcode, 16, 5);
18636 int rd = extract32(ctx->opcode, 11, 5);
18638 switch (extract32(ctx->opcode, 6, 3)) {
18639 case NM_POOL32AXF_1:
18641 int32_t op1 = extract32(ctx->opcode, 9, 3);
18642 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
18645 case NM_POOL32AXF_2:
18647 int32_t op1 = extract32(ctx->opcode, 12, 2);
18648 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
18651 case NM_POOL32AXF_4:
18653 int32_t op1 = extract32(ctx->opcode, 9, 7);
18654 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
18657 case NM_POOL32AXF_5:
18658 switch (extract32(ctx->opcode, 9, 7)) {
18659 #ifndef CONFIG_USER_ONLY
18661 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
18664 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
18667 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
18670 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
18673 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
18676 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
18679 check_cp0_enabled(ctx);
18681 TCGv t0 = tcg_temp_new();
18683 save_cpu_state(ctx, 1);
18684 gen_helper_di(t0, cpu_env);
18685 gen_store_gpr(t0, rt);
18686 /* Stop translation as we may have switched the execution mode */
18687 ctx->base.is_jmp = DISAS_STOP;
18692 check_cp0_enabled(ctx);
18694 TCGv t0 = tcg_temp_new();
18696 save_cpu_state(ctx, 1);
18697 gen_helper_ei(t0, cpu_env);
18698 gen_store_gpr(t0, rt);
18699 /* Stop translation as we may have switched the execution mode */
18700 ctx->base.is_jmp = DISAS_STOP;
18705 gen_load_srsgpr(rs, rt);
18708 gen_store_srsgpr(rs, rt);
18711 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
18714 gen_cp0(env, ctx, OPC_DERET, 0, 0);
18717 gen_cp0(env, ctx, OPC_ERET, 0, 0);
18721 generate_exception_end(ctx, EXCP_RI);
18725 case NM_POOL32AXF_7:
18727 int32_t op1 = extract32(ctx->opcode, 9, 3);
18728 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
18732 generate_exception_end(ctx, EXCP_RI);
18737 /* Immediate Value Compact Branches */
18738 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
18739 int rt, int32_t imm, int32_t offset)
18742 int bcond_compute = 0;
18743 TCGv t0 = tcg_temp_new();
18744 TCGv t1 = tcg_temp_new();
18746 gen_load_gpr(t0, rt);
18747 tcg_gen_movi_tl(t1, imm);
18748 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18750 /* Load needed operands and calculate btarget */
18753 if (rt == 0 && imm == 0) {
18754 /* Unconditional branch */
18755 } else if (rt == 0 && imm != 0) {
18760 cond = TCG_COND_EQ;
18766 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
18767 generate_exception_end(ctx, EXCP_RI);
18769 } else if (rt == 0 && opc == NM_BBEQZC) {
18770 /* Unconditional branch */
18771 } else if (rt == 0 && opc == NM_BBNEZC) {
18775 tcg_gen_shri_tl(t0, t0, imm);
18776 tcg_gen_andi_tl(t0, t0, 1);
18777 tcg_gen_movi_tl(t1, 0);
18779 if (opc == NM_BBEQZC) {
18780 cond = TCG_COND_EQ;
18782 cond = TCG_COND_NE;
18787 if (rt == 0 && imm == 0) {
18790 } else if (rt == 0 && imm != 0) {
18791 /* Unconditional branch */
18794 cond = TCG_COND_NE;
18798 if (rt == 0 && imm == 0) {
18799 /* Unconditional branch */
18802 cond = TCG_COND_GE;
18807 cond = TCG_COND_LT;
18810 if (rt == 0 && imm == 0) {
18811 /* Unconditional branch */
18814 cond = TCG_COND_GEU;
18819 cond = TCG_COND_LTU;
18822 MIPS_INVAL("Immediate Value Compact branch");
18823 generate_exception_end(ctx, EXCP_RI);
18827 if (bcond_compute == 0) {
18828 /* Uncoditional compact branch */
18829 gen_goto_tb(ctx, 0, ctx->btarget);
18831 /* Conditional compact branch */
18832 TCGLabel *fs = gen_new_label();
18834 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
18836 gen_goto_tb(ctx, 1, ctx->btarget);
18839 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
18847 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
18848 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
18851 TCGv t0 = tcg_temp_new();
18852 TCGv t1 = tcg_temp_new();
18855 gen_load_gpr(t0, rs);
18859 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
18862 /* calculate btarget */
18863 tcg_gen_shli_tl(t0, t0, 1);
18864 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
18865 gen_op_addr_add(ctx, btarget, t1, t0);
18867 /* unconditional branch to register */
18868 tcg_gen_mov_tl(cpu_PC, btarget);
18869 tcg_gen_lookup_and_goto_ptr();
18875 /* nanoMIPS Branches */
18876 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
18877 int rs, int rt, int32_t offset)
18879 int bcond_compute = 0;
18880 TCGv t0 = tcg_temp_new();
18881 TCGv t1 = tcg_temp_new();
18883 /* Load needed operands and calculate btarget */
18885 /* compact branch */
18888 gen_load_gpr(t0, rs);
18889 gen_load_gpr(t1, rt);
18891 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18895 if (rs == 0 || rs == rt) {
18896 /* OPC_BLEZALC, OPC_BGEZALC */
18897 /* OPC_BGTZALC, OPC_BLTZALC */
18898 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
18900 gen_load_gpr(t0, rs);
18901 gen_load_gpr(t1, rt);
18903 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18906 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18910 /* OPC_BEQZC, OPC_BNEZC */
18911 gen_load_gpr(t0, rs);
18913 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18915 /* OPC_JIC, OPC_JIALC */
18916 TCGv tbase = tcg_temp_new();
18917 TCGv toffset = tcg_temp_new();
18919 gen_load_gpr(tbase, rt);
18920 tcg_gen_movi_tl(toffset, offset);
18921 gen_op_addr_add(ctx, btarget, tbase, toffset);
18922 tcg_temp_free(tbase);
18923 tcg_temp_free(toffset);
18927 MIPS_INVAL("Compact branch/jump");
18928 generate_exception_end(ctx, EXCP_RI);
18932 if (bcond_compute == 0) {
18933 /* Uncoditional compact branch */
18936 gen_goto_tb(ctx, 0, ctx->btarget);
18939 MIPS_INVAL("Compact branch/jump");
18940 generate_exception_end(ctx, EXCP_RI);
18944 /* Conditional compact branch */
18945 TCGLabel *fs = gen_new_label();
18949 if (rs == 0 && rt != 0) {
18951 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18952 } else if (rs != 0 && rt != 0 && rs == rt) {
18954 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18957 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
18961 if (rs == 0 && rt != 0) {
18963 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18964 } else if (rs != 0 && rt != 0 && rs == rt) {
18966 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
18969 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
18973 if (rs == 0 && rt != 0) {
18975 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18976 } else if (rs != 0 && rt != 0 && rs == rt) {
18978 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18981 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
18985 if (rs == 0 && rt != 0) {
18987 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18988 } else if (rs != 0 && rt != 0 && rs == rt) {
18990 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
18993 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
18997 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19000 MIPS_INVAL("Compact conditional branch/jump");
19001 generate_exception_end(ctx, EXCP_RI);
19005 /* Generating branch here as compact branches don't have delay slot */
19006 gen_goto_tb(ctx, 1, ctx->btarget);
19009 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19018 /* nanoMIPS CP1 Branches */
19019 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19020 int32_t ft, int32_t offset)
19022 target_ulong btarget;
19023 TCGv_i64 t0 = tcg_temp_new_i64();
19025 gen_load_fpr64(ctx, t0, ft);
19026 tcg_gen_andi_i64(t0, t0, 1);
19028 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19032 tcg_gen_xori_i64(t0, t0, 1);
19033 ctx->hflags |= MIPS_HFLAG_BC;
19036 /* t0 already set */
19037 ctx->hflags |= MIPS_HFLAG_BC;
19040 MIPS_INVAL("cp1 cond branch");
19041 generate_exception_end(ctx, EXCP_RI);
19045 tcg_gen_trunc_i64_tl(bcond, t0);
19047 ctx->btarget = btarget;
19050 tcg_temp_free_i64(t0);
19054 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19057 t0 = tcg_temp_new();
19058 t1 = tcg_temp_new();
19060 gen_load_gpr(t0, rs);
19061 gen_load_gpr(t1, rt);
19063 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19064 /* PP.LSXS instructions require shifting */
19065 switch (extract32(ctx->opcode, 7, 4)) {
19070 tcg_gen_shli_tl(t0, t0, 1);
19077 tcg_gen_shli_tl(t0, t0, 2);
19081 tcg_gen_shli_tl(t0, t0, 3);
19085 gen_op_addr_add(ctx, t0, t0, t1);
19087 switch (extract32(ctx->opcode, 7, 4)) {
19089 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19091 gen_store_gpr(t0, rd);
19095 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19097 gen_store_gpr(t0, rd);
19101 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19103 gen_store_gpr(t0, rd);
19106 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19108 gen_store_gpr(t0, rd);
19112 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19114 gen_store_gpr(t0, rd);
19118 gen_load_gpr(t1, rd);
19119 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19125 gen_load_gpr(t1, rd);
19126 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19132 gen_load_gpr(t1, rd);
19133 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19137 /*case NM_LWC1XS:*/
19139 /*case NM_LDC1XS:*/
19141 /*case NM_SWC1XS:*/
19143 /*case NM_SDC1XS:*/
19144 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19145 check_cp1_enabled(ctx);
19146 switch (extract32(ctx->opcode, 7, 4)) {
19148 /*case NM_LWC1XS:*/
19149 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19152 /*case NM_LDC1XS:*/
19153 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19156 /*case NM_SWC1XS:*/
19157 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19160 /*case NM_SDC1XS:*/
19161 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19165 generate_exception_err(ctx, EXCP_CpU, 1);
19169 generate_exception_end(ctx, EXCP_RI);
19177 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19181 rt = extract32(ctx->opcode, 21, 5);
19182 rs = extract32(ctx->opcode, 16, 5);
19183 rd = extract32(ctx->opcode, 11, 5);
19185 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19186 generate_exception_end(ctx, EXCP_RI);
19189 check_cp1_enabled(ctx);
19190 switch (extract32(ctx->opcode, 0, 3)) {
19192 switch (extract32(ctx->opcode, 3, 7)) {
19194 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19197 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19200 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19203 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19206 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19209 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19212 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19215 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19218 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19221 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19224 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19227 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19230 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19233 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19236 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19239 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19242 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19245 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19248 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19251 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19254 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19257 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19260 generate_exception_end(ctx, EXCP_RI);
19265 switch (extract32(ctx->opcode, 3, 3)) {
19267 switch (extract32(ctx->opcode, 9, 1)) {
19269 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19272 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19277 switch (extract32(ctx->opcode, 9, 1)) {
19279 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19282 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19287 switch (extract32(ctx->opcode, 9, 1)) {
19289 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19292 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19297 switch (extract32(ctx->opcode, 9, 1)) {
19299 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19302 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19307 switch (extract32(ctx->opcode, 6, 8)) {
19309 gen_cp1(ctx, OPC_CFC1, rt, rs);
19312 gen_cp1(ctx, OPC_CTC1, rt, rs);
19315 gen_cp1(ctx, OPC_MFC1, rt, rs);
19318 gen_cp1(ctx, OPC_MTC1, rt, rs);
19321 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19324 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19327 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19330 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19333 switch (extract32(ctx->opcode, 6, 9)) {
19335 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19338 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19341 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19344 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19347 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19350 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19353 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19356 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19359 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19362 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19365 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19368 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19371 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19374 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19377 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19380 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
19383 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
19386 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
19389 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
19392 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
19395 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
19398 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
19401 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
19404 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
19407 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
19410 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
19413 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
19416 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
19419 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
19422 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
19425 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
19428 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
19431 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
19434 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
19437 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
19440 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
19443 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
19446 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
19449 generate_exception_end(ctx, EXCP_RI);
19458 switch (extract32(ctx->opcode, 3, 3)) {
19459 case NM_CMP_CONDN_S:
19460 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19462 case NM_CMP_CONDN_D:
19463 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19466 generate_exception_end(ctx, EXCP_RI);
19471 generate_exception_end(ctx, EXCP_RI);
19476 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
19477 int rd, int rs, int rt)
19480 TCGv t0 = tcg_temp_new();
19481 TCGv v1_t = tcg_temp_new();
19482 TCGv v2_t = tcg_temp_new();
19484 gen_load_gpr(v1_t, rs);
19485 gen_load_gpr(v2_t, rt);
19490 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
19494 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
19498 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
19500 case NM_CMPU_EQ_QB:
19502 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
19504 case NM_CMPU_LT_QB:
19506 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
19508 case NM_CMPU_LE_QB:
19510 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
19512 case NM_CMPGU_EQ_QB:
19514 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19515 gen_store_gpr(v1_t, ret);
19517 case NM_CMPGU_LT_QB:
19519 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19520 gen_store_gpr(v1_t, ret);
19522 case NM_CMPGU_LE_QB:
19524 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19525 gen_store_gpr(v1_t, ret);
19527 case NM_CMPGDU_EQ_QB:
19529 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19530 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19531 gen_store_gpr(v1_t, ret);
19533 case NM_CMPGDU_LT_QB:
19535 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19536 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19537 gen_store_gpr(v1_t, ret);
19539 case NM_CMPGDU_LE_QB:
19541 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19542 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19543 gen_store_gpr(v1_t, ret);
19547 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
19548 gen_store_gpr(v1_t, ret);
19552 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
19553 gen_store_gpr(v1_t, ret);
19557 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
19558 gen_store_gpr(v1_t, ret);
19562 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
19563 gen_store_gpr(v1_t, ret);
19567 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
19568 gen_store_gpr(v1_t, ret);
19572 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
19573 gen_store_gpr(v1_t, ret);
19577 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
19578 gen_store_gpr(v1_t, ret);
19582 switch (extract32(ctx->opcode, 10, 1)) {
19585 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
19586 gen_store_gpr(v1_t, ret);
19590 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19591 gen_store_gpr(v1_t, ret);
19595 case NM_ADDQH_R_PH:
19597 switch (extract32(ctx->opcode, 10, 1)) {
19600 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
19601 gen_store_gpr(v1_t, ret);
19605 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
19606 gen_store_gpr(v1_t, ret);
19612 switch (extract32(ctx->opcode, 10, 1)) {
19615 gen_helper_addqh_w(v1_t, v1_t, v2_t);
19616 gen_store_gpr(v1_t, ret);
19620 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
19621 gen_store_gpr(v1_t, ret);
19627 switch (extract32(ctx->opcode, 10, 1)) {
19630 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
19631 gen_store_gpr(v1_t, ret);
19635 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19636 gen_store_gpr(v1_t, ret);
19642 switch (extract32(ctx->opcode, 10, 1)) {
19645 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
19646 gen_store_gpr(v1_t, ret);
19650 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19651 gen_store_gpr(v1_t, ret);
19655 case NM_ADDUH_R_QB:
19657 switch (extract32(ctx->opcode, 10, 1)) {
19660 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
19661 gen_store_gpr(v1_t, ret);
19665 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
19666 gen_store_gpr(v1_t, ret);
19670 case NM_SHRAV_R_PH:
19672 switch (extract32(ctx->opcode, 10, 1)) {
19675 gen_helper_shra_ph(v1_t, v1_t, v2_t);
19676 gen_store_gpr(v1_t, ret);
19680 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
19681 gen_store_gpr(v1_t, ret);
19685 case NM_SHRAV_R_QB:
19687 switch (extract32(ctx->opcode, 10, 1)) {
19690 gen_helper_shra_qb(v1_t, v1_t, v2_t);
19691 gen_store_gpr(v1_t, ret);
19695 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
19696 gen_store_gpr(v1_t, ret);
19702 switch (extract32(ctx->opcode, 10, 1)) {
19705 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
19706 gen_store_gpr(v1_t, ret);
19710 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19711 gen_store_gpr(v1_t, ret);
19715 case NM_SUBQH_R_PH:
19717 switch (extract32(ctx->opcode, 10, 1)) {
19720 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
19721 gen_store_gpr(v1_t, ret);
19725 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
19726 gen_store_gpr(v1_t, ret);
19732 switch (extract32(ctx->opcode, 10, 1)) {
19735 gen_helper_subqh_w(v1_t, v1_t, v2_t);
19736 gen_store_gpr(v1_t, ret);
19740 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
19741 gen_store_gpr(v1_t, ret);
19747 switch (extract32(ctx->opcode, 10, 1)) {
19750 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
19751 gen_store_gpr(v1_t, ret);
19755 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19756 gen_store_gpr(v1_t, ret);
19762 switch (extract32(ctx->opcode, 10, 1)) {
19765 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
19766 gen_store_gpr(v1_t, ret);
19770 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19771 gen_store_gpr(v1_t, ret);
19775 case NM_SUBUH_R_QB:
19777 switch (extract32(ctx->opcode, 10, 1)) {
19780 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
19781 gen_store_gpr(v1_t, ret);
19785 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
19786 gen_store_gpr(v1_t, ret);
19790 case NM_SHLLV_S_PH:
19792 switch (extract32(ctx->opcode, 10, 1)) {
19795 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
19796 gen_store_gpr(v1_t, ret);
19800 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
19801 gen_store_gpr(v1_t, ret);
19805 case NM_PRECR_SRA_R_PH_W:
19807 switch (extract32(ctx->opcode, 10, 1)) {
19809 /* PRECR_SRA_PH_W */
19811 TCGv_i32 sa_t = tcg_const_i32(rd);
19812 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
19814 gen_store_gpr(v1_t, rt);
19815 tcg_temp_free_i32(sa_t);
19819 /* PRECR_SRA_R_PH_W */
19821 TCGv_i32 sa_t = tcg_const_i32(rd);
19822 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
19824 gen_store_gpr(v1_t, rt);
19825 tcg_temp_free_i32(sa_t);
19830 case NM_MULEU_S_PH_QBL:
19832 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
19833 gen_store_gpr(v1_t, ret);
19835 case NM_MULEU_S_PH_QBR:
19837 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
19838 gen_store_gpr(v1_t, ret);
19840 case NM_MULQ_RS_PH:
19842 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
19843 gen_store_gpr(v1_t, ret);
19847 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19848 gen_store_gpr(v1_t, ret);
19852 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
19853 gen_store_gpr(v1_t, ret);
19857 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
19858 gen_store_gpr(v1_t, ret);
19862 gen_load_gpr(t0, rs);
19864 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
19866 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
19870 gen_helper_modsub(v1_t, v1_t, v2_t);
19871 gen_store_gpr(v1_t, ret);
19875 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
19876 gen_store_gpr(v1_t, ret);
19880 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
19881 gen_store_gpr(v1_t, ret);
19885 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
19886 gen_store_gpr(v1_t, ret);
19890 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
19891 gen_store_gpr(v1_t, ret);
19895 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
19896 gen_store_gpr(v1_t, ret);
19901 TCGv tv0 = tcg_temp_new();
19902 TCGv tv1 = tcg_temp_new();
19903 int16_t imm = extract32(ctx->opcode, 16, 7);
19905 tcg_gen_movi_tl(tv0, rd >> 3);
19906 tcg_gen_movi_tl(tv1, imm);
19907 gen_helper_shilo(tv0, tv1, cpu_env);
19910 case NM_MULEQ_S_W_PHL:
19912 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
19913 gen_store_gpr(v1_t, ret);
19915 case NM_MULEQ_S_W_PHR:
19917 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
19918 gen_store_gpr(v1_t, ret);
19922 switch (extract32(ctx->opcode, 10, 1)) {
19925 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
19926 gen_store_gpr(v1_t, ret);
19930 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
19931 gen_store_gpr(v1_t, ret);
19935 case NM_PRECR_QB_PH:
19937 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
19938 gen_store_gpr(v1_t, ret);
19940 case NM_PRECRQ_QB_PH:
19942 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
19943 gen_store_gpr(v1_t, ret);
19945 case NM_PRECRQ_PH_W:
19947 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
19948 gen_store_gpr(v1_t, ret);
19950 case NM_PRECRQ_RS_PH_W:
19952 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
19953 gen_store_gpr(v1_t, ret);
19955 case NM_PRECRQU_S_QB_PH:
19957 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
19958 gen_store_gpr(v1_t, ret);
19962 tcg_gen_movi_tl(t0, rd);
19963 gen_helper_shra_r_w(v1_t, t0, v1_t);
19964 gen_store_gpr(v1_t, rt);
19968 tcg_gen_movi_tl(t0, rd >> 1);
19969 switch (extract32(ctx->opcode, 10, 1)) {
19972 gen_helper_shra_ph(v1_t, t0, v1_t);
19974 gen_store_gpr(v1_t, rt);
19977 gen_helper_shra_r_ph(v1_t, t0, v1_t);
19978 gen_store_gpr(v1_t, rt);
19984 tcg_gen_movi_tl(t0, rd >> 1);
19985 switch (extract32(ctx->opcode, 10, 2)) {
19988 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
19989 gen_store_gpr(v1_t, rt);
19993 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
19994 gen_store_gpr(v1_t, rt);
19997 generate_exception_end(ctx, EXCP_RI);
20003 tcg_gen_movi_tl(t0, rd);
20004 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20005 gen_store_gpr(v1_t, rt);
20011 imm = sextract32(ctx->opcode, 11, 11);
20012 imm = (int16_t)(imm << 6) >> 6;
20014 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20019 generate_exception_end(ctx, EXCP_RI);
20024 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20032 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20033 ctx->opcode = (ctx->opcode << 16) | insn;
20035 rt = extract32(ctx->opcode, 21, 5);
20036 rs = extract32(ctx->opcode, 16, 5);
20037 rd = extract32(ctx->opcode, 11, 5);
20039 op = extract32(ctx->opcode, 26, 6);
20044 switch (extract32(ctx->opcode, 19, 2)) {
20047 generate_exception_end(ctx, EXCP_RI);
20050 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20051 generate_exception_end(ctx, EXCP_SYSCALL);
20053 generate_exception_end(ctx, EXCP_RI);
20057 generate_exception_end(ctx, EXCP_BREAK);
20060 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20061 gen_helper_do_semihosting(cpu_env);
20063 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20064 generate_exception_end(ctx, EXCP_RI);
20066 generate_exception_end(ctx, EXCP_DBp);
20073 imm = extract32(ctx->opcode, 0, 16);
20075 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20077 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20079 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20084 offset = sextract32(ctx->opcode, 0, 1) << 21 |
20085 extract32(ctx->opcode, 1, 20) << 1;
20086 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20087 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20091 switch (ctx->opcode & 0x07) {
20093 gen_pool32a0_nanomips_insn(env, ctx);
20097 int32_t op1 = extract32(ctx->opcode, 3, 7);
20098 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20102 switch (extract32(ctx->opcode, 3, 3)) {
20104 gen_p_lsx(ctx, rd, rs, rt);
20107 /* In nanoMIPS, the shift field directly encodes the shift
20108 * amount, meaning that the supported shift values are in
20109 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20110 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20111 extract32(ctx->opcode, 9, 2) - 1);
20114 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20117 gen_pool32axf_nanomips_insn(env, ctx);
20120 generate_exception_end(ctx, EXCP_RI);
20125 generate_exception_end(ctx, EXCP_RI);
20130 switch (ctx->opcode & 0x03) {
20133 offset = extract32(ctx->opcode, 0, 21);
20134 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20138 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20141 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20144 generate_exception_end(ctx, EXCP_RI);
20150 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20151 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20152 switch (extract32(ctx->opcode, 16, 5)) {
20156 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20162 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20163 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20169 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20175 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20178 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20185 t0 = tcg_temp_new();
20187 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20190 tcg_gen_movi_tl(t0, addr);
20191 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20199 t0 = tcg_temp_new();
20200 t1 = tcg_temp_new();
20202 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20205 tcg_gen_movi_tl(t0, addr);
20206 gen_load_gpr(t1, rt);
20208 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20215 generate_exception_end(ctx, EXCP_RI);
20221 switch (extract32(ctx->opcode, 12, 4)) {
20223 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20226 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20229 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20232 switch (extract32(ctx->opcode, 20, 1)) {
20234 switch (ctx->opcode & 3) {
20236 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20237 extract32(ctx->opcode, 2, 1),
20238 extract32(ctx->opcode, 3, 9) << 3);
20241 case NM_RESTORE_JRC:
20242 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20243 extract32(ctx->opcode, 2, 1),
20244 extract32(ctx->opcode, 3, 9) << 3);
20245 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20246 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20250 generate_exception_end(ctx, EXCP_RI);
20255 generate_exception_end(ctx, EXCP_RI);
20260 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20263 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20267 TCGv t0 = tcg_temp_new();
20269 imm = extract32(ctx->opcode, 0, 12);
20270 gen_load_gpr(t0, rs);
20271 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20272 gen_store_gpr(t0, rt);
20278 imm = (int16_t) extract32(ctx->opcode, 0, 12);
20279 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20283 int shift = extract32(ctx->opcode, 0, 5);
20284 switch (extract32(ctx->opcode, 5, 4)) {
20286 if (rt == 0 && shift == 0) {
20288 } else if (rt == 0 && shift == 3) {
20289 /* EHB - treat as NOP */
20290 } else if (rt == 0 && shift == 5) {
20291 /* PAUSE - treat as NOP */
20292 } else if (rt == 0 && shift == 6) {
20294 gen_sync(extract32(ctx->opcode, 16, 5));
20297 gen_shift_imm(ctx, OPC_SLL, rt, rs,
20298 extract32(ctx->opcode, 0, 5));
20302 gen_shift_imm(ctx, OPC_SRL, rt, rs,
20303 extract32(ctx->opcode, 0, 5));
20306 gen_shift_imm(ctx, OPC_SRA, rt, rs,
20307 extract32(ctx->opcode, 0, 5));
20310 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20311 extract32(ctx->opcode, 0, 5));
20319 TCGv t0 = tcg_temp_new();
20320 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20321 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20323 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20325 gen_load_gpr(t0, rs);
20326 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20329 tcg_temp_free_i32(shift);
20330 tcg_temp_free_i32(shiftx);
20331 tcg_temp_free_i32(stripe);
20335 switch (((ctx->opcode >> 10) & 2) |
20336 (extract32(ctx->opcode, 5, 1))) {
20339 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20340 extract32(ctx->opcode, 6, 5));
20343 generate_exception_end(ctx, EXCP_RI);
20348 switch (((ctx->opcode >> 10) & 2) |
20349 (extract32(ctx->opcode, 5, 1))) {
20352 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20353 extract32(ctx->opcode, 6, 5));
20356 generate_exception_end(ctx, EXCP_RI);
20361 generate_exception_end(ctx, EXCP_RI);
20366 gen_pool32f_nanomips_insn(ctx);
20371 switch (extract32(ctx->opcode, 1, 1)) {
20374 tcg_gen_movi_tl(cpu_gpr[rt],
20375 sextract32(ctx->opcode, 0, 1) << 31 |
20376 extract32(ctx->opcode, 2, 10) << 21 |
20377 extract32(ctx->opcode, 12, 9) << 12);
20382 offset = sextract32(ctx->opcode, 0, 1) << 31 |
20383 extract32(ctx->opcode, 2, 10) << 21 |
20384 extract32(ctx->opcode, 12, 9) << 12;
20386 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
20387 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20394 uint32_t u = extract32(ctx->opcode, 0, 18);
20396 switch (extract32(ctx->opcode, 18, 3)) {
20398 gen_ld(ctx, OPC_LB, rt, 28, u);
20401 gen_st(ctx, OPC_SB, rt, 28, u);
20404 gen_ld(ctx, OPC_LBU, rt, 28, u);
20408 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
20413 switch (ctx->opcode & 1) {
20415 gen_ld(ctx, OPC_LH, rt, 28, u);
20418 gen_ld(ctx, OPC_LHU, rt, 28, u);
20424 switch (ctx->opcode & 1) {
20426 gen_st(ctx, OPC_SH, rt, 28, u);
20429 generate_exception_end(ctx, EXCP_RI);
20435 switch (ctx->opcode & 0x3) {
20437 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
20440 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
20443 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
20446 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
20451 generate_exception_end(ctx, EXCP_RI);
20458 uint32_t u = extract32(ctx->opcode, 0, 12);
20460 switch (extract32(ctx->opcode, 12, 4)) {
20464 /* Break the TB to be able to sync copied instructions
20466 ctx->base.is_jmp = DISAS_STOP;
20469 /* Treat as NOP. */
20473 gen_ld(ctx, OPC_LB, rt, rs, u);
20476 gen_ld(ctx, OPC_LH, rt, rs, u);
20479 gen_ld(ctx, OPC_LW, rt, rs, u);
20482 gen_ld(ctx, OPC_LBU, rt, rs, u);
20485 gen_ld(ctx, OPC_LHU, rt, rs, u);
20488 gen_st(ctx, OPC_SB, rt, rs, u);
20491 gen_st(ctx, OPC_SH, rt, rs, u);
20494 gen_st(ctx, OPC_SW, rt, rs, u);
20497 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
20500 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
20503 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
20506 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
20509 generate_exception_end(ctx, EXCP_RI);
20516 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
20517 extract32(ctx->opcode, 0, 8);
20519 switch (extract32(ctx->opcode, 8, 3)) {
20521 switch (extract32(ctx->opcode, 11, 4)) {
20523 gen_ld(ctx, OPC_LB, rt, rs, s);
20526 gen_ld(ctx, OPC_LH, rt, rs, s);
20529 gen_ld(ctx, OPC_LW, rt, rs, s);
20532 gen_ld(ctx, OPC_LBU, rt, rs, s);
20535 gen_ld(ctx, OPC_LHU, rt, rs, s);
20538 gen_st(ctx, OPC_SB, rt, rs, s);
20541 gen_st(ctx, OPC_SH, rt, rs, s);
20544 gen_st(ctx, OPC_SW, rt, rs, s);
20547 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
20550 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
20553 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
20556 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
20561 /* Break the TB to be able to sync copied instructions
20563 ctx->base.is_jmp = DISAS_STOP;
20566 /* Treat as NOP. */
20570 generate_exception_end(ctx, EXCP_RI);
20575 switch (extract32(ctx->opcode, 11, 4)) {
20580 TCGv t0 = tcg_temp_new();
20581 TCGv t1 = tcg_temp_new();
20583 gen_base_offset_addr(ctx, t0, rs, s);
20585 switch (extract32(ctx->opcode, 11, 4)) {
20587 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
20589 gen_store_gpr(t0, rt);
20592 gen_load_gpr(t1, rt);
20593 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
20602 switch (ctx->opcode & 0x03) {
20604 gen_ld(ctx, OPC_LL, rt, rs, s);
20608 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20613 switch (ctx->opcode & 0x03) {
20615 gen_st_cond(ctx, OPC_SC, rt, rs, s);
20619 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20624 check_cp0_enabled(ctx);
20625 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
20626 gen_cache_operation(ctx, rt, rs, s);
20635 int count = extract32(ctx->opcode, 12, 3);
20638 offset = sextract32(ctx->opcode, 15, 1) << 8 |
20639 extract32(ctx->opcode, 0, 8);
20640 TCGv va = tcg_temp_new();
20641 TCGv t1 = tcg_temp_new();
20642 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
20643 NM_P_LS_UAWM ? MO_UNALN : 0;
20645 count = (count == 0) ? 8 : count;
20646 while (counter != count) {
20647 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
20648 int this_offset = offset + (counter << 2);
20650 gen_base_offset_addr(ctx, va, rs, this_offset);
20652 switch (extract32(ctx->opcode, 11, 1)) {
20654 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
20656 gen_store_gpr(t1, this_rt);
20657 if ((this_rt == rs) &&
20658 (counter != (count - 1))) {
20659 /* UNPREDICTABLE */
20663 this_rt = (rt == 0) ? 0 : this_rt;
20664 gen_load_gpr(t1, this_rt);
20665 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
20676 generate_exception_end(ctx, EXCP_RI);
20684 TCGv t0 = tcg_temp_new();
20685 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
20686 extract32(ctx->opcode, 1, 20) << 1;
20687 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
20688 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
20689 extract32(ctx->opcode, 21, 3));
20690 gen_load_gpr(t0, rt);
20691 tcg_gen_mov_tl(cpu_gpr[rd], t0);
20692 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20698 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
20699 extract32(ctx->opcode, 1, 24) << 1;
20701 if ((extract32(ctx->opcode, 25, 1)) == 0) {
20703 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
20706 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20711 switch (extract32(ctx->opcode, 12, 4)) {
20714 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
20717 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
20720 generate_exception_end(ctx, EXCP_RI);
20726 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20727 extract32(ctx->opcode, 1, 13) << 1;
20728 switch (extract32(ctx->opcode, 14, 2)) {
20731 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
20734 s = sextract32(ctx->opcode, 0, 1) << 14 |
20735 extract32(ctx->opcode, 1, 13) << 1;
20736 check_cp1_enabled(ctx);
20737 switch (extract32(ctx->opcode, 16, 5)) {
20739 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
20742 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
20747 int32_t imm = extract32(ctx->opcode, 1, 13) |
20748 extract32(ctx->opcode, 0, 1) << 13;
20750 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
20755 generate_exception_end(ctx, EXCP_RI);
20761 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
20763 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
20767 if (rs == rt || rt == 0) {
20768 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
20769 } else if (rs == 0) {
20770 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
20772 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
20780 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20781 extract32(ctx->opcode, 1, 13) << 1;
20782 switch (extract32(ctx->opcode, 14, 2)) {
20785 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
20788 if (rs != 0 && rt != 0 && rs == rt) {
20790 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20792 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
20796 if (rs == 0 || rs == rt) {
20798 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20800 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
20804 generate_exception_end(ctx, EXCP_RI);
20811 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
20812 extract32(ctx->opcode, 1, 10) << 1;
20813 uint32_t u = extract32(ctx->opcode, 11, 7);
20815 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
20820 generate_exception_end(ctx, EXCP_RI);
20826 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
20829 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
20830 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
20831 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
20835 /* make sure instructions are on a halfword boundary */
20836 if (ctx->base.pc_next & 0x1) {
20837 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
20838 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
20839 tcg_temp_free(tmp);
20840 generate_exception_end(ctx, EXCP_AdEL);
20844 op = extract32(ctx->opcode, 10, 6);
20847 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20850 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
20851 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
20854 switch (extract32(ctx->opcode, 3, 2)) {
20855 case NM_P16_SYSCALL:
20856 if (extract32(ctx->opcode, 2, 1) == 0) {
20857 generate_exception_end(ctx, EXCP_SYSCALL);
20859 generate_exception_end(ctx, EXCP_RI);
20863 generate_exception_end(ctx, EXCP_BREAK);
20866 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
20867 gen_helper_do_semihosting(cpu_env);
20869 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20870 generate_exception_end(ctx, EXCP_RI);
20872 generate_exception_end(ctx, EXCP_DBp);
20877 generate_exception_end(ctx, EXCP_RI);
20884 int shift = extract32(ctx->opcode, 0, 3);
20886 shift = (shift == 0) ? 8 : shift;
20888 switch (extract32(ctx->opcode, 3, 1)) {
20896 gen_shift_imm(ctx, opc, rt, rs, shift);
20900 switch (ctx->opcode & 1) {
20902 gen_pool16c_nanomips_insn(ctx);
20905 gen_ldxs(ctx, rt, rs, rd);
20910 switch (extract32(ctx->opcode, 6, 1)) {
20912 imm = extract32(ctx->opcode, 0, 6) << 2;
20913 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
20916 generate_exception_end(ctx, EXCP_RI);
20921 switch (extract32(ctx->opcode, 3, 1)) {
20923 imm = extract32(ctx->opcode, 0, 3) << 2;
20924 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
20926 case NM_P_ADDIURS5:
20927 rt = extract32(ctx->opcode, 5, 5);
20929 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
20930 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
20931 (extract32(ctx->opcode, 0, 3));
20932 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
20938 switch (ctx->opcode & 0x1) {
20940 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
20943 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
20948 rt = (extract32(ctx->opcode, 9, 1) << 3) |
20949 extract32(ctx->opcode, 5, 3);
20950 rs = (extract32(ctx->opcode, 4, 1) << 3) |
20951 extract32(ctx->opcode, 0, 3);
20952 rt = decode_gpr_gpr4(rt);
20953 rs = decode_gpr_gpr4(rs);
20954 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
20955 (extract32(ctx->opcode, 3, 1))) {
20958 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
20962 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
20965 generate_exception_end(ctx, EXCP_RI);
20971 int imm = extract32(ctx->opcode, 0, 7);
20972 imm = (imm == 0x7f ? -1 : imm);
20974 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20980 uint32_t u = extract32(ctx->opcode, 0, 4);
20981 u = (u == 12) ? 0xff :
20982 (u == 13) ? 0xffff : u;
20983 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
20987 offset = extract32(ctx->opcode, 0, 2);
20988 switch (extract32(ctx->opcode, 2, 2)) {
20990 gen_ld(ctx, OPC_LB, rt, rs, offset);
20993 rt = decode_gpr_gpr3_src_store(
20994 NANOMIPS_EXTRACT_RD(ctx->opcode));
20995 gen_st(ctx, OPC_SB, rt, rs, offset);
20998 gen_ld(ctx, OPC_LBU, rt, rs, offset);
21001 generate_exception_end(ctx, EXCP_RI);
21006 offset = extract32(ctx->opcode, 1, 2) << 1;
21007 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21009 gen_ld(ctx, OPC_LH, rt, rs, offset);
21012 rt = decode_gpr_gpr3_src_store(
21013 NANOMIPS_EXTRACT_RD(ctx->opcode));
21014 gen_st(ctx, OPC_SH, rt, rs, offset);
21017 gen_ld(ctx, OPC_LHU, rt, rs, offset);
21020 generate_exception_end(ctx, EXCP_RI);
21025 offset = extract32(ctx->opcode, 0, 4) << 2;
21026 gen_ld(ctx, OPC_LW, rt, rs, offset);
21029 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21030 offset = extract32(ctx->opcode, 0, 5) << 2;
21031 gen_ld(ctx, OPC_LW, rt, 29, offset);
21035 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21036 extract32(ctx->opcode, 5, 3);
21037 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21038 extract32(ctx->opcode, 0, 3);
21039 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21040 (extract32(ctx->opcode, 8, 1) << 2);
21041 rt = decode_gpr_gpr4(rt);
21042 rs = decode_gpr_gpr4(rs);
21043 gen_ld(ctx, OPC_LW, rt, rs, offset);
21047 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21048 extract32(ctx->opcode, 5, 3);
21049 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21050 extract32(ctx->opcode, 0, 3);
21051 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21052 (extract32(ctx->opcode, 8, 1) << 2);
21053 rt = decode_gpr_gpr4_zero(rt);
21054 rs = decode_gpr_gpr4(rs);
21055 gen_st(ctx, OPC_SW, rt, rs, offset);
21058 offset = extract32(ctx->opcode, 0, 7) << 2;
21059 gen_ld(ctx, OPC_LW, rt, 28, offset);
21062 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21063 offset = extract32(ctx->opcode, 0, 5) << 2;
21064 gen_st(ctx, OPC_SW, rt, 29, offset);
21067 rt = decode_gpr_gpr3_src_store(
21068 NANOMIPS_EXTRACT_RD(ctx->opcode));
21069 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21070 offset = extract32(ctx->opcode, 0, 4) << 2;
21071 gen_st(ctx, OPC_SW, rt, rs, offset);
21074 rt = decode_gpr_gpr3_src_store(
21075 NANOMIPS_EXTRACT_RD(ctx->opcode));
21076 offset = extract32(ctx->opcode, 0, 7) << 2;
21077 gen_st(ctx, OPC_SW, rt, 28, offset);
21080 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21081 (sextract32(ctx->opcode, 0, 1) << 10) |
21082 (extract32(ctx->opcode, 1, 9) << 1));
21085 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21086 (sextract32(ctx->opcode, 0, 1) << 10) |
21087 (extract32(ctx->opcode, 1, 9) << 1));
21090 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21091 (sextract32(ctx->opcode, 0, 1) << 7) |
21092 (extract32(ctx->opcode, 1, 6) << 1));
21095 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21096 (sextract32(ctx->opcode, 0, 1) << 7) |
21097 (extract32(ctx->opcode, 1, 6) << 1));
21100 switch (ctx->opcode & 0xf) {
21103 switch (extract32(ctx->opcode, 4, 1)) {
21105 gen_compute_branch_nm(ctx, OPC_JR, 2,
21106 extract32(ctx->opcode, 5, 5), 0, 0);
21109 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21110 extract32(ctx->opcode, 5, 5), 31, 0);
21117 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21118 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21119 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21120 extract32(ctx->opcode, 0, 4) << 1);
21127 int count = extract32(ctx->opcode, 0, 4);
21128 int u = extract32(ctx->opcode, 4, 4) << 4;
21130 rt = 30 + extract32(ctx->opcode, 9, 1);
21131 switch (extract32(ctx->opcode, 8, 1)) {
21133 gen_save(ctx, rt, count, 0, u);
21135 case NM_RESTORE_JRC16:
21136 gen_restore(ctx, rt, count, 0, u);
21137 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21146 static const int gpr2reg1[] = {4, 5, 6, 7};
21147 static const int gpr2reg2[] = {5, 6, 7, 8};
21149 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21150 extract32(ctx->opcode, 8, 1);
21151 int r1 = gpr2reg1[rd2];
21152 int r2 = gpr2reg2[rd2];
21153 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21154 extract32(ctx->opcode, 0, 3);
21155 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21156 extract32(ctx->opcode, 5, 3);
21157 TCGv t0 = tcg_temp_new();
21158 TCGv t1 = tcg_temp_new();
21159 if (op == NM_MOVEP) {
21162 rs = decode_gpr_gpr4_zero(r3);
21163 rt = decode_gpr_gpr4_zero(r4);
21165 rd = decode_gpr_gpr4(r3);
21166 re = decode_gpr_gpr4(r4);
21170 gen_load_gpr(t0, rs);
21171 gen_load_gpr(t1, rt);
21172 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21173 tcg_gen_mov_tl(cpu_gpr[re], t1);
21179 return decode_nanomips_32_48_opc(env, ctx);
21186 /* SmartMIPS extension to MIPS32 */
21188 #if defined(TARGET_MIPS64)
21190 /* MDMX extension to MIPS64 */
21194 /* MIPSDSP functions. */
21195 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
21196 int rd, int base, int offset)
21201 t0 = tcg_temp_new();
21204 gen_load_gpr(t0, offset);
21205 } else if (offset == 0) {
21206 gen_load_gpr(t0, base);
21208 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21213 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
21214 gen_store_gpr(t0, rd);
21217 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
21218 gen_store_gpr(t0, rd);
21221 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
21222 gen_store_gpr(t0, rd);
21224 #if defined(TARGET_MIPS64)
21226 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
21227 gen_store_gpr(t0, rd);
21234 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21235 int ret, int v1, int v2)
21241 /* Treat as NOP. */
21245 v1_t = tcg_temp_new();
21246 v2_t = tcg_temp_new();
21248 gen_load_gpr(v1_t, v1);
21249 gen_load_gpr(v2_t, v2);
21252 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21253 case OPC_MULT_G_2E:
21257 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21259 case OPC_ADDUH_R_QB:
21260 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21263 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21265 case OPC_ADDQH_R_PH:
21266 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21269 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21271 case OPC_ADDQH_R_W:
21272 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21275 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21277 case OPC_SUBUH_R_QB:
21278 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21281 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
21283 case OPC_SUBQH_R_PH:
21284 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21287 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
21289 case OPC_SUBQH_R_W:
21290 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21294 case OPC_ABSQ_S_PH_DSP:
21296 case OPC_ABSQ_S_QB:
21298 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
21300 case OPC_ABSQ_S_PH:
21302 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
21306 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
21308 case OPC_PRECEQ_W_PHL:
21310 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
21311 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21313 case OPC_PRECEQ_W_PHR:
21315 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
21316 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
21317 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21319 case OPC_PRECEQU_PH_QBL:
21321 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
21323 case OPC_PRECEQU_PH_QBR:
21325 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
21327 case OPC_PRECEQU_PH_QBLA:
21329 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
21331 case OPC_PRECEQU_PH_QBRA:
21333 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
21335 case OPC_PRECEU_PH_QBL:
21337 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
21339 case OPC_PRECEU_PH_QBR:
21341 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
21343 case OPC_PRECEU_PH_QBLA:
21345 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
21347 case OPC_PRECEU_PH_QBRA:
21349 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
21353 case OPC_ADDU_QB_DSP:
21357 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21359 case OPC_ADDQ_S_PH:
21361 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21365 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21369 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21371 case OPC_ADDU_S_QB:
21373 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21377 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21379 case OPC_ADDU_S_PH:
21381 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21385 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21387 case OPC_SUBQ_S_PH:
21389 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21393 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21397 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21399 case OPC_SUBU_S_QB:
21401 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21405 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21407 case OPC_SUBU_S_PH:
21409 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21413 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21417 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21421 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
21423 case OPC_RADDU_W_QB:
21425 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
21429 case OPC_CMPU_EQ_QB_DSP:
21431 case OPC_PRECR_QB_PH:
21433 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21435 case OPC_PRECRQ_QB_PH:
21437 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21439 case OPC_PRECR_SRA_PH_W:
21442 TCGv_i32 sa_t = tcg_const_i32(v2);
21443 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
21445 tcg_temp_free_i32(sa_t);
21448 case OPC_PRECR_SRA_R_PH_W:
21451 TCGv_i32 sa_t = tcg_const_i32(v2);
21452 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
21454 tcg_temp_free_i32(sa_t);
21457 case OPC_PRECRQ_PH_W:
21459 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
21461 case OPC_PRECRQ_RS_PH_W:
21463 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21465 case OPC_PRECRQU_S_QB_PH:
21467 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21471 #ifdef TARGET_MIPS64
21472 case OPC_ABSQ_S_QH_DSP:
21474 case OPC_PRECEQ_L_PWL:
21476 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
21478 case OPC_PRECEQ_L_PWR:
21480 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
21482 case OPC_PRECEQ_PW_QHL:
21484 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
21486 case OPC_PRECEQ_PW_QHR:
21488 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
21490 case OPC_PRECEQ_PW_QHLA:
21492 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
21494 case OPC_PRECEQ_PW_QHRA:
21496 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
21498 case OPC_PRECEQU_QH_OBL:
21500 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
21502 case OPC_PRECEQU_QH_OBR:
21504 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
21506 case OPC_PRECEQU_QH_OBLA:
21508 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
21510 case OPC_PRECEQU_QH_OBRA:
21512 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
21514 case OPC_PRECEU_QH_OBL:
21516 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
21518 case OPC_PRECEU_QH_OBR:
21520 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
21522 case OPC_PRECEU_QH_OBLA:
21524 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
21526 case OPC_PRECEU_QH_OBRA:
21528 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
21530 case OPC_ABSQ_S_OB:
21532 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
21534 case OPC_ABSQ_S_PW:
21536 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
21538 case OPC_ABSQ_S_QH:
21540 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
21544 case OPC_ADDU_OB_DSP:
21546 case OPC_RADDU_L_OB:
21548 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
21552 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21554 case OPC_SUBQ_S_PW:
21556 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21560 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21562 case OPC_SUBQ_S_QH:
21564 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21568 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21570 case OPC_SUBU_S_OB:
21572 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21576 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21578 case OPC_SUBU_S_QH:
21580 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21584 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
21586 case OPC_SUBUH_R_OB:
21588 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21592 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21594 case OPC_ADDQ_S_PW:
21596 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21600 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21602 case OPC_ADDQ_S_QH:
21604 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21608 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21610 case OPC_ADDU_S_OB:
21612 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21616 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21618 case OPC_ADDU_S_QH:
21620 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21624 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
21626 case OPC_ADDUH_R_OB:
21628 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21632 case OPC_CMPU_EQ_OB_DSP:
21634 case OPC_PRECR_OB_QH:
21636 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21638 case OPC_PRECR_SRA_QH_PW:
21641 TCGv_i32 ret_t = tcg_const_i32(ret);
21642 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
21643 tcg_temp_free_i32(ret_t);
21646 case OPC_PRECR_SRA_R_QH_PW:
21649 TCGv_i32 sa_v = tcg_const_i32(ret);
21650 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
21651 tcg_temp_free_i32(sa_v);
21654 case OPC_PRECRQ_OB_QH:
21656 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21658 case OPC_PRECRQ_PW_L:
21660 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
21662 case OPC_PRECRQ_QH_PW:
21664 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
21666 case OPC_PRECRQ_RS_QH_PW:
21668 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21670 case OPC_PRECRQU_S_OB_QH:
21672 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21679 tcg_temp_free(v1_t);
21680 tcg_temp_free(v2_t);
21683 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
21684 int ret, int v1, int v2)
21692 /* Treat as NOP. */
21696 t0 = tcg_temp_new();
21697 v1_t = tcg_temp_new();
21698 v2_t = tcg_temp_new();
21700 tcg_gen_movi_tl(t0, v1);
21701 gen_load_gpr(v1_t, v1);
21702 gen_load_gpr(v2_t, v2);
21705 case OPC_SHLL_QB_DSP:
21707 op2 = MASK_SHLL_QB(ctx->opcode);
21711 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
21715 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21719 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21723 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21725 case OPC_SHLL_S_PH:
21727 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21729 case OPC_SHLLV_S_PH:
21731 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21735 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
21737 case OPC_SHLLV_S_W:
21739 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21743 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
21747 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
21751 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
21755 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
21759 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
21761 case OPC_SHRA_R_QB:
21763 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
21767 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
21769 case OPC_SHRAV_R_QB:
21771 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
21775 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
21777 case OPC_SHRA_R_PH:
21779 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
21783 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
21785 case OPC_SHRAV_R_PH:
21787 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
21791 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
21793 case OPC_SHRAV_R_W:
21795 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
21797 default: /* Invalid */
21798 MIPS_INVAL("MASK SHLL.QB");
21799 generate_exception_end(ctx, EXCP_RI);
21804 #ifdef TARGET_MIPS64
21805 case OPC_SHLL_OB_DSP:
21806 op2 = MASK_SHLL_OB(ctx->opcode);
21810 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21814 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21816 case OPC_SHLL_S_PW:
21818 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21820 case OPC_SHLLV_S_PW:
21822 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21826 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
21830 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21834 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21838 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21840 case OPC_SHLL_S_QH:
21842 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21844 case OPC_SHLLV_S_QH:
21846 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21850 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
21854 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
21856 case OPC_SHRA_R_OB:
21858 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
21860 case OPC_SHRAV_R_OB:
21862 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
21866 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
21870 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
21872 case OPC_SHRA_R_PW:
21874 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
21876 case OPC_SHRAV_R_PW:
21878 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
21882 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
21886 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
21888 case OPC_SHRA_R_QH:
21890 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
21892 case OPC_SHRAV_R_QH:
21894 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
21898 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
21902 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
21906 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
21910 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
21912 default: /* Invalid */
21913 MIPS_INVAL("MASK SHLL.OB");
21914 generate_exception_end(ctx, EXCP_RI);
21922 tcg_temp_free(v1_t);
21923 tcg_temp_free(v2_t);
21926 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
21927 int ret, int v1, int v2, int check_ret)
21933 if ((ret == 0) && (check_ret == 1)) {
21934 /* Treat as NOP. */
21938 t0 = tcg_temp_new_i32();
21939 v1_t = tcg_temp_new();
21940 v2_t = tcg_temp_new();
21942 tcg_gen_movi_i32(t0, ret);
21943 gen_load_gpr(v1_t, v1);
21944 gen_load_gpr(v2_t, v2);
21947 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
21948 * the same mask and op1. */
21949 case OPC_MULT_G_2E:
21953 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21956 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21959 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21961 case OPC_MULQ_RS_W:
21962 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21966 case OPC_DPA_W_PH_DSP:
21968 case OPC_DPAU_H_QBL:
21970 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
21972 case OPC_DPAU_H_QBR:
21974 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
21976 case OPC_DPSU_H_QBL:
21978 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
21980 case OPC_DPSU_H_QBR:
21982 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
21986 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
21988 case OPC_DPAX_W_PH:
21990 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
21992 case OPC_DPAQ_S_W_PH:
21994 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21996 case OPC_DPAQX_S_W_PH:
21998 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22000 case OPC_DPAQX_SA_W_PH:
22002 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22006 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22008 case OPC_DPSX_W_PH:
22010 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22012 case OPC_DPSQ_S_W_PH:
22014 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22016 case OPC_DPSQX_S_W_PH:
22018 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22020 case OPC_DPSQX_SA_W_PH:
22022 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22024 case OPC_MULSAQ_S_W_PH:
22026 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22028 case OPC_DPAQ_SA_L_W:
22030 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22032 case OPC_DPSQ_SA_L_W:
22034 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22036 case OPC_MAQ_S_W_PHL:
22038 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22040 case OPC_MAQ_S_W_PHR:
22042 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22044 case OPC_MAQ_SA_W_PHL:
22046 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22048 case OPC_MAQ_SA_W_PHR:
22050 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22052 case OPC_MULSA_W_PH:
22054 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22058 #ifdef TARGET_MIPS64
22059 case OPC_DPAQ_W_QH_DSP:
22061 int ac = ret & 0x03;
22062 tcg_gen_movi_i32(t0, ac);
22067 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22071 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22075 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22079 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22083 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22085 case OPC_DPAQ_S_W_QH:
22087 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22089 case OPC_DPAQ_SA_L_PW:
22091 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22093 case OPC_DPAU_H_OBL:
22095 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22097 case OPC_DPAU_H_OBR:
22099 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22103 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22105 case OPC_DPSQ_S_W_QH:
22107 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22109 case OPC_DPSQ_SA_L_PW:
22111 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22113 case OPC_DPSU_H_OBL:
22115 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22117 case OPC_DPSU_H_OBR:
22119 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22121 case OPC_MAQ_S_L_PWL:
22123 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22125 case OPC_MAQ_S_L_PWR:
22127 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22129 case OPC_MAQ_S_W_QHLL:
22131 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22133 case OPC_MAQ_SA_W_QHLL:
22135 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22137 case OPC_MAQ_S_W_QHLR:
22139 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22141 case OPC_MAQ_SA_W_QHLR:
22143 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22145 case OPC_MAQ_S_W_QHRL:
22147 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22149 case OPC_MAQ_SA_W_QHRL:
22151 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22153 case OPC_MAQ_S_W_QHRR:
22155 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22157 case OPC_MAQ_SA_W_QHRR:
22159 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22161 case OPC_MULSAQ_S_L_PW:
22163 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22165 case OPC_MULSAQ_S_W_QH:
22167 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22173 case OPC_ADDU_QB_DSP:
22175 case OPC_MULEU_S_PH_QBL:
22177 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22179 case OPC_MULEU_S_PH_QBR:
22181 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22183 case OPC_MULQ_RS_PH:
22185 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22187 case OPC_MULEQ_S_W_PHL:
22189 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22191 case OPC_MULEQ_S_W_PHR:
22193 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22195 case OPC_MULQ_S_PH:
22197 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22201 #ifdef TARGET_MIPS64
22202 case OPC_ADDU_OB_DSP:
22204 case OPC_MULEQ_S_PW_QHL:
22206 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22208 case OPC_MULEQ_S_PW_QHR:
22210 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22212 case OPC_MULEU_S_QH_OBL:
22214 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22216 case OPC_MULEU_S_QH_OBR:
22218 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22220 case OPC_MULQ_RS_QH:
22222 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22229 tcg_temp_free_i32(t0);
22230 tcg_temp_free(v1_t);
22231 tcg_temp_free(v2_t);
22234 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22242 /* Treat as NOP. */
22246 t0 = tcg_temp_new();
22247 val_t = tcg_temp_new();
22248 gen_load_gpr(val_t, val);
22251 case OPC_ABSQ_S_PH_DSP:
22255 gen_helper_bitrev(cpu_gpr[ret], val_t);
22260 target_long result;
22261 imm = (ctx->opcode >> 16) & 0xFF;
22262 result = (uint32_t)imm << 24 |
22263 (uint32_t)imm << 16 |
22264 (uint32_t)imm << 8 |
22266 result = (int32_t)result;
22267 tcg_gen_movi_tl(cpu_gpr[ret], result);
22272 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22273 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22274 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22275 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22276 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22277 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22282 imm = (ctx->opcode >> 16) & 0x03FF;
22283 imm = (int16_t)(imm << 6) >> 6;
22284 tcg_gen_movi_tl(cpu_gpr[ret], \
22285 (target_long)((int32_t)imm << 16 | \
22291 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22292 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22293 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22294 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22298 #ifdef TARGET_MIPS64
22299 case OPC_ABSQ_S_QH_DSP:
22306 imm = (ctx->opcode >> 16) & 0xFF;
22307 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
22308 temp = (temp << 16) | temp;
22309 temp = (temp << 32) | temp;
22310 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22318 imm = (ctx->opcode >> 16) & 0x03FF;
22319 imm = (int16_t)(imm << 6) >> 6;
22320 temp = ((target_long)imm << 32) \
22321 | ((target_long)imm & 0xFFFFFFFF);
22322 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22330 imm = (ctx->opcode >> 16) & 0x03FF;
22331 imm = (int16_t)(imm << 6) >> 6;
22333 temp = ((uint64_t)(uint16_t)imm << 48) |
22334 ((uint64_t)(uint16_t)imm << 32) |
22335 ((uint64_t)(uint16_t)imm << 16) |
22336 (uint64_t)(uint16_t)imm;
22337 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22342 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22343 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22344 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22345 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22346 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22347 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22348 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22352 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
22353 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22354 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22358 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22359 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22360 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22361 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22362 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22369 tcg_temp_free(val_t);
22372 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
22373 uint32_t op1, uint32_t op2,
22374 int ret, int v1, int v2, int check_ret)
22380 if ((ret == 0) && (check_ret == 1)) {
22381 /* Treat as NOP. */
22385 t1 = tcg_temp_new();
22386 v1_t = tcg_temp_new();
22387 v2_t = tcg_temp_new();
22389 gen_load_gpr(v1_t, v1);
22390 gen_load_gpr(v2_t, v2);
22393 case OPC_CMPU_EQ_QB_DSP:
22395 case OPC_CMPU_EQ_QB:
22397 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
22399 case OPC_CMPU_LT_QB:
22401 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
22403 case OPC_CMPU_LE_QB:
22405 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
22407 case OPC_CMPGU_EQ_QB:
22409 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
22411 case OPC_CMPGU_LT_QB:
22413 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
22415 case OPC_CMPGU_LE_QB:
22417 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
22419 case OPC_CMPGDU_EQ_QB:
22421 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
22422 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22423 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22424 tcg_gen_shli_tl(t1, t1, 24);
22425 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22427 case OPC_CMPGDU_LT_QB:
22429 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
22430 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22431 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22432 tcg_gen_shli_tl(t1, t1, 24);
22433 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22435 case OPC_CMPGDU_LE_QB:
22437 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
22438 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22439 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22440 tcg_gen_shli_tl(t1, t1, 24);
22441 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22443 case OPC_CMP_EQ_PH:
22445 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
22447 case OPC_CMP_LT_PH:
22449 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
22451 case OPC_CMP_LE_PH:
22453 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
22457 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22461 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22463 case OPC_PACKRL_PH:
22465 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
22469 #ifdef TARGET_MIPS64
22470 case OPC_CMPU_EQ_OB_DSP:
22472 case OPC_CMP_EQ_PW:
22474 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
22476 case OPC_CMP_LT_PW:
22478 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
22480 case OPC_CMP_LE_PW:
22482 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
22484 case OPC_CMP_EQ_QH:
22486 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
22488 case OPC_CMP_LT_QH:
22490 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
22492 case OPC_CMP_LE_QH:
22494 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
22496 case OPC_CMPGDU_EQ_OB:
22498 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22500 case OPC_CMPGDU_LT_OB:
22502 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22504 case OPC_CMPGDU_LE_OB:
22506 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22508 case OPC_CMPGU_EQ_OB:
22510 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
22512 case OPC_CMPGU_LT_OB:
22514 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
22516 case OPC_CMPGU_LE_OB:
22518 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
22520 case OPC_CMPU_EQ_OB:
22522 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
22524 case OPC_CMPU_LT_OB:
22526 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
22528 case OPC_CMPU_LE_OB:
22530 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
22532 case OPC_PACKRL_PW:
22534 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
22538 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22542 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22546 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22554 tcg_temp_free(v1_t);
22555 tcg_temp_free(v2_t);
22558 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
22559 uint32_t op1, int rt, int rs, int sa)
22566 /* Treat as NOP. */
22570 t0 = tcg_temp_new();
22571 gen_load_gpr(t0, rs);
22574 case OPC_APPEND_DSP:
22575 switch (MASK_APPEND(ctx->opcode)) {
22578 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
22580 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22584 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
22585 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22586 tcg_gen_shli_tl(t0, t0, 32 - sa);
22587 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22589 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22593 if (sa != 0 && sa != 2) {
22594 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22595 tcg_gen_ext32u_tl(t0, t0);
22596 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
22597 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22599 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22601 default: /* Invalid */
22602 MIPS_INVAL("MASK APPEND");
22603 generate_exception_end(ctx, EXCP_RI);
22607 #ifdef TARGET_MIPS64
22608 case OPC_DAPPEND_DSP:
22609 switch (MASK_DAPPEND(ctx->opcode)) {
22612 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
22616 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
22617 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
22618 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
22622 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22623 tcg_gen_shli_tl(t0, t0, 64 - sa);
22624 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22629 if (sa != 0 && sa != 2 && sa != 4) {
22630 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22631 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
22632 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22635 default: /* Invalid */
22636 MIPS_INVAL("MASK DAPPEND");
22637 generate_exception_end(ctx, EXCP_RI);
22646 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22647 int ret, int v1, int v2, int check_ret)
22656 if ((ret == 0) && (check_ret == 1)) {
22657 /* Treat as NOP. */
22661 t0 = tcg_temp_new();
22662 t1 = tcg_temp_new();
22663 v1_t = tcg_temp_new();
22664 v2_t = tcg_temp_new();
22666 gen_load_gpr(v1_t, v1);
22667 gen_load_gpr(v2_t, v2);
22670 case OPC_EXTR_W_DSP:
22674 tcg_gen_movi_tl(t0, v2);
22675 tcg_gen_movi_tl(t1, v1);
22676 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
22679 tcg_gen_movi_tl(t0, v2);
22680 tcg_gen_movi_tl(t1, v1);
22681 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22683 case OPC_EXTR_RS_W:
22684 tcg_gen_movi_tl(t0, v2);
22685 tcg_gen_movi_tl(t1, v1);
22686 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22689 tcg_gen_movi_tl(t0, v2);
22690 tcg_gen_movi_tl(t1, v1);
22691 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22693 case OPC_EXTRV_S_H:
22694 tcg_gen_movi_tl(t0, v2);
22695 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
22698 tcg_gen_movi_tl(t0, v2);
22699 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22701 case OPC_EXTRV_R_W:
22702 tcg_gen_movi_tl(t0, v2);
22703 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22705 case OPC_EXTRV_RS_W:
22706 tcg_gen_movi_tl(t0, v2);
22707 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22710 tcg_gen_movi_tl(t0, v2);
22711 tcg_gen_movi_tl(t1, v1);
22712 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
22715 tcg_gen_movi_tl(t0, v2);
22716 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
22719 tcg_gen_movi_tl(t0, v2);
22720 tcg_gen_movi_tl(t1, v1);
22721 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
22724 tcg_gen_movi_tl(t0, v2);
22725 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22728 imm = (ctx->opcode >> 20) & 0x3F;
22729 tcg_gen_movi_tl(t0, ret);
22730 tcg_gen_movi_tl(t1, imm);
22731 gen_helper_shilo(t0, t1, cpu_env);
22734 tcg_gen_movi_tl(t0, ret);
22735 gen_helper_shilo(t0, v1_t, cpu_env);
22738 tcg_gen_movi_tl(t0, ret);
22739 gen_helper_mthlip(t0, v1_t, cpu_env);
22742 imm = (ctx->opcode >> 11) & 0x3FF;
22743 tcg_gen_movi_tl(t0, imm);
22744 gen_helper_wrdsp(v1_t, t0, cpu_env);
22747 imm = (ctx->opcode >> 16) & 0x03FF;
22748 tcg_gen_movi_tl(t0, imm);
22749 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
22753 #ifdef TARGET_MIPS64
22754 case OPC_DEXTR_W_DSP:
22758 tcg_gen_movi_tl(t0, ret);
22759 gen_helper_dmthlip(v1_t, t0, cpu_env);
22763 int shift = (ctx->opcode >> 19) & 0x7F;
22764 int ac = (ctx->opcode >> 11) & 0x03;
22765 tcg_gen_movi_tl(t0, shift);
22766 tcg_gen_movi_tl(t1, ac);
22767 gen_helper_dshilo(t0, t1, cpu_env);
22772 int ac = (ctx->opcode >> 11) & 0x03;
22773 tcg_gen_movi_tl(t0, ac);
22774 gen_helper_dshilo(v1_t, t0, cpu_env);
22778 tcg_gen_movi_tl(t0, v2);
22779 tcg_gen_movi_tl(t1, v1);
22781 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
22784 tcg_gen_movi_tl(t0, v2);
22785 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
22788 tcg_gen_movi_tl(t0, v2);
22789 tcg_gen_movi_tl(t1, v1);
22790 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
22793 tcg_gen_movi_tl(t0, v2);
22794 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22797 tcg_gen_movi_tl(t0, v2);
22798 tcg_gen_movi_tl(t1, v1);
22799 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
22801 case OPC_DEXTR_R_L:
22802 tcg_gen_movi_tl(t0, v2);
22803 tcg_gen_movi_tl(t1, v1);
22804 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
22806 case OPC_DEXTR_RS_L:
22807 tcg_gen_movi_tl(t0, v2);
22808 tcg_gen_movi_tl(t1, v1);
22809 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
22812 tcg_gen_movi_tl(t0, v2);
22813 tcg_gen_movi_tl(t1, v1);
22814 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
22816 case OPC_DEXTR_R_W:
22817 tcg_gen_movi_tl(t0, v2);
22818 tcg_gen_movi_tl(t1, v1);
22819 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22821 case OPC_DEXTR_RS_W:
22822 tcg_gen_movi_tl(t0, v2);
22823 tcg_gen_movi_tl(t1, v1);
22824 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22826 case OPC_DEXTR_S_H:
22827 tcg_gen_movi_tl(t0, v2);
22828 tcg_gen_movi_tl(t1, v1);
22829 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22831 case OPC_DEXTRV_S_H:
22832 tcg_gen_movi_tl(t0, v2);
22833 tcg_gen_movi_tl(t1, v1);
22834 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22837 tcg_gen_movi_tl(t0, v2);
22838 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22840 case OPC_DEXTRV_R_L:
22841 tcg_gen_movi_tl(t0, v2);
22842 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22844 case OPC_DEXTRV_RS_L:
22845 tcg_gen_movi_tl(t0, v2);
22846 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22849 tcg_gen_movi_tl(t0, v2);
22850 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22852 case OPC_DEXTRV_R_W:
22853 tcg_gen_movi_tl(t0, v2);
22854 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22856 case OPC_DEXTRV_RS_W:
22857 tcg_gen_movi_tl(t0, v2);
22858 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22867 tcg_temp_free(v1_t);
22868 tcg_temp_free(v2_t);
22871 /* End MIPSDSP functions. */
22873 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
22875 int rs, rt, rd, sa;
22878 rs = (ctx->opcode >> 21) & 0x1f;
22879 rt = (ctx->opcode >> 16) & 0x1f;
22880 rd = (ctx->opcode >> 11) & 0x1f;
22881 sa = (ctx->opcode >> 6) & 0x1f;
22883 op1 = MASK_SPECIAL(ctx->opcode);
22886 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
22892 op2 = MASK_R6_MULDIV(ctx->opcode);
22902 gen_r6_muldiv(ctx, op2, rd, rs, rt);
22905 MIPS_INVAL("special_r6 muldiv");
22906 generate_exception_end(ctx, EXCP_RI);
22912 gen_cond_move(ctx, op1, rd, rs, rt);
22916 if (rt == 0 && sa == 1) {
22917 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22918 We need additionally to check other fields */
22919 gen_cl(ctx, op1, rd, rs);
22921 generate_exception_end(ctx, EXCP_RI);
22925 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
22926 gen_helper_do_semihosting(cpu_env);
22928 if (ctx->hflags & MIPS_HFLAG_SBRI) {
22929 generate_exception_end(ctx, EXCP_RI);
22931 generate_exception_end(ctx, EXCP_DBp);
22935 #if defined(TARGET_MIPS64)
22937 check_mips_64(ctx);
22938 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
22942 if (rt == 0 && sa == 1) {
22943 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22944 We need additionally to check other fields */
22945 check_mips_64(ctx);
22946 gen_cl(ctx, op1, rd, rs);
22948 generate_exception_end(ctx, EXCP_RI);
22956 op2 = MASK_R6_MULDIV(ctx->opcode);
22966 check_mips_64(ctx);
22967 gen_r6_muldiv(ctx, op2, rd, rs, rt);
22970 MIPS_INVAL("special_r6 muldiv");
22971 generate_exception_end(ctx, EXCP_RI);
22976 default: /* Invalid */
22977 MIPS_INVAL("special_r6");
22978 generate_exception_end(ctx, EXCP_RI);
22983 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
22985 int rs, rt, rd, sa;
22988 rs = (ctx->opcode >> 21) & 0x1f;
22989 rt = (ctx->opcode >> 16) & 0x1f;
22990 rd = (ctx->opcode >> 11) & 0x1f;
22991 sa = (ctx->opcode >> 6) & 0x1f;
22993 op1 = MASK_SPECIAL(ctx->opcode);
22995 case OPC_MOVN: /* Conditional move */
22997 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
22998 INSN_LOONGSON2E | INSN_LOONGSON2F);
22999 gen_cond_move(ctx, op1, rd, rs, rt);
23001 case OPC_MFHI: /* Move from HI/LO */
23003 gen_HILO(ctx, op1, rs & 3, rd);
23006 case OPC_MTLO: /* Move to HI/LO */
23007 gen_HILO(ctx, op1, rd & 3, rs);
23010 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23011 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23012 check_cp1_enabled(ctx);
23013 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23014 (ctx->opcode >> 16) & 1);
23016 generate_exception_err(ctx, EXCP_CpU, 1);
23022 check_insn(ctx, INSN_VR54XX);
23023 op1 = MASK_MUL_VR54XX(ctx->opcode);
23024 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23026 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23031 gen_muldiv(ctx, op1, 0, rs, rt);
23033 #if defined(TARGET_MIPS64)
23038 check_insn(ctx, ISA_MIPS3);
23039 check_mips_64(ctx);
23040 gen_muldiv(ctx, op1, 0, rs, rt);
23044 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23047 #ifdef MIPS_STRICT_STANDARD
23048 MIPS_INVAL("SPIM");
23049 generate_exception_end(ctx, EXCP_RI);
23051 /* Implemented as RI exception for now. */
23052 MIPS_INVAL("spim (unofficial)");
23053 generate_exception_end(ctx, EXCP_RI);
23056 default: /* Invalid */
23057 MIPS_INVAL("special_legacy");
23058 generate_exception_end(ctx, EXCP_RI);
23063 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
23065 int rs, rt, rd, sa;
23068 rs = (ctx->opcode >> 21) & 0x1f;
23069 rt = (ctx->opcode >> 16) & 0x1f;
23070 rd = (ctx->opcode >> 11) & 0x1f;
23071 sa = (ctx->opcode >> 6) & 0x1f;
23073 op1 = MASK_SPECIAL(ctx->opcode);
23075 case OPC_SLL: /* Shift with immediate */
23076 if (sa == 5 && rd == 0 &&
23077 rs == 0 && rt == 0) { /* PAUSE */
23078 if ((ctx->insn_flags & ISA_MIPS32R6) &&
23079 (ctx->hflags & MIPS_HFLAG_BMASK)) {
23080 generate_exception_end(ctx, EXCP_RI);
23086 gen_shift_imm(ctx, op1, rd, rt, sa);
23089 switch ((ctx->opcode >> 21) & 0x1f) {
23091 /* rotr is decoded as srl on non-R2 CPUs */
23092 if (ctx->insn_flags & ISA_MIPS32R2) {
23097 gen_shift_imm(ctx, op1, rd, rt, sa);
23100 generate_exception_end(ctx, EXCP_RI);
23108 gen_arith(ctx, op1, rd, rs, rt);
23110 case OPC_SLLV: /* Shifts */
23112 gen_shift(ctx, op1, rd, rs, rt);
23115 switch ((ctx->opcode >> 6) & 0x1f) {
23117 /* rotrv is decoded as srlv on non-R2 CPUs */
23118 if (ctx->insn_flags & ISA_MIPS32R2) {
23123 gen_shift(ctx, op1, rd, rs, rt);
23126 generate_exception_end(ctx, EXCP_RI);
23130 case OPC_SLT: /* Set on less than */
23132 gen_slt(ctx, op1, rd, rs, rt);
23134 case OPC_AND: /* Logic*/
23138 gen_logic(ctx, op1, rd, rs, rt);
23141 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23143 case OPC_TGE: /* Traps */
23149 check_insn(ctx, ISA_MIPS2);
23150 gen_trap(ctx, op1, rs, rt, -1);
23152 case OPC_LSA: /* OPC_PMON */
23153 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23154 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23155 decode_opc_special_r6(env, ctx);
23157 /* Pmon entry point, also R4010 selsl */
23158 #ifdef MIPS_STRICT_STANDARD
23159 MIPS_INVAL("PMON / selsl");
23160 generate_exception_end(ctx, EXCP_RI);
23162 gen_helper_0e0i(pmon, sa);
23167 generate_exception_end(ctx, EXCP_SYSCALL);
23170 generate_exception_end(ctx, EXCP_BREAK);
23173 check_insn(ctx, ISA_MIPS2);
23174 gen_sync(extract32(ctx->opcode, 6, 5));
23177 #if defined(TARGET_MIPS64)
23178 /* MIPS64 specific opcodes */
23183 check_insn(ctx, ISA_MIPS3);
23184 check_mips_64(ctx);
23185 gen_shift_imm(ctx, op1, rd, rt, sa);
23188 switch ((ctx->opcode >> 21) & 0x1f) {
23190 /* drotr is decoded as dsrl on non-R2 CPUs */
23191 if (ctx->insn_flags & ISA_MIPS32R2) {
23196 check_insn(ctx, ISA_MIPS3);
23197 check_mips_64(ctx);
23198 gen_shift_imm(ctx, op1, rd, rt, sa);
23201 generate_exception_end(ctx, EXCP_RI);
23206 switch ((ctx->opcode >> 21) & 0x1f) {
23208 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23209 if (ctx->insn_flags & ISA_MIPS32R2) {
23214 check_insn(ctx, ISA_MIPS3);
23215 check_mips_64(ctx);
23216 gen_shift_imm(ctx, op1, rd, rt, sa);
23219 generate_exception_end(ctx, EXCP_RI);
23227 check_insn(ctx, ISA_MIPS3);
23228 check_mips_64(ctx);
23229 gen_arith(ctx, op1, rd, rs, rt);
23233 check_insn(ctx, ISA_MIPS3);
23234 check_mips_64(ctx);
23235 gen_shift(ctx, op1, rd, rs, rt);
23238 switch ((ctx->opcode >> 6) & 0x1f) {
23240 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23241 if (ctx->insn_flags & ISA_MIPS32R2) {
23246 check_insn(ctx, ISA_MIPS3);
23247 check_mips_64(ctx);
23248 gen_shift(ctx, op1, rd, rs, rt);
23251 generate_exception_end(ctx, EXCP_RI);
23256 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23257 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23258 decode_opc_special_r6(env, ctx);
23263 if (ctx->insn_flags & ISA_MIPS32R6) {
23264 decode_opc_special_r6(env, ctx);
23266 decode_opc_special_legacy(env, ctx);
23271 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
23276 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23278 rs = (ctx->opcode >> 21) & 0x1f;
23279 rt = (ctx->opcode >> 16) & 0x1f;
23280 rd = (ctx->opcode >> 11) & 0x1f;
23282 op1 = MASK_SPECIAL2(ctx->opcode);
23284 case OPC_MADD: /* Multiply and add/sub */
23288 check_insn(ctx, ISA_MIPS32);
23289 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23292 gen_arith(ctx, op1, rd, rs, rt);
23295 case OPC_DIVU_G_2F:
23296 case OPC_MULT_G_2F:
23297 case OPC_MULTU_G_2F:
23299 case OPC_MODU_G_2F:
23300 check_insn(ctx, INSN_LOONGSON2F);
23301 gen_loongson_integer(ctx, op1, rd, rs, rt);
23305 check_insn(ctx, ISA_MIPS32);
23306 gen_cl(ctx, op1, rd, rs);
23309 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23310 gen_helper_do_semihosting(cpu_env);
23312 /* XXX: not clear which exception should be raised
23313 * when in debug mode...
23315 check_insn(ctx, ISA_MIPS32);
23316 generate_exception_end(ctx, EXCP_DBp);
23319 #if defined(TARGET_MIPS64)
23322 check_insn(ctx, ISA_MIPS64);
23323 check_mips_64(ctx);
23324 gen_cl(ctx, op1, rd, rs);
23326 case OPC_DMULT_G_2F:
23327 case OPC_DMULTU_G_2F:
23328 case OPC_DDIV_G_2F:
23329 case OPC_DDIVU_G_2F:
23330 case OPC_DMOD_G_2F:
23331 case OPC_DMODU_G_2F:
23332 check_insn(ctx, INSN_LOONGSON2F);
23333 gen_loongson_integer(ctx, op1, rd, rs, rt);
23336 default: /* Invalid */
23337 MIPS_INVAL("special2_legacy");
23338 generate_exception_end(ctx, EXCP_RI);
23343 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
23345 int rs, rt, rd, sa;
23349 rs = (ctx->opcode >> 21) & 0x1f;
23350 rt = (ctx->opcode >> 16) & 0x1f;
23351 rd = (ctx->opcode >> 11) & 0x1f;
23352 sa = (ctx->opcode >> 6) & 0x1f;
23353 imm = (int16_t)ctx->opcode >> 7;
23355 op1 = MASK_SPECIAL3(ctx->opcode);
23359 /* hint codes 24-31 are reserved and signal RI */
23360 generate_exception_end(ctx, EXCP_RI);
23362 /* Treat as NOP. */
23365 check_cp0_enabled(ctx);
23366 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23367 gen_cache_operation(ctx, rt, rs, imm);
23371 gen_st_cond(ctx, op1, rt, rs, imm);
23374 gen_ld(ctx, op1, rt, rs, imm);
23379 /* Treat as NOP. */
23382 op2 = MASK_BSHFL(ctx->opcode);
23385 case OPC_ALIGN_END:
23386 gen_align(ctx, 32, rd, rs, rt, sa & 3);
23389 gen_bitswap(ctx, op2, rd, rt);
23394 #if defined(TARGET_MIPS64)
23396 gen_st_cond(ctx, op1, rt, rs, imm);
23399 gen_ld(ctx, op1, rt, rs, imm);
23402 check_mips_64(ctx);
23405 /* Treat as NOP. */
23408 op2 = MASK_DBSHFL(ctx->opcode);
23411 case OPC_DALIGN_END:
23412 gen_align(ctx, 64, rd, rs, rt, sa & 7);
23415 gen_bitswap(ctx, op2, rd, rt);
23422 default: /* Invalid */
23423 MIPS_INVAL("special3_r6");
23424 generate_exception_end(ctx, EXCP_RI);
23429 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
23434 rs = (ctx->opcode >> 21) & 0x1f;
23435 rt = (ctx->opcode >> 16) & 0x1f;
23436 rd = (ctx->opcode >> 11) & 0x1f;
23438 op1 = MASK_SPECIAL3(ctx->opcode);
23441 case OPC_DIVU_G_2E:
23443 case OPC_MODU_G_2E:
23444 case OPC_MULT_G_2E:
23445 case OPC_MULTU_G_2E:
23446 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23447 * the same mask and op1. */
23448 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
23449 op2 = MASK_ADDUH_QB(ctx->opcode);
23452 case OPC_ADDUH_R_QB:
23454 case OPC_ADDQH_R_PH:
23456 case OPC_ADDQH_R_W:
23458 case OPC_SUBUH_R_QB:
23460 case OPC_SUBQH_R_PH:
23462 case OPC_SUBQH_R_W:
23463 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23468 case OPC_MULQ_RS_W:
23469 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23472 MIPS_INVAL("MASK ADDUH.QB");
23473 generate_exception_end(ctx, EXCP_RI);
23476 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
23477 gen_loongson_integer(ctx, op1, rd, rs, rt);
23479 generate_exception_end(ctx, EXCP_RI);
23483 op2 = MASK_LX(ctx->opcode);
23485 #if defined(TARGET_MIPS64)
23491 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
23493 default: /* Invalid */
23494 MIPS_INVAL("MASK LX");
23495 generate_exception_end(ctx, EXCP_RI);
23499 case OPC_ABSQ_S_PH_DSP:
23500 op2 = MASK_ABSQ_S_PH(ctx->opcode);
23502 case OPC_ABSQ_S_QB:
23503 case OPC_ABSQ_S_PH:
23505 case OPC_PRECEQ_W_PHL:
23506 case OPC_PRECEQ_W_PHR:
23507 case OPC_PRECEQU_PH_QBL:
23508 case OPC_PRECEQU_PH_QBR:
23509 case OPC_PRECEQU_PH_QBLA:
23510 case OPC_PRECEQU_PH_QBRA:
23511 case OPC_PRECEU_PH_QBL:
23512 case OPC_PRECEU_PH_QBR:
23513 case OPC_PRECEU_PH_QBLA:
23514 case OPC_PRECEU_PH_QBRA:
23515 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23522 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23525 MIPS_INVAL("MASK ABSQ_S.PH");
23526 generate_exception_end(ctx, EXCP_RI);
23530 case OPC_ADDU_QB_DSP:
23531 op2 = MASK_ADDU_QB(ctx->opcode);
23534 case OPC_ADDQ_S_PH:
23537 case OPC_ADDU_S_QB:
23539 case OPC_ADDU_S_PH:
23541 case OPC_SUBQ_S_PH:
23544 case OPC_SUBU_S_QB:
23546 case OPC_SUBU_S_PH:
23550 case OPC_RADDU_W_QB:
23551 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23553 case OPC_MULEU_S_PH_QBL:
23554 case OPC_MULEU_S_PH_QBR:
23555 case OPC_MULQ_RS_PH:
23556 case OPC_MULEQ_S_W_PHL:
23557 case OPC_MULEQ_S_W_PHR:
23558 case OPC_MULQ_S_PH:
23559 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23561 default: /* Invalid */
23562 MIPS_INVAL("MASK ADDU.QB");
23563 generate_exception_end(ctx, EXCP_RI);
23568 case OPC_CMPU_EQ_QB_DSP:
23569 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
23571 case OPC_PRECR_SRA_PH_W:
23572 case OPC_PRECR_SRA_R_PH_W:
23573 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
23575 case OPC_PRECR_QB_PH:
23576 case OPC_PRECRQ_QB_PH:
23577 case OPC_PRECRQ_PH_W:
23578 case OPC_PRECRQ_RS_PH_W:
23579 case OPC_PRECRQU_S_QB_PH:
23580 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23582 case OPC_CMPU_EQ_QB:
23583 case OPC_CMPU_LT_QB:
23584 case OPC_CMPU_LE_QB:
23585 case OPC_CMP_EQ_PH:
23586 case OPC_CMP_LT_PH:
23587 case OPC_CMP_LE_PH:
23588 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
23590 case OPC_CMPGU_EQ_QB:
23591 case OPC_CMPGU_LT_QB:
23592 case OPC_CMPGU_LE_QB:
23593 case OPC_CMPGDU_EQ_QB:
23594 case OPC_CMPGDU_LT_QB:
23595 case OPC_CMPGDU_LE_QB:
23598 case OPC_PACKRL_PH:
23599 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23601 default: /* Invalid */
23602 MIPS_INVAL("MASK CMPU.EQ.QB");
23603 generate_exception_end(ctx, EXCP_RI);
23607 case OPC_SHLL_QB_DSP:
23608 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23610 case OPC_DPA_W_PH_DSP:
23611 op2 = MASK_DPA_W_PH(ctx->opcode);
23613 case OPC_DPAU_H_QBL:
23614 case OPC_DPAU_H_QBR:
23615 case OPC_DPSU_H_QBL:
23616 case OPC_DPSU_H_QBR:
23618 case OPC_DPAX_W_PH:
23619 case OPC_DPAQ_S_W_PH:
23620 case OPC_DPAQX_S_W_PH:
23621 case OPC_DPAQX_SA_W_PH:
23623 case OPC_DPSX_W_PH:
23624 case OPC_DPSQ_S_W_PH:
23625 case OPC_DPSQX_S_W_PH:
23626 case OPC_DPSQX_SA_W_PH:
23627 case OPC_MULSAQ_S_W_PH:
23628 case OPC_DPAQ_SA_L_W:
23629 case OPC_DPSQ_SA_L_W:
23630 case OPC_MAQ_S_W_PHL:
23631 case OPC_MAQ_S_W_PHR:
23632 case OPC_MAQ_SA_W_PHL:
23633 case OPC_MAQ_SA_W_PHR:
23634 case OPC_MULSA_W_PH:
23635 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23637 default: /* Invalid */
23638 MIPS_INVAL("MASK DPAW.PH");
23639 generate_exception_end(ctx, EXCP_RI);
23644 op2 = MASK_INSV(ctx->opcode);
23655 t0 = tcg_temp_new();
23656 t1 = tcg_temp_new();
23658 gen_load_gpr(t0, rt);
23659 gen_load_gpr(t1, rs);
23661 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
23667 default: /* Invalid */
23668 MIPS_INVAL("MASK INSV");
23669 generate_exception_end(ctx, EXCP_RI);
23673 case OPC_APPEND_DSP:
23674 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23676 case OPC_EXTR_W_DSP:
23677 op2 = MASK_EXTR_W(ctx->opcode);
23681 case OPC_EXTR_RS_W:
23683 case OPC_EXTRV_S_H:
23685 case OPC_EXTRV_R_W:
23686 case OPC_EXTRV_RS_W:
23691 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23694 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
23700 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23702 default: /* Invalid */
23703 MIPS_INVAL("MASK EXTR.W");
23704 generate_exception_end(ctx, EXCP_RI);
23708 #if defined(TARGET_MIPS64)
23709 case OPC_DDIV_G_2E:
23710 case OPC_DDIVU_G_2E:
23711 case OPC_DMULT_G_2E:
23712 case OPC_DMULTU_G_2E:
23713 case OPC_DMOD_G_2E:
23714 case OPC_DMODU_G_2E:
23715 check_insn(ctx, INSN_LOONGSON2E);
23716 gen_loongson_integer(ctx, op1, rd, rs, rt);
23718 case OPC_ABSQ_S_QH_DSP:
23719 op2 = MASK_ABSQ_S_QH(ctx->opcode);
23721 case OPC_PRECEQ_L_PWL:
23722 case OPC_PRECEQ_L_PWR:
23723 case OPC_PRECEQ_PW_QHL:
23724 case OPC_PRECEQ_PW_QHR:
23725 case OPC_PRECEQ_PW_QHLA:
23726 case OPC_PRECEQ_PW_QHRA:
23727 case OPC_PRECEQU_QH_OBL:
23728 case OPC_PRECEQU_QH_OBR:
23729 case OPC_PRECEQU_QH_OBLA:
23730 case OPC_PRECEQU_QH_OBRA:
23731 case OPC_PRECEU_QH_OBL:
23732 case OPC_PRECEU_QH_OBR:
23733 case OPC_PRECEU_QH_OBLA:
23734 case OPC_PRECEU_QH_OBRA:
23735 case OPC_ABSQ_S_OB:
23736 case OPC_ABSQ_S_PW:
23737 case OPC_ABSQ_S_QH:
23738 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23746 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23748 default: /* Invalid */
23749 MIPS_INVAL("MASK ABSQ_S.QH");
23750 generate_exception_end(ctx, EXCP_RI);
23754 case OPC_ADDU_OB_DSP:
23755 op2 = MASK_ADDU_OB(ctx->opcode);
23757 case OPC_RADDU_L_OB:
23759 case OPC_SUBQ_S_PW:
23761 case OPC_SUBQ_S_QH:
23763 case OPC_SUBU_S_OB:
23765 case OPC_SUBU_S_QH:
23767 case OPC_SUBUH_R_OB:
23769 case OPC_ADDQ_S_PW:
23771 case OPC_ADDQ_S_QH:
23773 case OPC_ADDU_S_OB:
23775 case OPC_ADDU_S_QH:
23777 case OPC_ADDUH_R_OB:
23778 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23780 case OPC_MULEQ_S_PW_QHL:
23781 case OPC_MULEQ_S_PW_QHR:
23782 case OPC_MULEU_S_QH_OBL:
23783 case OPC_MULEU_S_QH_OBR:
23784 case OPC_MULQ_RS_QH:
23785 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23787 default: /* Invalid */
23788 MIPS_INVAL("MASK ADDU.OB");
23789 generate_exception_end(ctx, EXCP_RI);
23793 case OPC_CMPU_EQ_OB_DSP:
23794 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
23796 case OPC_PRECR_SRA_QH_PW:
23797 case OPC_PRECR_SRA_R_QH_PW:
23798 /* Return value is rt. */
23799 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
23801 case OPC_PRECR_OB_QH:
23802 case OPC_PRECRQ_OB_QH:
23803 case OPC_PRECRQ_PW_L:
23804 case OPC_PRECRQ_QH_PW:
23805 case OPC_PRECRQ_RS_QH_PW:
23806 case OPC_PRECRQU_S_OB_QH:
23807 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23809 case OPC_CMPU_EQ_OB:
23810 case OPC_CMPU_LT_OB:
23811 case OPC_CMPU_LE_OB:
23812 case OPC_CMP_EQ_QH:
23813 case OPC_CMP_LT_QH:
23814 case OPC_CMP_LE_QH:
23815 case OPC_CMP_EQ_PW:
23816 case OPC_CMP_LT_PW:
23817 case OPC_CMP_LE_PW:
23818 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
23820 case OPC_CMPGDU_EQ_OB:
23821 case OPC_CMPGDU_LT_OB:
23822 case OPC_CMPGDU_LE_OB:
23823 case OPC_CMPGU_EQ_OB:
23824 case OPC_CMPGU_LT_OB:
23825 case OPC_CMPGU_LE_OB:
23826 case OPC_PACKRL_PW:
23830 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23832 default: /* Invalid */
23833 MIPS_INVAL("MASK CMPU_EQ.OB");
23834 generate_exception_end(ctx, EXCP_RI);
23838 case OPC_DAPPEND_DSP:
23839 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23841 case OPC_DEXTR_W_DSP:
23842 op2 = MASK_DEXTR_W(ctx->opcode);
23849 case OPC_DEXTR_R_L:
23850 case OPC_DEXTR_RS_L:
23852 case OPC_DEXTR_R_W:
23853 case OPC_DEXTR_RS_W:
23854 case OPC_DEXTR_S_H:
23856 case OPC_DEXTRV_R_L:
23857 case OPC_DEXTRV_RS_L:
23858 case OPC_DEXTRV_S_H:
23860 case OPC_DEXTRV_R_W:
23861 case OPC_DEXTRV_RS_W:
23862 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23867 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23869 default: /* Invalid */
23870 MIPS_INVAL("MASK EXTR.W");
23871 generate_exception_end(ctx, EXCP_RI);
23875 case OPC_DPAQ_W_QH_DSP:
23876 op2 = MASK_DPAQ_W_QH(ctx->opcode);
23878 case OPC_DPAU_H_OBL:
23879 case OPC_DPAU_H_OBR:
23880 case OPC_DPSU_H_OBL:
23881 case OPC_DPSU_H_OBR:
23883 case OPC_DPAQ_S_W_QH:
23885 case OPC_DPSQ_S_W_QH:
23886 case OPC_MULSAQ_S_W_QH:
23887 case OPC_DPAQ_SA_L_PW:
23888 case OPC_DPSQ_SA_L_PW:
23889 case OPC_MULSAQ_S_L_PW:
23890 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23892 case OPC_MAQ_S_W_QHLL:
23893 case OPC_MAQ_S_W_QHLR:
23894 case OPC_MAQ_S_W_QHRL:
23895 case OPC_MAQ_S_W_QHRR:
23896 case OPC_MAQ_SA_W_QHLL:
23897 case OPC_MAQ_SA_W_QHLR:
23898 case OPC_MAQ_SA_W_QHRL:
23899 case OPC_MAQ_SA_W_QHRR:
23900 case OPC_MAQ_S_L_PWL:
23901 case OPC_MAQ_S_L_PWR:
23906 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23908 default: /* Invalid */
23909 MIPS_INVAL("MASK DPAQ.W.QH");
23910 generate_exception_end(ctx, EXCP_RI);
23914 case OPC_DINSV_DSP:
23915 op2 = MASK_INSV(ctx->opcode);
23926 t0 = tcg_temp_new();
23927 t1 = tcg_temp_new();
23929 gen_load_gpr(t0, rt);
23930 gen_load_gpr(t1, rs);
23932 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
23938 default: /* Invalid */
23939 MIPS_INVAL("MASK DINSV");
23940 generate_exception_end(ctx, EXCP_RI);
23944 case OPC_SHLL_OB_DSP:
23945 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23948 default: /* Invalid */
23949 MIPS_INVAL("special3_legacy");
23950 generate_exception_end(ctx, EXCP_RI);
23955 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
23957 int rs, rt, rd, sa;
23961 rs = (ctx->opcode >> 21) & 0x1f;
23962 rt = (ctx->opcode >> 16) & 0x1f;
23963 rd = (ctx->opcode >> 11) & 0x1f;
23964 sa = (ctx->opcode >> 6) & 0x1f;
23965 imm = sextract32(ctx->opcode, 7, 9);
23967 op1 = MASK_SPECIAL3(ctx->opcode);
23970 * EVA loads and stores overlap Loongson 2E instructions decoded by
23971 * decode_opc_special3_legacy(), so be careful to allow their decoding when
23978 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23986 check_cp0_enabled(ctx);
23987 gen_ld(ctx, op1, rt, rs, imm);
23991 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23996 check_cp0_enabled(ctx);
23997 gen_st(ctx, op1, rt, rs, imm);
24000 check_cp0_enabled(ctx);
24001 gen_st_cond(ctx, op1, rt, rs, imm);
24004 check_cp0_enabled(ctx);
24005 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
24006 gen_cache_operation(ctx, rt, rs, imm);
24008 /* Treat as NOP. */
24011 check_cp0_enabled(ctx);
24012 /* Treat as NOP. */
24020 check_insn(ctx, ISA_MIPS32R2);
24021 gen_bitops(ctx, op1, rt, rs, sa, rd);
24024 op2 = MASK_BSHFL(ctx->opcode);
24027 case OPC_ALIGN_END:
24029 check_insn(ctx, ISA_MIPS32R6);
24030 decode_opc_special3_r6(env, ctx);
24033 check_insn(ctx, ISA_MIPS32R2);
24034 gen_bshfl(ctx, op2, rt, rd);
24038 #if defined(TARGET_MIPS64)
24045 check_insn(ctx, ISA_MIPS64R2);
24046 check_mips_64(ctx);
24047 gen_bitops(ctx, op1, rt, rs, sa, rd);
24050 op2 = MASK_DBSHFL(ctx->opcode);
24053 case OPC_DALIGN_END:
24055 check_insn(ctx, ISA_MIPS32R6);
24056 decode_opc_special3_r6(env, ctx);
24059 check_insn(ctx, ISA_MIPS64R2);
24060 check_mips_64(ctx);
24061 op2 = MASK_DBSHFL(ctx->opcode);
24062 gen_bshfl(ctx, op2, rt, rd);
24068 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
24073 TCGv t0 = tcg_temp_new();
24074 TCGv t1 = tcg_temp_new();
24076 gen_load_gpr(t0, rt);
24077 gen_load_gpr(t1, rs);
24078 gen_helper_fork(t0, t1);
24086 TCGv t0 = tcg_temp_new();
24088 gen_load_gpr(t0, rs);
24089 gen_helper_yield(t0, cpu_env, t0);
24090 gen_store_gpr(t0, rd);
24095 if (ctx->insn_flags & ISA_MIPS32R6) {
24096 decode_opc_special3_r6(env, ctx);
24098 decode_opc_special3_legacy(env, ctx);
24103 /* MIPS SIMD Architecture (MSA) */
24104 static inline int check_msa_access(DisasContext *ctx)
24106 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
24107 !(ctx->hflags & MIPS_HFLAG_F64))) {
24108 generate_exception_end(ctx, EXCP_RI);
24112 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
24113 if (ctx->insn_flags & ASE_MSA) {
24114 generate_exception_end(ctx, EXCP_MSADIS);
24117 generate_exception_end(ctx, EXCP_RI);
24124 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
24126 /* generates tcg ops to check if any element is 0 */
24127 /* Note this function only works with MSA_WRLEN = 128 */
24128 uint64_t eval_zero_or_big = 0;
24129 uint64_t eval_big = 0;
24130 TCGv_i64 t0 = tcg_temp_new_i64();
24131 TCGv_i64 t1 = tcg_temp_new_i64();
24134 eval_zero_or_big = 0x0101010101010101ULL;
24135 eval_big = 0x8080808080808080ULL;
24138 eval_zero_or_big = 0x0001000100010001ULL;
24139 eval_big = 0x8000800080008000ULL;
24142 eval_zero_or_big = 0x0000000100000001ULL;
24143 eval_big = 0x8000000080000000ULL;
24146 eval_zero_or_big = 0x0000000000000001ULL;
24147 eval_big = 0x8000000000000000ULL;
24150 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
24151 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
24152 tcg_gen_andi_i64(t0, t0, eval_big);
24153 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
24154 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
24155 tcg_gen_andi_i64(t1, t1, eval_big);
24156 tcg_gen_or_i64(t0, t0, t1);
24157 /* if all bits are zero then all elements are not zero */
24158 /* if some bit is non-zero then some element is zero */
24159 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
24160 tcg_gen_trunc_i64_tl(tresult, t0);
24161 tcg_temp_free_i64(t0);
24162 tcg_temp_free_i64(t1);
24165 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
24167 uint8_t df = (ctx->opcode >> 21) & 0x3;
24168 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24169 int64_t s16 = (int16_t)ctx->opcode;
24171 check_msa_access(ctx);
24173 if (ctx->hflags & MIPS_HFLAG_BMASK) {
24174 generate_exception_end(ctx, EXCP_RI);
24181 TCGv_i64 t0 = tcg_temp_new_i64();
24182 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
24183 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
24184 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
24185 tcg_gen_trunc_i64_tl(bcond, t0);
24186 tcg_temp_free_i64(t0);
24193 gen_check_zero_element(bcond, df, wt);
24199 gen_check_zero_element(bcond, df, wt);
24200 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
24204 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
24206 ctx->hflags |= MIPS_HFLAG_BC;
24207 ctx->hflags |= MIPS_HFLAG_BDS32;
24210 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
24212 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
24213 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
24214 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24215 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24217 TCGv_i32 twd = tcg_const_i32(wd);
24218 TCGv_i32 tws = tcg_const_i32(ws);
24219 TCGv_i32 ti8 = tcg_const_i32(i8);
24221 switch (MASK_MSA_I8(ctx->opcode)) {
24223 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
24226 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
24229 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
24232 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
24235 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
24238 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
24241 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
24247 uint8_t df = (ctx->opcode >> 24) & 0x3;
24248 if (df == DF_DOUBLE) {
24249 generate_exception_end(ctx, EXCP_RI);
24251 TCGv_i32 tdf = tcg_const_i32(df);
24252 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
24253 tcg_temp_free_i32(tdf);
24258 MIPS_INVAL("MSA instruction");
24259 generate_exception_end(ctx, EXCP_RI);
24263 tcg_temp_free_i32(twd);
24264 tcg_temp_free_i32(tws);
24265 tcg_temp_free_i32(ti8);
24268 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
24270 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24271 uint8_t df = (ctx->opcode >> 21) & 0x3;
24272 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
24273 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
24274 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24275 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24277 TCGv_i32 tdf = tcg_const_i32(df);
24278 TCGv_i32 twd = tcg_const_i32(wd);
24279 TCGv_i32 tws = tcg_const_i32(ws);
24280 TCGv_i32 timm = tcg_temp_new_i32();
24281 tcg_gen_movi_i32(timm, u5);
24283 switch (MASK_MSA_I5(ctx->opcode)) {
24285 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
24288 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
24290 case OPC_MAXI_S_df:
24291 tcg_gen_movi_i32(timm, s5);
24292 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
24294 case OPC_MAXI_U_df:
24295 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
24297 case OPC_MINI_S_df:
24298 tcg_gen_movi_i32(timm, s5);
24299 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
24301 case OPC_MINI_U_df:
24302 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
24305 tcg_gen_movi_i32(timm, s5);
24306 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
24308 case OPC_CLTI_S_df:
24309 tcg_gen_movi_i32(timm, s5);
24310 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
24312 case OPC_CLTI_U_df:
24313 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
24315 case OPC_CLEI_S_df:
24316 tcg_gen_movi_i32(timm, s5);
24317 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
24319 case OPC_CLEI_U_df:
24320 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
24324 int32_t s10 = sextract32(ctx->opcode, 11, 10);
24325 tcg_gen_movi_i32(timm, s10);
24326 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
24330 MIPS_INVAL("MSA instruction");
24331 generate_exception_end(ctx, EXCP_RI);
24335 tcg_temp_free_i32(tdf);
24336 tcg_temp_free_i32(twd);
24337 tcg_temp_free_i32(tws);
24338 tcg_temp_free_i32(timm);
24341 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
24343 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24344 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
24345 uint32_t df = 0, m = 0;
24346 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24347 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24354 if ((dfm & 0x40) == 0x00) {
24357 } else if ((dfm & 0x60) == 0x40) {
24360 } else if ((dfm & 0x70) == 0x60) {
24363 } else if ((dfm & 0x78) == 0x70) {
24367 generate_exception_end(ctx, EXCP_RI);
24371 tdf = tcg_const_i32(df);
24372 tm = tcg_const_i32(m);
24373 twd = tcg_const_i32(wd);
24374 tws = tcg_const_i32(ws);
24376 switch (MASK_MSA_BIT(ctx->opcode)) {
24378 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
24381 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
24384 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
24387 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
24390 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
24393 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
24395 case OPC_BINSLI_df:
24396 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
24398 case OPC_BINSRI_df:
24399 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
24402 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
24405 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
24408 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
24411 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
24414 MIPS_INVAL("MSA instruction");
24415 generate_exception_end(ctx, EXCP_RI);
24419 tcg_temp_free_i32(tdf);
24420 tcg_temp_free_i32(tm);
24421 tcg_temp_free_i32(twd);
24422 tcg_temp_free_i32(tws);
24425 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
24427 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24428 uint8_t df = (ctx->opcode >> 21) & 0x3;
24429 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24430 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24431 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24433 TCGv_i32 tdf = tcg_const_i32(df);
24434 TCGv_i32 twd = tcg_const_i32(wd);
24435 TCGv_i32 tws = tcg_const_i32(ws);
24436 TCGv_i32 twt = tcg_const_i32(wt);
24438 switch (MASK_MSA_3R(ctx->opcode)) {
24440 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
24443 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
24446 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
24449 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
24451 case OPC_SUBS_S_df:
24452 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
24455 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
24458 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
24461 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
24464 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
24467 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
24469 case OPC_ADDS_A_df:
24470 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
24472 case OPC_SUBS_U_df:
24473 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
24476 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
24479 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
24482 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
24485 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
24488 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
24491 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
24493 case OPC_ADDS_S_df:
24494 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
24496 case OPC_SUBSUS_U_df:
24497 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
24500 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
24503 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
24506 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
24509 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
24512 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
24515 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
24517 case OPC_ADDS_U_df:
24518 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
24520 case OPC_SUBSUU_S_df:
24521 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
24524 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
24527 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
24530 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
24533 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
24536 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
24538 case OPC_ASUB_S_df:
24539 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
24542 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
24545 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
24548 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
24551 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
24554 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
24557 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
24559 case OPC_ASUB_U_df:
24560 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
24563 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
24566 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
24569 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
24572 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
24574 case OPC_AVER_S_df:
24575 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
24578 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
24581 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
24584 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
24587 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
24589 case OPC_AVER_U_df:
24590 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
24593 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
24596 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
24599 case OPC_DOTP_S_df:
24600 case OPC_DOTP_U_df:
24601 case OPC_DPADD_S_df:
24602 case OPC_DPADD_U_df:
24603 case OPC_DPSUB_S_df:
24604 case OPC_HADD_S_df:
24605 case OPC_DPSUB_U_df:
24606 case OPC_HADD_U_df:
24607 case OPC_HSUB_S_df:
24608 case OPC_HSUB_U_df:
24609 if (df == DF_BYTE) {
24610 generate_exception_end(ctx, EXCP_RI);
24613 switch (MASK_MSA_3R(ctx->opcode)) {
24614 case OPC_DOTP_S_df:
24615 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
24617 case OPC_DOTP_U_df:
24618 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
24620 case OPC_DPADD_S_df:
24621 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
24623 case OPC_DPADD_U_df:
24624 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
24626 case OPC_DPSUB_S_df:
24627 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
24629 case OPC_HADD_S_df:
24630 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
24632 case OPC_DPSUB_U_df:
24633 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
24635 case OPC_HADD_U_df:
24636 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
24638 case OPC_HSUB_S_df:
24639 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
24641 case OPC_HSUB_U_df:
24642 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
24647 MIPS_INVAL("MSA instruction");
24648 generate_exception_end(ctx, EXCP_RI);
24651 tcg_temp_free_i32(twd);
24652 tcg_temp_free_i32(tws);
24653 tcg_temp_free_i32(twt);
24654 tcg_temp_free_i32(tdf);
24657 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
24659 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
24660 uint8_t source = (ctx->opcode >> 11) & 0x1f;
24661 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
24662 TCGv telm = tcg_temp_new();
24663 TCGv_i32 tsr = tcg_const_i32(source);
24664 TCGv_i32 tdt = tcg_const_i32(dest);
24666 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
24668 gen_load_gpr(telm, source);
24669 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
24672 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
24673 gen_store_gpr(telm, dest);
24676 gen_helper_msa_move_v(cpu_env, tdt, tsr);
24679 MIPS_INVAL("MSA instruction");
24680 generate_exception_end(ctx, EXCP_RI);
24684 tcg_temp_free(telm);
24685 tcg_temp_free_i32(tdt);
24686 tcg_temp_free_i32(tsr);
24689 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
24692 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24693 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24694 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24696 TCGv_i32 tws = tcg_const_i32(ws);
24697 TCGv_i32 twd = tcg_const_i32(wd);
24698 TCGv_i32 tn = tcg_const_i32(n);
24699 TCGv_i32 tdf = tcg_const_i32(df);
24701 switch (MASK_MSA_ELM(ctx->opcode)) {
24703 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
24705 case OPC_SPLATI_df:
24706 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
24709 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
24711 case OPC_COPY_S_df:
24712 case OPC_COPY_U_df:
24713 case OPC_INSERT_df:
24714 #if !defined(TARGET_MIPS64)
24715 /* Double format valid only for MIPS64 */
24716 if (df == DF_DOUBLE) {
24717 generate_exception_end(ctx, EXCP_RI);
24721 switch (MASK_MSA_ELM(ctx->opcode)) {
24722 case OPC_COPY_S_df:
24723 if (likely(wd != 0)) {
24724 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
24727 case OPC_COPY_U_df:
24728 if (likely(wd != 0)) {
24729 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
24732 case OPC_INSERT_df:
24733 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
24738 MIPS_INVAL("MSA instruction");
24739 generate_exception_end(ctx, EXCP_RI);
24741 tcg_temp_free_i32(twd);
24742 tcg_temp_free_i32(tws);
24743 tcg_temp_free_i32(tn);
24744 tcg_temp_free_i32(tdf);
24747 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
24749 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
24750 uint32_t df = 0, n = 0;
24752 if ((dfn & 0x30) == 0x00) {
24755 } else if ((dfn & 0x38) == 0x20) {
24758 } else if ((dfn & 0x3c) == 0x30) {
24761 } else if ((dfn & 0x3e) == 0x38) {
24764 } else if (dfn == 0x3E) {
24765 /* CTCMSA, CFCMSA, MOVE.V */
24766 gen_msa_elm_3e(env, ctx);
24769 generate_exception_end(ctx, EXCP_RI);
24773 gen_msa_elm_df(env, ctx, df, n);
24776 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
24778 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24779 uint8_t df = (ctx->opcode >> 21) & 0x1;
24780 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24781 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24782 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24784 TCGv_i32 twd = tcg_const_i32(wd);
24785 TCGv_i32 tws = tcg_const_i32(ws);
24786 TCGv_i32 twt = tcg_const_i32(wt);
24787 TCGv_i32 tdf = tcg_temp_new_i32();
24789 /* adjust df value for floating-point instruction */
24790 tcg_gen_movi_i32(tdf, df + 2);
24792 switch (MASK_MSA_3RF(ctx->opcode)) {
24794 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
24797 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
24800 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
24803 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
24806 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
24809 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
24812 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
24815 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
24818 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
24821 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
24824 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
24827 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
24830 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
24833 tcg_gen_movi_i32(tdf, df + 1);
24834 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
24837 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
24840 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
24842 case OPC_MADD_Q_df:
24843 tcg_gen_movi_i32(tdf, df + 1);
24844 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
24847 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
24849 case OPC_MSUB_Q_df:
24850 tcg_gen_movi_i32(tdf, df + 1);
24851 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
24854 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
24857 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
24860 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
24863 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
24866 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
24869 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
24872 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
24875 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
24878 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
24881 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
24884 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
24887 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
24890 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
24892 case OPC_MULR_Q_df:
24893 tcg_gen_movi_i32(tdf, df + 1);
24894 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
24897 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
24899 case OPC_FMIN_A_df:
24900 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
24902 case OPC_MADDR_Q_df:
24903 tcg_gen_movi_i32(tdf, df + 1);
24904 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
24907 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
24910 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
24912 case OPC_MSUBR_Q_df:
24913 tcg_gen_movi_i32(tdf, df + 1);
24914 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
24917 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
24919 case OPC_FMAX_A_df:
24920 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
24923 MIPS_INVAL("MSA instruction");
24924 generate_exception_end(ctx, EXCP_RI);
24928 tcg_temp_free_i32(twd);
24929 tcg_temp_free_i32(tws);
24930 tcg_temp_free_i32(twt);
24931 tcg_temp_free_i32(tdf);
24934 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
24936 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24937 (op & (0x7 << 18)))
24938 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24939 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24940 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24941 uint8_t df = (ctx->opcode >> 16) & 0x3;
24942 TCGv_i32 twd = tcg_const_i32(wd);
24943 TCGv_i32 tws = tcg_const_i32(ws);
24944 TCGv_i32 twt = tcg_const_i32(wt);
24945 TCGv_i32 tdf = tcg_const_i32(df);
24947 switch (MASK_MSA_2R(ctx->opcode)) {
24949 #if !defined(TARGET_MIPS64)
24950 /* Double format valid only for MIPS64 */
24951 if (df == DF_DOUBLE) {
24952 generate_exception_end(ctx, EXCP_RI);
24956 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
24959 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
24962 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
24965 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
24968 MIPS_INVAL("MSA instruction");
24969 generate_exception_end(ctx, EXCP_RI);
24973 tcg_temp_free_i32(twd);
24974 tcg_temp_free_i32(tws);
24975 tcg_temp_free_i32(twt);
24976 tcg_temp_free_i32(tdf);
24979 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
24981 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24982 (op & (0xf << 17)))
24983 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24984 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24985 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24986 uint8_t df = (ctx->opcode >> 16) & 0x1;
24987 TCGv_i32 twd = tcg_const_i32(wd);
24988 TCGv_i32 tws = tcg_const_i32(ws);
24989 TCGv_i32 twt = tcg_const_i32(wt);
24990 /* adjust df value for floating-point instruction */
24991 TCGv_i32 tdf = tcg_const_i32(df + 2);
24993 switch (MASK_MSA_2RF(ctx->opcode)) {
24994 case OPC_FCLASS_df:
24995 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
24997 case OPC_FTRUNC_S_df:
24998 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
25000 case OPC_FTRUNC_U_df:
25001 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
25004 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
25006 case OPC_FRSQRT_df:
25007 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
25010 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
25013 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
25016 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
25018 case OPC_FEXUPL_df:
25019 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
25021 case OPC_FEXUPR_df:
25022 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
25025 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
25028 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
25030 case OPC_FTINT_S_df:
25031 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
25033 case OPC_FTINT_U_df:
25034 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
25036 case OPC_FFINT_S_df:
25037 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
25039 case OPC_FFINT_U_df:
25040 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
25044 tcg_temp_free_i32(twd);
25045 tcg_temp_free_i32(tws);
25046 tcg_temp_free_i32(twt);
25047 tcg_temp_free_i32(tdf);
25050 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
25052 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
25053 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25054 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25055 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25056 TCGv_i32 twd = tcg_const_i32(wd);
25057 TCGv_i32 tws = tcg_const_i32(ws);
25058 TCGv_i32 twt = tcg_const_i32(wt);
25060 switch (MASK_MSA_VEC(ctx->opcode)) {
25062 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
25065 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
25068 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
25071 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
25074 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
25077 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
25080 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
25083 MIPS_INVAL("MSA instruction");
25084 generate_exception_end(ctx, EXCP_RI);
25088 tcg_temp_free_i32(twd);
25089 tcg_temp_free_i32(tws);
25090 tcg_temp_free_i32(twt);
25093 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
25095 switch (MASK_MSA_VEC(ctx->opcode)) {
25103 gen_msa_vec_v(env, ctx);
25106 gen_msa_2r(env, ctx);
25109 gen_msa_2rf(env, ctx);
25112 MIPS_INVAL("MSA instruction");
25113 generate_exception_end(ctx, EXCP_RI);
25118 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
25120 uint32_t opcode = ctx->opcode;
25121 check_insn(ctx, ASE_MSA);
25122 check_msa_access(ctx);
25124 switch (MASK_MSA_MINOR(opcode)) {
25125 case OPC_MSA_I8_00:
25126 case OPC_MSA_I8_01:
25127 case OPC_MSA_I8_02:
25128 gen_msa_i8(env, ctx);
25130 case OPC_MSA_I5_06:
25131 case OPC_MSA_I5_07:
25132 gen_msa_i5(env, ctx);
25134 case OPC_MSA_BIT_09:
25135 case OPC_MSA_BIT_0A:
25136 gen_msa_bit(env, ctx);
25138 case OPC_MSA_3R_0D:
25139 case OPC_MSA_3R_0E:
25140 case OPC_MSA_3R_0F:
25141 case OPC_MSA_3R_10:
25142 case OPC_MSA_3R_11:
25143 case OPC_MSA_3R_12:
25144 case OPC_MSA_3R_13:
25145 case OPC_MSA_3R_14:
25146 case OPC_MSA_3R_15:
25147 gen_msa_3r(env, ctx);
25150 gen_msa_elm(env, ctx);
25152 case OPC_MSA_3RF_1A:
25153 case OPC_MSA_3RF_1B:
25154 case OPC_MSA_3RF_1C:
25155 gen_msa_3rf(env, ctx);
25158 gen_msa_vec(env, ctx);
25169 int32_t s10 = sextract32(ctx->opcode, 16, 10);
25170 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
25171 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25172 uint8_t df = (ctx->opcode >> 0) & 0x3;
25174 TCGv_i32 twd = tcg_const_i32(wd);
25175 TCGv taddr = tcg_temp_new();
25176 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
25178 switch (MASK_MSA_MINOR(opcode)) {
25180 gen_helper_msa_ld_b(cpu_env, twd, taddr);
25183 gen_helper_msa_ld_h(cpu_env, twd, taddr);
25186 gen_helper_msa_ld_w(cpu_env, twd, taddr);
25189 gen_helper_msa_ld_d(cpu_env, twd, taddr);
25192 gen_helper_msa_st_b(cpu_env, twd, taddr);
25195 gen_helper_msa_st_h(cpu_env, twd, taddr);
25198 gen_helper_msa_st_w(cpu_env, twd, taddr);
25201 gen_helper_msa_st_d(cpu_env, twd, taddr);
25205 tcg_temp_free_i32(twd);
25206 tcg_temp_free(taddr);
25210 MIPS_INVAL("MSA instruction");
25211 generate_exception_end(ctx, EXCP_RI);
25217 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
25220 int rs, rt, rd, sa;
25224 /* make sure instructions are on a word boundary */
25225 if (ctx->base.pc_next & 0x3) {
25226 env->CP0_BadVAddr = ctx->base.pc_next;
25227 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
25231 /* Handle blikely not taken case */
25232 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
25233 TCGLabel *l1 = gen_new_label();
25235 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
25236 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
25237 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
25241 op = MASK_OP_MAJOR(ctx->opcode);
25242 rs = (ctx->opcode >> 21) & 0x1f;
25243 rt = (ctx->opcode >> 16) & 0x1f;
25244 rd = (ctx->opcode >> 11) & 0x1f;
25245 sa = (ctx->opcode >> 6) & 0x1f;
25246 imm = (int16_t)ctx->opcode;
25249 decode_opc_special(env, ctx);
25252 decode_opc_special2_legacy(env, ctx);
25255 decode_opc_special3(env, ctx);
25258 op1 = MASK_REGIMM(ctx->opcode);
25260 case OPC_BLTZL: /* REGIMM branches */
25264 check_insn(ctx, ISA_MIPS2);
25265 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25269 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25273 if (ctx->insn_flags & ISA_MIPS32R6) {
25275 /* OPC_NAL, OPC_BAL */
25276 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
25278 generate_exception_end(ctx, EXCP_RI);
25281 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25284 case OPC_TGEI: /* REGIMM traps */
25291 check_insn(ctx, ISA_MIPS2);
25292 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25293 gen_trap(ctx, op1, rs, -1, imm);
25296 check_insn(ctx, ISA_MIPS32R6);
25297 generate_exception_end(ctx, EXCP_RI);
25300 check_insn(ctx, ISA_MIPS32R2);
25301 /* Break the TB to be able to sync copied instructions
25303 ctx->base.is_jmp = DISAS_STOP;
25305 case OPC_BPOSGE32: /* MIPS DSP branch */
25306 #if defined(TARGET_MIPS64)
25310 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
25312 #if defined(TARGET_MIPS64)
25314 check_insn(ctx, ISA_MIPS32R6);
25315 check_mips_64(ctx);
25317 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
25321 check_insn(ctx, ISA_MIPS32R6);
25322 check_mips_64(ctx);
25324 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
25328 default: /* Invalid */
25329 MIPS_INVAL("regimm");
25330 generate_exception_end(ctx, EXCP_RI);
25335 check_cp0_enabled(ctx);
25336 op1 = MASK_CP0(ctx->opcode);
25344 #if defined(TARGET_MIPS64)
25348 #ifndef CONFIG_USER_ONLY
25349 gen_cp0(env, ctx, op1, rt, rd);
25350 #endif /* !CONFIG_USER_ONLY */
25368 #ifndef CONFIG_USER_ONLY
25369 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
25370 #endif /* !CONFIG_USER_ONLY */
25373 #ifndef CONFIG_USER_ONLY
25376 TCGv t0 = tcg_temp_new();
25378 op2 = MASK_MFMC0(ctx->opcode);
25382 gen_helper_dmt(t0);
25383 gen_store_gpr(t0, rt);
25387 gen_helper_emt(t0);
25388 gen_store_gpr(t0, rt);
25392 gen_helper_dvpe(t0, cpu_env);
25393 gen_store_gpr(t0, rt);
25397 gen_helper_evpe(t0, cpu_env);
25398 gen_store_gpr(t0, rt);
25401 check_insn(ctx, ISA_MIPS32R6);
25403 gen_helper_dvp(t0, cpu_env);
25404 gen_store_gpr(t0, rt);
25408 check_insn(ctx, ISA_MIPS32R6);
25410 gen_helper_evp(t0, cpu_env);
25411 gen_store_gpr(t0, rt);
25415 check_insn(ctx, ISA_MIPS32R2);
25416 save_cpu_state(ctx, 1);
25417 gen_helper_di(t0, cpu_env);
25418 gen_store_gpr(t0, rt);
25419 /* Stop translation as we may have switched
25420 the execution mode. */
25421 ctx->base.is_jmp = DISAS_STOP;
25424 check_insn(ctx, ISA_MIPS32R2);
25425 save_cpu_state(ctx, 1);
25426 gen_helper_ei(t0, cpu_env);
25427 gen_store_gpr(t0, rt);
25428 /* DISAS_STOP isn't sufficient, we need to ensure we break
25429 out of translated code to check for pending interrupts */
25430 gen_save_pc(ctx->base.pc_next + 4);
25431 ctx->base.is_jmp = DISAS_EXIT;
25433 default: /* Invalid */
25434 MIPS_INVAL("mfmc0");
25435 generate_exception_end(ctx, EXCP_RI);
25440 #endif /* !CONFIG_USER_ONLY */
25443 check_insn(ctx, ISA_MIPS32R2);
25444 gen_load_srsgpr(rt, rd);
25447 check_insn(ctx, ISA_MIPS32R2);
25448 gen_store_srsgpr(rt, rd);
25452 generate_exception_end(ctx, EXCP_RI);
25456 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
25457 if (ctx->insn_flags & ISA_MIPS32R6) {
25458 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
25459 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25462 /* Arithmetic with immediate opcode */
25463 gen_arith_imm(ctx, op, rt, rs, imm);
25467 gen_arith_imm(ctx, op, rt, rs, imm);
25469 case OPC_SLTI: /* Set on less than with immediate opcode */
25471 gen_slt_imm(ctx, op, rt, rs, imm);
25473 case OPC_ANDI: /* Arithmetic with immediate opcode */
25474 case OPC_LUI: /* OPC_AUI */
25477 gen_logic_imm(ctx, op, rt, rs, imm);
25479 case OPC_J: /* Jump */
25481 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25482 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25485 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
25486 if (ctx->insn_flags & ISA_MIPS32R6) {
25488 generate_exception_end(ctx, EXCP_RI);
25491 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
25492 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25495 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25498 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
25499 if (ctx->insn_flags & ISA_MIPS32R6) {
25501 generate_exception_end(ctx, EXCP_RI);
25504 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
25505 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25508 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25511 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
25514 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25516 check_insn(ctx, ISA_MIPS32R6);
25517 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
25518 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25521 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
25524 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25526 check_insn(ctx, ISA_MIPS32R6);
25527 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
25528 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25533 check_insn(ctx, ISA_MIPS2);
25534 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25538 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25540 case OPC_LL: /* Load and stores */
25541 check_insn(ctx, ISA_MIPS2);
25545 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25553 gen_ld(ctx, op, rt, rs, imm);
25557 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25562 gen_st(ctx, op, rt, rs, imm);
25565 check_insn(ctx, ISA_MIPS2);
25566 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25567 gen_st_cond(ctx, op, rt, rs, imm);
25570 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25571 check_cp0_enabled(ctx);
25572 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
25573 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25574 gen_cache_operation(ctx, rt, rs, imm);
25576 /* Treat as NOP. */
25579 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25580 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
25581 /* Treat as NOP. */
25584 /* Floating point (COP1). */
25589 gen_cop1_ldst(ctx, op, rt, rs, imm);
25593 op1 = MASK_CP1(ctx->opcode);
25598 check_cp1_enabled(ctx);
25599 check_insn(ctx, ISA_MIPS32R2);
25605 check_cp1_enabled(ctx);
25606 gen_cp1(ctx, op1, rt, rd);
25608 #if defined(TARGET_MIPS64)
25611 check_cp1_enabled(ctx);
25612 check_insn(ctx, ISA_MIPS3);
25613 check_mips_64(ctx);
25614 gen_cp1(ctx, op1, rt, rd);
25617 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
25618 check_cp1_enabled(ctx);
25619 if (ctx->insn_flags & ISA_MIPS32R6) {
25621 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25626 check_insn(ctx, ASE_MIPS3D);
25627 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25628 (rt >> 2) & 0x7, imm << 2);
25632 check_cp1_enabled(ctx);
25633 check_insn(ctx, ISA_MIPS32R6);
25634 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25638 check_cp1_enabled(ctx);
25639 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25641 check_insn(ctx, ASE_MIPS3D);
25644 check_cp1_enabled(ctx);
25645 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25646 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25647 (rt >> 2) & 0x7, imm << 2);
25654 check_cp1_enabled(ctx);
25655 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25661 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
25662 check_cp1_enabled(ctx);
25663 if (ctx->insn_flags & ISA_MIPS32R6) {
25665 case R6_OPC_CMP_AF_S:
25666 case R6_OPC_CMP_UN_S:
25667 case R6_OPC_CMP_EQ_S:
25668 case R6_OPC_CMP_UEQ_S:
25669 case R6_OPC_CMP_LT_S:
25670 case R6_OPC_CMP_ULT_S:
25671 case R6_OPC_CMP_LE_S:
25672 case R6_OPC_CMP_ULE_S:
25673 case R6_OPC_CMP_SAF_S:
25674 case R6_OPC_CMP_SUN_S:
25675 case R6_OPC_CMP_SEQ_S:
25676 case R6_OPC_CMP_SEUQ_S:
25677 case R6_OPC_CMP_SLT_S:
25678 case R6_OPC_CMP_SULT_S:
25679 case R6_OPC_CMP_SLE_S:
25680 case R6_OPC_CMP_SULE_S:
25681 case R6_OPC_CMP_OR_S:
25682 case R6_OPC_CMP_UNE_S:
25683 case R6_OPC_CMP_NE_S:
25684 case R6_OPC_CMP_SOR_S:
25685 case R6_OPC_CMP_SUNE_S:
25686 case R6_OPC_CMP_SNE_S:
25687 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25689 case R6_OPC_CMP_AF_D:
25690 case R6_OPC_CMP_UN_D:
25691 case R6_OPC_CMP_EQ_D:
25692 case R6_OPC_CMP_UEQ_D:
25693 case R6_OPC_CMP_LT_D:
25694 case R6_OPC_CMP_ULT_D:
25695 case R6_OPC_CMP_LE_D:
25696 case R6_OPC_CMP_ULE_D:
25697 case R6_OPC_CMP_SAF_D:
25698 case R6_OPC_CMP_SUN_D:
25699 case R6_OPC_CMP_SEQ_D:
25700 case R6_OPC_CMP_SEUQ_D:
25701 case R6_OPC_CMP_SLT_D:
25702 case R6_OPC_CMP_SULT_D:
25703 case R6_OPC_CMP_SLE_D:
25704 case R6_OPC_CMP_SULE_D:
25705 case R6_OPC_CMP_OR_D:
25706 case R6_OPC_CMP_UNE_D:
25707 case R6_OPC_CMP_NE_D:
25708 case R6_OPC_CMP_SOR_D:
25709 case R6_OPC_CMP_SUNE_D:
25710 case R6_OPC_CMP_SNE_D:
25711 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25714 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
25715 rt, rd, sa, (imm >> 8) & 0x7);
25720 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25735 check_insn(ctx, ASE_MSA);
25736 gen_msa_branch(env, ctx, op1);
25740 generate_exception_end(ctx, EXCP_RI);
25745 /* Compact branches [R6] and COP2 [non-R6] */
25746 case OPC_BC: /* OPC_LWC2 */
25747 case OPC_BALC: /* OPC_SWC2 */
25748 if (ctx->insn_flags & ISA_MIPS32R6) {
25749 /* OPC_BC, OPC_BALC */
25750 gen_compute_compact_branch(ctx, op, 0, 0,
25751 sextract32(ctx->opcode << 2, 0, 28));
25753 /* OPC_LWC2, OPC_SWC2 */
25754 /* COP2: Not implemented. */
25755 generate_exception_err(ctx, EXCP_CpU, 2);
25758 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
25759 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
25760 if (ctx->insn_flags & ISA_MIPS32R6) {
25762 /* OPC_BEQZC, OPC_BNEZC */
25763 gen_compute_compact_branch(ctx, op, rs, 0,
25764 sextract32(ctx->opcode << 2, 0, 23));
25766 /* OPC_JIC, OPC_JIALC */
25767 gen_compute_compact_branch(ctx, op, 0, rt, imm);
25770 /* OPC_LWC2, OPC_SWC2 */
25771 /* COP2: Not implemented. */
25772 generate_exception_err(ctx, EXCP_CpU, 2);
25776 check_insn(ctx, INSN_LOONGSON2F);
25777 /* Note that these instructions use different fields. */
25778 gen_loongson_multimedia(ctx, sa, rd, rt);
25782 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25783 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
25784 check_cp1_enabled(ctx);
25785 op1 = MASK_CP3(ctx->opcode);
25789 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25795 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25796 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
25799 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25800 /* Treat as NOP. */
25803 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25817 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25818 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
25822 generate_exception_end(ctx, EXCP_RI);
25826 generate_exception_err(ctx, EXCP_CpU, 1);
25830 #if defined(TARGET_MIPS64)
25831 /* MIPS64 opcodes */
25835 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25839 check_insn(ctx, ISA_MIPS3);
25840 check_mips_64(ctx);
25841 gen_ld(ctx, op, rt, rs, imm);
25845 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25848 check_insn(ctx, ISA_MIPS3);
25849 check_mips_64(ctx);
25850 gen_st(ctx, op, rt, rs, imm);
25853 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25854 check_insn(ctx, ISA_MIPS3);
25855 check_mips_64(ctx);
25856 gen_st_cond(ctx, op, rt, rs, imm);
25858 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25859 if (ctx->insn_flags & ISA_MIPS32R6) {
25860 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25861 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25864 check_insn(ctx, ISA_MIPS3);
25865 check_mips_64(ctx);
25866 gen_arith_imm(ctx, op, rt, rs, imm);
25870 check_insn(ctx, ISA_MIPS3);
25871 check_mips_64(ctx);
25872 gen_arith_imm(ctx, op, rt, rs, imm);
25875 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
25876 if (ctx->insn_flags & ISA_MIPS32R6) {
25877 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25879 MIPS_INVAL("major opcode");
25880 generate_exception_end(ctx, EXCP_RI);
25884 case OPC_DAUI: /* OPC_JALX */
25885 if (ctx->insn_flags & ISA_MIPS32R6) {
25886 #if defined(TARGET_MIPS64)
25888 check_mips_64(ctx);
25890 generate_exception(ctx, EXCP_RI);
25891 } else if (rt != 0) {
25892 TCGv t0 = tcg_temp_new();
25893 gen_load_gpr(t0, rs);
25894 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
25898 generate_exception_end(ctx, EXCP_RI);
25899 MIPS_INVAL("major opcode");
25903 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
25904 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25905 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25908 case OPC_MSA: /* OPC_MDMX */
25909 /* MDMX: Not implemented. */
25913 check_insn(ctx, ISA_MIPS32R6);
25914 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
25916 default: /* Invalid */
25917 MIPS_INVAL("major opcode");
25918 generate_exception_end(ctx, EXCP_RI);
25923 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
25925 DisasContext *ctx = container_of(dcbase, DisasContext, base);
25926 CPUMIPSState *env = cs->env_ptr;
25928 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
25929 ctx->saved_pc = -1;
25930 ctx->insn_flags = env->insn_flags;
25931 ctx->CP0_Config1 = env->CP0_Config1;
25932 ctx->CP0_Config2 = env->CP0_Config2;
25933 ctx->CP0_Config3 = env->CP0_Config3;
25934 ctx->CP0_Config5 = env->CP0_Config5;
25936 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
25937 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
25938 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
25939 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
25940 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
25941 ctx->PAMask = env->PAMask;
25942 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
25943 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
25944 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
25945 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
25946 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
25947 /* Restore delay slot state from the tb context. */
25948 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
25949 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
25950 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
25951 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
25952 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
25953 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
25954 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
25955 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
25956 restore_cpu_state(env, ctx);
25957 #ifdef CONFIG_USER_ONLY
25958 ctx->mem_idx = MIPS_HFLAG_UM;
25960 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
25962 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
25963 MO_UNALN : MO_ALIGN;
25965 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
25969 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
25973 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
25975 DisasContext *ctx = container_of(dcbase, DisasContext, base);
25977 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
25981 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
25982 const CPUBreakpoint *bp)
25984 DisasContext *ctx = container_of(dcbase, DisasContext, base);
25986 save_cpu_state(ctx, 1);
25987 ctx->base.is_jmp = DISAS_NORETURN;
25988 gen_helper_raise_exception_debug(cpu_env);
25989 /* The address covered by the breakpoint must be included in
25990 [tb->pc, tb->pc + tb->size) in order to for it to be
25991 properly cleared -- thus we increment the PC here so that
25992 the logic setting tb->size below does the right thing. */
25993 ctx->base.pc_next += 4;
25997 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
25999 CPUMIPSState *env = cs->env_ptr;
26000 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26004 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
26005 if (ctx->insn_flags & ISA_NANOMIPS32) {
26006 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26007 insn_bytes = decode_nanomips_opc(env, ctx);
26008 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
26009 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
26011 decode_opc(env, ctx);
26012 } else if (ctx->insn_flags & ASE_MICROMIPS) {
26013 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26014 insn_bytes = decode_micromips_opc(env, ctx);
26015 } else if (ctx->insn_flags & ASE_MIPS16) {
26016 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26017 insn_bytes = decode_mips16_opc(env, ctx);
26019 generate_exception_end(ctx, EXCP_RI);
26020 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
26024 if (ctx->hflags & MIPS_HFLAG_BMASK) {
26025 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
26026 MIPS_HFLAG_FBNSLOT))) {
26027 /* force to generate branch as there is neither delay nor
26031 if ((ctx->hflags & MIPS_HFLAG_M16) &&
26032 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
26033 /* Force to generate branch as microMIPS R6 doesn't restrict
26034 branches in the forbidden slot. */
26039 gen_branch(ctx, insn_bytes);
26041 ctx->base.pc_next += insn_bytes;
26043 if (ctx->base.is_jmp != DISAS_NEXT) {
26046 /* Execute a branch and its delay slot as a single instruction.
26047 This is what GDB expects and is consistent with what the
26048 hardware does (e.g. if a delay slot instruction faults, the
26049 reported PC is the PC of the branch). */
26050 if (ctx->base.singlestep_enabled &&
26051 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
26052 ctx->base.is_jmp = DISAS_TOO_MANY;
26054 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
26055 ctx->base.is_jmp = DISAS_TOO_MANY;
26059 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
26061 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26063 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
26064 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
26065 gen_helper_raise_exception_debug(cpu_env);
26067 switch (ctx->base.is_jmp) {
26069 gen_save_pc(ctx->base.pc_next);
26070 tcg_gen_lookup_and_goto_ptr();
26073 case DISAS_TOO_MANY:
26074 save_cpu_state(ctx, 0);
26075 gen_goto_tb(ctx, 0, ctx->base.pc_next);
26078 tcg_gen_exit_tb(NULL, 0);
26080 case DISAS_NORETURN:
26083 g_assert_not_reached();
26088 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
26090 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
26091 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
26094 static const TranslatorOps mips_tr_ops = {
26095 .init_disas_context = mips_tr_init_disas_context,
26096 .tb_start = mips_tr_tb_start,
26097 .insn_start = mips_tr_insn_start,
26098 .breakpoint_check = mips_tr_breakpoint_check,
26099 .translate_insn = mips_tr_translate_insn,
26100 .tb_stop = mips_tr_tb_stop,
26101 .disas_log = mips_tr_disas_log,
26104 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
26108 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
26111 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
26115 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
26117 #define printfpr(fp) \
26120 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
26121 " fd:%13g fs:%13g psu: %13g\n", \
26122 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
26123 (double)(fp)->fd, \
26124 (double)(fp)->fs[FP_ENDIAN_IDX], \
26125 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
26128 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
26129 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
26130 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
26131 " fd:%13g fs:%13g psu:%13g\n", \
26132 tmp.w[FP_ENDIAN_IDX], tmp.d, \
26134 (double)tmp.fs[FP_ENDIAN_IDX], \
26135 (double)tmp.fs[!FP_ENDIAN_IDX]); \
26140 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
26141 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
26142 get_float_exception_flags(&env->active_fpu.fp_status));
26143 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
26144 fpu_fprintf(f, "%3s: ", fregnames[i]);
26145 printfpr(&env->active_fpu.fpr[i]);
26151 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
26154 MIPSCPU *cpu = MIPS_CPU(cs);
26155 CPUMIPSState *env = &cpu->env;
26158 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
26159 " LO=0x" TARGET_FMT_lx " ds %04x "
26160 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
26161 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
26162 env->hflags, env->btarget, env->bcond);
26163 for (i = 0; i < 32; i++) {
26165 cpu_fprintf(f, "GPR%02d:", i);
26166 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
26168 cpu_fprintf(f, "\n");
26171 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
26172 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
26173 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
26175 env->CP0_Config0, env->CP0_Config1, env->lladdr);
26176 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
26177 env->CP0_Config2, env->CP0_Config3);
26178 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
26179 env->CP0_Config4, env->CP0_Config5);
26180 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
26181 fpu_dump_state(env, f, cpu_fprintf, flags);
26185 void mips_tcg_init(void)
26190 for (i = 1; i < 32; i++)
26191 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
26192 offsetof(CPUMIPSState, active_tc.gpr[i]),
26195 for (i = 0; i < 32; i++) {
26196 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
26198 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
26199 /* The scalar floating-point unit (FPU) registers are mapped on
26200 * the MSA vector registers. */
26201 fpu_f64[i] = msa_wr_d[i * 2];
26202 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
26203 msa_wr_d[i * 2 + 1] =
26204 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
26207 cpu_PC = tcg_global_mem_new(cpu_env,
26208 offsetof(CPUMIPSState, active_tc.PC), "PC");
26209 for (i = 0; i < MIPS_DSP_ACC; i++) {
26210 cpu_HI[i] = tcg_global_mem_new(cpu_env,
26211 offsetof(CPUMIPSState, active_tc.HI[i]),
26213 cpu_LO[i] = tcg_global_mem_new(cpu_env,
26214 offsetof(CPUMIPSState, active_tc.LO[i]),
26217 cpu_dspctrl = tcg_global_mem_new(cpu_env,
26218 offsetof(CPUMIPSState, active_tc.DSPControl),
26220 bcond = tcg_global_mem_new(cpu_env,
26221 offsetof(CPUMIPSState, bcond), "bcond");
26222 btarget = tcg_global_mem_new(cpu_env,
26223 offsetof(CPUMIPSState, btarget), "btarget");
26224 hflags = tcg_global_mem_new_i32(cpu_env,
26225 offsetof(CPUMIPSState, hflags), "hflags");
26227 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
26228 offsetof(CPUMIPSState, active_fpu.fcr0),
26230 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
26231 offsetof(CPUMIPSState, active_fpu.fcr31),
26235 #include "translate_init.inc.c"
26237 void cpu_mips_realize_env(CPUMIPSState *env)
26239 env->exception_base = (int32_t)0xBFC00000;
26241 #ifndef CONFIG_USER_ONLY
26242 mmu_init(env, env->cpu_model);
26244 fpu_init(env, env->cpu_model);
26245 mvp_init(env, env->cpu_model);
26248 bool cpu_supports_cps_smp(const char *cpu_type)
26250 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26251 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
26254 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
26256 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26257 return (mcc->cpu_def->insn_flags & isa) != 0;
26260 void cpu_set_exception_base(int vp_index, target_ulong address)
26262 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
26263 vp->env.exception_base = address;
26266 void cpu_state_reset(CPUMIPSState *env)
26268 MIPSCPU *cpu = mips_env_get_cpu(env);
26269 CPUState *cs = CPU(cpu);
26271 /* Reset registers to their default values */
26272 env->CP0_PRid = env->cpu_model->CP0_PRid;
26273 env->CP0_Config0 = env->cpu_model->CP0_Config0;
26274 #ifdef TARGET_WORDS_BIGENDIAN
26275 env->CP0_Config0 |= (1 << CP0C0_BE);
26277 env->CP0_Config1 = env->cpu_model->CP0_Config1;
26278 env->CP0_Config2 = env->cpu_model->CP0_Config2;
26279 env->CP0_Config3 = env->cpu_model->CP0_Config3;
26280 env->CP0_Config4 = env->cpu_model->CP0_Config4;
26281 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
26282 env->CP0_Config5 = env->cpu_model->CP0_Config5;
26283 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
26284 env->CP0_Config6 = env->cpu_model->CP0_Config6;
26285 env->CP0_Config7 = env->cpu_model->CP0_Config7;
26286 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
26287 << env->cpu_model->CP0_LLAddr_shift;
26288 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
26289 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
26290 env->CCRes = env->cpu_model->CCRes;
26291 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
26292 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
26293 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
26294 env->current_tc = 0;
26295 env->SEGBITS = env->cpu_model->SEGBITS;
26296 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
26297 #if defined(TARGET_MIPS64)
26298 if (env->cpu_model->insn_flags & ISA_MIPS3) {
26299 env->SEGMask |= 3ULL << 62;
26302 env->PABITS = env->cpu_model->PABITS;
26303 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
26304 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
26305 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
26306 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
26307 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
26308 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
26309 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
26310 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
26311 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
26312 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
26313 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
26314 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
26315 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
26316 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
26317 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
26318 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
26319 env->msair = env->cpu_model->MSAIR;
26320 env->insn_flags = env->cpu_model->insn_flags;
26322 #if defined(CONFIG_USER_ONLY)
26323 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
26324 # ifdef TARGET_MIPS64
26325 /* Enable 64-bit register mode. */
26326 env->CP0_Status |= (1 << CP0St_PX);
26328 # ifdef TARGET_ABI_MIPSN64
26329 /* Enable 64-bit address mode. */
26330 env->CP0_Status |= (1 << CP0St_UX);
26332 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
26333 hardware registers. */
26334 env->CP0_HWREna |= 0x0000000F;
26335 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
26336 env->CP0_Status |= (1 << CP0St_CU1);
26338 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
26339 env->CP0_Status |= (1 << CP0St_MX);
26341 # if defined(TARGET_MIPS64)
26342 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
26343 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
26344 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
26345 env->CP0_Status |= (1 << CP0St_FR);
26349 if (env->hflags & MIPS_HFLAG_BMASK) {
26350 /* If the exception was raised from a delay slot,
26351 come back to the jump. */
26352 env->CP0_ErrorEPC = (env->active_tc.PC
26353 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
26355 env->CP0_ErrorEPC = env->active_tc.PC;
26357 env->active_tc.PC = env->exception_base;
26358 env->CP0_Random = env->tlb->nb_tlb - 1;
26359 env->tlb->tlb_in_use = env->tlb->nb_tlb;
26360 env->CP0_Wired = 0;
26361 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
26362 env->CP0_EBase = (cs->cpu_index & 0x3FF);
26363 if (mips_um_ksegs_enabled()) {
26364 env->CP0_EBase |= 0x40000000;
26366 env->CP0_EBase |= (int32_t)0x80000000;
26368 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
26369 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
26371 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
26373 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
26374 /* vectored interrupts not implemented, timer on int 7,
26375 no performance counters. */
26376 env->CP0_IntCtl = 0xe0000000;
26380 for (i = 0; i < 7; i++) {
26381 env->CP0_WatchLo[i] = 0;
26382 env->CP0_WatchHi[i] = 0x80000000;
26384 env->CP0_WatchLo[7] = 0;
26385 env->CP0_WatchHi[7] = 0;
26387 /* Count register increments in debug mode, EJTAG version 1 */
26388 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
26390 cpu_mips_store_count(env, 1);
26392 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
26395 /* Only TC0 on VPE 0 starts as active. */
26396 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
26397 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
26398 env->tcs[i].CP0_TCHalt = 1;
26400 env->active_tc.CP0_TCHalt = 1;
26403 if (cs->cpu_index == 0) {
26404 /* VPE0 starts up enabled. */
26405 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
26406 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
26408 /* TC0 starts up unhalted. */
26410 env->active_tc.CP0_TCHalt = 0;
26411 env->tcs[0].CP0_TCHalt = 0;
26412 /* With thread 0 active. */
26413 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
26414 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
26419 * Configure default legacy segmentation control. We use this regardless of
26420 * whether segmentation control is presented to the guest.
26422 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
26423 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
26424 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
26425 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
26426 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
26427 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26429 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
26430 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26431 (3 << CP0SC_C)) << 16;
26432 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
26433 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26434 (1 << CP0SC_EU) | (2 << CP0SC_C);
26435 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
26436 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26437 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
26438 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
26439 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
26441 if ((env->insn_flags & ISA_MIPS32R6) &&
26442 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
26443 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
26444 env->CP0_Status |= (1 << CP0St_FR);
26447 if (env->insn_flags & ISA_MIPS32R6) {
26449 env->CP0_PWSize = 0x40;
26455 env->CP0_PWField = 0x0C30C302;
26462 env->CP0_PWField = 0x02;
26465 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
26466 /* microMIPS on reset when Config3.ISA is 3 */
26467 env->hflags |= MIPS_HFLAG_M16;
26471 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
26475 compute_hflags(env);
26476 restore_fp_status(env);
26477 restore_pamask(env);
26478 cs->exception_index = EXCP_NONE;
26480 if (semihosting_get_argc()) {
26481 /* UHI interface can be used to obtain argc and argv */
26482 env->active_tc.gpr[4] = -1;
26486 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
26487 target_ulong *data)
26489 env->active_tc.PC = data[0];
26490 env->hflags &= ~MIPS_HFLAG_BMASK;
26491 env->hflags |= data[1];
26492 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
26493 case MIPS_HFLAG_BR:
26495 case MIPS_HFLAG_BC:
26496 case MIPS_HFLAG_BL:
26498 env->btarget = data[2];