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);
2482 * This code generates a "reserved instruction" exception if the
2483 * Config3 MT bit is NOT set.
2485 static inline void check_mt(DisasContext *ctx)
2487 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2488 generate_exception_end(ctx, EXCP_RI);
2492 #ifndef CONFIG_USER_ONLY
2494 * This code generates a "coprocessor unusable" exception if CP0 is not
2495 * available, and, if that is not the case, generates a "reserved instruction"
2496 * exception if the Config5 MT bit is NOT set. This is needed for availability
2497 * control of some of MT ASE instructions.
2499 static inline void check_cp0_mt(DisasContext *ctx)
2501 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2502 generate_exception_err(ctx, EXCP_CpU, 0);
2504 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2505 generate_exception_err(ctx, EXCP_RI, 0);
2512 * This code generates a "reserved instruction" exception if the
2513 * Config5 NMS bit is set.
2515 static inline void check_nms(DisasContext *ctx)
2517 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2518 generate_exception_end(ctx, EXCP_RI);
2523 /* Define small wrappers for gen_load_fpr* so that we have a uniform
2524 calling interface for 32 and 64-bit FPRs. No sense in changing
2525 all callers for gen_load_fpr32 when we need the CTX parameter for
2527 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2528 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2529 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2530 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2531 int ft, int fs, int cc) \
2533 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
2534 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
2543 check_cp1_registers(ctx, fs | ft); \
2551 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
2552 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
2554 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
2555 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
2556 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
2557 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
2558 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
2559 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
2560 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
2561 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
2562 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
2563 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
2564 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
2565 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
2566 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
2567 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
2568 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
2569 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
2572 tcg_temp_free_i##bits (fp0); \
2573 tcg_temp_free_i##bits (fp1); \
2576 FOP_CONDS(, 0, d, FMT_D, 64)
2577 FOP_CONDS(abs, 1, d, FMT_D, 64)
2578 FOP_CONDS(, 0, s, FMT_S, 32)
2579 FOP_CONDS(abs, 1, s, FMT_S, 32)
2580 FOP_CONDS(, 0, ps, FMT_PS, 64)
2581 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
2584 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
2585 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
2586 int ft, int fs, int fd) \
2588 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
2589 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
2590 if (ifmt == FMT_D) { \
2591 check_cp1_registers(ctx, fs | ft | fd); \
2593 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
2594 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
2597 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
2600 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
2603 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
2606 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
2609 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
2612 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
2615 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
2618 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2621 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2624 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2627 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2630 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2633 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2636 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2639 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2642 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2645 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2648 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2651 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2654 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2657 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2660 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2666 tcg_temp_free_i ## bits (fp0); \
2667 tcg_temp_free_i ## bits (fp1); \
2670 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2671 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2673 #undef gen_ldcmp_fpr32
2674 #undef gen_ldcmp_fpr64
2676 /* load/store instructions. */
2677 #ifdef CONFIG_USER_ONLY
2678 #define OP_LD_ATOMIC(insn,fname) \
2679 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2680 DisasContext *ctx) \
2682 TCGv t0 = tcg_temp_new(); \
2683 tcg_gen_mov_tl(t0, arg1); \
2684 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2685 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2686 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2687 tcg_temp_free(t0); \
2690 #define OP_LD_ATOMIC(insn,fname) \
2691 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2692 DisasContext *ctx) \
2694 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2697 OP_LD_ATOMIC(ll,ld32s);
2698 #if defined(TARGET_MIPS64)
2699 OP_LD_ATOMIC(lld,ld64);
2703 #ifdef CONFIG_USER_ONLY
2704 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2705 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2706 DisasContext *ctx) \
2708 TCGv t0 = tcg_temp_new(); \
2709 TCGLabel *l1 = gen_new_label(); \
2710 TCGLabel *l2 = gen_new_label(); \
2712 tcg_gen_andi_tl(t0, arg2, almask); \
2713 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2714 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2715 generate_exception(ctx, EXCP_AdES); \
2716 gen_set_label(l1); \
2717 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2718 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2719 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2720 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2721 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2722 generate_exception_end(ctx, EXCP_SC); \
2723 gen_set_label(l2); \
2724 tcg_gen_movi_tl(t0, 0); \
2725 gen_store_gpr(t0, rt); \
2726 tcg_temp_free(t0); \
2729 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2730 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2731 DisasContext *ctx) \
2733 TCGv t0 = tcg_temp_new(); \
2734 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
2735 gen_store_gpr(t0, rt); \
2736 tcg_temp_free(t0); \
2739 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2740 #if defined(TARGET_MIPS64)
2741 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2745 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2746 int base, int offset)
2749 tcg_gen_movi_tl(addr, offset);
2750 } else if (offset == 0) {
2751 gen_load_gpr(addr, base);
2753 tcg_gen_movi_tl(addr, offset);
2754 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2758 static target_ulong pc_relative_pc (DisasContext *ctx)
2760 target_ulong pc = ctx->base.pc_next;
2762 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2763 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2768 pc &= ~(target_ulong)3;
2773 static void gen_ld(DisasContext *ctx, uint32_t opc,
2774 int rt, int base, int offset)
2777 int mem_idx = ctx->mem_idx;
2779 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2780 /* Loongson CPU uses a load to zero register for prefetch.
2781 We emulate it as a NOP. On other CPU we must perform the
2782 actual memory access. */
2786 t0 = tcg_temp_new();
2787 gen_base_offset_addr(ctx, t0, base, offset);
2790 #if defined(TARGET_MIPS64)
2792 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2793 ctx->default_tcg_memop_mask);
2794 gen_store_gpr(t0, rt);
2797 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2798 ctx->default_tcg_memop_mask);
2799 gen_store_gpr(t0, rt);
2803 op_ld_lld(t0, t0, mem_idx, ctx);
2804 gen_store_gpr(t0, rt);
2807 t1 = tcg_temp_new();
2808 /* Do a byte access to possibly trigger a page
2809 fault with the unaligned address. */
2810 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2811 tcg_gen_andi_tl(t1, t0, 7);
2812 #ifndef TARGET_WORDS_BIGENDIAN
2813 tcg_gen_xori_tl(t1, t1, 7);
2815 tcg_gen_shli_tl(t1, t1, 3);
2816 tcg_gen_andi_tl(t0, t0, ~7);
2817 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2818 tcg_gen_shl_tl(t0, t0, t1);
2819 t2 = tcg_const_tl(-1);
2820 tcg_gen_shl_tl(t2, t2, t1);
2821 gen_load_gpr(t1, rt);
2822 tcg_gen_andc_tl(t1, t1, t2);
2824 tcg_gen_or_tl(t0, t0, t1);
2826 gen_store_gpr(t0, rt);
2829 t1 = tcg_temp_new();
2830 /* Do a byte access to possibly trigger a page
2831 fault with the unaligned address. */
2832 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2833 tcg_gen_andi_tl(t1, t0, 7);
2834 #ifdef TARGET_WORDS_BIGENDIAN
2835 tcg_gen_xori_tl(t1, t1, 7);
2837 tcg_gen_shli_tl(t1, t1, 3);
2838 tcg_gen_andi_tl(t0, t0, ~7);
2839 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2840 tcg_gen_shr_tl(t0, t0, t1);
2841 tcg_gen_xori_tl(t1, t1, 63);
2842 t2 = tcg_const_tl(0xfffffffffffffffeull);
2843 tcg_gen_shl_tl(t2, t2, t1);
2844 gen_load_gpr(t1, rt);
2845 tcg_gen_and_tl(t1, t1, t2);
2847 tcg_gen_or_tl(t0, t0, t1);
2849 gen_store_gpr(t0, rt);
2852 t1 = tcg_const_tl(pc_relative_pc(ctx));
2853 gen_op_addr_add(ctx, t0, t0, t1);
2855 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2856 gen_store_gpr(t0, rt);
2860 t1 = tcg_const_tl(pc_relative_pc(ctx));
2861 gen_op_addr_add(ctx, t0, t0, t1);
2863 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2864 gen_store_gpr(t0, rt);
2867 mem_idx = MIPS_HFLAG_UM;
2870 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2871 ctx->default_tcg_memop_mask);
2872 gen_store_gpr(t0, rt);
2875 mem_idx = MIPS_HFLAG_UM;
2878 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2879 ctx->default_tcg_memop_mask);
2880 gen_store_gpr(t0, rt);
2883 mem_idx = MIPS_HFLAG_UM;
2886 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2887 ctx->default_tcg_memop_mask);
2888 gen_store_gpr(t0, rt);
2891 mem_idx = MIPS_HFLAG_UM;
2894 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2895 gen_store_gpr(t0, rt);
2898 mem_idx = MIPS_HFLAG_UM;
2901 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2902 gen_store_gpr(t0, rt);
2905 mem_idx = MIPS_HFLAG_UM;
2908 t1 = tcg_temp_new();
2909 /* Do a byte access to possibly trigger a page
2910 fault with the unaligned address. */
2911 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2912 tcg_gen_andi_tl(t1, t0, 3);
2913 #ifndef TARGET_WORDS_BIGENDIAN
2914 tcg_gen_xori_tl(t1, t1, 3);
2916 tcg_gen_shli_tl(t1, t1, 3);
2917 tcg_gen_andi_tl(t0, t0, ~3);
2918 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2919 tcg_gen_shl_tl(t0, t0, t1);
2920 t2 = tcg_const_tl(-1);
2921 tcg_gen_shl_tl(t2, t2, t1);
2922 gen_load_gpr(t1, rt);
2923 tcg_gen_andc_tl(t1, t1, t2);
2925 tcg_gen_or_tl(t0, t0, t1);
2927 tcg_gen_ext32s_tl(t0, t0);
2928 gen_store_gpr(t0, rt);
2931 mem_idx = MIPS_HFLAG_UM;
2934 t1 = tcg_temp_new();
2935 /* Do a byte access to possibly trigger a page
2936 fault with the unaligned address. */
2937 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2938 tcg_gen_andi_tl(t1, t0, 3);
2939 #ifdef TARGET_WORDS_BIGENDIAN
2940 tcg_gen_xori_tl(t1, t1, 3);
2942 tcg_gen_shli_tl(t1, t1, 3);
2943 tcg_gen_andi_tl(t0, t0, ~3);
2944 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2945 tcg_gen_shr_tl(t0, t0, t1);
2946 tcg_gen_xori_tl(t1, t1, 31);
2947 t2 = tcg_const_tl(0xfffffffeull);
2948 tcg_gen_shl_tl(t2, t2, t1);
2949 gen_load_gpr(t1, rt);
2950 tcg_gen_and_tl(t1, t1, t2);
2952 tcg_gen_or_tl(t0, t0, t1);
2954 tcg_gen_ext32s_tl(t0, t0);
2955 gen_store_gpr(t0, rt);
2958 mem_idx = MIPS_HFLAG_UM;
2962 op_ld_ll(t0, t0, mem_idx, ctx);
2963 gen_store_gpr(t0, rt);
2969 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
2970 uint32_t reg1, uint32_t reg2)
2972 TCGv taddr = tcg_temp_new();
2973 TCGv_i64 tval = tcg_temp_new_i64();
2974 TCGv tmp1 = tcg_temp_new();
2975 TCGv tmp2 = tcg_temp_new();
2977 gen_base_offset_addr(ctx, taddr, base, offset);
2978 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
2979 #ifdef TARGET_WORDS_BIGENDIAN
2980 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
2982 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
2984 gen_store_gpr(tmp1, reg1);
2985 tcg_temp_free(tmp1);
2986 gen_store_gpr(tmp2, reg2);
2987 tcg_temp_free(tmp2);
2988 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
2989 tcg_temp_free_i64(tval);
2990 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
2991 tcg_temp_free(taddr);
2995 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2996 int base, int offset)
2998 TCGv t0 = tcg_temp_new();
2999 TCGv t1 = tcg_temp_new();
3000 int mem_idx = ctx->mem_idx;
3002 gen_base_offset_addr(ctx, t0, base, offset);
3003 gen_load_gpr(t1, rt);
3005 #if defined(TARGET_MIPS64)
3007 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3008 ctx->default_tcg_memop_mask);
3011 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3014 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3018 mem_idx = MIPS_HFLAG_UM;
3021 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3022 ctx->default_tcg_memop_mask);
3025 mem_idx = MIPS_HFLAG_UM;
3028 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3029 ctx->default_tcg_memop_mask);
3032 mem_idx = MIPS_HFLAG_UM;
3035 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3038 mem_idx = MIPS_HFLAG_UM;
3041 gen_helper_0e2i(swl, t1, t0, mem_idx);
3044 mem_idx = MIPS_HFLAG_UM;
3047 gen_helper_0e2i(swr, t1, t0, mem_idx);
3055 /* Store conditional */
3056 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3057 int base, int16_t offset)
3060 int mem_idx = ctx->mem_idx;
3062 #ifdef CONFIG_USER_ONLY
3063 t0 = tcg_temp_local_new();
3064 t1 = tcg_temp_local_new();
3066 t0 = tcg_temp_new();
3067 t1 = tcg_temp_new();
3069 gen_base_offset_addr(ctx, t0, base, offset);
3070 gen_load_gpr(t1, rt);
3072 #if defined(TARGET_MIPS64)
3075 op_st_scd(t1, t0, rt, mem_idx, ctx);
3079 mem_idx = MIPS_HFLAG_UM;
3083 op_st_sc(t1, t0, rt, mem_idx, ctx);
3090 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3091 uint32_t reg1, uint32_t reg2)
3093 TCGv taddr = tcg_temp_local_new();
3094 TCGv lladdr = tcg_temp_local_new();
3095 TCGv_i64 tval = tcg_temp_new_i64();
3096 TCGv_i64 llval = tcg_temp_new_i64();
3097 TCGv_i64 val = tcg_temp_new_i64();
3098 TCGv tmp1 = tcg_temp_new();
3099 TCGv tmp2 = tcg_temp_new();
3100 TCGLabel *lab_fail = gen_new_label();
3101 TCGLabel *lab_done = gen_new_label();
3103 gen_base_offset_addr(ctx, taddr, base, offset);
3105 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3106 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3108 gen_load_gpr(tmp1, reg1);
3109 gen_load_gpr(tmp2, reg2);
3111 #ifdef TARGET_WORDS_BIGENDIAN
3112 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3114 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3117 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3118 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3119 ctx->mem_idx, MO_64);
3121 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3123 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3125 gen_set_label(lab_fail);
3128 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3130 gen_set_label(lab_done);
3131 tcg_gen_movi_tl(lladdr, -1);
3132 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3135 /* Load and store */
3136 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3139 /* Don't do NOP if destination is zero: we must perform the actual
3144 TCGv_i32 fp0 = tcg_temp_new_i32();
3145 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3146 ctx->default_tcg_memop_mask);
3147 gen_store_fpr32(ctx, fp0, ft);
3148 tcg_temp_free_i32(fp0);
3153 TCGv_i32 fp0 = tcg_temp_new_i32();
3154 gen_load_fpr32(ctx, fp0, ft);
3155 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3156 ctx->default_tcg_memop_mask);
3157 tcg_temp_free_i32(fp0);
3162 TCGv_i64 fp0 = tcg_temp_new_i64();
3163 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3164 ctx->default_tcg_memop_mask);
3165 gen_store_fpr64(ctx, fp0, ft);
3166 tcg_temp_free_i64(fp0);
3171 TCGv_i64 fp0 = tcg_temp_new_i64();
3172 gen_load_fpr64(ctx, fp0, ft);
3173 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3174 ctx->default_tcg_memop_mask);
3175 tcg_temp_free_i64(fp0);
3179 MIPS_INVAL("flt_ldst");
3180 generate_exception_end(ctx, EXCP_RI);
3185 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3186 int rs, int16_t imm)
3188 TCGv t0 = tcg_temp_new();
3190 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3191 check_cp1_enabled(ctx);
3195 check_insn(ctx, ISA_MIPS2);
3198 gen_base_offset_addr(ctx, t0, rs, imm);
3199 gen_flt_ldst(ctx, op, rt, t0);
3202 generate_exception_err(ctx, EXCP_CpU, 1);
3207 /* Arithmetic with immediate operand */
3208 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3209 int rt, int rs, int imm)
3211 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3213 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3214 /* If no destination, treat it as a NOP.
3215 For addi, we must generate the overflow exception when needed. */
3221 TCGv t0 = tcg_temp_local_new();
3222 TCGv t1 = tcg_temp_new();
3223 TCGv t2 = tcg_temp_new();
3224 TCGLabel *l1 = gen_new_label();
3226 gen_load_gpr(t1, rs);
3227 tcg_gen_addi_tl(t0, t1, uimm);
3228 tcg_gen_ext32s_tl(t0, t0);
3230 tcg_gen_xori_tl(t1, t1, ~uimm);
3231 tcg_gen_xori_tl(t2, t0, uimm);
3232 tcg_gen_and_tl(t1, t1, t2);
3234 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3236 /* operands of same sign, result different sign */
3237 generate_exception(ctx, EXCP_OVERFLOW);
3239 tcg_gen_ext32s_tl(t0, t0);
3240 gen_store_gpr(t0, rt);
3246 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3247 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3249 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3252 #if defined(TARGET_MIPS64)
3255 TCGv t0 = tcg_temp_local_new();
3256 TCGv t1 = tcg_temp_new();
3257 TCGv t2 = tcg_temp_new();
3258 TCGLabel *l1 = gen_new_label();
3260 gen_load_gpr(t1, rs);
3261 tcg_gen_addi_tl(t0, t1, uimm);
3263 tcg_gen_xori_tl(t1, t1, ~uimm);
3264 tcg_gen_xori_tl(t2, t0, uimm);
3265 tcg_gen_and_tl(t1, t1, t2);
3267 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3269 /* operands of same sign, result different sign */
3270 generate_exception(ctx, EXCP_OVERFLOW);
3272 gen_store_gpr(t0, rt);
3278 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3280 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3287 /* Logic with immediate operand */
3288 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3289 int rt, int rs, int16_t imm)
3294 /* If no destination, treat it as a NOP. */
3297 uimm = (uint16_t)imm;
3300 if (likely(rs != 0))
3301 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3303 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3307 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3309 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3312 if (likely(rs != 0))
3313 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3315 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3318 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3320 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3321 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3323 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3332 /* Set on less than with immediate operand */
3333 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3334 int rt, int rs, int16_t imm)
3336 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3340 /* If no destination, treat it as a NOP. */
3343 t0 = tcg_temp_new();
3344 gen_load_gpr(t0, rs);
3347 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3350 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3356 /* Shifts with immediate operand */
3357 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3358 int rt, int rs, int16_t imm)
3360 target_ulong uimm = ((uint16_t)imm) & 0x1f;
3364 /* If no destination, treat it as a NOP. */
3368 t0 = tcg_temp_new();
3369 gen_load_gpr(t0, rs);
3372 tcg_gen_shli_tl(t0, t0, uimm);
3373 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3376 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3380 tcg_gen_ext32u_tl(t0, t0);
3381 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3383 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3388 TCGv_i32 t1 = tcg_temp_new_i32();
3390 tcg_gen_trunc_tl_i32(t1, t0);
3391 tcg_gen_rotri_i32(t1, t1, uimm);
3392 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3393 tcg_temp_free_i32(t1);
3395 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3398 #if defined(TARGET_MIPS64)
3400 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3403 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3406 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3410 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3412 tcg_gen_mov_tl(cpu_gpr[rt], t0);
3416 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3419 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
3422 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
3425 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
3433 static void gen_arith(DisasContext *ctx, uint32_t opc,
3434 int rd, int rs, int rt)
3436 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3437 && opc != OPC_DADD && opc != OPC_DSUB) {
3438 /* If no destination, treat it as a NOP.
3439 For add & sub, we must generate the overflow exception when needed. */
3446 TCGv t0 = tcg_temp_local_new();
3447 TCGv t1 = tcg_temp_new();
3448 TCGv t2 = tcg_temp_new();
3449 TCGLabel *l1 = gen_new_label();
3451 gen_load_gpr(t1, rs);
3452 gen_load_gpr(t2, rt);
3453 tcg_gen_add_tl(t0, t1, t2);
3454 tcg_gen_ext32s_tl(t0, t0);
3455 tcg_gen_xor_tl(t1, t1, t2);
3456 tcg_gen_xor_tl(t2, t0, t2);
3457 tcg_gen_andc_tl(t1, t2, t1);
3459 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3461 /* operands of same sign, result different sign */
3462 generate_exception(ctx, EXCP_OVERFLOW);
3464 gen_store_gpr(t0, rd);
3469 if (rs != 0 && rt != 0) {
3470 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3471 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3472 } else if (rs == 0 && rt != 0) {
3473 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3474 } else if (rs != 0 && rt == 0) {
3475 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3477 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3482 TCGv t0 = tcg_temp_local_new();
3483 TCGv t1 = tcg_temp_new();
3484 TCGv t2 = tcg_temp_new();
3485 TCGLabel *l1 = gen_new_label();
3487 gen_load_gpr(t1, rs);
3488 gen_load_gpr(t2, rt);
3489 tcg_gen_sub_tl(t0, t1, t2);
3490 tcg_gen_ext32s_tl(t0, t0);
3491 tcg_gen_xor_tl(t2, t1, t2);
3492 tcg_gen_xor_tl(t1, t0, t1);
3493 tcg_gen_and_tl(t1, t1, t2);
3495 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3497 /* operands of different sign, first operand and result different sign */
3498 generate_exception(ctx, EXCP_OVERFLOW);
3500 gen_store_gpr(t0, rd);
3505 if (rs != 0 && rt != 0) {
3506 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3507 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3508 } else if (rs == 0 && rt != 0) {
3509 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3510 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3511 } else if (rs != 0 && rt == 0) {
3512 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3514 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3517 #if defined(TARGET_MIPS64)
3520 TCGv t0 = tcg_temp_local_new();
3521 TCGv t1 = tcg_temp_new();
3522 TCGv t2 = tcg_temp_new();
3523 TCGLabel *l1 = gen_new_label();
3525 gen_load_gpr(t1, rs);
3526 gen_load_gpr(t2, rt);
3527 tcg_gen_add_tl(t0, t1, t2);
3528 tcg_gen_xor_tl(t1, t1, t2);
3529 tcg_gen_xor_tl(t2, t0, t2);
3530 tcg_gen_andc_tl(t1, t2, t1);
3532 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3534 /* operands of same sign, result different sign */
3535 generate_exception(ctx, EXCP_OVERFLOW);
3537 gen_store_gpr(t0, rd);
3542 if (rs != 0 && rt != 0) {
3543 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3544 } else if (rs == 0 && rt != 0) {
3545 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3546 } else if (rs != 0 && rt == 0) {
3547 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3549 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3554 TCGv t0 = tcg_temp_local_new();
3555 TCGv t1 = tcg_temp_new();
3556 TCGv t2 = tcg_temp_new();
3557 TCGLabel *l1 = gen_new_label();
3559 gen_load_gpr(t1, rs);
3560 gen_load_gpr(t2, rt);
3561 tcg_gen_sub_tl(t0, t1, t2);
3562 tcg_gen_xor_tl(t2, t1, t2);
3563 tcg_gen_xor_tl(t1, t0, t1);
3564 tcg_gen_and_tl(t1, t1, t2);
3566 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3568 /* operands of different sign, first operand and result different sign */
3569 generate_exception(ctx, EXCP_OVERFLOW);
3571 gen_store_gpr(t0, rd);
3576 if (rs != 0 && rt != 0) {
3577 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3578 } else if (rs == 0 && rt != 0) {
3579 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3580 } else if (rs != 0 && rt == 0) {
3581 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3583 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3588 if (likely(rs != 0 && rt != 0)) {
3589 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3590 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3592 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3598 /* Conditional move */
3599 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
3600 int rd, int rs, int rt)
3605 /* If no destination, treat it as a NOP. */
3609 t0 = tcg_temp_new();
3610 gen_load_gpr(t0, rt);
3611 t1 = tcg_const_tl(0);
3612 t2 = tcg_temp_new();
3613 gen_load_gpr(t2, rs);
3616 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
3619 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
3622 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
3625 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
3634 static void gen_logic(DisasContext *ctx, uint32_t opc,
3635 int rd, int rs, int rt)
3638 /* If no destination, treat it as a NOP. */
3644 if (likely(rs != 0 && rt != 0)) {
3645 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3647 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3651 if (rs != 0 && rt != 0) {
3652 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3653 } else if (rs == 0 && rt != 0) {
3654 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
3655 } else if (rs != 0 && rt == 0) {
3656 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
3658 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
3662 if (likely(rs != 0 && rt != 0)) {
3663 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3664 } else if (rs == 0 && rt != 0) {
3665 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3666 } else if (rs != 0 && rt == 0) {
3667 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3669 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3673 if (likely(rs != 0 && rt != 0)) {
3674 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3675 } else if (rs == 0 && rt != 0) {
3676 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3677 } else if (rs != 0 && rt == 0) {
3678 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3680 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3686 /* Set on lower than */
3687 static void gen_slt(DisasContext *ctx, uint32_t opc,
3688 int rd, int rs, int rt)
3693 /* If no destination, treat it as a NOP. */
3697 t0 = tcg_temp_new();
3698 t1 = tcg_temp_new();
3699 gen_load_gpr(t0, rs);
3700 gen_load_gpr(t1, rt);
3703 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
3706 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
3714 static void gen_shift(DisasContext *ctx, uint32_t opc,
3715 int rd, int rs, int rt)
3720 /* If no destination, treat it as a NOP.
3721 For add & sub, we must generate the overflow exception when needed. */
3725 t0 = tcg_temp_new();
3726 t1 = tcg_temp_new();
3727 gen_load_gpr(t0, rs);
3728 gen_load_gpr(t1, rt);
3731 tcg_gen_andi_tl(t0, t0, 0x1f);
3732 tcg_gen_shl_tl(t0, t1, t0);
3733 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3736 tcg_gen_andi_tl(t0, t0, 0x1f);
3737 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3740 tcg_gen_ext32u_tl(t1, t1);
3741 tcg_gen_andi_tl(t0, t0, 0x1f);
3742 tcg_gen_shr_tl(t0, t1, t0);
3743 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3747 TCGv_i32 t2 = tcg_temp_new_i32();
3748 TCGv_i32 t3 = tcg_temp_new_i32();
3750 tcg_gen_trunc_tl_i32(t2, t0);
3751 tcg_gen_trunc_tl_i32(t3, t1);
3752 tcg_gen_andi_i32(t2, t2, 0x1f);
3753 tcg_gen_rotr_i32(t2, t3, t2);
3754 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3755 tcg_temp_free_i32(t2);
3756 tcg_temp_free_i32(t3);
3759 #if defined(TARGET_MIPS64)
3761 tcg_gen_andi_tl(t0, t0, 0x3f);
3762 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
3765 tcg_gen_andi_tl(t0, t0, 0x3f);
3766 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3769 tcg_gen_andi_tl(t0, t0, 0x3f);
3770 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3773 tcg_gen_andi_tl(t0, t0, 0x3f);
3774 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3782 /* Arithmetic on HI/LO registers */
3783 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3785 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3796 #if defined(TARGET_MIPS64)
3798 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3802 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3806 #if defined(TARGET_MIPS64)
3808 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3812 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3817 #if defined(TARGET_MIPS64)
3819 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3823 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3826 tcg_gen_movi_tl(cpu_HI[acc], 0);
3831 #if defined(TARGET_MIPS64)
3833 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3837 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3840 tcg_gen_movi_tl(cpu_LO[acc], 0);
3846 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3849 TCGv t0 = tcg_const_tl(addr);
3850 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3851 gen_store_gpr(t0, reg);
3855 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3861 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3864 offset = sextract32(ctx->opcode << 2, 0, 21);
3865 addr = addr_add(ctx, pc, offset);
3866 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3870 offset = sextract32(ctx->opcode << 2, 0, 21);
3871 addr = addr_add(ctx, pc, offset);
3872 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3874 #if defined(TARGET_MIPS64)
3877 offset = sextract32(ctx->opcode << 2, 0, 21);
3878 addr = addr_add(ctx, pc, offset);
3879 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3883 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3886 offset = sextract32(ctx->opcode, 0, 16) << 16;
3887 addr = addr_add(ctx, pc, offset);
3888 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3893 offset = sextract32(ctx->opcode, 0, 16) << 16;
3894 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3895 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3898 #if defined(TARGET_MIPS64)
3899 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3900 case R6_OPC_LDPC + (1 << 16):
3901 case R6_OPC_LDPC + (2 << 16):
3902 case R6_OPC_LDPC + (3 << 16):
3904 offset = sextract32(ctx->opcode << 3, 0, 21);
3905 addr = addr_add(ctx, (pc & ~0x7), offset);
3906 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3910 MIPS_INVAL("OPC_PCREL");
3911 generate_exception_end(ctx, EXCP_RI);
3918 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3927 t0 = tcg_temp_new();
3928 t1 = tcg_temp_new();
3930 gen_load_gpr(t0, rs);
3931 gen_load_gpr(t1, rt);
3936 TCGv t2 = tcg_temp_new();
3937 TCGv t3 = tcg_temp_new();
3938 tcg_gen_ext32s_tl(t0, t0);
3939 tcg_gen_ext32s_tl(t1, t1);
3940 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3941 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3942 tcg_gen_and_tl(t2, t2, t3);
3943 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3944 tcg_gen_or_tl(t2, t2, t3);
3945 tcg_gen_movi_tl(t3, 0);
3946 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3947 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3948 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3955 TCGv t2 = tcg_temp_new();
3956 TCGv t3 = tcg_temp_new();
3957 tcg_gen_ext32s_tl(t0, t0);
3958 tcg_gen_ext32s_tl(t1, t1);
3959 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3960 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3961 tcg_gen_and_tl(t2, t2, t3);
3962 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3963 tcg_gen_or_tl(t2, t2, t3);
3964 tcg_gen_movi_tl(t3, 0);
3965 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3966 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3967 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3974 TCGv t2 = tcg_const_tl(0);
3975 TCGv t3 = tcg_const_tl(1);
3976 tcg_gen_ext32u_tl(t0, t0);
3977 tcg_gen_ext32u_tl(t1, t1);
3978 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3979 tcg_gen_divu_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_remu_tl(cpu_gpr[rd], t0, t1);
3993 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4000 TCGv_i32 t2 = tcg_temp_new_i32();
4001 TCGv_i32 t3 = tcg_temp_new_i32();
4002 tcg_gen_trunc_tl_i32(t2, t0);
4003 tcg_gen_trunc_tl_i32(t3, t1);
4004 tcg_gen_mul_i32(t2, t2, t3);
4005 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4006 tcg_temp_free_i32(t2);
4007 tcg_temp_free_i32(t3);
4012 TCGv_i32 t2 = tcg_temp_new_i32();
4013 TCGv_i32 t3 = tcg_temp_new_i32();
4014 tcg_gen_trunc_tl_i32(t2, t0);
4015 tcg_gen_trunc_tl_i32(t3, t1);
4016 tcg_gen_muls2_i32(t2, t3, t2, t3);
4017 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4018 tcg_temp_free_i32(t2);
4019 tcg_temp_free_i32(t3);
4024 TCGv_i32 t2 = tcg_temp_new_i32();
4025 TCGv_i32 t3 = tcg_temp_new_i32();
4026 tcg_gen_trunc_tl_i32(t2, t0);
4027 tcg_gen_trunc_tl_i32(t3, t1);
4028 tcg_gen_mul_i32(t2, t2, t3);
4029 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4030 tcg_temp_free_i32(t2);
4031 tcg_temp_free_i32(t3);
4036 TCGv_i32 t2 = tcg_temp_new_i32();
4037 TCGv_i32 t3 = tcg_temp_new_i32();
4038 tcg_gen_trunc_tl_i32(t2, t0);
4039 tcg_gen_trunc_tl_i32(t3, t1);
4040 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4041 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4042 tcg_temp_free_i32(t2);
4043 tcg_temp_free_i32(t3);
4046 #if defined(TARGET_MIPS64)
4049 TCGv t2 = tcg_temp_new();
4050 TCGv t3 = tcg_temp_new();
4051 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4052 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4053 tcg_gen_and_tl(t2, t2, t3);
4054 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4055 tcg_gen_or_tl(t2, t2, t3);
4056 tcg_gen_movi_tl(t3, 0);
4057 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4058 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4065 TCGv t2 = tcg_temp_new();
4066 TCGv t3 = tcg_temp_new();
4067 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4068 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4069 tcg_gen_and_tl(t2, t2, t3);
4070 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4071 tcg_gen_or_tl(t2, t2, t3);
4072 tcg_gen_movi_tl(t3, 0);
4073 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4074 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4081 TCGv t2 = tcg_const_tl(0);
4082 TCGv t3 = tcg_const_tl(1);
4083 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4084 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4091 TCGv t2 = tcg_const_tl(0);
4092 TCGv t3 = tcg_const_tl(1);
4093 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4094 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4100 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4104 TCGv t2 = tcg_temp_new();
4105 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4110 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4114 TCGv t2 = tcg_temp_new();
4115 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4121 MIPS_INVAL("r6 mul/div");
4122 generate_exception_end(ctx, EXCP_RI);
4130 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4131 int acc, int rs, int rt)
4135 t0 = tcg_temp_new();
4136 t1 = tcg_temp_new();
4138 gen_load_gpr(t0, rs);
4139 gen_load_gpr(t1, rt);
4148 TCGv t2 = tcg_temp_new();
4149 TCGv t3 = tcg_temp_new();
4150 tcg_gen_ext32s_tl(t0, t0);
4151 tcg_gen_ext32s_tl(t1, t1);
4152 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4153 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4154 tcg_gen_and_tl(t2, t2, t3);
4155 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4156 tcg_gen_or_tl(t2, t2, t3);
4157 tcg_gen_movi_tl(t3, 0);
4158 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4159 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4160 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4161 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4162 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4169 TCGv t2 = tcg_const_tl(0);
4170 TCGv t3 = tcg_const_tl(1);
4171 tcg_gen_ext32u_tl(t0, t0);
4172 tcg_gen_ext32u_tl(t1, t1);
4173 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4174 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4175 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4176 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4177 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4184 TCGv_i32 t2 = tcg_temp_new_i32();
4185 TCGv_i32 t3 = tcg_temp_new_i32();
4186 tcg_gen_trunc_tl_i32(t2, t0);
4187 tcg_gen_trunc_tl_i32(t3, t1);
4188 tcg_gen_muls2_i32(t2, t3, t2, t3);
4189 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4190 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4191 tcg_temp_free_i32(t2);
4192 tcg_temp_free_i32(t3);
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_mulu2_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);
4208 #if defined(TARGET_MIPS64)
4211 TCGv t2 = tcg_temp_new();
4212 TCGv t3 = tcg_temp_new();
4213 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4214 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4215 tcg_gen_and_tl(t2, t2, t3);
4216 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4217 tcg_gen_or_tl(t2, t2, t3);
4218 tcg_gen_movi_tl(t3, 0);
4219 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4220 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4221 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4228 TCGv t2 = tcg_const_tl(0);
4229 TCGv t3 = tcg_const_tl(1);
4230 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4231 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4232 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4238 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4241 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4246 TCGv_i64 t2 = tcg_temp_new_i64();
4247 TCGv_i64 t3 = tcg_temp_new_i64();
4249 tcg_gen_ext_tl_i64(t2, t0);
4250 tcg_gen_ext_tl_i64(t3, t1);
4251 tcg_gen_mul_i64(t2, t2, t3);
4252 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4253 tcg_gen_add_i64(t2, t2, t3);
4254 tcg_temp_free_i64(t3);
4255 gen_move_low32(cpu_LO[acc], t2);
4256 gen_move_high32(cpu_HI[acc], t2);
4257 tcg_temp_free_i64(t2);
4262 TCGv_i64 t2 = tcg_temp_new_i64();
4263 TCGv_i64 t3 = tcg_temp_new_i64();
4265 tcg_gen_ext32u_tl(t0, t0);
4266 tcg_gen_ext32u_tl(t1, t1);
4267 tcg_gen_extu_tl_i64(t2, t0);
4268 tcg_gen_extu_tl_i64(t3, t1);
4269 tcg_gen_mul_i64(t2, t2, t3);
4270 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4271 tcg_gen_add_i64(t2, t2, t3);
4272 tcg_temp_free_i64(t3);
4273 gen_move_low32(cpu_LO[acc], t2);
4274 gen_move_high32(cpu_HI[acc], t2);
4275 tcg_temp_free_i64(t2);
4280 TCGv_i64 t2 = tcg_temp_new_i64();
4281 TCGv_i64 t3 = tcg_temp_new_i64();
4283 tcg_gen_ext_tl_i64(t2, t0);
4284 tcg_gen_ext_tl_i64(t3, t1);
4285 tcg_gen_mul_i64(t2, t2, t3);
4286 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4287 tcg_gen_sub_i64(t2, t3, t2);
4288 tcg_temp_free_i64(t3);
4289 gen_move_low32(cpu_LO[acc], t2);
4290 gen_move_high32(cpu_HI[acc], t2);
4291 tcg_temp_free_i64(t2);
4296 TCGv_i64 t2 = tcg_temp_new_i64();
4297 TCGv_i64 t3 = tcg_temp_new_i64();
4299 tcg_gen_ext32u_tl(t0, t0);
4300 tcg_gen_ext32u_tl(t1, t1);
4301 tcg_gen_extu_tl_i64(t2, t0);
4302 tcg_gen_extu_tl_i64(t3, t1);
4303 tcg_gen_mul_i64(t2, t2, t3);
4304 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4305 tcg_gen_sub_i64(t2, t3, t2);
4306 tcg_temp_free_i64(t3);
4307 gen_move_low32(cpu_LO[acc], t2);
4308 gen_move_high32(cpu_HI[acc], t2);
4309 tcg_temp_free_i64(t2);
4313 MIPS_INVAL("mul/div");
4314 generate_exception_end(ctx, EXCP_RI);
4322 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4323 int rd, int rs, int rt)
4325 TCGv t0 = tcg_temp_new();
4326 TCGv t1 = tcg_temp_new();
4328 gen_load_gpr(t0, rs);
4329 gen_load_gpr(t1, rt);
4332 case OPC_VR54XX_MULS:
4333 gen_helper_muls(t0, cpu_env, t0, t1);
4335 case OPC_VR54XX_MULSU:
4336 gen_helper_mulsu(t0, cpu_env, t0, t1);
4338 case OPC_VR54XX_MACC:
4339 gen_helper_macc(t0, cpu_env, t0, t1);
4341 case OPC_VR54XX_MACCU:
4342 gen_helper_maccu(t0, cpu_env, t0, t1);
4344 case OPC_VR54XX_MSAC:
4345 gen_helper_msac(t0, cpu_env, t0, t1);
4347 case OPC_VR54XX_MSACU:
4348 gen_helper_msacu(t0, cpu_env, t0, t1);
4350 case OPC_VR54XX_MULHI:
4351 gen_helper_mulhi(t0, cpu_env, t0, t1);
4353 case OPC_VR54XX_MULHIU:
4354 gen_helper_mulhiu(t0, cpu_env, t0, t1);
4356 case OPC_VR54XX_MULSHI:
4357 gen_helper_mulshi(t0, cpu_env, t0, t1);
4359 case OPC_VR54XX_MULSHIU:
4360 gen_helper_mulshiu(t0, cpu_env, t0, t1);
4362 case OPC_VR54XX_MACCHI:
4363 gen_helper_macchi(t0, cpu_env, t0, t1);
4365 case OPC_VR54XX_MACCHIU:
4366 gen_helper_macchiu(t0, cpu_env, t0, t1);
4368 case OPC_VR54XX_MSACHI:
4369 gen_helper_msachi(t0, cpu_env, t0, t1);
4371 case OPC_VR54XX_MSACHIU:
4372 gen_helper_msachiu(t0, cpu_env, t0, t1);
4375 MIPS_INVAL("mul vr54xx");
4376 generate_exception_end(ctx, EXCP_RI);
4379 gen_store_gpr(t0, rd);
4386 static void gen_cl (DisasContext *ctx, uint32_t opc,
4396 gen_load_gpr(t0, rs);
4401 #if defined(TARGET_MIPS64)
4405 tcg_gen_not_tl(t0, t0);
4414 tcg_gen_ext32u_tl(t0, t0);
4415 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
4416 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
4418 #if defined(TARGET_MIPS64)
4423 tcg_gen_clzi_i64(t0, t0, 64);
4429 /* Godson integer instructions */
4430 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
4431 int rd, int rs, int rt)
4443 case OPC_MULTU_G_2E:
4444 case OPC_MULTU_G_2F:
4445 #if defined(TARGET_MIPS64)
4446 case OPC_DMULT_G_2E:
4447 case OPC_DMULT_G_2F:
4448 case OPC_DMULTU_G_2E:
4449 case OPC_DMULTU_G_2F:
4451 t0 = tcg_temp_new();
4452 t1 = tcg_temp_new();
4455 t0 = tcg_temp_local_new();
4456 t1 = tcg_temp_local_new();
4460 gen_load_gpr(t0, rs);
4461 gen_load_gpr(t1, rt);
4466 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4467 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4469 case OPC_MULTU_G_2E:
4470 case OPC_MULTU_G_2F:
4471 tcg_gen_ext32u_tl(t0, t0);
4472 tcg_gen_ext32u_tl(t1, t1);
4473 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4474 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4479 TCGLabel *l1 = gen_new_label();
4480 TCGLabel *l2 = gen_new_label();
4481 TCGLabel *l3 = gen_new_label();
4482 tcg_gen_ext32s_tl(t0, t0);
4483 tcg_gen_ext32s_tl(t1, t1);
4484 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4485 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4488 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4489 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4490 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4493 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4494 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4501 TCGLabel *l1 = gen_new_label();
4502 TCGLabel *l2 = gen_new_label();
4503 tcg_gen_ext32u_tl(t0, t0);
4504 tcg_gen_ext32u_tl(t1, t1);
4505 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4506 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4509 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4510 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4517 TCGLabel *l1 = gen_new_label();
4518 TCGLabel *l2 = gen_new_label();
4519 TCGLabel *l3 = gen_new_label();
4520 tcg_gen_ext32u_tl(t0, t0);
4521 tcg_gen_ext32u_tl(t1, t1);
4522 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4523 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4524 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4526 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4529 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4530 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4537 TCGLabel *l1 = gen_new_label();
4538 TCGLabel *l2 = gen_new_label();
4539 tcg_gen_ext32u_tl(t0, t0);
4540 tcg_gen_ext32u_tl(t1, t1);
4541 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4542 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4545 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4546 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4550 #if defined(TARGET_MIPS64)
4551 case OPC_DMULT_G_2E:
4552 case OPC_DMULT_G_2F:
4553 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4555 case OPC_DMULTU_G_2E:
4556 case OPC_DMULTU_G_2F:
4557 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4562 TCGLabel *l1 = gen_new_label();
4563 TCGLabel *l2 = gen_new_label();
4564 TCGLabel *l3 = gen_new_label();
4565 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4566 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4569 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4570 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4571 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4574 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4578 case OPC_DDIVU_G_2E:
4579 case OPC_DDIVU_G_2F:
4581 TCGLabel *l1 = gen_new_label();
4582 TCGLabel *l2 = gen_new_label();
4583 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4584 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4587 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4594 TCGLabel *l1 = gen_new_label();
4595 TCGLabel *l2 = gen_new_label();
4596 TCGLabel *l3 = gen_new_label();
4597 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4598 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4599 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4601 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4604 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4608 case OPC_DMODU_G_2E:
4609 case OPC_DMODU_G_2F:
4611 TCGLabel *l1 = gen_new_label();
4612 TCGLabel *l2 = gen_new_label();
4613 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4614 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4617 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4628 /* Loongson multimedia instructions */
4629 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4631 uint32_t opc, shift_max;
4634 opc = MASK_LMI(ctx->opcode);
4640 t0 = tcg_temp_local_new_i64();
4641 t1 = tcg_temp_local_new_i64();
4644 t0 = tcg_temp_new_i64();
4645 t1 = tcg_temp_new_i64();
4649 check_cp1_enabled(ctx);
4650 gen_load_fpr64(ctx, t0, rs);
4651 gen_load_fpr64(ctx, t1, rt);
4653 #define LMI_HELPER(UP, LO) \
4654 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
4655 #define LMI_HELPER_1(UP, LO) \
4656 case OPC_##UP: gen_helper_##LO(t0, t0); break
4657 #define LMI_DIRECT(UP, LO, OP) \
4658 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
4661 LMI_HELPER(PADDSH, paddsh);
4662 LMI_HELPER(PADDUSH, paddush);
4663 LMI_HELPER(PADDH, paddh);
4664 LMI_HELPER(PADDW, paddw);
4665 LMI_HELPER(PADDSB, paddsb);
4666 LMI_HELPER(PADDUSB, paddusb);
4667 LMI_HELPER(PADDB, paddb);
4669 LMI_HELPER(PSUBSH, psubsh);
4670 LMI_HELPER(PSUBUSH, psubush);
4671 LMI_HELPER(PSUBH, psubh);
4672 LMI_HELPER(PSUBW, psubw);
4673 LMI_HELPER(PSUBSB, psubsb);
4674 LMI_HELPER(PSUBUSB, psubusb);
4675 LMI_HELPER(PSUBB, psubb);
4677 LMI_HELPER(PSHUFH, pshufh);
4678 LMI_HELPER(PACKSSWH, packsswh);
4679 LMI_HELPER(PACKSSHB, packsshb);
4680 LMI_HELPER(PACKUSHB, packushb);
4682 LMI_HELPER(PUNPCKLHW, punpcklhw);
4683 LMI_HELPER(PUNPCKHHW, punpckhhw);
4684 LMI_HELPER(PUNPCKLBH, punpcklbh);
4685 LMI_HELPER(PUNPCKHBH, punpckhbh);
4686 LMI_HELPER(PUNPCKLWD, punpcklwd);
4687 LMI_HELPER(PUNPCKHWD, punpckhwd);
4689 LMI_HELPER(PAVGH, pavgh);
4690 LMI_HELPER(PAVGB, pavgb);
4691 LMI_HELPER(PMAXSH, pmaxsh);
4692 LMI_HELPER(PMINSH, pminsh);
4693 LMI_HELPER(PMAXUB, pmaxub);
4694 LMI_HELPER(PMINUB, pminub);
4696 LMI_HELPER(PCMPEQW, pcmpeqw);
4697 LMI_HELPER(PCMPGTW, pcmpgtw);
4698 LMI_HELPER(PCMPEQH, pcmpeqh);
4699 LMI_HELPER(PCMPGTH, pcmpgth);
4700 LMI_HELPER(PCMPEQB, pcmpeqb);
4701 LMI_HELPER(PCMPGTB, pcmpgtb);
4703 LMI_HELPER(PSLLW, psllw);
4704 LMI_HELPER(PSLLH, psllh);
4705 LMI_HELPER(PSRLW, psrlw);
4706 LMI_HELPER(PSRLH, psrlh);
4707 LMI_HELPER(PSRAW, psraw);
4708 LMI_HELPER(PSRAH, psrah);
4710 LMI_HELPER(PMULLH, pmullh);
4711 LMI_HELPER(PMULHH, pmulhh);
4712 LMI_HELPER(PMULHUH, pmulhuh);
4713 LMI_HELPER(PMADDHW, pmaddhw);
4715 LMI_HELPER(PASUBUB, pasubub);
4716 LMI_HELPER_1(BIADD, biadd);
4717 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4719 LMI_DIRECT(PADDD, paddd, add);
4720 LMI_DIRECT(PSUBD, psubd, sub);
4721 LMI_DIRECT(XOR_CP2, xor, xor);
4722 LMI_DIRECT(NOR_CP2, nor, nor);
4723 LMI_DIRECT(AND_CP2, and, and);
4724 LMI_DIRECT(OR_CP2, or, or);
4727 tcg_gen_andc_i64(t0, t1, t0);
4731 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4734 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4737 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4740 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4744 tcg_gen_andi_i64(t1, t1, 3);
4745 tcg_gen_shli_i64(t1, t1, 4);
4746 tcg_gen_shr_i64(t0, t0, t1);
4747 tcg_gen_ext16u_i64(t0, t0);
4751 tcg_gen_add_i64(t0, t0, t1);
4752 tcg_gen_ext32s_i64(t0, t0);
4755 tcg_gen_sub_i64(t0, t0, t1);
4756 tcg_gen_ext32s_i64(t0, t0);
4778 /* Make sure shift count isn't TCG undefined behaviour. */
4779 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4784 tcg_gen_shl_i64(t0, t0, t1);
4788 /* Since SRA is UndefinedResult without sign-extended inputs,
4789 we can treat SRA and DSRA the same. */
4790 tcg_gen_sar_i64(t0, t0, t1);
4793 /* We want to shift in zeros for SRL; zero-extend first. */
4794 tcg_gen_ext32u_i64(t0, t0);
4797 tcg_gen_shr_i64(t0, t0, t1);
4801 if (shift_max == 32) {
4802 tcg_gen_ext32s_i64(t0, t0);
4805 /* Shifts larger than MAX produce zero. */
4806 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4807 tcg_gen_neg_i64(t1, t1);
4808 tcg_gen_and_i64(t0, t0, t1);
4814 TCGv_i64 t2 = tcg_temp_new_i64();
4815 TCGLabel *lab = gen_new_label();
4817 tcg_gen_mov_i64(t2, t0);
4818 tcg_gen_add_i64(t0, t1, t2);
4819 if (opc == OPC_ADD_CP2) {
4820 tcg_gen_ext32s_i64(t0, t0);
4822 tcg_gen_xor_i64(t1, t1, t2);
4823 tcg_gen_xor_i64(t2, t2, t0);
4824 tcg_gen_andc_i64(t1, t2, t1);
4825 tcg_temp_free_i64(t2);
4826 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4827 generate_exception(ctx, EXCP_OVERFLOW);
4835 TCGv_i64 t2 = tcg_temp_new_i64();
4836 TCGLabel *lab = gen_new_label();
4838 tcg_gen_mov_i64(t2, t0);
4839 tcg_gen_sub_i64(t0, t1, t2);
4840 if (opc == OPC_SUB_CP2) {
4841 tcg_gen_ext32s_i64(t0, t0);
4843 tcg_gen_xor_i64(t1, t1, t2);
4844 tcg_gen_xor_i64(t2, t2, t0);
4845 tcg_gen_and_i64(t1, t1, t2);
4846 tcg_temp_free_i64(t2);
4847 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4848 generate_exception(ctx, EXCP_OVERFLOW);
4854 tcg_gen_ext32u_i64(t0, t0);
4855 tcg_gen_ext32u_i64(t1, t1);
4856 tcg_gen_mul_i64(t0, t0, t1);
4865 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4866 FD field is the CC field? */
4868 MIPS_INVAL("loongson_cp2");
4869 generate_exception_end(ctx, EXCP_RI);
4876 gen_store_fpr64(ctx, t0, rd);
4878 tcg_temp_free_i64(t0);
4879 tcg_temp_free_i64(t1);
4883 static void gen_trap (DisasContext *ctx, uint32_t opc,
4884 int rs, int rt, int16_t imm)
4887 TCGv t0 = tcg_temp_new();
4888 TCGv t1 = tcg_temp_new();
4891 /* Load needed operands */
4899 /* Compare two registers */
4901 gen_load_gpr(t0, rs);
4902 gen_load_gpr(t1, rt);
4912 /* Compare register to immediate */
4913 if (rs != 0 || imm != 0) {
4914 gen_load_gpr(t0, rs);
4915 tcg_gen_movi_tl(t1, (int32_t)imm);
4922 case OPC_TEQ: /* rs == rs */
4923 case OPC_TEQI: /* r0 == 0 */
4924 case OPC_TGE: /* rs >= rs */
4925 case OPC_TGEI: /* r0 >= 0 */
4926 case OPC_TGEU: /* rs >= rs unsigned */
4927 case OPC_TGEIU: /* r0 >= 0 unsigned */
4929 generate_exception_end(ctx, EXCP_TRAP);
4931 case OPC_TLT: /* rs < rs */
4932 case OPC_TLTI: /* r0 < 0 */
4933 case OPC_TLTU: /* rs < rs unsigned */
4934 case OPC_TLTIU: /* r0 < 0 unsigned */
4935 case OPC_TNE: /* rs != rs */
4936 case OPC_TNEI: /* r0 != 0 */
4937 /* Never trap: treat as NOP. */
4941 TCGLabel *l1 = gen_new_label();
4946 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4950 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4954 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4958 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4962 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4966 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4969 generate_exception(ctx, EXCP_TRAP);
4976 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4978 if (unlikely(ctx->base.singlestep_enabled)) {
4982 #ifndef CONFIG_USER_ONLY
4983 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4989 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4991 if (use_goto_tb(ctx, dest)) {
4994 tcg_gen_exit_tb(ctx->base.tb, n);
4997 if (ctx->base.singlestep_enabled) {
4998 save_cpu_state(ctx, 0);
4999 gen_helper_raise_exception_debug(cpu_env);
5001 tcg_gen_lookup_and_goto_ptr();
5005 /* Branches (before delay slot) */
5006 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5008 int rs, int rt, int32_t offset,
5011 target_ulong btgt = -1;
5013 int bcond_compute = 0;
5014 TCGv t0 = tcg_temp_new();
5015 TCGv t1 = tcg_temp_new();
5017 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5018 #ifdef MIPS_DEBUG_DISAS
5019 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5020 TARGET_FMT_lx "\n", ctx->base.pc_next);
5022 generate_exception_end(ctx, EXCP_RI);
5026 /* Load needed operands */
5032 /* Compare two registers */
5034 gen_load_gpr(t0, rs);
5035 gen_load_gpr(t1, rt);
5038 btgt = ctx->base.pc_next + insn_bytes + offset;
5052 /* Compare to zero */
5054 gen_load_gpr(t0, rs);
5057 btgt = ctx->base.pc_next + insn_bytes + offset;
5060 #if defined(TARGET_MIPS64)
5062 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5064 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5067 btgt = ctx->base.pc_next + insn_bytes + offset;
5072 /* Jump to immediate */
5073 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5078 /* Jump to register */
5079 if (offset != 0 && offset != 16) {
5080 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5081 others are reserved. */
5082 MIPS_INVAL("jump hint");
5083 generate_exception_end(ctx, EXCP_RI);
5086 gen_load_gpr(btarget, rs);
5089 MIPS_INVAL("branch/jump");
5090 generate_exception_end(ctx, EXCP_RI);
5093 if (bcond_compute == 0) {
5094 /* No condition to be computed */
5096 case OPC_BEQ: /* rx == rx */
5097 case OPC_BEQL: /* rx == rx likely */
5098 case OPC_BGEZ: /* 0 >= 0 */
5099 case OPC_BGEZL: /* 0 >= 0 likely */
5100 case OPC_BLEZ: /* 0 <= 0 */
5101 case OPC_BLEZL: /* 0 <= 0 likely */
5103 ctx->hflags |= MIPS_HFLAG_B;
5105 case OPC_BGEZAL: /* 0 >= 0 */
5106 case OPC_BGEZALL: /* 0 >= 0 likely */
5107 /* Always take and link */
5109 ctx->hflags |= MIPS_HFLAG_B;
5111 case OPC_BNE: /* rx != rx */
5112 case OPC_BGTZ: /* 0 > 0 */
5113 case OPC_BLTZ: /* 0 < 0 */
5116 case OPC_BLTZAL: /* 0 < 0 */
5117 /* Handle as an unconditional branch to get correct delay
5120 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5121 ctx->hflags |= MIPS_HFLAG_B;
5123 case OPC_BLTZALL: /* 0 < 0 likely */
5124 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5125 /* Skip the instruction in the delay slot */
5126 ctx->base.pc_next += 4;
5128 case OPC_BNEL: /* rx != rx likely */
5129 case OPC_BGTZL: /* 0 > 0 likely */
5130 case OPC_BLTZL: /* 0 < 0 likely */
5131 /* Skip the instruction in the delay slot */
5132 ctx->base.pc_next += 4;
5135 ctx->hflags |= MIPS_HFLAG_B;
5138 ctx->hflags |= MIPS_HFLAG_BX;
5142 ctx->hflags |= MIPS_HFLAG_B;
5145 ctx->hflags |= MIPS_HFLAG_BR;
5149 ctx->hflags |= MIPS_HFLAG_BR;
5152 MIPS_INVAL("branch/jump");
5153 generate_exception_end(ctx, EXCP_RI);
5159 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5162 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5165 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5168 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5171 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5174 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5177 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5181 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5185 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5188 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5191 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5194 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5197 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5200 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5203 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5205 #if defined(TARGET_MIPS64)
5207 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5211 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5214 ctx->hflags |= MIPS_HFLAG_BC;
5217 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5220 ctx->hflags |= MIPS_HFLAG_BL;
5223 MIPS_INVAL("conditional branch/jump");
5224 generate_exception_end(ctx, EXCP_RI);
5229 ctx->btarget = btgt;
5231 switch (delayslot_size) {
5233 ctx->hflags |= MIPS_HFLAG_BDS16;
5236 ctx->hflags |= MIPS_HFLAG_BDS32;
5241 int post_delay = insn_bytes + delayslot_size;
5242 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5244 tcg_gen_movi_tl(cpu_gpr[blink],
5245 ctx->base.pc_next + post_delay + lowbit);
5249 if (insn_bytes == 2)
5250 ctx->hflags |= MIPS_HFLAG_B16;
5256 /* nanoMIPS Branches */
5257 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5259 int rs, int rt, int32_t offset)
5261 target_ulong btgt = -1;
5262 int bcond_compute = 0;
5263 TCGv t0 = tcg_temp_new();
5264 TCGv t1 = tcg_temp_new();
5266 /* Load needed operands */
5270 /* Compare two registers */
5272 gen_load_gpr(t0, rs);
5273 gen_load_gpr(t1, rt);
5276 btgt = ctx->base.pc_next + insn_bytes + offset;
5279 /* Compare to zero */
5281 gen_load_gpr(t0, rs);
5284 btgt = ctx->base.pc_next + insn_bytes + offset;
5287 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5289 btgt = ctx->base.pc_next + insn_bytes + offset;
5293 /* Jump to register */
5294 if (offset != 0 && offset != 16) {
5295 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5296 others are reserved. */
5297 MIPS_INVAL("jump hint");
5298 generate_exception_end(ctx, EXCP_RI);
5301 gen_load_gpr(btarget, rs);
5304 MIPS_INVAL("branch/jump");
5305 generate_exception_end(ctx, EXCP_RI);
5308 if (bcond_compute == 0) {
5309 /* No condition to be computed */
5311 case OPC_BEQ: /* rx == rx */
5313 ctx->hflags |= MIPS_HFLAG_B;
5315 case OPC_BGEZAL: /* 0 >= 0 */
5316 /* Always take and link */
5317 tcg_gen_movi_tl(cpu_gpr[31],
5318 ctx->base.pc_next + insn_bytes);
5319 ctx->hflags |= MIPS_HFLAG_B;
5321 case OPC_BNE: /* rx != rx */
5322 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5323 /* Skip the instruction in the delay slot */
5324 ctx->base.pc_next += 4;
5327 ctx->hflags |= MIPS_HFLAG_BR;
5331 tcg_gen_movi_tl(cpu_gpr[rt],
5332 ctx->base.pc_next + insn_bytes);
5334 ctx->hflags |= MIPS_HFLAG_BR;
5337 MIPS_INVAL("branch/jump");
5338 generate_exception_end(ctx, EXCP_RI);
5344 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5347 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5350 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5351 tcg_gen_movi_tl(cpu_gpr[31],
5352 ctx->base.pc_next + insn_bytes);
5355 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5357 ctx->hflags |= MIPS_HFLAG_BC;
5360 MIPS_INVAL("conditional branch/jump");
5361 generate_exception_end(ctx, EXCP_RI);
5366 ctx->btarget = btgt;
5369 if (insn_bytes == 2) {
5370 ctx->hflags |= MIPS_HFLAG_B16;
5377 /* special3 bitfield operations */
5378 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
5379 int rs, int lsb, int msb)
5381 TCGv t0 = tcg_temp_new();
5382 TCGv t1 = tcg_temp_new();
5384 gen_load_gpr(t1, rs);
5387 if (lsb + msb > 31) {
5391 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5393 /* The two checks together imply that lsb == 0,
5394 so this is a simple sign-extension. */
5395 tcg_gen_ext32s_tl(t0, t1);
5398 #if defined(TARGET_MIPS64)
5407 if (lsb + msb > 63) {
5410 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5417 gen_load_gpr(t0, rt);
5418 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5419 tcg_gen_ext32s_tl(t0, t0);
5421 #if defined(TARGET_MIPS64)
5432 gen_load_gpr(t0, rt);
5433 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5438 MIPS_INVAL("bitops");
5439 generate_exception_end(ctx, EXCP_RI);
5444 gen_store_gpr(t0, rt);
5449 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
5454 /* If no destination, treat it as a NOP. */
5458 t0 = tcg_temp_new();
5459 gen_load_gpr(t0, rt);
5463 TCGv t1 = tcg_temp_new();
5464 TCGv t2 = tcg_const_tl(0x00FF00FF);
5466 tcg_gen_shri_tl(t1, t0, 8);
5467 tcg_gen_and_tl(t1, t1, t2);
5468 tcg_gen_and_tl(t0, t0, t2);
5469 tcg_gen_shli_tl(t0, t0, 8);
5470 tcg_gen_or_tl(t0, t0, t1);
5473 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5477 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5480 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5482 #if defined(TARGET_MIPS64)
5485 TCGv t1 = tcg_temp_new();
5486 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5488 tcg_gen_shri_tl(t1, t0, 8);
5489 tcg_gen_and_tl(t1, t1, t2);
5490 tcg_gen_and_tl(t0, t0, t2);
5491 tcg_gen_shli_tl(t0, t0, 8);
5492 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5499 TCGv t1 = tcg_temp_new();
5500 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5502 tcg_gen_shri_tl(t1, t0, 16);
5503 tcg_gen_and_tl(t1, t1, t2);
5504 tcg_gen_and_tl(t0, t0, t2);
5505 tcg_gen_shli_tl(t0, t0, 16);
5506 tcg_gen_or_tl(t0, t0, t1);
5507 tcg_gen_shri_tl(t1, t0, 32);
5508 tcg_gen_shli_tl(t0, t0, 32);
5509 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5516 MIPS_INVAL("bsfhl");
5517 generate_exception_end(ctx, EXCP_RI);
5524 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
5533 t0 = tcg_temp_new();
5534 t1 = tcg_temp_new();
5535 gen_load_gpr(t0, rs);
5536 gen_load_gpr(t1, rt);
5537 tcg_gen_shli_tl(t0, t0, imm2 + 1);
5538 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
5539 if (opc == OPC_LSA) {
5540 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5549 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5557 t0 = tcg_temp_new();
5558 if (bits == 0 || bits == wordsz) {
5560 gen_load_gpr(t0, rt);
5562 gen_load_gpr(t0, rs);
5566 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5568 #if defined(TARGET_MIPS64)
5570 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5575 TCGv t1 = tcg_temp_new();
5576 gen_load_gpr(t0, rt);
5577 gen_load_gpr(t1, rs);
5581 TCGv_i64 t2 = tcg_temp_new_i64();
5582 tcg_gen_concat_tl_i64(t2, t1, t0);
5583 tcg_gen_shri_i64(t2, t2, 32 - bits);
5584 gen_move_low32(cpu_gpr[rd], t2);
5585 tcg_temp_free_i64(t2);
5588 #if defined(TARGET_MIPS64)
5590 tcg_gen_shli_tl(t0, t0, bits);
5591 tcg_gen_shri_tl(t1, t1, 64 - bits);
5592 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5602 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5605 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5608 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5611 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
5614 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5621 t0 = tcg_temp_new();
5622 gen_load_gpr(t0, rt);
5625 gen_helper_bitswap(cpu_gpr[rd], t0);
5627 #if defined(TARGET_MIPS64)
5629 gen_helper_dbitswap(cpu_gpr[rd], t0);
5636 #ifndef CONFIG_USER_ONLY
5637 /* CP0 (MMU and control) */
5638 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5640 TCGv_i64 t0 = tcg_temp_new_i64();
5641 TCGv_i64 t1 = tcg_temp_new_i64();
5643 tcg_gen_ext_tl_i64(t0, arg);
5644 tcg_gen_ld_i64(t1, cpu_env, off);
5645 #if defined(TARGET_MIPS64)
5646 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5648 tcg_gen_concat32_i64(t1, t1, t0);
5650 tcg_gen_st_i64(t1, cpu_env, off);
5651 tcg_temp_free_i64(t1);
5652 tcg_temp_free_i64(t0);
5655 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5657 TCGv_i64 t0 = tcg_temp_new_i64();
5658 TCGv_i64 t1 = tcg_temp_new_i64();
5660 tcg_gen_ext_tl_i64(t0, arg);
5661 tcg_gen_ld_i64(t1, cpu_env, off);
5662 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_mfhc0_entrylo(TCGv arg, target_ulong off)
5670 TCGv_i64 t0 = tcg_temp_new_i64();
5672 tcg_gen_ld_i64(t0, cpu_env, off);
5673 #if defined(TARGET_MIPS64)
5674 tcg_gen_shri_i64(t0, t0, 30);
5676 tcg_gen_shri_i64(t0, t0, 32);
5678 gen_move_low32(arg, t0);
5679 tcg_temp_free_i64(t0);
5682 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5684 TCGv_i64 t0 = tcg_temp_new_i64();
5686 tcg_gen_ld_i64(t0, cpu_env, off);
5687 tcg_gen_shri_i64(t0, t0, 32 + shift);
5688 gen_move_low32(arg, t0);
5689 tcg_temp_free_i64(t0);
5692 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
5694 TCGv_i32 t0 = tcg_temp_new_i32();
5696 tcg_gen_ld_i32(t0, cpu_env, off);
5697 tcg_gen_ext_i32_tl(arg, t0);
5698 tcg_temp_free_i32(t0);
5701 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
5703 tcg_gen_ld_tl(arg, cpu_env, off);
5704 tcg_gen_ext32s_tl(arg, arg);
5707 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
5709 TCGv_i32 t0 = tcg_temp_new_i32();
5711 tcg_gen_trunc_tl_i32(t0, arg);
5712 tcg_gen_st_i32(t0, cpu_env, off);
5713 tcg_temp_free_i32(t0);
5716 #define CP0_CHECK(c) \
5719 goto cp0_unimplemented; \
5723 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5725 const char *rn = "invalid";
5731 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5732 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5736 goto cp0_unimplemented;
5742 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5743 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5747 goto cp0_unimplemented;
5753 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
5754 ctx->CP0_LLAddr_shift);
5758 CP0_CHECK(ctx->mrp);
5759 gen_helper_mfhc0_maar(arg, cpu_env);
5763 goto cp0_unimplemented;
5772 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5776 goto cp0_unimplemented;
5780 goto cp0_unimplemented;
5782 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5786 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5787 tcg_gen_movi_tl(arg, 0);
5790 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5792 const char *rn = "invalid";
5793 uint64_t mask = ctx->PAMask >> 36;
5799 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5800 tcg_gen_andi_tl(arg, arg, mask);
5801 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5805 goto cp0_unimplemented;
5811 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5812 tcg_gen_andi_tl(arg, arg, mask);
5813 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5817 goto cp0_unimplemented;
5823 /* LLAddr is read-only (the only exception is bit 0 if LLB is
5824 supported); the CP0_LLAddr_rw_bitmask does not seem to be
5825 relevant for modern MIPS cores supporting MTHC0, therefore
5826 treating MTHC0 to LLAddr as NOP. */
5830 CP0_CHECK(ctx->mrp);
5831 gen_helper_mthc0_maar(cpu_env, arg);
5835 goto cp0_unimplemented;
5844 tcg_gen_andi_tl(arg, arg, mask);
5845 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5849 goto cp0_unimplemented;
5853 goto cp0_unimplemented;
5855 trace_mips_translate_c0("mthc0", rn, reg, sel);
5858 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5861 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5863 if (ctx->insn_flags & ISA_MIPS32R6) {
5864 tcg_gen_movi_tl(arg, 0);
5866 tcg_gen_movi_tl(arg, ~0);
5870 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5872 const char *rn = "invalid";
5875 check_insn(ctx, ISA_MIPS32);
5881 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5885 CP0_CHECK(ctx->insn_flags & ASE_MT);
5886 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5890 CP0_CHECK(ctx->insn_flags & ASE_MT);
5891 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5895 CP0_CHECK(ctx->insn_flags & ASE_MT);
5896 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5901 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5905 goto cp0_unimplemented;
5911 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5912 gen_helper_mfc0_random(arg, cpu_env);
5916 CP0_CHECK(ctx->insn_flags & ASE_MT);
5917 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5921 CP0_CHECK(ctx->insn_flags & ASE_MT);
5922 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5926 CP0_CHECK(ctx->insn_flags & ASE_MT);
5927 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5931 CP0_CHECK(ctx->insn_flags & ASE_MT);
5932 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5936 CP0_CHECK(ctx->insn_flags & ASE_MT);
5937 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5941 CP0_CHECK(ctx->insn_flags & ASE_MT);
5942 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5943 rn = "VPEScheFBack";
5946 CP0_CHECK(ctx->insn_flags & ASE_MT);
5947 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5951 goto cp0_unimplemented;
5958 TCGv_i64 tmp = tcg_temp_new_i64();
5959 tcg_gen_ld_i64(tmp, cpu_env,
5960 offsetof(CPUMIPSState, CP0_EntryLo0));
5961 #if defined(TARGET_MIPS64)
5963 /* Move RI/XI fields to bits 31:30 */
5964 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5965 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5968 gen_move_low32(arg, tmp);
5969 tcg_temp_free_i64(tmp);
5974 CP0_CHECK(ctx->insn_flags & ASE_MT);
5975 gen_helper_mfc0_tcstatus(arg, cpu_env);
5979 CP0_CHECK(ctx->insn_flags & ASE_MT);
5980 gen_helper_mfc0_tcbind(arg, cpu_env);
5984 CP0_CHECK(ctx->insn_flags & ASE_MT);
5985 gen_helper_mfc0_tcrestart(arg, cpu_env);
5989 CP0_CHECK(ctx->insn_flags & ASE_MT);
5990 gen_helper_mfc0_tchalt(arg, cpu_env);
5994 CP0_CHECK(ctx->insn_flags & ASE_MT);
5995 gen_helper_mfc0_tccontext(arg, cpu_env);
5999 CP0_CHECK(ctx->insn_flags & ASE_MT);
6000 gen_helper_mfc0_tcschedule(arg, cpu_env);
6004 CP0_CHECK(ctx->insn_flags & ASE_MT);
6005 gen_helper_mfc0_tcschefback(arg, cpu_env);
6009 goto cp0_unimplemented;
6016 TCGv_i64 tmp = tcg_temp_new_i64();
6017 tcg_gen_ld_i64(tmp, cpu_env,
6018 offsetof(CPUMIPSState, CP0_EntryLo1));
6019 #if defined(TARGET_MIPS64)
6021 /* Move RI/XI fields to bits 31:30 */
6022 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6023 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6026 gen_move_low32(arg, tmp);
6027 tcg_temp_free_i64(tmp);
6033 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6034 rn = "GlobalNumber";
6037 goto cp0_unimplemented;
6043 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6044 tcg_gen_ext32s_tl(arg, arg);
6048 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6049 rn = "ContextConfig";
6050 goto cp0_unimplemented;
6052 CP0_CHECK(ctx->ulri);
6053 tcg_gen_ld_tl(arg, cpu_env,
6054 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6055 tcg_gen_ext32s_tl(arg, arg);
6059 goto cp0_unimplemented;
6065 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6069 check_insn(ctx, ISA_MIPS32R2);
6070 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6075 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6076 tcg_gen_ext32s_tl(arg, arg);
6081 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6082 tcg_gen_ext32s_tl(arg, arg);
6087 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6088 tcg_gen_ext32s_tl(arg, arg);
6092 goto cp0_unimplemented;
6098 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6102 check_insn(ctx, ISA_MIPS32R2);
6103 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6107 check_insn(ctx, ISA_MIPS32R2);
6108 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6112 check_insn(ctx, ISA_MIPS32R2);
6113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6117 check_insn(ctx, ISA_MIPS32R2);
6118 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6122 check_insn(ctx, ISA_MIPS32R2);
6123 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6127 goto cp0_unimplemented;
6133 check_insn(ctx, ISA_MIPS32R2);
6134 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6138 goto cp0_unimplemented;
6144 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6145 tcg_gen_ext32s_tl(arg, arg);
6150 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6155 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6160 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6161 tcg_gen_andi_tl(arg, arg, ~0xffff);
6165 goto cp0_unimplemented;
6171 /* Mark as an IO operation because we read the time. */
6172 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6175 gen_helper_mfc0_count(arg, cpu_env);
6176 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6179 /* Break the TB to be able to take timer interrupts immediately
6180 after reading count. DISAS_STOP isn't sufficient, we need to
6181 ensure we break completely out of translated code. */
6182 gen_save_pc(ctx->base.pc_next + 4);
6183 ctx->base.is_jmp = DISAS_EXIT;
6186 /* 6,7 are implementation dependent */
6188 goto cp0_unimplemented;
6194 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6195 tcg_gen_ext32s_tl(arg, arg);
6199 goto cp0_unimplemented;
6205 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6208 /* 6,7 are implementation dependent */
6210 goto cp0_unimplemented;
6216 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6220 check_insn(ctx, ISA_MIPS32R2);
6221 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6225 check_insn(ctx, ISA_MIPS32R2);
6226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6230 check_insn(ctx, ISA_MIPS32R2);
6231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6235 goto cp0_unimplemented;
6241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6245 goto cp0_unimplemented;
6251 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6252 tcg_gen_ext32s_tl(arg, arg);
6256 goto cp0_unimplemented;
6262 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6266 check_insn(ctx, ISA_MIPS32R2);
6267 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6268 tcg_gen_ext32s_tl(arg, arg);
6272 check_insn(ctx, ISA_MIPS32R2);
6273 CP0_CHECK(ctx->cmgcr);
6274 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6275 tcg_gen_ext32s_tl(arg, arg);
6279 goto cp0_unimplemented;
6285 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6289 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6297 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6301 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6305 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6308 /* 6,7 are implementation dependent */
6310 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6318 goto cp0_unimplemented;
6324 gen_helper_mfc0_lladdr(arg, cpu_env);
6328 CP0_CHECK(ctx->mrp);
6329 gen_helper_mfc0_maar(arg, cpu_env);
6333 CP0_CHECK(ctx->mrp);
6334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6338 goto cp0_unimplemented;
6351 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6352 gen_helper_1e0i(mfc0_watchlo, arg, sel);
6356 goto cp0_unimplemented;
6369 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6370 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6374 goto cp0_unimplemented;
6380 #if defined(TARGET_MIPS64)
6381 check_insn(ctx, ISA_MIPS3);
6382 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6383 tcg_gen_ext32s_tl(arg, arg);
6388 goto cp0_unimplemented;
6392 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6393 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6396 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6400 goto cp0_unimplemented;
6404 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6405 rn = "'Diagnostic"; /* implementation dependent */
6410 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6414 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
6415 rn = "TraceControl";
6416 goto cp0_unimplemented;
6418 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
6419 rn = "TraceControl2";
6420 goto cp0_unimplemented;
6422 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
6423 rn = "UserTraceData";
6424 goto cp0_unimplemented;
6426 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
6428 goto cp0_unimplemented;
6430 goto cp0_unimplemented;
6437 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6438 tcg_gen_ext32s_tl(arg, arg);
6442 goto cp0_unimplemented;
6448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6449 rn = "Performance0";
6452 // gen_helper_mfc0_performance1(arg);
6453 rn = "Performance1";
6454 goto cp0_unimplemented;
6456 // gen_helper_mfc0_performance2(arg);
6457 rn = "Performance2";
6458 goto cp0_unimplemented;
6460 // gen_helper_mfc0_performance3(arg);
6461 rn = "Performance3";
6462 goto cp0_unimplemented;
6464 // gen_helper_mfc0_performance4(arg);
6465 rn = "Performance4";
6466 goto cp0_unimplemented;
6468 // gen_helper_mfc0_performance5(arg);
6469 rn = "Performance5";
6470 goto cp0_unimplemented;
6472 // gen_helper_mfc0_performance6(arg);
6473 rn = "Performance6";
6474 goto cp0_unimplemented;
6476 // gen_helper_mfc0_performance7(arg);
6477 rn = "Performance7";
6478 goto cp0_unimplemented;
6480 goto cp0_unimplemented;
6486 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6490 goto cp0_unimplemented;
6499 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6503 goto cp0_unimplemented;
6513 TCGv_i64 tmp = tcg_temp_new_i64();
6514 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6515 gen_move_low32(arg, tmp);
6516 tcg_temp_free_i64(tmp);
6524 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6528 goto cp0_unimplemented;
6537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6548 goto cp0_unimplemented;
6554 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6555 tcg_gen_ext32s_tl(arg, arg);
6559 goto cp0_unimplemented;
6566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6575 CP0_CHECK(ctx->kscrexist & (1 << sel));
6576 tcg_gen_ld_tl(arg, cpu_env,
6577 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6578 tcg_gen_ext32s_tl(arg, arg);
6582 goto cp0_unimplemented;
6586 goto cp0_unimplemented;
6588 trace_mips_translate_c0("mfc0", rn, reg, sel);
6592 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6593 gen_mfc0_unimplemented(ctx, arg);
6596 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6598 const char *rn = "invalid";
6601 check_insn(ctx, ISA_MIPS32);
6603 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6611 gen_helper_mtc0_index(cpu_env, arg);
6615 CP0_CHECK(ctx->insn_flags & ASE_MT);
6616 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6620 CP0_CHECK(ctx->insn_flags & ASE_MT);
6625 CP0_CHECK(ctx->insn_flags & ASE_MT);
6635 goto cp0_unimplemented;
6645 CP0_CHECK(ctx->insn_flags & ASE_MT);
6646 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6650 CP0_CHECK(ctx->insn_flags & ASE_MT);
6651 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6655 CP0_CHECK(ctx->insn_flags & ASE_MT);
6656 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6660 CP0_CHECK(ctx->insn_flags & ASE_MT);
6661 gen_helper_mtc0_yqmask(cpu_env, arg);
6665 CP0_CHECK(ctx->insn_flags & ASE_MT);
6666 tcg_gen_st_tl(arg, cpu_env,
6667 offsetof(CPUMIPSState, CP0_VPESchedule));
6671 CP0_CHECK(ctx->insn_flags & ASE_MT);
6672 tcg_gen_st_tl(arg, cpu_env,
6673 offsetof(CPUMIPSState, CP0_VPEScheFBack));
6674 rn = "VPEScheFBack";
6677 CP0_CHECK(ctx->insn_flags & ASE_MT);
6678 gen_helper_mtc0_vpeopt(cpu_env, arg);
6682 goto cp0_unimplemented;
6688 gen_helper_mtc0_entrylo0(cpu_env, arg);
6692 CP0_CHECK(ctx->insn_flags & ASE_MT);
6693 gen_helper_mtc0_tcstatus(cpu_env, arg);
6697 CP0_CHECK(ctx->insn_flags & ASE_MT);
6698 gen_helper_mtc0_tcbind(cpu_env, arg);
6702 CP0_CHECK(ctx->insn_flags & ASE_MT);
6703 gen_helper_mtc0_tcrestart(cpu_env, arg);
6707 CP0_CHECK(ctx->insn_flags & ASE_MT);
6708 gen_helper_mtc0_tchalt(cpu_env, arg);
6712 CP0_CHECK(ctx->insn_flags & ASE_MT);
6713 gen_helper_mtc0_tccontext(cpu_env, arg);
6717 CP0_CHECK(ctx->insn_flags & ASE_MT);
6718 gen_helper_mtc0_tcschedule(cpu_env, arg);
6722 CP0_CHECK(ctx->insn_flags & ASE_MT);
6723 gen_helper_mtc0_tcschefback(cpu_env, arg);
6727 goto cp0_unimplemented;
6733 gen_helper_mtc0_entrylo1(cpu_env, arg);
6739 rn = "GlobalNumber";
6742 goto cp0_unimplemented;
6748 gen_helper_mtc0_context(cpu_env, arg);
6752 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6753 rn = "ContextConfig";
6754 goto cp0_unimplemented;
6756 CP0_CHECK(ctx->ulri);
6757 tcg_gen_st_tl(arg, cpu_env,
6758 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6762 goto cp0_unimplemented;
6768 gen_helper_mtc0_pagemask(cpu_env, arg);
6772 check_insn(ctx, ISA_MIPS32R2);
6773 gen_helper_mtc0_pagegrain(cpu_env, arg);
6775 ctx->base.is_jmp = DISAS_STOP;
6779 gen_helper_mtc0_segctl0(cpu_env, arg);
6784 gen_helper_mtc0_segctl1(cpu_env, arg);
6789 gen_helper_mtc0_segctl2(cpu_env, arg);
6793 goto cp0_unimplemented;
6799 gen_helper_mtc0_wired(cpu_env, arg);
6803 check_insn(ctx, ISA_MIPS32R2);
6804 gen_helper_mtc0_srsconf0(cpu_env, arg);
6808 check_insn(ctx, ISA_MIPS32R2);
6809 gen_helper_mtc0_srsconf1(cpu_env, arg);
6813 check_insn(ctx, ISA_MIPS32R2);
6814 gen_helper_mtc0_srsconf2(cpu_env, arg);
6818 check_insn(ctx, ISA_MIPS32R2);
6819 gen_helper_mtc0_srsconf3(cpu_env, arg);
6823 check_insn(ctx, ISA_MIPS32R2);
6824 gen_helper_mtc0_srsconf4(cpu_env, arg);
6828 goto cp0_unimplemented;
6834 check_insn(ctx, ISA_MIPS32R2);
6835 gen_helper_mtc0_hwrena(cpu_env, arg);
6836 ctx->base.is_jmp = DISAS_STOP;
6840 goto cp0_unimplemented;
6862 goto cp0_unimplemented;
6868 gen_helper_mtc0_count(cpu_env, arg);
6871 /* 6,7 are implementation dependent */
6873 goto cp0_unimplemented;
6879 gen_helper_mtc0_entryhi(cpu_env, arg);
6883 goto cp0_unimplemented;
6889 gen_helper_mtc0_compare(cpu_env, arg);
6892 /* 6,7 are implementation dependent */
6894 goto cp0_unimplemented;
6900 save_cpu_state(ctx, 1);
6901 gen_helper_mtc0_status(cpu_env, arg);
6902 /* DISAS_STOP isn't good enough here, hflags may have changed. */
6903 gen_save_pc(ctx->base.pc_next + 4);
6904 ctx->base.is_jmp = DISAS_EXIT;
6908 check_insn(ctx, ISA_MIPS32R2);
6909 gen_helper_mtc0_intctl(cpu_env, arg);
6910 /* Stop translation as we may have switched the execution mode */
6911 ctx->base.is_jmp = DISAS_STOP;
6915 check_insn(ctx, ISA_MIPS32R2);
6916 gen_helper_mtc0_srsctl(cpu_env, arg);
6917 /* Stop translation as we may have switched the execution mode */
6918 ctx->base.is_jmp = DISAS_STOP;
6922 check_insn(ctx, ISA_MIPS32R2);
6923 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6924 /* Stop translation as we may have switched the execution mode */
6925 ctx->base.is_jmp = DISAS_STOP;
6929 goto cp0_unimplemented;
6935 save_cpu_state(ctx, 1);
6936 gen_helper_mtc0_cause(cpu_env, arg);
6937 /* Stop translation as we may have triggered an interrupt.
6938 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6939 * translated code to check for pending interrupts. */
6940 gen_save_pc(ctx->base.pc_next + 4);
6941 ctx->base.is_jmp = DISAS_EXIT;
6945 goto cp0_unimplemented;
6951 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6955 goto cp0_unimplemented;
6965 check_insn(ctx, ISA_MIPS32R2);
6966 gen_helper_mtc0_ebase(cpu_env, arg);
6970 goto cp0_unimplemented;
6976 gen_helper_mtc0_config0(cpu_env, arg);
6978 /* Stop translation as we may have switched the execution mode */
6979 ctx->base.is_jmp = DISAS_STOP;
6982 /* ignored, read only */
6986 gen_helper_mtc0_config2(cpu_env, arg);
6988 /* Stop translation as we may have switched the execution mode */
6989 ctx->base.is_jmp = DISAS_STOP;
6992 gen_helper_mtc0_config3(cpu_env, arg);
6994 /* Stop translation as we may have switched the execution mode */
6995 ctx->base.is_jmp = DISAS_STOP;
6998 gen_helper_mtc0_config4(cpu_env, arg);
7000 ctx->base.is_jmp = DISAS_STOP;
7003 gen_helper_mtc0_config5(cpu_env, arg);
7005 /* Stop translation as we may have switched the execution mode */
7006 ctx->base.is_jmp = DISAS_STOP;
7008 /* 6,7 are implementation dependent */
7018 rn = "Invalid config selector";
7019 goto cp0_unimplemented;
7025 gen_helper_mtc0_lladdr(cpu_env, arg);
7029 CP0_CHECK(ctx->mrp);
7030 gen_helper_mtc0_maar(cpu_env, arg);
7034 CP0_CHECK(ctx->mrp);
7035 gen_helper_mtc0_maari(cpu_env, arg);
7039 goto cp0_unimplemented;
7052 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7053 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7057 goto cp0_unimplemented;
7070 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7071 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7075 goto cp0_unimplemented;
7081 #if defined(TARGET_MIPS64)
7082 check_insn(ctx, ISA_MIPS3);
7083 gen_helper_mtc0_xcontext(cpu_env, arg);
7088 goto cp0_unimplemented;
7092 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7093 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7096 gen_helper_mtc0_framemask(cpu_env, arg);
7100 goto cp0_unimplemented;
7105 rn = "Diagnostic"; /* implementation dependent */
7110 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7111 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7112 gen_save_pc(ctx->base.pc_next + 4);
7113 ctx->base.is_jmp = DISAS_EXIT;
7117 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7118 rn = "TraceControl";
7119 /* Stop translation as we may have switched the execution mode */
7120 ctx->base.is_jmp = DISAS_STOP;
7121 goto cp0_unimplemented;
7123 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7124 rn = "TraceControl2";
7125 /* Stop translation as we may have switched the execution mode */
7126 ctx->base.is_jmp = DISAS_STOP;
7127 goto cp0_unimplemented;
7129 /* Stop translation as we may have switched the execution mode */
7130 ctx->base.is_jmp = DISAS_STOP;
7131 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7132 rn = "UserTraceData";
7133 /* Stop translation as we may have switched the execution mode */
7134 ctx->base.is_jmp = DISAS_STOP;
7135 goto cp0_unimplemented;
7137 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7138 /* Stop translation as we may have switched the execution mode */
7139 ctx->base.is_jmp = DISAS_STOP;
7141 goto cp0_unimplemented;
7143 goto cp0_unimplemented;
7150 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7154 goto cp0_unimplemented;
7160 gen_helper_mtc0_performance0(cpu_env, arg);
7161 rn = "Performance0";
7164 // gen_helper_mtc0_performance1(arg);
7165 rn = "Performance1";
7166 goto cp0_unimplemented;
7168 // gen_helper_mtc0_performance2(arg);
7169 rn = "Performance2";
7170 goto cp0_unimplemented;
7172 // gen_helper_mtc0_performance3(arg);
7173 rn = "Performance3";
7174 goto cp0_unimplemented;
7176 // gen_helper_mtc0_performance4(arg);
7177 rn = "Performance4";
7178 goto cp0_unimplemented;
7180 // gen_helper_mtc0_performance5(arg);
7181 rn = "Performance5";
7182 goto cp0_unimplemented;
7184 // gen_helper_mtc0_performance6(arg);
7185 rn = "Performance6";
7186 goto cp0_unimplemented;
7188 // gen_helper_mtc0_performance7(arg);
7189 rn = "Performance7";
7190 goto cp0_unimplemented;
7192 goto cp0_unimplemented;
7198 gen_helper_mtc0_errctl(cpu_env, arg);
7199 ctx->base.is_jmp = DISAS_STOP;
7203 goto cp0_unimplemented;
7216 goto cp0_unimplemented;
7225 gen_helper_mtc0_taglo(cpu_env, arg);
7232 gen_helper_mtc0_datalo(cpu_env, arg);
7236 goto cp0_unimplemented;
7245 gen_helper_mtc0_taghi(cpu_env, arg);
7252 gen_helper_mtc0_datahi(cpu_env, arg);
7257 goto cp0_unimplemented;
7263 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7267 goto cp0_unimplemented;
7274 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7283 CP0_CHECK(ctx->kscrexist & (1 << sel));
7284 tcg_gen_st_tl(arg, cpu_env,
7285 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7289 goto cp0_unimplemented;
7293 goto cp0_unimplemented;
7295 trace_mips_translate_c0("mtc0", rn, reg, sel);
7297 /* For simplicity assume that all writes can cause interrupts. */
7298 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7300 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
7301 * translated code to check for pending interrupts. */
7302 gen_save_pc(ctx->base.pc_next + 4);
7303 ctx->base.is_jmp = DISAS_EXIT;
7308 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7311 #if defined(TARGET_MIPS64)
7312 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7314 const char *rn = "invalid";
7317 check_insn(ctx, ISA_MIPS64);
7323 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7327 CP0_CHECK(ctx->insn_flags & ASE_MT);
7328 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7332 CP0_CHECK(ctx->insn_flags & ASE_MT);
7333 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7337 CP0_CHECK(ctx->insn_flags & ASE_MT);
7338 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7347 goto cp0_unimplemented;
7353 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7354 gen_helper_mfc0_random(arg, cpu_env);
7358 CP0_CHECK(ctx->insn_flags & ASE_MT);
7359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7363 CP0_CHECK(ctx->insn_flags & ASE_MT);
7364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7368 CP0_CHECK(ctx->insn_flags & ASE_MT);
7369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7373 CP0_CHECK(ctx->insn_flags & ASE_MT);
7374 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
7378 CP0_CHECK(ctx->insn_flags & ASE_MT);
7379 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7383 CP0_CHECK(ctx->insn_flags & ASE_MT);
7384 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7385 rn = "VPEScheFBack";
7388 CP0_CHECK(ctx->insn_flags & ASE_MT);
7389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7393 goto cp0_unimplemented;
7399 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7403 CP0_CHECK(ctx->insn_flags & ASE_MT);
7404 gen_helper_mfc0_tcstatus(arg, cpu_env);
7408 CP0_CHECK(ctx->insn_flags & ASE_MT);
7409 gen_helper_mfc0_tcbind(arg, cpu_env);
7413 CP0_CHECK(ctx->insn_flags & ASE_MT);
7414 gen_helper_dmfc0_tcrestart(arg, cpu_env);
7418 CP0_CHECK(ctx->insn_flags & ASE_MT);
7419 gen_helper_dmfc0_tchalt(arg, cpu_env);
7423 CP0_CHECK(ctx->insn_flags & ASE_MT);
7424 gen_helper_dmfc0_tccontext(arg, cpu_env);
7428 CP0_CHECK(ctx->insn_flags & ASE_MT);
7429 gen_helper_dmfc0_tcschedule(arg, cpu_env);
7433 CP0_CHECK(ctx->insn_flags & ASE_MT);
7434 gen_helper_dmfc0_tcschefback(arg, cpu_env);
7438 goto cp0_unimplemented;
7444 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7450 rn = "GlobalNumber";
7453 goto cp0_unimplemented;
7459 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7463 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
7464 rn = "ContextConfig";
7465 goto cp0_unimplemented;
7467 CP0_CHECK(ctx->ulri);
7468 tcg_gen_ld_tl(arg, cpu_env,
7469 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7473 goto cp0_unimplemented;
7479 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7483 check_insn(ctx, ISA_MIPS32R2);
7484 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7489 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7494 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7499 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7503 goto cp0_unimplemented;
7509 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7513 check_insn(ctx, ISA_MIPS32R2);
7514 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7518 check_insn(ctx, ISA_MIPS32R2);
7519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7523 check_insn(ctx, ISA_MIPS32R2);
7524 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7528 check_insn(ctx, ISA_MIPS32R2);
7529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7533 check_insn(ctx, ISA_MIPS32R2);
7534 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7538 goto cp0_unimplemented;
7544 check_insn(ctx, ISA_MIPS32R2);
7545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7549 goto cp0_unimplemented;
7555 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7571 tcg_gen_andi_tl(arg, arg, ~0xffff);
7575 goto cp0_unimplemented;
7581 /* Mark as an IO operation because we read the time. */
7582 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7585 gen_helper_mfc0_count(arg, cpu_env);
7586 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7589 /* Break the TB to be able to take timer interrupts immediately
7590 after reading count. DISAS_STOP isn't sufficient, we need to
7591 ensure we break completely out of translated code. */
7592 gen_save_pc(ctx->base.pc_next + 4);
7593 ctx->base.is_jmp = DISAS_EXIT;
7596 /* 6,7 are implementation dependent */
7598 goto cp0_unimplemented;
7604 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7608 goto cp0_unimplemented;
7614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7617 /* 6,7 are implementation dependent */
7619 goto cp0_unimplemented;
7625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7629 check_insn(ctx, ISA_MIPS32R2);
7630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7634 check_insn(ctx, ISA_MIPS32R2);
7635 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7639 check_insn(ctx, ISA_MIPS32R2);
7640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7644 goto cp0_unimplemented;
7650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7654 goto cp0_unimplemented;
7660 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7664 goto cp0_unimplemented;
7670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7674 check_insn(ctx, ISA_MIPS32R2);
7675 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7679 check_insn(ctx, ISA_MIPS32R2);
7680 CP0_CHECK(ctx->cmgcr);
7681 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7685 goto cp0_unimplemented;
7691 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7695 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7699 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7703 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7707 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7711 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7714 /* 6,7 are implementation dependent */
7716 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7720 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7724 goto cp0_unimplemented;
7730 gen_helper_dmfc0_lladdr(arg, cpu_env);
7734 CP0_CHECK(ctx->mrp);
7735 gen_helper_dmfc0_maar(arg, cpu_env);
7739 CP0_CHECK(ctx->mrp);
7740 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7744 goto cp0_unimplemented;
7757 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7758 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7762 goto cp0_unimplemented;
7775 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7776 gen_helper_1e0i(mfc0_watchhi, arg, sel);
7780 goto cp0_unimplemented;
7786 check_insn(ctx, ISA_MIPS3);
7787 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7791 goto cp0_unimplemented;
7795 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7796 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7803 goto cp0_unimplemented;
7807 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7808 rn = "'Diagnostic"; /* implementation dependent */
7813 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7817 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
7818 rn = "TraceControl";
7819 goto cp0_unimplemented;
7821 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
7822 rn = "TraceControl2";
7823 goto cp0_unimplemented;
7825 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
7826 rn = "UserTraceData";
7827 goto cp0_unimplemented;
7829 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
7831 goto cp0_unimplemented;
7833 goto cp0_unimplemented;
7840 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7844 goto cp0_unimplemented;
7850 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7851 rn = "Performance0";
7854 // gen_helper_dmfc0_performance1(arg);
7855 rn = "Performance1";
7856 goto cp0_unimplemented;
7858 // gen_helper_dmfc0_performance2(arg);
7859 rn = "Performance2";
7860 goto cp0_unimplemented;
7862 // gen_helper_dmfc0_performance3(arg);
7863 rn = "Performance3";
7864 goto cp0_unimplemented;
7866 // gen_helper_dmfc0_performance4(arg);
7867 rn = "Performance4";
7868 goto cp0_unimplemented;
7870 // gen_helper_dmfc0_performance5(arg);
7871 rn = "Performance5";
7872 goto cp0_unimplemented;
7874 // gen_helper_dmfc0_performance6(arg);
7875 rn = "Performance6";
7876 goto cp0_unimplemented;
7878 // gen_helper_dmfc0_performance7(arg);
7879 rn = "Performance7";
7880 goto cp0_unimplemented;
7882 goto cp0_unimplemented;
7888 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7892 goto cp0_unimplemented;
7902 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7906 goto cp0_unimplemented;
7915 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7922 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7926 goto cp0_unimplemented;
7935 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7942 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7946 goto cp0_unimplemented;
7952 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7956 goto cp0_unimplemented;
7963 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7972 CP0_CHECK(ctx->kscrexist & (1 << sel));
7973 tcg_gen_ld_tl(arg, cpu_env,
7974 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7978 goto cp0_unimplemented;
7982 goto cp0_unimplemented;
7984 trace_mips_translate_c0("dmfc0", rn, reg, sel);
7988 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
7989 gen_mfc0_unimplemented(ctx, arg);
7992 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7994 const char *rn = "invalid";
7997 check_insn(ctx, ISA_MIPS64);
7999 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8007 gen_helper_mtc0_index(cpu_env, arg);
8011 CP0_CHECK(ctx->insn_flags & ASE_MT);
8012 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8016 CP0_CHECK(ctx->insn_flags & ASE_MT);
8021 CP0_CHECK(ctx->insn_flags & ASE_MT);
8031 goto cp0_unimplemented;
8041 CP0_CHECK(ctx->insn_flags & ASE_MT);
8042 gen_helper_mtc0_vpecontrol(cpu_env, arg);
8046 CP0_CHECK(ctx->insn_flags & ASE_MT);
8047 gen_helper_mtc0_vpeconf0(cpu_env, arg);
8051 CP0_CHECK(ctx->insn_flags & ASE_MT);
8052 gen_helper_mtc0_vpeconf1(cpu_env, arg);
8056 CP0_CHECK(ctx->insn_flags & ASE_MT);
8057 gen_helper_mtc0_yqmask(cpu_env, arg);
8061 CP0_CHECK(ctx->insn_flags & ASE_MT);
8062 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8066 CP0_CHECK(ctx->insn_flags & ASE_MT);
8067 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8068 rn = "VPEScheFBack";
8071 CP0_CHECK(ctx->insn_flags & ASE_MT);
8072 gen_helper_mtc0_vpeopt(cpu_env, arg);
8076 goto cp0_unimplemented;
8082 gen_helper_dmtc0_entrylo0(cpu_env, arg);
8086 CP0_CHECK(ctx->insn_flags & ASE_MT);
8087 gen_helper_mtc0_tcstatus(cpu_env, arg);
8091 CP0_CHECK(ctx->insn_flags & ASE_MT);
8092 gen_helper_mtc0_tcbind(cpu_env, arg);
8096 CP0_CHECK(ctx->insn_flags & ASE_MT);
8097 gen_helper_mtc0_tcrestart(cpu_env, arg);
8101 CP0_CHECK(ctx->insn_flags & ASE_MT);
8102 gen_helper_mtc0_tchalt(cpu_env, arg);
8106 CP0_CHECK(ctx->insn_flags & ASE_MT);
8107 gen_helper_mtc0_tccontext(cpu_env, arg);
8111 CP0_CHECK(ctx->insn_flags & ASE_MT);
8112 gen_helper_mtc0_tcschedule(cpu_env, arg);
8116 CP0_CHECK(ctx->insn_flags & ASE_MT);
8117 gen_helper_mtc0_tcschefback(cpu_env, arg);
8121 goto cp0_unimplemented;
8127 gen_helper_dmtc0_entrylo1(cpu_env, arg);
8133 rn = "GlobalNumber";
8136 goto cp0_unimplemented;
8142 gen_helper_mtc0_context(cpu_env, arg);
8146 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8147 rn = "ContextConfig";
8148 goto cp0_unimplemented;
8150 CP0_CHECK(ctx->ulri);
8151 tcg_gen_st_tl(arg, cpu_env,
8152 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8156 goto cp0_unimplemented;
8162 gen_helper_mtc0_pagemask(cpu_env, arg);
8166 check_insn(ctx, ISA_MIPS32R2);
8167 gen_helper_mtc0_pagegrain(cpu_env, arg);
8172 gen_helper_mtc0_segctl0(cpu_env, arg);
8177 gen_helper_mtc0_segctl1(cpu_env, arg);
8182 gen_helper_mtc0_segctl2(cpu_env, arg);
8186 goto cp0_unimplemented;
8192 gen_helper_mtc0_wired(cpu_env, arg);
8196 check_insn(ctx, ISA_MIPS32R2);
8197 gen_helper_mtc0_srsconf0(cpu_env, arg);
8201 check_insn(ctx, ISA_MIPS32R2);
8202 gen_helper_mtc0_srsconf1(cpu_env, arg);
8206 check_insn(ctx, ISA_MIPS32R2);
8207 gen_helper_mtc0_srsconf2(cpu_env, arg);
8211 check_insn(ctx, ISA_MIPS32R2);
8212 gen_helper_mtc0_srsconf3(cpu_env, arg);
8216 check_insn(ctx, ISA_MIPS32R2);
8217 gen_helper_mtc0_srsconf4(cpu_env, arg);
8221 goto cp0_unimplemented;
8227 check_insn(ctx, ISA_MIPS32R2);
8228 gen_helper_mtc0_hwrena(cpu_env, arg);
8229 ctx->base.is_jmp = DISAS_STOP;
8233 goto cp0_unimplemented;
8255 goto cp0_unimplemented;
8261 gen_helper_mtc0_count(cpu_env, arg);
8264 /* 6,7 are implementation dependent */
8266 goto cp0_unimplemented;
8268 /* Stop translation as we may have switched the execution mode */
8269 ctx->base.is_jmp = DISAS_STOP;
8274 gen_helper_mtc0_entryhi(cpu_env, arg);
8278 goto cp0_unimplemented;
8284 gen_helper_mtc0_compare(cpu_env, arg);
8287 /* 6,7 are implementation dependent */
8289 goto cp0_unimplemented;
8291 /* Stop translation as we may have switched the execution mode */
8292 ctx->base.is_jmp = DISAS_STOP;
8297 save_cpu_state(ctx, 1);
8298 gen_helper_mtc0_status(cpu_env, arg);
8299 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8300 gen_save_pc(ctx->base.pc_next + 4);
8301 ctx->base.is_jmp = DISAS_EXIT;
8305 check_insn(ctx, ISA_MIPS32R2);
8306 gen_helper_mtc0_intctl(cpu_env, arg);
8307 /* Stop translation as we may have switched the execution mode */
8308 ctx->base.is_jmp = DISAS_STOP;
8312 check_insn(ctx, ISA_MIPS32R2);
8313 gen_helper_mtc0_srsctl(cpu_env, arg);
8314 /* Stop translation as we may have switched the execution mode */
8315 ctx->base.is_jmp = DISAS_STOP;
8319 check_insn(ctx, ISA_MIPS32R2);
8320 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8321 /* Stop translation as we may have switched the execution mode */
8322 ctx->base.is_jmp = DISAS_STOP;
8326 goto cp0_unimplemented;
8332 save_cpu_state(ctx, 1);
8333 gen_helper_mtc0_cause(cpu_env, arg);
8334 /* Stop translation as we may have triggered an interrupt.
8335 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8336 * translated code to check for pending interrupts. */
8337 gen_save_pc(ctx->base.pc_next + 4);
8338 ctx->base.is_jmp = DISAS_EXIT;
8342 goto cp0_unimplemented;
8348 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8352 goto cp0_unimplemented;
8362 check_insn(ctx, ISA_MIPS32R2);
8363 gen_helper_mtc0_ebase(cpu_env, arg);
8367 goto cp0_unimplemented;
8373 gen_helper_mtc0_config0(cpu_env, arg);
8375 /* Stop translation as we may have switched the execution mode */
8376 ctx->base.is_jmp = DISAS_STOP;
8379 /* ignored, read only */
8383 gen_helper_mtc0_config2(cpu_env, arg);
8385 /* Stop translation as we may have switched the execution mode */
8386 ctx->base.is_jmp = DISAS_STOP;
8389 gen_helper_mtc0_config3(cpu_env, arg);
8391 /* Stop translation as we may have switched the execution mode */
8392 ctx->base.is_jmp = DISAS_STOP;
8395 /* currently ignored */
8399 gen_helper_mtc0_config5(cpu_env, arg);
8401 /* Stop translation as we may have switched the execution mode */
8402 ctx->base.is_jmp = DISAS_STOP;
8404 /* 6,7 are implementation dependent */
8406 rn = "Invalid config selector";
8407 goto cp0_unimplemented;
8413 gen_helper_mtc0_lladdr(cpu_env, arg);
8417 CP0_CHECK(ctx->mrp);
8418 gen_helper_mtc0_maar(cpu_env, arg);
8422 CP0_CHECK(ctx->mrp);
8423 gen_helper_mtc0_maari(cpu_env, arg);
8427 goto cp0_unimplemented;
8440 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8441 gen_helper_0e1i(mtc0_watchlo, arg, sel);
8445 goto cp0_unimplemented;
8458 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8459 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8463 goto cp0_unimplemented;
8469 check_insn(ctx, ISA_MIPS3);
8470 gen_helper_mtc0_xcontext(cpu_env, arg);
8474 goto cp0_unimplemented;
8478 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8479 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8482 gen_helper_mtc0_framemask(cpu_env, arg);
8486 goto cp0_unimplemented;
8491 rn = "Diagnostic"; /* implementation dependent */
8496 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8497 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8498 gen_save_pc(ctx->base.pc_next + 4);
8499 ctx->base.is_jmp = DISAS_EXIT;
8503 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8504 /* Stop translation as we may have switched the execution mode */
8505 ctx->base.is_jmp = DISAS_STOP;
8506 rn = "TraceControl";
8507 goto cp0_unimplemented;
8509 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8510 /* Stop translation as we may have switched the execution mode */
8511 ctx->base.is_jmp = DISAS_STOP;
8512 rn = "TraceControl2";
8513 goto cp0_unimplemented;
8515 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8516 /* Stop translation as we may have switched the execution mode */
8517 ctx->base.is_jmp = DISAS_STOP;
8518 rn = "UserTraceData";
8519 goto cp0_unimplemented;
8521 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8522 /* Stop translation as we may have switched the execution mode */
8523 ctx->base.is_jmp = DISAS_STOP;
8525 goto cp0_unimplemented;
8527 goto cp0_unimplemented;
8534 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8538 goto cp0_unimplemented;
8544 gen_helper_mtc0_performance0(cpu_env, arg);
8545 rn = "Performance0";
8548 // gen_helper_mtc0_performance1(cpu_env, arg);
8549 rn = "Performance1";
8550 goto cp0_unimplemented;
8552 // gen_helper_mtc0_performance2(cpu_env, arg);
8553 rn = "Performance2";
8554 goto cp0_unimplemented;
8556 // gen_helper_mtc0_performance3(cpu_env, arg);
8557 rn = "Performance3";
8558 goto cp0_unimplemented;
8560 // gen_helper_mtc0_performance4(cpu_env, arg);
8561 rn = "Performance4";
8562 goto cp0_unimplemented;
8564 // gen_helper_mtc0_performance5(cpu_env, arg);
8565 rn = "Performance5";
8566 goto cp0_unimplemented;
8568 // gen_helper_mtc0_performance6(cpu_env, arg);
8569 rn = "Performance6";
8570 goto cp0_unimplemented;
8572 // gen_helper_mtc0_performance7(cpu_env, arg);
8573 rn = "Performance7";
8574 goto cp0_unimplemented;
8576 goto cp0_unimplemented;
8582 gen_helper_mtc0_errctl(cpu_env, arg);
8583 ctx->base.is_jmp = DISAS_STOP;
8587 goto cp0_unimplemented;
8600 goto cp0_unimplemented;
8609 gen_helper_mtc0_taglo(cpu_env, arg);
8616 gen_helper_mtc0_datalo(cpu_env, arg);
8620 goto cp0_unimplemented;
8629 gen_helper_mtc0_taghi(cpu_env, arg);
8636 gen_helper_mtc0_datahi(cpu_env, arg);
8641 goto cp0_unimplemented;
8647 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8651 goto cp0_unimplemented;
8658 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8667 CP0_CHECK(ctx->kscrexist & (1 << sel));
8668 tcg_gen_st_tl(arg, cpu_env,
8669 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8673 goto cp0_unimplemented;
8677 goto cp0_unimplemented;
8679 trace_mips_translate_c0("dmtc0", rn, reg, sel);
8681 /* For simplicity assume that all writes can cause interrupts. */
8682 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8684 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8685 * translated code to check for pending interrupts. */
8686 gen_save_pc(ctx->base.pc_next + 4);
8687 ctx->base.is_jmp = DISAS_EXIT;
8692 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8694 #endif /* TARGET_MIPS64 */
8696 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8697 int u, int sel, int h)
8699 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8700 TCGv t0 = tcg_temp_local_new();
8702 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8703 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8704 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
8705 tcg_gen_movi_tl(t0, -1);
8706 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8707 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8708 tcg_gen_movi_tl(t0, -1);
8714 gen_helper_mftc0_vpecontrol(t0, cpu_env);
8717 gen_helper_mftc0_vpeconf0(t0, cpu_env);
8727 gen_helper_mftc0_tcstatus(t0, cpu_env);
8730 gen_helper_mftc0_tcbind(t0, cpu_env);
8733 gen_helper_mftc0_tcrestart(t0, cpu_env);
8736 gen_helper_mftc0_tchalt(t0, cpu_env);
8739 gen_helper_mftc0_tccontext(t0, cpu_env);
8742 gen_helper_mftc0_tcschedule(t0, cpu_env);
8745 gen_helper_mftc0_tcschefback(t0, cpu_env);
8748 gen_mfc0(ctx, t0, rt, sel);
8755 gen_helper_mftc0_entryhi(t0, cpu_env);
8758 gen_mfc0(ctx, t0, rt, sel);
8764 gen_helper_mftc0_status(t0, cpu_env);
8767 gen_mfc0(ctx, t0, rt, sel);
8773 gen_helper_mftc0_cause(t0, cpu_env);
8783 gen_helper_mftc0_epc(t0, cpu_env);
8793 gen_helper_mftc0_ebase(t0, cpu_env);
8810 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8820 gen_helper_mftc0_debug(t0, cpu_env);
8823 gen_mfc0(ctx, t0, rt, sel);
8828 gen_mfc0(ctx, t0, rt, sel);
8830 } else switch (sel) {
8831 /* GPR registers. */
8833 gen_helper_1e0i(mftgpr, t0, rt);
8835 /* Auxiliary CPU registers */
8839 gen_helper_1e0i(mftlo, t0, 0);
8842 gen_helper_1e0i(mfthi, t0, 0);
8845 gen_helper_1e0i(mftacx, t0, 0);
8848 gen_helper_1e0i(mftlo, t0, 1);
8851 gen_helper_1e0i(mfthi, t0, 1);
8854 gen_helper_1e0i(mftacx, t0, 1);
8857 gen_helper_1e0i(mftlo, t0, 2);
8860 gen_helper_1e0i(mfthi, t0, 2);
8863 gen_helper_1e0i(mftacx, t0, 2);
8866 gen_helper_1e0i(mftlo, t0, 3);
8869 gen_helper_1e0i(mfthi, t0, 3);
8872 gen_helper_1e0i(mftacx, t0, 3);
8875 gen_helper_mftdsp(t0, cpu_env);
8881 /* Floating point (COP1). */
8883 /* XXX: For now we support only a single FPU context. */
8885 TCGv_i32 fp0 = tcg_temp_new_i32();
8887 gen_load_fpr32(ctx, fp0, rt);
8888 tcg_gen_ext_i32_tl(t0, fp0);
8889 tcg_temp_free_i32(fp0);
8891 TCGv_i32 fp0 = tcg_temp_new_i32();
8893 gen_load_fpr32h(ctx, fp0, rt);
8894 tcg_gen_ext_i32_tl(t0, fp0);
8895 tcg_temp_free_i32(fp0);
8899 /* XXX: For now we support only a single FPU context. */
8900 gen_helper_1e0i(cfc1, t0, rt);
8902 /* COP2: Not implemented. */
8909 trace_mips_translate_tr("mftr", rt, u, sel, h);
8910 gen_store_gpr(t0, rd);
8916 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8917 generate_exception_end(ctx, EXCP_RI);
8920 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8921 int u, int sel, int h)
8923 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8924 TCGv t0 = tcg_temp_local_new();
8926 gen_load_gpr(t0, rt);
8927 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8928 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8929 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
8931 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8932 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8939 gen_helper_mttc0_vpecontrol(cpu_env, t0);
8942 gen_helper_mttc0_vpeconf0(cpu_env, t0);
8952 gen_helper_mttc0_tcstatus(cpu_env, t0);
8955 gen_helper_mttc0_tcbind(cpu_env, t0);
8958 gen_helper_mttc0_tcrestart(cpu_env, t0);
8961 gen_helper_mttc0_tchalt(cpu_env, t0);
8964 gen_helper_mttc0_tccontext(cpu_env, t0);
8967 gen_helper_mttc0_tcschedule(cpu_env, t0);
8970 gen_helper_mttc0_tcschefback(cpu_env, t0);
8973 gen_mtc0(ctx, t0, rd, sel);
8980 gen_helper_mttc0_entryhi(cpu_env, t0);
8983 gen_mtc0(ctx, t0, rd, sel);
8989 gen_helper_mttc0_status(cpu_env, t0);
8992 gen_mtc0(ctx, t0, rd, sel);
8998 gen_helper_mttc0_cause(cpu_env, t0);
9008 gen_helper_mttc0_ebase(cpu_env, t0);
9018 gen_helper_mttc0_debug(cpu_env, t0);
9021 gen_mtc0(ctx, t0, rd, sel);
9026 gen_mtc0(ctx, t0, rd, sel);
9028 } else switch (sel) {
9029 /* GPR registers. */
9031 gen_helper_0e1i(mttgpr, t0, rd);
9033 /* Auxiliary CPU registers */
9037 gen_helper_0e1i(mttlo, t0, 0);
9040 gen_helper_0e1i(mtthi, t0, 0);
9043 gen_helper_0e1i(mttacx, t0, 0);
9046 gen_helper_0e1i(mttlo, t0, 1);
9049 gen_helper_0e1i(mtthi, t0, 1);
9052 gen_helper_0e1i(mttacx, t0, 1);
9055 gen_helper_0e1i(mttlo, t0, 2);
9058 gen_helper_0e1i(mtthi, t0, 2);
9061 gen_helper_0e1i(mttacx, t0, 2);
9064 gen_helper_0e1i(mttlo, t0, 3);
9067 gen_helper_0e1i(mtthi, t0, 3);
9070 gen_helper_0e1i(mttacx, t0, 3);
9073 gen_helper_mttdsp(cpu_env, t0);
9079 /* Floating point (COP1). */
9081 /* XXX: For now we support only a single FPU context. */
9083 TCGv_i32 fp0 = tcg_temp_new_i32();
9085 tcg_gen_trunc_tl_i32(fp0, t0);
9086 gen_store_fpr32(ctx, fp0, rd);
9087 tcg_temp_free_i32(fp0);
9089 TCGv_i32 fp0 = tcg_temp_new_i32();
9091 tcg_gen_trunc_tl_i32(fp0, t0);
9092 gen_store_fpr32h(ctx, fp0, rd);
9093 tcg_temp_free_i32(fp0);
9097 /* XXX: For now we support only a single FPU context. */
9099 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9101 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9102 tcg_temp_free_i32(fs_tmp);
9104 /* Stop translation as we may have changed hflags */
9105 ctx->base.is_jmp = DISAS_STOP;
9107 /* COP2: Not implemented. */
9114 trace_mips_translate_tr("mttr", rd, u, sel, h);
9120 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9121 generate_exception_end(ctx, EXCP_RI);
9124 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9126 const char *opn = "ldst";
9128 check_cp0_enabled(ctx);
9135 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9140 TCGv t0 = tcg_temp_new();
9142 gen_load_gpr(t0, rt);
9143 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9148 #if defined(TARGET_MIPS64)
9150 check_insn(ctx, ISA_MIPS3);
9155 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9159 check_insn(ctx, ISA_MIPS3);
9161 TCGv t0 = tcg_temp_new();
9163 gen_load_gpr(t0, rt);
9164 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9176 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9182 TCGv t0 = tcg_temp_new();
9183 gen_load_gpr(t0, rt);
9184 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9190 check_cp0_enabled(ctx);
9195 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9196 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9200 check_cp0_enabled(ctx);
9201 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9202 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9207 if (!env->tlb->helper_tlbwi)
9209 gen_helper_tlbwi(cpu_env);
9214 if (!env->tlb->helper_tlbinv) {
9217 gen_helper_tlbinv(cpu_env);
9218 } /* treat as nop if TLBINV not supported */
9223 if (!env->tlb->helper_tlbinvf) {
9226 gen_helper_tlbinvf(cpu_env);
9227 } /* treat as nop if TLBINV not supported */
9231 if (!env->tlb->helper_tlbwr)
9233 gen_helper_tlbwr(cpu_env);
9237 if (!env->tlb->helper_tlbp)
9239 gen_helper_tlbp(cpu_env);
9243 if (!env->tlb->helper_tlbr)
9245 gen_helper_tlbr(cpu_env);
9247 case OPC_ERET: /* OPC_ERETNC */
9248 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9249 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9252 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9253 if (ctx->opcode & (1 << bit_shift)) {
9256 check_insn(ctx, ISA_MIPS32R5);
9257 gen_helper_eretnc(cpu_env);
9261 check_insn(ctx, ISA_MIPS2);
9262 gen_helper_eret(cpu_env);
9264 ctx->base.is_jmp = DISAS_EXIT;
9269 check_insn(ctx, ISA_MIPS32);
9270 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9271 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9274 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9276 generate_exception_end(ctx, EXCP_RI);
9278 gen_helper_deret(cpu_env);
9279 ctx->base.is_jmp = DISAS_EXIT;
9284 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
9285 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9286 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9289 /* If we get an exception, we want to restart at next instruction */
9290 ctx->base.pc_next += 4;
9291 save_cpu_state(ctx, 1);
9292 ctx->base.pc_next -= 4;
9293 gen_helper_wait(cpu_env);
9294 ctx->base.is_jmp = DISAS_NORETURN;
9299 generate_exception_end(ctx, EXCP_RI);
9302 (void)opn; /* avoid a compiler warning */
9304 #endif /* !CONFIG_USER_ONLY */
9306 /* CP1 Branches (before delay slot) */
9307 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9308 int32_t cc, int32_t offset)
9310 target_ulong btarget;
9311 TCGv_i32 t0 = tcg_temp_new_i32();
9313 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9314 generate_exception_end(ctx, EXCP_RI);
9319 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
9321 btarget = ctx->base.pc_next + 4 + offset;
9325 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9326 tcg_gen_not_i32(t0, t0);
9327 tcg_gen_andi_i32(t0, t0, 1);
9328 tcg_gen_extu_i32_tl(bcond, t0);
9331 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9332 tcg_gen_not_i32(t0, t0);
9333 tcg_gen_andi_i32(t0, t0, 1);
9334 tcg_gen_extu_i32_tl(bcond, t0);
9337 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9338 tcg_gen_andi_i32(t0, t0, 1);
9339 tcg_gen_extu_i32_tl(bcond, t0);
9342 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9343 tcg_gen_andi_i32(t0, t0, 1);
9344 tcg_gen_extu_i32_tl(bcond, t0);
9346 ctx->hflags |= MIPS_HFLAG_BL;
9350 TCGv_i32 t1 = tcg_temp_new_i32();
9351 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9352 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9353 tcg_gen_nand_i32(t0, t0, t1);
9354 tcg_temp_free_i32(t1);
9355 tcg_gen_andi_i32(t0, t0, 1);
9356 tcg_gen_extu_i32_tl(bcond, t0);
9361 TCGv_i32 t1 = tcg_temp_new_i32();
9362 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9363 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9364 tcg_gen_or_i32(t0, t0, t1);
9365 tcg_temp_free_i32(t1);
9366 tcg_gen_andi_i32(t0, t0, 1);
9367 tcg_gen_extu_i32_tl(bcond, t0);
9372 TCGv_i32 t1 = tcg_temp_new_i32();
9373 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9374 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9375 tcg_gen_and_i32(t0, t0, t1);
9376 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9377 tcg_gen_and_i32(t0, t0, t1);
9378 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9379 tcg_gen_nand_i32(t0, t0, t1);
9380 tcg_temp_free_i32(t1);
9381 tcg_gen_andi_i32(t0, t0, 1);
9382 tcg_gen_extu_i32_tl(bcond, t0);
9387 TCGv_i32 t1 = tcg_temp_new_i32();
9388 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9389 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9390 tcg_gen_or_i32(t0, t0, t1);
9391 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9392 tcg_gen_or_i32(t0, t0, t1);
9393 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9394 tcg_gen_or_i32(t0, t0, t1);
9395 tcg_temp_free_i32(t1);
9396 tcg_gen_andi_i32(t0, t0, 1);
9397 tcg_gen_extu_i32_tl(bcond, t0);
9400 ctx->hflags |= MIPS_HFLAG_BC;
9403 MIPS_INVAL("cp1 cond branch");
9404 generate_exception_end(ctx, EXCP_RI);
9407 ctx->btarget = btarget;
9408 ctx->hflags |= MIPS_HFLAG_BDS32;
9410 tcg_temp_free_i32(t0);
9413 /* R6 CP1 Branches */
9414 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9415 int32_t ft, int32_t offset,
9418 target_ulong btarget;
9419 TCGv_i64 t0 = tcg_temp_new_i64();
9421 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9422 #ifdef MIPS_DEBUG_DISAS
9423 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9424 "\n", ctx->base.pc_next);
9426 generate_exception_end(ctx, EXCP_RI);
9430 gen_load_fpr64(ctx, t0, ft);
9431 tcg_gen_andi_i64(t0, t0, 1);
9433 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9437 tcg_gen_xori_i64(t0, t0, 1);
9438 ctx->hflags |= MIPS_HFLAG_BC;
9441 /* t0 already set */
9442 ctx->hflags |= MIPS_HFLAG_BC;
9445 MIPS_INVAL("cp1 cond branch");
9446 generate_exception_end(ctx, EXCP_RI);
9450 tcg_gen_trunc_i64_tl(bcond, t0);
9452 ctx->btarget = btarget;
9454 switch (delayslot_size) {
9456 ctx->hflags |= MIPS_HFLAG_BDS16;
9459 ctx->hflags |= MIPS_HFLAG_BDS32;
9464 tcg_temp_free_i64(t0);
9467 /* Coprocessor 1 (FPU) */
9469 #define FOP(func, fmt) (((fmt) << 21) | (func))
9472 OPC_ADD_S = FOP(0, FMT_S),
9473 OPC_SUB_S = FOP(1, FMT_S),
9474 OPC_MUL_S = FOP(2, FMT_S),
9475 OPC_DIV_S = FOP(3, FMT_S),
9476 OPC_SQRT_S = FOP(4, FMT_S),
9477 OPC_ABS_S = FOP(5, FMT_S),
9478 OPC_MOV_S = FOP(6, FMT_S),
9479 OPC_NEG_S = FOP(7, FMT_S),
9480 OPC_ROUND_L_S = FOP(8, FMT_S),
9481 OPC_TRUNC_L_S = FOP(9, FMT_S),
9482 OPC_CEIL_L_S = FOP(10, FMT_S),
9483 OPC_FLOOR_L_S = FOP(11, FMT_S),
9484 OPC_ROUND_W_S = FOP(12, FMT_S),
9485 OPC_TRUNC_W_S = FOP(13, FMT_S),
9486 OPC_CEIL_W_S = FOP(14, FMT_S),
9487 OPC_FLOOR_W_S = FOP(15, FMT_S),
9488 OPC_SEL_S = FOP(16, FMT_S),
9489 OPC_MOVCF_S = FOP(17, FMT_S),
9490 OPC_MOVZ_S = FOP(18, FMT_S),
9491 OPC_MOVN_S = FOP(19, FMT_S),
9492 OPC_SELEQZ_S = FOP(20, FMT_S),
9493 OPC_RECIP_S = FOP(21, FMT_S),
9494 OPC_RSQRT_S = FOP(22, FMT_S),
9495 OPC_SELNEZ_S = FOP(23, FMT_S),
9496 OPC_MADDF_S = FOP(24, FMT_S),
9497 OPC_MSUBF_S = FOP(25, FMT_S),
9498 OPC_RINT_S = FOP(26, FMT_S),
9499 OPC_CLASS_S = FOP(27, FMT_S),
9500 OPC_MIN_S = FOP(28, FMT_S),
9501 OPC_RECIP2_S = FOP(28, FMT_S),
9502 OPC_MINA_S = FOP(29, FMT_S),
9503 OPC_RECIP1_S = FOP(29, FMT_S),
9504 OPC_MAX_S = FOP(30, FMT_S),
9505 OPC_RSQRT1_S = FOP(30, FMT_S),
9506 OPC_MAXA_S = FOP(31, FMT_S),
9507 OPC_RSQRT2_S = FOP(31, FMT_S),
9508 OPC_CVT_D_S = FOP(33, FMT_S),
9509 OPC_CVT_W_S = FOP(36, FMT_S),
9510 OPC_CVT_L_S = FOP(37, FMT_S),
9511 OPC_CVT_PS_S = FOP(38, FMT_S),
9512 OPC_CMP_F_S = FOP (48, FMT_S),
9513 OPC_CMP_UN_S = FOP (49, FMT_S),
9514 OPC_CMP_EQ_S = FOP (50, FMT_S),
9515 OPC_CMP_UEQ_S = FOP (51, FMT_S),
9516 OPC_CMP_OLT_S = FOP (52, FMT_S),
9517 OPC_CMP_ULT_S = FOP (53, FMT_S),
9518 OPC_CMP_OLE_S = FOP (54, FMT_S),
9519 OPC_CMP_ULE_S = FOP (55, FMT_S),
9520 OPC_CMP_SF_S = FOP (56, FMT_S),
9521 OPC_CMP_NGLE_S = FOP (57, FMT_S),
9522 OPC_CMP_SEQ_S = FOP (58, FMT_S),
9523 OPC_CMP_NGL_S = FOP (59, FMT_S),
9524 OPC_CMP_LT_S = FOP (60, FMT_S),
9525 OPC_CMP_NGE_S = FOP (61, FMT_S),
9526 OPC_CMP_LE_S = FOP (62, FMT_S),
9527 OPC_CMP_NGT_S = FOP (63, FMT_S),
9529 OPC_ADD_D = FOP(0, FMT_D),
9530 OPC_SUB_D = FOP(1, FMT_D),
9531 OPC_MUL_D = FOP(2, FMT_D),
9532 OPC_DIV_D = FOP(3, FMT_D),
9533 OPC_SQRT_D = FOP(4, FMT_D),
9534 OPC_ABS_D = FOP(5, FMT_D),
9535 OPC_MOV_D = FOP(6, FMT_D),
9536 OPC_NEG_D = FOP(7, FMT_D),
9537 OPC_ROUND_L_D = FOP(8, FMT_D),
9538 OPC_TRUNC_L_D = FOP(9, FMT_D),
9539 OPC_CEIL_L_D = FOP(10, FMT_D),
9540 OPC_FLOOR_L_D = FOP(11, FMT_D),
9541 OPC_ROUND_W_D = FOP(12, FMT_D),
9542 OPC_TRUNC_W_D = FOP(13, FMT_D),
9543 OPC_CEIL_W_D = FOP(14, FMT_D),
9544 OPC_FLOOR_W_D = FOP(15, FMT_D),
9545 OPC_SEL_D = FOP(16, FMT_D),
9546 OPC_MOVCF_D = FOP(17, FMT_D),
9547 OPC_MOVZ_D = FOP(18, FMT_D),
9548 OPC_MOVN_D = FOP(19, FMT_D),
9549 OPC_SELEQZ_D = FOP(20, FMT_D),
9550 OPC_RECIP_D = FOP(21, FMT_D),
9551 OPC_RSQRT_D = FOP(22, FMT_D),
9552 OPC_SELNEZ_D = FOP(23, FMT_D),
9553 OPC_MADDF_D = FOP(24, FMT_D),
9554 OPC_MSUBF_D = FOP(25, FMT_D),
9555 OPC_RINT_D = FOP(26, FMT_D),
9556 OPC_CLASS_D = FOP(27, FMT_D),
9557 OPC_MIN_D = FOP(28, FMT_D),
9558 OPC_RECIP2_D = FOP(28, FMT_D),
9559 OPC_MINA_D = FOP(29, FMT_D),
9560 OPC_RECIP1_D = FOP(29, FMT_D),
9561 OPC_MAX_D = FOP(30, FMT_D),
9562 OPC_RSQRT1_D = FOP(30, FMT_D),
9563 OPC_MAXA_D = FOP(31, FMT_D),
9564 OPC_RSQRT2_D = FOP(31, FMT_D),
9565 OPC_CVT_S_D = FOP(32, FMT_D),
9566 OPC_CVT_W_D = FOP(36, FMT_D),
9567 OPC_CVT_L_D = FOP(37, FMT_D),
9568 OPC_CMP_F_D = FOP (48, FMT_D),
9569 OPC_CMP_UN_D = FOP (49, FMT_D),
9570 OPC_CMP_EQ_D = FOP (50, FMT_D),
9571 OPC_CMP_UEQ_D = FOP (51, FMT_D),
9572 OPC_CMP_OLT_D = FOP (52, FMT_D),
9573 OPC_CMP_ULT_D = FOP (53, FMT_D),
9574 OPC_CMP_OLE_D = FOP (54, FMT_D),
9575 OPC_CMP_ULE_D = FOP (55, FMT_D),
9576 OPC_CMP_SF_D = FOP (56, FMT_D),
9577 OPC_CMP_NGLE_D = FOP (57, FMT_D),
9578 OPC_CMP_SEQ_D = FOP (58, FMT_D),
9579 OPC_CMP_NGL_D = FOP (59, FMT_D),
9580 OPC_CMP_LT_D = FOP (60, FMT_D),
9581 OPC_CMP_NGE_D = FOP (61, FMT_D),
9582 OPC_CMP_LE_D = FOP (62, FMT_D),
9583 OPC_CMP_NGT_D = FOP (63, FMT_D),
9585 OPC_CVT_S_W = FOP(32, FMT_W),
9586 OPC_CVT_D_W = FOP(33, FMT_W),
9587 OPC_CVT_S_L = FOP(32, FMT_L),
9588 OPC_CVT_D_L = FOP(33, FMT_L),
9589 OPC_CVT_PS_PW = FOP(38, FMT_W),
9591 OPC_ADD_PS = FOP(0, FMT_PS),
9592 OPC_SUB_PS = FOP(1, FMT_PS),
9593 OPC_MUL_PS = FOP(2, FMT_PS),
9594 OPC_DIV_PS = FOP(3, FMT_PS),
9595 OPC_ABS_PS = FOP(5, FMT_PS),
9596 OPC_MOV_PS = FOP(6, FMT_PS),
9597 OPC_NEG_PS = FOP(7, FMT_PS),
9598 OPC_MOVCF_PS = FOP(17, FMT_PS),
9599 OPC_MOVZ_PS = FOP(18, FMT_PS),
9600 OPC_MOVN_PS = FOP(19, FMT_PS),
9601 OPC_ADDR_PS = FOP(24, FMT_PS),
9602 OPC_MULR_PS = FOP(26, FMT_PS),
9603 OPC_RECIP2_PS = FOP(28, FMT_PS),
9604 OPC_RECIP1_PS = FOP(29, FMT_PS),
9605 OPC_RSQRT1_PS = FOP(30, FMT_PS),
9606 OPC_RSQRT2_PS = FOP(31, FMT_PS),
9608 OPC_CVT_S_PU = FOP(32, FMT_PS),
9609 OPC_CVT_PW_PS = FOP(36, FMT_PS),
9610 OPC_CVT_S_PL = FOP(40, FMT_PS),
9611 OPC_PLL_PS = FOP(44, FMT_PS),
9612 OPC_PLU_PS = FOP(45, FMT_PS),
9613 OPC_PUL_PS = FOP(46, FMT_PS),
9614 OPC_PUU_PS = FOP(47, FMT_PS),
9615 OPC_CMP_F_PS = FOP (48, FMT_PS),
9616 OPC_CMP_UN_PS = FOP (49, FMT_PS),
9617 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
9618 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
9619 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
9620 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
9621 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
9622 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
9623 OPC_CMP_SF_PS = FOP (56, FMT_PS),
9624 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
9625 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
9626 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
9627 OPC_CMP_LT_PS = FOP (60, FMT_PS),
9628 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
9629 OPC_CMP_LE_PS = FOP (62, FMT_PS),
9630 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
9634 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
9635 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
9636 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
9637 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
9638 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
9639 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
9640 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
9641 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
9642 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
9643 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
9644 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
9645 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9646 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
9647 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9648 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
9649 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9650 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
9651 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
9652 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
9653 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
9654 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9655 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
9657 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
9658 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
9659 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
9660 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
9661 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
9662 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
9663 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
9664 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
9665 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
9666 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
9667 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
9668 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9669 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
9670 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9671 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
9672 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9673 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
9674 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
9675 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
9676 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
9677 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9678 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
9680 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
9682 TCGv t0 = tcg_temp_new();
9687 TCGv_i32 fp0 = tcg_temp_new_i32();
9689 gen_load_fpr32(ctx, fp0, fs);
9690 tcg_gen_ext_i32_tl(t0, fp0);
9691 tcg_temp_free_i32(fp0);
9693 gen_store_gpr(t0, rt);
9696 gen_load_gpr(t0, rt);
9698 TCGv_i32 fp0 = tcg_temp_new_i32();
9700 tcg_gen_trunc_tl_i32(fp0, t0);
9701 gen_store_fpr32(ctx, fp0, fs);
9702 tcg_temp_free_i32(fp0);
9706 gen_helper_1e0i(cfc1, t0, fs);
9707 gen_store_gpr(t0, rt);
9710 gen_load_gpr(t0, rt);
9711 save_cpu_state(ctx, 0);
9713 TCGv_i32 fs_tmp = tcg_const_i32(fs);
9715 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9716 tcg_temp_free_i32(fs_tmp);
9718 /* Stop translation as we may have changed hflags */
9719 ctx->base.is_jmp = DISAS_STOP;
9721 #if defined(TARGET_MIPS64)
9723 gen_load_fpr64(ctx, t0, fs);
9724 gen_store_gpr(t0, rt);
9727 gen_load_gpr(t0, rt);
9728 gen_store_fpr64(ctx, t0, fs);
9733 TCGv_i32 fp0 = tcg_temp_new_i32();
9735 gen_load_fpr32h(ctx, fp0, fs);
9736 tcg_gen_ext_i32_tl(t0, fp0);
9737 tcg_temp_free_i32(fp0);
9739 gen_store_gpr(t0, rt);
9742 gen_load_gpr(t0, rt);
9744 TCGv_i32 fp0 = tcg_temp_new_i32();
9746 tcg_gen_trunc_tl_i32(fp0, t0);
9747 gen_store_fpr32h(ctx, fp0, fs);
9748 tcg_temp_free_i32(fp0);
9752 MIPS_INVAL("cp1 move");
9753 generate_exception_end(ctx, EXCP_RI);
9761 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
9777 l1 = gen_new_label();
9778 t0 = tcg_temp_new_i32();
9779 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9780 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9781 tcg_temp_free_i32(t0);
9783 tcg_gen_movi_tl(cpu_gpr[rd], 0);
9785 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
9790 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9794 TCGv_i32 t0 = tcg_temp_new_i32();
9795 TCGLabel *l1 = gen_new_label();
9802 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9803 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9804 gen_load_fpr32(ctx, t0, fs);
9805 gen_store_fpr32(ctx, t0, fd);
9807 tcg_temp_free_i32(t0);
9810 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
9813 TCGv_i32 t0 = tcg_temp_new_i32();
9815 TCGLabel *l1 = gen_new_label();
9822 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9823 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9824 tcg_temp_free_i32(t0);
9825 fp0 = tcg_temp_new_i64();
9826 gen_load_fpr64(ctx, fp0, fs);
9827 gen_store_fpr64(ctx, fp0, fd);
9828 tcg_temp_free_i64(fp0);
9832 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9836 TCGv_i32 t0 = tcg_temp_new_i32();
9837 TCGLabel *l1 = gen_new_label();
9838 TCGLabel *l2 = gen_new_label();
9845 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9846 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9847 gen_load_fpr32(ctx, t0, fs);
9848 gen_store_fpr32(ctx, t0, fd);
9851 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
9852 tcg_gen_brcondi_i32(cond, t0, 0, l2);
9853 gen_load_fpr32h(ctx, t0, fs);
9854 gen_store_fpr32h(ctx, t0, fd);
9855 tcg_temp_free_i32(t0);
9859 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9862 TCGv_i32 t1 = tcg_const_i32(0);
9863 TCGv_i32 fp0 = tcg_temp_new_i32();
9864 TCGv_i32 fp1 = tcg_temp_new_i32();
9865 TCGv_i32 fp2 = tcg_temp_new_i32();
9866 gen_load_fpr32(ctx, fp0, fd);
9867 gen_load_fpr32(ctx, fp1, ft);
9868 gen_load_fpr32(ctx, fp2, fs);
9872 tcg_gen_andi_i32(fp0, fp0, 1);
9873 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9876 tcg_gen_andi_i32(fp1, fp1, 1);
9877 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9880 tcg_gen_andi_i32(fp1, fp1, 1);
9881 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9884 MIPS_INVAL("gen_sel_s");
9885 generate_exception_end(ctx, EXCP_RI);
9889 gen_store_fpr32(ctx, fp0, fd);
9890 tcg_temp_free_i32(fp2);
9891 tcg_temp_free_i32(fp1);
9892 tcg_temp_free_i32(fp0);
9893 tcg_temp_free_i32(t1);
9896 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9899 TCGv_i64 t1 = tcg_const_i64(0);
9900 TCGv_i64 fp0 = tcg_temp_new_i64();
9901 TCGv_i64 fp1 = tcg_temp_new_i64();
9902 TCGv_i64 fp2 = tcg_temp_new_i64();
9903 gen_load_fpr64(ctx, fp0, fd);
9904 gen_load_fpr64(ctx, fp1, ft);
9905 gen_load_fpr64(ctx, fp2, fs);
9909 tcg_gen_andi_i64(fp0, fp0, 1);
9910 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9913 tcg_gen_andi_i64(fp1, fp1, 1);
9914 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9917 tcg_gen_andi_i64(fp1, fp1, 1);
9918 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9921 MIPS_INVAL("gen_sel_d");
9922 generate_exception_end(ctx, EXCP_RI);
9926 gen_store_fpr64(ctx, fp0, fd);
9927 tcg_temp_free_i64(fp2);
9928 tcg_temp_free_i64(fp1);
9929 tcg_temp_free_i64(fp0);
9930 tcg_temp_free_i64(t1);
9933 static void gen_farith (DisasContext *ctx, enum fopcode op1,
9934 int ft, int fs, int fd, int cc)
9936 uint32_t func = ctx->opcode & 0x3f;
9940 TCGv_i32 fp0 = tcg_temp_new_i32();
9941 TCGv_i32 fp1 = tcg_temp_new_i32();
9943 gen_load_fpr32(ctx, fp0, fs);
9944 gen_load_fpr32(ctx, fp1, ft);
9945 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
9946 tcg_temp_free_i32(fp1);
9947 gen_store_fpr32(ctx, fp0, fd);
9948 tcg_temp_free_i32(fp0);
9953 TCGv_i32 fp0 = tcg_temp_new_i32();
9954 TCGv_i32 fp1 = tcg_temp_new_i32();
9956 gen_load_fpr32(ctx, fp0, fs);
9957 gen_load_fpr32(ctx, fp1, ft);
9958 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
9959 tcg_temp_free_i32(fp1);
9960 gen_store_fpr32(ctx, fp0, fd);
9961 tcg_temp_free_i32(fp0);
9966 TCGv_i32 fp0 = tcg_temp_new_i32();
9967 TCGv_i32 fp1 = tcg_temp_new_i32();
9969 gen_load_fpr32(ctx, fp0, fs);
9970 gen_load_fpr32(ctx, fp1, ft);
9971 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9972 tcg_temp_free_i32(fp1);
9973 gen_store_fpr32(ctx, fp0, fd);
9974 tcg_temp_free_i32(fp0);
9979 TCGv_i32 fp0 = tcg_temp_new_i32();
9980 TCGv_i32 fp1 = tcg_temp_new_i32();
9982 gen_load_fpr32(ctx, fp0, fs);
9983 gen_load_fpr32(ctx, fp1, ft);
9984 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9985 tcg_temp_free_i32(fp1);
9986 gen_store_fpr32(ctx, fp0, fd);
9987 tcg_temp_free_i32(fp0);
9992 TCGv_i32 fp0 = tcg_temp_new_i32();
9994 gen_load_fpr32(ctx, fp0, fs);
9995 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9996 gen_store_fpr32(ctx, fp0, fd);
9997 tcg_temp_free_i32(fp0);
10002 TCGv_i32 fp0 = tcg_temp_new_i32();
10004 gen_load_fpr32(ctx, fp0, fs);
10005 if (ctx->abs2008) {
10006 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10008 gen_helper_float_abs_s(fp0, fp0);
10010 gen_store_fpr32(ctx, fp0, fd);
10011 tcg_temp_free_i32(fp0);
10016 TCGv_i32 fp0 = tcg_temp_new_i32();
10018 gen_load_fpr32(ctx, fp0, fs);
10019 gen_store_fpr32(ctx, fp0, fd);
10020 tcg_temp_free_i32(fp0);
10025 TCGv_i32 fp0 = tcg_temp_new_i32();
10027 gen_load_fpr32(ctx, fp0, fs);
10028 if (ctx->abs2008) {
10029 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10031 gen_helper_float_chs_s(fp0, fp0);
10033 gen_store_fpr32(ctx, fp0, fd);
10034 tcg_temp_free_i32(fp0);
10037 case OPC_ROUND_L_S:
10038 check_cp1_64bitmode(ctx);
10040 TCGv_i32 fp32 = tcg_temp_new_i32();
10041 TCGv_i64 fp64 = tcg_temp_new_i64();
10043 gen_load_fpr32(ctx, fp32, fs);
10044 if (ctx->nan2008) {
10045 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10047 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10049 tcg_temp_free_i32(fp32);
10050 gen_store_fpr64(ctx, fp64, fd);
10051 tcg_temp_free_i64(fp64);
10054 case OPC_TRUNC_L_S:
10055 check_cp1_64bitmode(ctx);
10057 TCGv_i32 fp32 = tcg_temp_new_i32();
10058 TCGv_i64 fp64 = tcg_temp_new_i64();
10060 gen_load_fpr32(ctx, fp32, fs);
10061 if (ctx->nan2008) {
10062 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10064 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10066 tcg_temp_free_i32(fp32);
10067 gen_store_fpr64(ctx, fp64, fd);
10068 tcg_temp_free_i64(fp64);
10072 check_cp1_64bitmode(ctx);
10074 TCGv_i32 fp32 = tcg_temp_new_i32();
10075 TCGv_i64 fp64 = tcg_temp_new_i64();
10077 gen_load_fpr32(ctx, fp32, fs);
10078 if (ctx->nan2008) {
10079 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10081 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10083 tcg_temp_free_i32(fp32);
10084 gen_store_fpr64(ctx, fp64, fd);
10085 tcg_temp_free_i64(fp64);
10088 case OPC_FLOOR_L_S:
10089 check_cp1_64bitmode(ctx);
10091 TCGv_i32 fp32 = tcg_temp_new_i32();
10092 TCGv_i64 fp64 = tcg_temp_new_i64();
10094 gen_load_fpr32(ctx, fp32, fs);
10095 if (ctx->nan2008) {
10096 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10098 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10100 tcg_temp_free_i32(fp32);
10101 gen_store_fpr64(ctx, fp64, fd);
10102 tcg_temp_free_i64(fp64);
10105 case OPC_ROUND_W_S:
10107 TCGv_i32 fp0 = tcg_temp_new_i32();
10109 gen_load_fpr32(ctx, fp0, fs);
10110 if (ctx->nan2008) {
10111 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10113 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10115 gen_store_fpr32(ctx, fp0, fd);
10116 tcg_temp_free_i32(fp0);
10119 case OPC_TRUNC_W_S:
10121 TCGv_i32 fp0 = tcg_temp_new_i32();
10123 gen_load_fpr32(ctx, fp0, fs);
10124 if (ctx->nan2008) {
10125 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10127 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10129 gen_store_fpr32(ctx, fp0, fd);
10130 tcg_temp_free_i32(fp0);
10135 TCGv_i32 fp0 = tcg_temp_new_i32();
10137 gen_load_fpr32(ctx, fp0, fs);
10138 if (ctx->nan2008) {
10139 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10141 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10143 gen_store_fpr32(ctx, fp0, fd);
10144 tcg_temp_free_i32(fp0);
10147 case OPC_FLOOR_W_S:
10149 TCGv_i32 fp0 = tcg_temp_new_i32();
10151 gen_load_fpr32(ctx, fp0, fs);
10152 if (ctx->nan2008) {
10153 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10155 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10157 gen_store_fpr32(ctx, fp0, fd);
10158 tcg_temp_free_i32(fp0);
10162 check_insn(ctx, ISA_MIPS32R6);
10163 gen_sel_s(ctx, op1, fd, ft, fs);
10166 check_insn(ctx, ISA_MIPS32R6);
10167 gen_sel_s(ctx, op1, fd, ft, fs);
10170 check_insn(ctx, ISA_MIPS32R6);
10171 gen_sel_s(ctx, op1, fd, ft, fs);
10174 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10175 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10178 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10180 TCGLabel *l1 = gen_new_label();
10184 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10186 fp0 = tcg_temp_new_i32();
10187 gen_load_fpr32(ctx, fp0, fs);
10188 gen_store_fpr32(ctx, fp0, fd);
10189 tcg_temp_free_i32(fp0);
10194 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10196 TCGLabel *l1 = gen_new_label();
10200 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10201 fp0 = tcg_temp_new_i32();
10202 gen_load_fpr32(ctx, fp0, fs);
10203 gen_store_fpr32(ctx, fp0, fd);
10204 tcg_temp_free_i32(fp0);
10211 TCGv_i32 fp0 = tcg_temp_new_i32();
10213 gen_load_fpr32(ctx, fp0, fs);
10214 gen_helper_float_recip_s(fp0, cpu_env, fp0);
10215 gen_store_fpr32(ctx, fp0, fd);
10216 tcg_temp_free_i32(fp0);
10221 TCGv_i32 fp0 = tcg_temp_new_i32();
10223 gen_load_fpr32(ctx, fp0, fs);
10224 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10225 gen_store_fpr32(ctx, fp0, fd);
10226 tcg_temp_free_i32(fp0);
10230 check_insn(ctx, ISA_MIPS32R6);
10232 TCGv_i32 fp0 = tcg_temp_new_i32();
10233 TCGv_i32 fp1 = tcg_temp_new_i32();
10234 TCGv_i32 fp2 = tcg_temp_new_i32();
10235 gen_load_fpr32(ctx, fp0, fs);
10236 gen_load_fpr32(ctx, fp1, ft);
10237 gen_load_fpr32(ctx, fp2, fd);
10238 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10239 gen_store_fpr32(ctx, fp2, fd);
10240 tcg_temp_free_i32(fp2);
10241 tcg_temp_free_i32(fp1);
10242 tcg_temp_free_i32(fp0);
10246 check_insn(ctx, ISA_MIPS32R6);
10248 TCGv_i32 fp0 = tcg_temp_new_i32();
10249 TCGv_i32 fp1 = tcg_temp_new_i32();
10250 TCGv_i32 fp2 = tcg_temp_new_i32();
10251 gen_load_fpr32(ctx, fp0, fs);
10252 gen_load_fpr32(ctx, fp1, ft);
10253 gen_load_fpr32(ctx, fp2, fd);
10254 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10255 gen_store_fpr32(ctx, fp2, fd);
10256 tcg_temp_free_i32(fp2);
10257 tcg_temp_free_i32(fp1);
10258 tcg_temp_free_i32(fp0);
10262 check_insn(ctx, ISA_MIPS32R6);
10264 TCGv_i32 fp0 = tcg_temp_new_i32();
10265 gen_load_fpr32(ctx, fp0, fs);
10266 gen_helper_float_rint_s(fp0, cpu_env, fp0);
10267 gen_store_fpr32(ctx, fp0, fd);
10268 tcg_temp_free_i32(fp0);
10272 check_insn(ctx, ISA_MIPS32R6);
10274 TCGv_i32 fp0 = tcg_temp_new_i32();
10275 gen_load_fpr32(ctx, fp0, fs);
10276 gen_helper_float_class_s(fp0, cpu_env, fp0);
10277 gen_store_fpr32(ctx, fp0, fd);
10278 tcg_temp_free_i32(fp0);
10281 case OPC_MIN_S: /* OPC_RECIP2_S */
10282 if (ctx->insn_flags & ISA_MIPS32R6) {
10284 TCGv_i32 fp0 = tcg_temp_new_i32();
10285 TCGv_i32 fp1 = tcg_temp_new_i32();
10286 TCGv_i32 fp2 = tcg_temp_new_i32();
10287 gen_load_fpr32(ctx, fp0, fs);
10288 gen_load_fpr32(ctx, fp1, ft);
10289 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10290 gen_store_fpr32(ctx, fp2, fd);
10291 tcg_temp_free_i32(fp2);
10292 tcg_temp_free_i32(fp1);
10293 tcg_temp_free_i32(fp0);
10296 check_cp1_64bitmode(ctx);
10298 TCGv_i32 fp0 = tcg_temp_new_i32();
10299 TCGv_i32 fp1 = tcg_temp_new_i32();
10301 gen_load_fpr32(ctx, fp0, fs);
10302 gen_load_fpr32(ctx, fp1, ft);
10303 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10304 tcg_temp_free_i32(fp1);
10305 gen_store_fpr32(ctx, fp0, fd);
10306 tcg_temp_free_i32(fp0);
10310 case OPC_MINA_S: /* OPC_RECIP1_S */
10311 if (ctx->insn_flags & ISA_MIPS32R6) {
10313 TCGv_i32 fp0 = tcg_temp_new_i32();
10314 TCGv_i32 fp1 = tcg_temp_new_i32();
10315 TCGv_i32 fp2 = tcg_temp_new_i32();
10316 gen_load_fpr32(ctx, fp0, fs);
10317 gen_load_fpr32(ctx, fp1, ft);
10318 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10319 gen_store_fpr32(ctx, fp2, fd);
10320 tcg_temp_free_i32(fp2);
10321 tcg_temp_free_i32(fp1);
10322 tcg_temp_free_i32(fp0);
10325 check_cp1_64bitmode(ctx);
10327 TCGv_i32 fp0 = tcg_temp_new_i32();
10329 gen_load_fpr32(ctx, fp0, fs);
10330 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10331 gen_store_fpr32(ctx, fp0, fd);
10332 tcg_temp_free_i32(fp0);
10336 case OPC_MAX_S: /* OPC_RSQRT1_S */
10337 if (ctx->insn_flags & ISA_MIPS32R6) {
10339 TCGv_i32 fp0 = tcg_temp_new_i32();
10340 TCGv_i32 fp1 = tcg_temp_new_i32();
10341 gen_load_fpr32(ctx, fp0, fs);
10342 gen_load_fpr32(ctx, fp1, ft);
10343 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10344 gen_store_fpr32(ctx, fp1, fd);
10345 tcg_temp_free_i32(fp1);
10346 tcg_temp_free_i32(fp0);
10349 check_cp1_64bitmode(ctx);
10351 TCGv_i32 fp0 = tcg_temp_new_i32();
10353 gen_load_fpr32(ctx, fp0, fs);
10354 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10355 gen_store_fpr32(ctx, fp0, fd);
10356 tcg_temp_free_i32(fp0);
10360 case OPC_MAXA_S: /* OPC_RSQRT2_S */
10361 if (ctx->insn_flags & ISA_MIPS32R6) {
10363 TCGv_i32 fp0 = tcg_temp_new_i32();
10364 TCGv_i32 fp1 = tcg_temp_new_i32();
10365 gen_load_fpr32(ctx, fp0, fs);
10366 gen_load_fpr32(ctx, fp1, ft);
10367 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10368 gen_store_fpr32(ctx, fp1, fd);
10369 tcg_temp_free_i32(fp1);
10370 tcg_temp_free_i32(fp0);
10373 check_cp1_64bitmode(ctx);
10375 TCGv_i32 fp0 = tcg_temp_new_i32();
10376 TCGv_i32 fp1 = tcg_temp_new_i32();
10378 gen_load_fpr32(ctx, fp0, fs);
10379 gen_load_fpr32(ctx, fp1, ft);
10380 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10381 tcg_temp_free_i32(fp1);
10382 gen_store_fpr32(ctx, fp0, fd);
10383 tcg_temp_free_i32(fp0);
10388 check_cp1_registers(ctx, fd);
10390 TCGv_i32 fp32 = tcg_temp_new_i32();
10391 TCGv_i64 fp64 = tcg_temp_new_i64();
10393 gen_load_fpr32(ctx, fp32, fs);
10394 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10395 tcg_temp_free_i32(fp32);
10396 gen_store_fpr64(ctx, fp64, fd);
10397 tcg_temp_free_i64(fp64);
10402 TCGv_i32 fp0 = tcg_temp_new_i32();
10404 gen_load_fpr32(ctx, fp0, fs);
10405 if (ctx->nan2008) {
10406 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10408 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10410 gen_store_fpr32(ctx, fp0, fd);
10411 tcg_temp_free_i32(fp0);
10415 check_cp1_64bitmode(ctx);
10417 TCGv_i32 fp32 = tcg_temp_new_i32();
10418 TCGv_i64 fp64 = tcg_temp_new_i64();
10420 gen_load_fpr32(ctx, fp32, fs);
10421 if (ctx->nan2008) {
10422 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10424 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10426 tcg_temp_free_i32(fp32);
10427 gen_store_fpr64(ctx, fp64, fd);
10428 tcg_temp_free_i64(fp64);
10434 TCGv_i64 fp64 = tcg_temp_new_i64();
10435 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10436 TCGv_i32 fp32_1 = tcg_temp_new_i32();
10438 gen_load_fpr32(ctx, fp32_0, fs);
10439 gen_load_fpr32(ctx, fp32_1, ft);
10440 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10441 tcg_temp_free_i32(fp32_1);
10442 tcg_temp_free_i32(fp32_0);
10443 gen_store_fpr64(ctx, fp64, fd);
10444 tcg_temp_free_i64(fp64);
10450 case OPC_CMP_UEQ_S:
10451 case OPC_CMP_OLT_S:
10452 case OPC_CMP_ULT_S:
10453 case OPC_CMP_OLE_S:
10454 case OPC_CMP_ULE_S:
10456 case OPC_CMP_NGLE_S:
10457 case OPC_CMP_SEQ_S:
10458 case OPC_CMP_NGL_S:
10460 case OPC_CMP_NGE_S:
10462 case OPC_CMP_NGT_S:
10463 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10464 if (ctx->opcode & (1 << 6)) {
10465 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
10467 gen_cmp_s(ctx, func-48, ft, fs, cc);
10471 check_cp1_registers(ctx, fs | ft | fd);
10473 TCGv_i64 fp0 = tcg_temp_new_i64();
10474 TCGv_i64 fp1 = tcg_temp_new_i64();
10476 gen_load_fpr64(ctx, fp0, fs);
10477 gen_load_fpr64(ctx, fp1, ft);
10478 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10479 tcg_temp_free_i64(fp1);
10480 gen_store_fpr64(ctx, fp0, fd);
10481 tcg_temp_free_i64(fp0);
10485 check_cp1_registers(ctx, fs | ft | fd);
10487 TCGv_i64 fp0 = tcg_temp_new_i64();
10488 TCGv_i64 fp1 = tcg_temp_new_i64();
10490 gen_load_fpr64(ctx, fp0, fs);
10491 gen_load_fpr64(ctx, fp1, ft);
10492 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10493 tcg_temp_free_i64(fp1);
10494 gen_store_fpr64(ctx, fp0, fd);
10495 tcg_temp_free_i64(fp0);
10499 check_cp1_registers(ctx, fs | ft | fd);
10501 TCGv_i64 fp0 = tcg_temp_new_i64();
10502 TCGv_i64 fp1 = tcg_temp_new_i64();
10504 gen_load_fpr64(ctx, fp0, fs);
10505 gen_load_fpr64(ctx, fp1, ft);
10506 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10507 tcg_temp_free_i64(fp1);
10508 gen_store_fpr64(ctx, fp0, fd);
10509 tcg_temp_free_i64(fp0);
10513 check_cp1_registers(ctx, fs | ft | fd);
10515 TCGv_i64 fp0 = tcg_temp_new_i64();
10516 TCGv_i64 fp1 = tcg_temp_new_i64();
10518 gen_load_fpr64(ctx, fp0, fs);
10519 gen_load_fpr64(ctx, fp1, ft);
10520 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10521 tcg_temp_free_i64(fp1);
10522 gen_store_fpr64(ctx, fp0, fd);
10523 tcg_temp_free_i64(fp0);
10527 check_cp1_registers(ctx, fs | fd);
10529 TCGv_i64 fp0 = tcg_temp_new_i64();
10531 gen_load_fpr64(ctx, fp0, fs);
10532 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10533 gen_store_fpr64(ctx, fp0, fd);
10534 tcg_temp_free_i64(fp0);
10538 check_cp1_registers(ctx, fs | fd);
10540 TCGv_i64 fp0 = tcg_temp_new_i64();
10542 gen_load_fpr64(ctx, fp0, fs);
10543 if (ctx->abs2008) {
10544 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10546 gen_helper_float_abs_d(fp0, fp0);
10548 gen_store_fpr64(ctx, fp0, fd);
10549 tcg_temp_free_i64(fp0);
10553 check_cp1_registers(ctx, fs | fd);
10555 TCGv_i64 fp0 = tcg_temp_new_i64();
10557 gen_load_fpr64(ctx, fp0, fs);
10558 gen_store_fpr64(ctx, fp0, fd);
10559 tcg_temp_free_i64(fp0);
10563 check_cp1_registers(ctx, fs | fd);
10565 TCGv_i64 fp0 = tcg_temp_new_i64();
10567 gen_load_fpr64(ctx, fp0, fs);
10568 if (ctx->abs2008) {
10569 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10571 gen_helper_float_chs_d(fp0, fp0);
10573 gen_store_fpr64(ctx, fp0, fd);
10574 tcg_temp_free_i64(fp0);
10577 case OPC_ROUND_L_D:
10578 check_cp1_64bitmode(ctx);
10580 TCGv_i64 fp0 = tcg_temp_new_i64();
10582 gen_load_fpr64(ctx, fp0, fs);
10583 if (ctx->nan2008) {
10584 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10586 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10588 gen_store_fpr64(ctx, fp0, fd);
10589 tcg_temp_free_i64(fp0);
10592 case OPC_TRUNC_L_D:
10593 check_cp1_64bitmode(ctx);
10595 TCGv_i64 fp0 = tcg_temp_new_i64();
10597 gen_load_fpr64(ctx, fp0, fs);
10598 if (ctx->nan2008) {
10599 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10601 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10603 gen_store_fpr64(ctx, fp0, fd);
10604 tcg_temp_free_i64(fp0);
10608 check_cp1_64bitmode(ctx);
10610 TCGv_i64 fp0 = tcg_temp_new_i64();
10612 gen_load_fpr64(ctx, fp0, fs);
10613 if (ctx->nan2008) {
10614 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10616 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10618 gen_store_fpr64(ctx, fp0, fd);
10619 tcg_temp_free_i64(fp0);
10622 case OPC_FLOOR_L_D:
10623 check_cp1_64bitmode(ctx);
10625 TCGv_i64 fp0 = tcg_temp_new_i64();
10627 gen_load_fpr64(ctx, fp0, fs);
10628 if (ctx->nan2008) {
10629 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10631 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10633 gen_store_fpr64(ctx, fp0, fd);
10634 tcg_temp_free_i64(fp0);
10637 case OPC_ROUND_W_D:
10638 check_cp1_registers(ctx, fs);
10640 TCGv_i32 fp32 = tcg_temp_new_i32();
10641 TCGv_i64 fp64 = tcg_temp_new_i64();
10643 gen_load_fpr64(ctx, fp64, fs);
10644 if (ctx->nan2008) {
10645 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10647 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10649 tcg_temp_free_i64(fp64);
10650 gen_store_fpr32(ctx, fp32, fd);
10651 tcg_temp_free_i32(fp32);
10654 case OPC_TRUNC_W_D:
10655 check_cp1_registers(ctx, fs);
10657 TCGv_i32 fp32 = tcg_temp_new_i32();
10658 TCGv_i64 fp64 = tcg_temp_new_i64();
10660 gen_load_fpr64(ctx, fp64, fs);
10661 if (ctx->nan2008) {
10662 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10664 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10666 tcg_temp_free_i64(fp64);
10667 gen_store_fpr32(ctx, fp32, fd);
10668 tcg_temp_free_i32(fp32);
10672 check_cp1_registers(ctx, fs);
10674 TCGv_i32 fp32 = tcg_temp_new_i32();
10675 TCGv_i64 fp64 = tcg_temp_new_i64();
10677 gen_load_fpr64(ctx, fp64, fs);
10678 if (ctx->nan2008) {
10679 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10681 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10683 tcg_temp_free_i64(fp64);
10684 gen_store_fpr32(ctx, fp32, fd);
10685 tcg_temp_free_i32(fp32);
10688 case OPC_FLOOR_W_D:
10689 check_cp1_registers(ctx, fs);
10691 TCGv_i32 fp32 = tcg_temp_new_i32();
10692 TCGv_i64 fp64 = tcg_temp_new_i64();
10694 gen_load_fpr64(ctx, fp64, fs);
10695 if (ctx->nan2008) {
10696 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10698 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10700 tcg_temp_free_i64(fp64);
10701 gen_store_fpr32(ctx, fp32, fd);
10702 tcg_temp_free_i32(fp32);
10706 check_insn(ctx, ISA_MIPS32R6);
10707 gen_sel_d(ctx, op1, fd, ft, fs);
10710 check_insn(ctx, ISA_MIPS32R6);
10711 gen_sel_d(ctx, op1, fd, ft, fs);
10714 check_insn(ctx, ISA_MIPS32R6);
10715 gen_sel_d(ctx, op1, fd, ft, fs);
10718 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10719 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10722 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10724 TCGLabel *l1 = gen_new_label();
10728 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10730 fp0 = tcg_temp_new_i64();
10731 gen_load_fpr64(ctx, fp0, fs);
10732 gen_store_fpr64(ctx, fp0, fd);
10733 tcg_temp_free_i64(fp0);
10738 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10740 TCGLabel *l1 = gen_new_label();
10744 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10745 fp0 = tcg_temp_new_i64();
10746 gen_load_fpr64(ctx, fp0, fs);
10747 gen_store_fpr64(ctx, fp0, fd);
10748 tcg_temp_free_i64(fp0);
10754 check_cp1_registers(ctx, fs | fd);
10756 TCGv_i64 fp0 = tcg_temp_new_i64();
10758 gen_load_fpr64(ctx, fp0, fs);
10759 gen_helper_float_recip_d(fp0, cpu_env, fp0);
10760 gen_store_fpr64(ctx, fp0, fd);
10761 tcg_temp_free_i64(fp0);
10765 check_cp1_registers(ctx, fs | fd);
10767 TCGv_i64 fp0 = tcg_temp_new_i64();
10769 gen_load_fpr64(ctx, fp0, fs);
10770 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10771 gen_store_fpr64(ctx, fp0, fd);
10772 tcg_temp_free_i64(fp0);
10776 check_insn(ctx, ISA_MIPS32R6);
10778 TCGv_i64 fp0 = tcg_temp_new_i64();
10779 TCGv_i64 fp1 = tcg_temp_new_i64();
10780 TCGv_i64 fp2 = tcg_temp_new_i64();
10781 gen_load_fpr64(ctx, fp0, fs);
10782 gen_load_fpr64(ctx, fp1, ft);
10783 gen_load_fpr64(ctx, fp2, fd);
10784 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10785 gen_store_fpr64(ctx, fp2, fd);
10786 tcg_temp_free_i64(fp2);
10787 tcg_temp_free_i64(fp1);
10788 tcg_temp_free_i64(fp0);
10792 check_insn(ctx, ISA_MIPS32R6);
10794 TCGv_i64 fp0 = tcg_temp_new_i64();
10795 TCGv_i64 fp1 = tcg_temp_new_i64();
10796 TCGv_i64 fp2 = tcg_temp_new_i64();
10797 gen_load_fpr64(ctx, fp0, fs);
10798 gen_load_fpr64(ctx, fp1, ft);
10799 gen_load_fpr64(ctx, fp2, fd);
10800 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10801 gen_store_fpr64(ctx, fp2, fd);
10802 tcg_temp_free_i64(fp2);
10803 tcg_temp_free_i64(fp1);
10804 tcg_temp_free_i64(fp0);
10808 check_insn(ctx, ISA_MIPS32R6);
10810 TCGv_i64 fp0 = tcg_temp_new_i64();
10811 gen_load_fpr64(ctx, fp0, fs);
10812 gen_helper_float_rint_d(fp0, cpu_env, fp0);
10813 gen_store_fpr64(ctx, fp0, fd);
10814 tcg_temp_free_i64(fp0);
10818 check_insn(ctx, ISA_MIPS32R6);
10820 TCGv_i64 fp0 = tcg_temp_new_i64();
10821 gen_load_fpr64(ctx, fp0, fs);
10822 gen_helper_float_class_d(fp0, cpu_env, fp0);
10823 gen_store_fpr64(ctx, fp0, fd);
10824 tcg_temp_free_i64(fp0);
10827 case OPC_MIN_D: /* OPC_RECIP2_D */
10828 if (ctx->insn_flags & ISA_MIPS32R6) {
10830 TCGv_i64 fp0 = tcg_temp_new_i64();
10831 TCGv_i64 fp1 = tcg_temp_new_i64();
10832 gen_load_fpr64(ctx, fp0, fs);
10833 gen_load_fpr64(ctx, fp1, ft);
10834 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10835 gen_store_fpr64(ctx, fp1, fd);
10836 tcg_temp_free_i64(fp1);
10837 tcg_temp_free_i64(fp0);
10840 check_cp1_64bitmode(ctx);
10842 TCGv_i64 fp0 = tcg_temp_new_i64();
10843 TCGv_i64 fp1 = tcg_temp_new_i64();
10845 gen_load_fpr64(ctx, fp0, fs);
10846 gen_load_fpr64(ctx, fp1, ft);
10847 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10848 tcg_temp_free_i64(fp1);
10849 gen_store_fpr64(ctx, fp0, fd);
10850 tcg_temp_free_i64(fp0);
10854 case OPC_MINA_D: /* OPC_RECIP1_D */
10855 if (ctx->insn_flags & ISA_MIPS32R6) {
10857 TCGv_i64 fp0 = tcg_temp_new_i64();
10858 TCGv_i64 fp1 = tcg_temp_new_i64();
10859 gen_load_fpr64(ctx, fp0, fs);
10860 gen_load_fpr64(ctx, fp1, ft);
10861 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10862 gen_store_fpr64(ctx, fp1, fd);
10863 tcg_temp_free_i64(fp1);
10864 tcg_temp_free_i64(fp0);
10867 check_cp1_64bitmode(ctx);
10869 TCGv_i64 fp0 = tcg_temp_new_i64();
10871 gen_load_fpr64(ctx, fp0, fs);
10872 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10873 gen_store_fpr64(ctx, fp0, fd);
10874 tcg_temp_free_i64(fp0);
10878 case OPC_MAX_D: /* OPC_RSQRT1_D */
10879 if (ctx->insn_flags & ISA_MIPS32R6) {
10881 TCGv_i64 fp0 = tcg_temp_new_i64();
10882 TCGv_i64 fp1 = tcg_temp_new_i64();
10883 gen_load_fpr64(ctx, fp0, fs);
10884 gen_load_fpr64(ctx, fp1, ft);
10885 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10886 gen_store_fpr64(ctx, fp1, fd);
10887 tcg_temp_free_i64(fp1);
10888 tcg_temp_free_i64(fp0);
10891 check_cp1_64bitmode(ctx);
10893 TCGv_i64 fp0 = tcg_temp_new_i64();
10895 gen_load_fpr64(ctx, fp0, fs);
10896 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10897 gen_store_fpr64(ctx, fp0, fd);
10898 tcg_temp_free_i64(fp0);
10902 case OPC_MAXA_D: /* OPC_RSQRT2_D */
10903 if (ctx->insn_flags & ISA_MIPS32R6) {
10905 TCGv_i64 fp0 = tcg_temp_new_i64();
10906 TCGv_i64 fp1 = tcg_temp_new_i64();
10907 gen_load_fpr64(ctx, fp0, fs);
10908 gen_load_fpr64(ctx, fp1, ft);
10909 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10910 gen_store_fpr64(ctx, fp1, fd);
10911 tcg_temp_free_i64(fp1);
10912 tcg_temp_free_i64(fp0);
10915 check_cp1_64bitmode(ctx);
10917 TCGv_i64 fp0 = tcg_temp_new_i64();
10918 TCGv_i64 fp1 = tcg_temp_new_i64();
10920 gen_load_fpr64(ctx, fp0, fs);
10921 gen_load_fpr64(ctx, fp1, ft);
10922 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10923 tcg_temp_free_i64(fp1);
10924 gen_store_fpr64(ctx, fp0, fd);
10925 tcg_temp_free_i64(fp0);
10932 case OPC_CMP_UEQ_D:
10933 case OPC_CMP_OLT_D:
10934 case OPC_CMP_ULT_D:
10935 case OPC_CMP_OLE_D:
10936 case OPC_CMP_ULE_D:
10938 case OPC_CMP_NGLE_D:
10939 case OPC_CMP_SEQ_D:
10940 case OPC_CMP_NGL_D:
10942 case OPC_CMP_NGE_D:
10944 case OPC_CMP_NGT_D:
10945 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10946 if (ctx->opcode & (1 << 6)) {
10947 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
10949 gen_cmp_d(ctx, func-48, ft, fs, cc);
10953 check_cp1_registers(ctx, fs);
10955 TCGv_i32 fp32 = tcg_temp_new_i32();
10956 TCGv_i64 fp64 = tcg_temp_new_i64();
10958 gen_load_fpr64(ctx, fp64, fs);
10959 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
10960 tcg_temp_free_i64(fp64);
10961 gen_store_fpr32(ctx, fp32, fd);
10962 tcg_temp_free_i32(fp32);
10966 check_cp1_registers(ctx, fs);
10968 TCGv_i32 fp32 = tcg_temp_new_i32();
10969 TCGv_i64 fp64 = tcg_temp_new_i64();
10971 gen_load_fpr64(ctx, fp64, fs);
10972 if (ctx->nan2008) {
10973 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10975 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10977 tcg_temp_free_i64(fp64);
10978 gen_store_fpr32(ctx, fp32, fd);
10979 tcg_temp_free_i32(fp32);
10983 check_cp1_64bitmode(ctx);
10985 TCGv_i64 fp0 = tcg_temp_new_i64();
10987 gen_load_fpr64(ctx, fp0, fs);
10988 if (ctx->nan2008) {
10989 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10991 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10993 gen_store_fpr64(ctx, fp0, fd);
10994 tcg_temp_free_i64(fp0);
10999 TCGv_i32 fp0 = tcg_temp_new_i32();
11001 gen_load_fpr32(ctx, fp0, fs);
11002 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11003 gen_store_fpr32(ctx, fp0, fd);
11004 tcg_temp_free_i32(fp0);
11008 check_cp1_registers(ctx, fd);
11010 TCGv_i32 fp32 = tcg_temp_new_i32();
11011 TCGv_i64 fp64 = tcg_temp_new_i64();
11013 gen_load_fpr32(ctx, fp32, fs);
11014 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11015 tcg_temp_free_i32(fp32);
11016 gen_store_fpr64(ctx, fp64, fd);
11017 tcg_temp_free_i64(fp64);
11021 check_cp1_64bitmode(ctx);
11023 TCGv_i32 fp32 = tcg_temp_new_i32();
11024 TCGv_i64 fp64 = tcg_temp_new_i64();
11026 gen_load_fpr64(ctx, fp64, fs);
11027 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11028 tcg_temp_free_i64(fp64);
11029 gen_store_fpr32(ctx, fp32, fd);
11030 tcg_temp_free_i32(fp32);
11034 check_cp1_64bitmode(ctx);
11036 TCGv_i64 fp0 = tcg_temp_new_i64();
11038 gen_load_fpr64(ctx, fp0, fs);
11039 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11040 gen_store_fpr64(ctx, fp0, fd);
11041 tcg_temp_free_i64(fp0);
11044 case OPC_CVT_PS_PW:
11047 TCGv_i64 fp0 = tcg_temp_new_i64();
11049 gen_load_fpr64(ctx, fp0, fs);
11050 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11051 gen_store_fpr64(ctx, fp0, fd);
11052 tcg_temp_free_i64(fp0);
11058 TCGv_i64 fp0 = tcg_temp_new_i64();
11059 TCGv_i64 fp1 = tcg_temp_new_i64();
11061 gen_load_fpr64(ctx, fp0, fs);
11062 gen_load_fpr64(ctx, fp1, ft);
11063 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11064 tcg_temp_free_i64(fp1);
11065 gen_store_fpr64(ctx, fp0, fd);
11066 tcg_temp_free_i64(fp0);
11072 TCGv_i64 fp0 = tcg_temp_new_i64();
11073 TCGv_i64 fp1 = tcg_temp_new_i64();
11075 gen_load_fpr64(ctx, fp0, fs);
11076 gen_load_fpr64(ctx, fp1, ft);
11077 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11078 tcg_temp_free_i64(fp1);
11079 gen_store_fpr64(ctx, fp0, fd);
11080 tcg_temp_free_i64(fp0);
11086 TCGv_i64 fp0 = tcg_temp_new_i64();
11087 TCGv_i64 fp1 = tcg_temp_new_i64();
11089 gen_load_fpr64(ctx, fp0, fs);
11090 gen_load_fpr64(ctx, fp1, ft);
11091 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11092 tcg_temp_free_i64(fp1);
11093 gen_store_fpr64(ctx, fp0, fd);
11094 tcg_temp_free_i64(fp0);
11100 TCGv_i64 fp0 = tcg_temp_new_i64();
11102 gen_load_fpr64(ctx, fp0, fs);
11103 gen_helper_float_abs_ps(fp0, fp0);
11104 gen_store_fpr64(ctx, fp0, fd);
11105 tcg_temp_free_i64(fp0);
11111 TCGv_i64 fp0 = tcg_temp_new_i64();
11113 gen_load_fpr64(ctx, fp0, fs);
11114 gen_store_fpr64(ctx, fp0, fd);
11115 tcg_temp_free_i64(fp0);
11121 TCGv_i64 fp0 = tcg_temp_new_i64();
11123 gen_load_fpr64(ctx, fp0, fs);
11124 gen_helper_float_chs_ps(fp0, fp0);
11125 gen_store_fpr64(ctx, fp0, fd);
11126 tcg_temp_free_i64(fp0);
11131 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11136 TCGLabel *l1 = gen_new_label();
11140 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11141 fp0 = tcg_temp_new_i64();
11142 gen_load_fpr64(ctx, fp0, fs);
11143 gen_store_fpr64(ctx, fp0, fd);
11144 tcg_temp_free_i64(fp0);
11151 TCGLabel *l1 = gen_new_label();
11155 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11156 fp0 = tcg_temp_new_i64();
11157 gen_load_fpr64(ctx, fp0, fs);
11158 gen_store_fpr64(ctx, fp0, fd);
11159 tcg_temp_free_i64(fp0);
11167 TCGv_i64 fp0 = tcg_temp_new_i64();
11168 TCGv_i64 fp1 = tcg_temp_new_i64();
11170 gen_load_fpr64(ctx, fp0, ft);
11171 gen_load_fpr64(ctx, fp1, fs);
11172 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11173 tcg_temp_free_i64(fp1);
11174 gen_store_fpr64(ctx, fp0, fd);
11175 tcg_temp_free_i64(fp0);
11181 TCGv_i64 fp0 = tcg_temp_new_i64();
11182 TCGv_i64 fp1 = tcg_temp_new_i64();
11184 gen_load_fpr64(ctx, fp0, ft);
11185 gen_load_fpr64(ctx, fp1, fs);
11186 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11187 tcg_temp_free_i64(fp1);
11188 gen_store_fpr64(ctx, fp0, fd);
11189 tcg_temp_free_i64(fp0);
11192 case OPC_RECIP2_PS:
11195 TCGv_i64 fp0 = tcg_temp_new_i64();
11196 TCGv_i64 fp1 = tcg_temp_new_i64();
11198 gen_load_fpr64(ctx, fp0, fs);
11199 gen_load_fpr64(ctx, fp1, ft);
11200 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11201 tcg_temp_free_i64(fp1);
11202 gen_store_fpr64(ctx, fp0, fd);
11203 tcg_temp_free_i64(fp0);
11206 case OPC_RECIP1_PS:
11209 TCGv_i64 fp0 = tcg_temp_new_i64();
11211 gen_load_fpr64(ctx, fp0, fs);
11212 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11213 gen_store_fpr64(ctx, fp0, fd);
11214 tcg_temp_free_i64(fp0);
11217 case OPC_RSQRT1_PS:
11220 TCGv_i64 fp0 = tcg_temp_new_i64();
11222 gen_load_fpr64(ctx, fp0, fs);
11223 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11224 gen_store_fpr64(ctx, fp0, fd);
11225 tcg_temp_free_i64(fp0);
11228 case OPC_RSQRT2_PS:
11231 TCGv_i64 fp0 = tcg_temp_new_i64();
11232 TCGv_i64 fp1 = tcg_temp_new_i64();
11234 gen_load_fpr64(ctx, fp0, fs);
11235 gen_load_fpr64(ctx, fp1, ft);
11236 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11237 tcg_temp_free_i64(fp1);
11238 gen_store_fpr64(ctx, fp0, fd);
11239 tcg_temp_free_i64(fp0);
11243 check_cp1_64bitmode(ctx);
11245 TCGv_i32 fp0 = tcg_temp_new_i32();
11247 gen_load_fpr32h(ctx, fp0, fs);
11248 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11249 gen_store_fpr32(ctx, fp0, fd);
11250 tcg_temp_free_i32(fp0);
11253 case OPC_CVT_PW_PS:
11256 TCGv_i64 fp0 = tcg_temp_new_i64();
11258 gen_load_fpr64(ctx, fp0, fs);
11259 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11260 gen_store_fpr64(ctx, fp0, fd);
11261 tcg_temp_free_i64(fp0);
11265 check_cp1_64bitmode(ctx);
11267 TCGv_i32 fp0 = tcg_temp_new_i32();
11269 gen_load_fpr32(ctx, fp0, fs);
11270 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11271 gen_store_fpr32(ctx, fp0, fd);
11272 tcg_temp_free_i32(fp0);
11278 TCGv_i32 fp0 = tcg_temp_new_i32();
11279 TCGv_i32 fp1 = tcg_temp_new_i32();
11281 gen_load_fpr32(ctx, fp0, fs);
11282 gen_load_fpr32(ctx, fp1, ft);
11283 gen_store_fpr32h(ctx, fp0, fd);
11284 gen_store_fpr32(ctx, fp1, fd);
11285 tcg_temp_free_i32(fp0);
11286 tcg_temp_free_i32(fp1);
11292 TCGv_i32 fp0 = tcg_temp_new_i32();
11293 TCGv_i32 fp1 = tcg_temp_new_i32();
11295 gen_load_fpr32(ctx, fp0, fs);
11296 gen_load_fpr32h(ctx, fp1, ft);
11297 gen_store_fpr32(ctx, fp1, fd);
11298 gen_store_fpr32h(ctx, fp0, fd);
11299 tcg_temp_free_i32(fp0);
11300 tcg_temp_free_i32(fp1);
11306 TCGv_i32 fp0 = tcg_temp_new_i32();
11307 TCGv_i32 fp1 = tcg_temp_new_i32();
11309 gen_load_fpr32h(ctx, fp0, fs);
11310 gen_load_fpr32(ctx, fp1, ft);
11311 gen_store_fpr32(ctx, fp1, fd);
11312 gen_store_fpr32h(ctx, fp0, fd);
11313 tcg_temp_free_i32(fp0);
11314 tcg_temp_free_i32(fp1);
11320 TCGv_i32 fp0 = tcg_temp_new_i32();
11321 TCGv_i32 fp1 = tcg_temp_new_i32();
11323 gen_load_fpr32h(ctx, fp0, fs);
11324 gen_load_fpr32h(ctx, fp1, ft);
11325 gen_store_fpr32(ctx, fp1, fd);
11326 gen_store_fpr32h(ctx, fp0, fd);
11327 tcg_temp_free_i32(fp0);
11328 tcg_temp_free_i32(fp1);
11332 case OPC_CMP_UN_PS:
11333 case OPC_CMP_EQ_PS:
11334 case OPC_CMP_UEQ_PS:
11335 case OPC_CMP_OLT_PS:
11336 case OPC_CMP_ULT_PS:
11337 case OPC_CMP_OLE_PS:
11338 case OPC_CMP_ULE_PS:
11339 case OPC_CMP_SF_PS:
11340 case OPC_CMP_NGLE_PS:
11341 case OPC_CMP_SEQ_PS:
11342 case OPC_CMP_NGL_PS:
11343 case OPC_CMP_LT_PS:
11344 case OPC_CMP_NGE_PS:
11345 case OPC_CMP_LE_PS:
11346 case OPC_CMP_NGT_PS:
11347 if (ctx->opcode & (1 << 6)) {
11348 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
11350 gen_cmp_ps(ctx, func-48, ft, fs, cc);
11354 MIPS_INVAL("farith");
11355 generate_exception_end(ctx, EXCP_RI);
11360 /* Coprocessor 3 (FPU) */
11361 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
11362 int fd, int fs, int base, int index)
11364 TCGv t0 = tcg_temp_new();
11367 gen_load_gpr(t0, index);
11368 } else if (index == 0) {
11369 gen_load_gpr(t0, base);
11371 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11373 /* Don't do NOP if destination is zero: we must perform the actual
11379 TCGv_i32 fp0 = tcg_temp_new_i32();
11381 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11382 tcg_gen_trunc_tl_i32(fp0, t0);
11383 gen_store_fpr32(ctx, fp0, fd);
11384 tcg_temp_free_i32(fp0);
11389 check_cp1_registers(ctx, fd);
11391 TCGv_i64 fp0 = tcg_temp_new_i64();
11392 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11393 gen_store_fpr64(ctx, fp0, fd);
11394 tcg_temp_free_i64(fp0);
11398 check_cp1_64bitmode(ctx);
11399 tcg_gen_andi_tl(t0, t0, ~0x7);
11401 TCGv_i64 fp0 = tcg_temp_new_i64();
11403 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11404 gen_store_fpr64(ctx, fp0, fd);
11405 tcg_temp_free_i64(fp0);
11411 TCGv_i32 fp0 = tcg_temp_new_i32();
11412 gen_load_fpr32(ctx, fp0, fs);
11413 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11414 tcg_temp_free_i32(fp0);
11419 check_cp1_registers(ctx, fs);
11421 TCGv_i64 fp0 = tcg_temp_new_i64();
11422 gen_load_fpr64(ctx, fp0, fs);
11423 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11424 tcg_temp_free_i64(fp0);
11428 check_cp1_64bitmode(ctx);
11429 tcg_gen_andi_tl(t0, t0, ~0x7);
11431 TCGv_i64 fp0 = tcg_temp_new_i64();
11432 gen_load_fpr64(ctx, fp0, fs);
11433 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11434 tcg_temp_free_i64(fp0);
11441 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
11442 int fd, int fr, int fs, int ft)
11448 TCGv t0 = tcg_temp_local_new();
11449 TCGv_i32 fp = tcg_temp_new_i32();
11450 TCGv_i32 fph = tcg_temp_new_i32();
11451 TCGLabel *l1 = gen_new_label();
11452 TCGLabel *l2 = gen_new_label();
11454 gen_load_gpr(t0, fr);
11455 tcg_gen_andi_tl(t0, t0, 0x7);
11457 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11458 gen_load_fpr32(ctx, fp, fs);
11459 gen_load_fpr32h(ctx, fph, fs);
11460 gen_store_fpr32(ctx, fp, fd);
11461 gen_store_fpr32h(ctx, fph, fd);
11464 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11466 #ifdef TARGET_WORDS_BIGENDIAN
11467 gen_load_fpr32(ctx, fp, fs);
11468 gen_load_fpr32h(ctx, fph, ft);
11469 gen_store_fpr32h(ctx, fp, fd);
11470 gen_store_fpr32(ctx, fph, fd);
11472 gen_load_fpr32h(ctx, fph, fs);
11473 gen_load_fpr32(ctx, fp, ft);
11474 gen_store_fpr32(ctx, fph, fd);
11475 gen_store_fpr32h(ctx, fp, fd);
11478 tcg_temp_free_i32(fp);
11479 tcg_temp_free_i32(fph);
11485 TCGv_i32 fp0 = tcg_temp_new_i32();
11486 TCGv_i32 fp1 = tcg_temp_new_i32();
11487 TCGv_i32 fp2 = tcg_temp_new_i32();
11489 gen_load_fpr32(ctx, fp0, fs);
11490 gen_load_fpr32(ctx, fp1, ft);
11491 gen_load_fpr32(ctx, fp2, fr);
11492 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11493 tcg_temp_free_i32(fp0);
11494 tcg_temp_free_i32(fp1);
11495 gen_store_fpr32(ctx, fp2, fd);
11496 tcg_temp_free_i32(fp2);
11501 check_cp1_registers(ctx, fd | fs | ft | fr);
11503 TCGv_i64 fp0 = tcg_temp_new_i64();
11504 TCGv_i64 fp1 = tcg_temp_new_i64();
11505 TCGv_i64 fp2 = tcg_temp_new_i64();
11507 gen_load_fpr64(ctx, fp0, fs);
11508 gen_load_fpr64(ctx, fp1, ft);
11509 gen_load_fpr64(ctx, fp2, fr);
11510 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11511 tcg_temp_free_i64(fp0);
11512 tcg_temp_free_i64(fp1);
11513 gen_store_fpr64(ctx, fp2, fd);
11514 tcg_temp_free_i64(fp2);
11520 TCGv_i64 fp0 = tcg_temp_new_i64();
11521 TCGv_i64 fp1 = tcg_temp_new_i64();
11522 TCGv_i64 fp2 = tcg_temp_new_i64();
11524 gen_load_fpr64(ctx, fp0, fs);
11525 gen_load_fpr64(ctx, fp1, ft);
11526 gen_load_fpr64(ctx, fp2, fr);
11527 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11528 tcg_temp_free_i64(fp0);
11529 tcg_temp_free_i64(fp1);
11530 gen_store_fpr64(ctx, fp2, fd);
11531 tcg_temp_free_i64(fp2);
11537 TCGv_i32 fp0 = tcg_temp_new_i32();
11538 TCGv_i32 fp1 = tcg_temp_new_i32();
11539 TCGv_i32 fp2 = tcg_temp_new_i32();
11541 gen_load_fpr32(ctx, fp0, fs);
11542 gen_load_fpr32(ctx, fp1, ft);
11543 gen_load_fpr32(ctx, fp2, fr);
11544 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11545 tcg_temp_free_i32(fp0);
11546 tcg_temp_free_i32(fp1);
11547 gen_store_fpr32(ctx, fp2, fd);
11548 tcg_temp_free_i32(fp2);
11553 check_cp1_registers(ctx, fd | fs | ft | fr);
11555 TCGv_i64 fp0 = tcg_temp_new_i64();
11556 TCGv_i64 fp1 = tcg_temp_new_i64();
11557 TCGv_i64 fp2 = tcg_temp_new_i64();
11559 gen_load_fpr64(ctx, fp0, fs);
11560 gen_load_fpr64(ctx, fp1, ft);
11561 gen_load_fpr64(ctx, fp2, fr);
11562 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11563 tcg_temp_free_i64(fp0);
11564 tcg_temp_free_i64(fp1);
11565 gen_store_fpr64(ctx, fp2, fd);
11566 tcg_temp_free_i64(fp2);
11572 TCGv_i64 fp0 = tcg_temp_new_i64();
11573 TCGv_i64 fp1 = tcg_temp_new_i64();
11574 TCGv_i64 fp2 = tcg_temp_new_i64();
11576 gen_load_fpr64(ctx, fp0, fs);
11577 gen_load_fpr64(ctx, fp1, ft);
11578 gen_load_fpr64(ctx, fp2, fr);
11579 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11580 tcg_temp_free_i64(fp0);
11581 tcg_temp_free_i64(fp1);
11582 gen_store_fpr64(ctx, fp2, fd);
11583 tcg_temp_free_i64(fp2);
11589 TCGv_i32 fp0 = tcg_temp_new_i32();
11590 TCGv_i32 fp1 = tcg_temp_new_i32();
11591 TCGv_i32 fp2 = tcg_temp_new_i32();
11593 gen_load_fpr32(ctx, fp0, fs);
11594 gen_load_fpr32(ctx, fp1, ft);
11595 gen_load_fpr32(ctx, fp2, fr);
11596 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11597 tcg_temp_free_i32(fp0);
11598 tcg_temp_free_i32(fp1);
11599 gen_store_fpr32(ctx, fp2, fd);
11600 tcg_temp_free_i32(fp2);
11605 check_cp1_registers(ctx, fd | fs | ft | fr);
11607 TCGv_i64 fp0 = tcg_temp_new_i64();
11608 TCGv_i64 fp1 = tcg_temp_new_i64();
11609 TCGv_i64 fp2 = tcg_temp_new_i64();
11611 gen_load_fpr64(ctx, fp0, fs);
11612 gen_load_fpr64(ctx, fp1, ft);
11613 gen_load_fpr64(ctx, fp2, fr);
11614 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11615 tcg_temp_free_i64(fp0);
11616 tcg_temp_free_i64(fp1);
11617 gen_store_fpr64(ctx, fp2, fd);
11618 tcg_temp_free_i64(fp2);
11624 TCGv_i64 fp0 = tcg_temp_new_i64();
11625 TCGv_i64 fp1 = tcg_temp_new_i64();
11626 TCGv_i64 fp2 = tcg_temp_new_i64();
11628 gen_load_fpr64(ctx, fp0, fs);
11629 gen_load_fpr64(ctx, fp1, ft);
11630 gen_load_fpr64(ctx, fp2, fr);
11631 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11632 tcg_temp_free_i64(fp0);
11633 tcg_temp_free_i64(fp1);
11634 gen_store_fpr64(ctx, fp2, fd);
11635 tcg_temp_free_i64(fp2);
11641 TCGv_i32 fp0 = tcg_temp_new_i32();
11642 TCGv_i32 fp1 = tcg_temp_new_i32();
11643 TCGv_i32 fp2 = tcg_temp_new_i32();
11645 gen_load_fpr32(ctx, fp0, fs);
11646 gen_load_fpr32(ctx, fp1, ft);
11647 gen_load_fpr32(ctx, fp2, fr);
11648 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11649 tcg_temp_free_i32(fp0);
11650 tcg_temp_free_i32(fp1);
11651 gen_store_fpr32(ctx, fp2, fd);
11652 tcg_temp_free_i32(fp2);
11657 check_cp1_registers(ctx, fd | fs | ft | fr);
11659 TCGv_i64 fp0 = tcg_temp_new_i64();
11660 TCGv_i64 fp1 = tcg_temp_new_i64();
11661 TCGv_i64 fp2 = tcg_temp_new_i64();
11663 gen_load_fpr64(ctx, fp0, fs);
11664 gen_load_fpr64(ctx, fp1, ft);
11665 gen_load_fpr64(ctx, fp2, fr);
11666 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11667 tcg_temp_free_i64(fp0);
11668 tcg_temp_free_i64(fp1);
11669 gen_store_fpr64(ctx, fp2, fd);
11670 tcg_temp_free_i64(fp2);
11676 TCGv_i64 fp0 = tcg_temp_new_i64();
11677 TCGv_i64 fp1 = tcg_temp_new_i64();
11678 TCGv_i64 fp2 = tcg_temp_new_i64();
11680 gen_load_fpr64(ctx, fp0, fs);
11681 gen_load_fpr64(ctx, fp1, ft);
11682 gen_load_fpr64(ctx, fp2, fr);
11683 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11684 tcg_temp_free_i64(fp0);
11685 tcg_temp_free_i64(fp1);
11686 gen_store_fpr64(ctx, fp2, fd);
11687 tcg_temp_free_i64(fp2);
11691 MIPS_INVAL("flt3_arith");
11692 generate_exception_end(ctx, EXCP_RI);
11697 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11701 #if !defined(CONFIG_USER_ONLY)
11702 /* The Linux kernel will emulate rdhwr if it's not supported natively.
11703 Therefore only check the ISA in system mode. */
11704 check_insn(ctx, ISA_MIPS32R2);
11706 t0 = tcg_temp_new();
11710 gen_helper_rdhwr_cpunum(t0, cpu_env);
11711 gen_store_gpr(t0, rt);
11714 gen_helper_rdhwr_synci_step(t0, cpu_env);
11715 gen_store_gpr(t0, rt);
11718 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11721 gen_helper_rdhwr_cc(t0, cpu_env);
11722 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11725 gen_store_gpr(t0, rt);
11726 /* Break the TB to be able to take timer interrupts immediately
11727 after reading count. DISAS_STOP isn't sufficient, we need to ensure
11728 we break completely out of translated code. */
11729 gen_save_pc(ctx->base.pc_next + 4);
11730 ctx->base.is_jmp = DISAS_EXIT;
11733 gen_helper_rdhwr_ccres(t0, cpu_env);
11734 gen_store_gpr(t0, rt);
11737 check_insn(ctx, ISA_MIPS32R6);
11739 /* Performance counter registers are not implemented other than
11740 * control register 0.
11742 generate_exception(ctx, EXCP_RI);
11744 gen_helper_rdhwr_performance(t0, cpu_env);
11745 gen_store_gpr(t0, rt);
11748 check_insn(ctx, ISA_MIPS32R6);
11749 gen_helper_rdhwr_xnp(t0, cpu_env);
11750 gen_store_gpr(t0, rt);
11753 #if defined(CONFIG_USER_ONLY)
11754 tcg_gen_ld_tl(t0, cpu_env,
11755 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11756 gen_store_gpr(t0, rt);
11759 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11760 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11761 tcg_gen_ld_tl(t0, cpu_env,
11762 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11763 gen_store_gpr(t0, rt);
11765 generate_exception_end(ctx, EXCP_RI);
11769 default: /* Invalid */
11770 MIPS_INVAL("rdhwr");
11771 generate_exception_end(ctx, EXCP_RI);
11777 static inline void clear_branch_hflags(DisasContext *ctx)
11779 ctx->hflags &= ~MIPS_HFLAG_BMASK;
11780 if (ctx->base.is_jmp == DISAS_NEXT) {
11781 save_cpu_state(ctx, 0);
11783 /* it is not safe to save ctx->hflags as hflags may be changed
11784 in execution time by the instruction in delay / forbidden slot. */
11785 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11789 static void gen_branch(DisasContext *ctx, int insn_bytes)
11791 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11792 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11793 /* Branches completion */
11794 clear_branch_hflags(ctx);
11795 ctx->base.is_jmp = DISAS_NORETURN;
11796 /* FIXME: Need to clear can_do_io. */
11797 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11798 case MIPS_HFLAG_FBNSLOT:
11799 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11802 /* unconditional branch */
11803 if (proc_hflags & MIPS_HFLAG_BX) {
11804 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11806 gen_goto_tb(ctx, 0, ctx->btarget);
11808 case MIPS_HFLAG_BL:
11809 /* blikely taken case */
11810 gen_goto_tb(ctx, 0, ctx->btarget);
11812 case MIPS_HFLAG_BC:
11813 /* Conditional branch */
11815 TCGLabel *l1 = gen_new_label();
11817 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11818 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11820 gen_goto_tb(ctx, 0, ctx->btarget);
11823 case MIPS_HFLAG_BR:
11824 /* unconditional branch to register */
11825 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11826 TCGv t0 = tcg_temp_new();
11827 TCGv_i32 t1 = tcg_temp_new_i32();
11829 tcg_gen_andi_tl(t0, btarget, 0x1);
11830 tcg_gen_trunc_tl_i32(t1, t0);
11832 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11833 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11834 tcg_gen_or_i32(hflags, hflags, t1);
11835 tcg_temp_free_i32(t1);
11837 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11839 tcg_gen_mov_tl(cpu_PC, btarget);
11841 if (ctx->base.singlestep_enabled) {
11842 save_cpu_state(ctx, 0);
11843 gen_helper_raise_exception_debug(cpu_env);
11845 tcg_gen_lookup_and_goto_ptr();
11848 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
11854 /* Compact Branches */
11855 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11856 int rs, int rt, int32_t offset)
11858 int bcond_compute = 0;
11859 TCGv t0 = tcg_temp_new();
11860 TCGv t1 = tcg_temp_new();
11861 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11863 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11864 #ifdef MIPS_DEBUG_DISAS
11865 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11866 "\n", ctx->base.pc_next);
11868 generate_exception_end(ctx, EXCP_RI);
11872 /* Load needed operands and calculate btarget */
11874 /* compact branch */
11875 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11876 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11877 gen_load_gpr(t0, rs);
11878 gen_load_gpr(t1, rt);
11880 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11881 if (rs <= rt && rs == 0) {
11882 /* OPC_BEQZALC, OPC_BNEZALC */
11883 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11886 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11887 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11888 gen_load_gpr(t0, rs);
11889 gen_load_gpr(t1, rt);
11891 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11893 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11894 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11895 if (rs == 0 || rs == rt) {
11896 /* OPC_BLEZALC, OPC_BGEZALC */
11897 /* OPC_BGTZALC, OPC_BLTZALC */
11898 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11900 gen_load_gpr(t0, rs);
11901 gen_load_gpr(t1, rt);
11903 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11907 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11912 /* OPC_BEQZC, OPC_BNEZC */
11913 gen_load_gpr(t0, rs);
11915 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11917 /* OPC_JIC, OPC_JIALC */
11918 TCGv tbase = tcg_temp_new();
11919 TCGv toffset = tcg_temp_new();
11921 gen_load_gpr(tbase, rt);
11922 tcg_gen_movi_tl(toffset, offset);
11923 gen_op_addr_add(ctx, btarget, tbase, toffset);
11924 tcg_temp_free(tbase);
11925 tcg_temp_free(toffset);
11929 MIPS_INVAL("Compact branch/jump");
11930 generate_exception_end(ctx, EXCP_RI);
11934 if (bcond_compute == 0) {
11935 /* Uncoditional compact branch */
11938 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11941 ctx->hflags |= MIPS_HFLAG_BR;
11944 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11947 ctx->hflags |= MIPS_HFLAG_B;
11950 MIPS_INVAL("Compact branch/jump");
11951 generate_exception_end(ctx, EXCP_RI);
11955 /* Generating branch here as compact branches don't have delay slot */
11956 gen_branch(ctx, 4);
11958 /* Conditional compact branch */
11959 TCGLabel *fs = gen_new_label();
11960 save_cpu_state(ctx, 0);
11963 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11964 if (rs == 0 && rt != 0) {
11966 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11967 } else if (rs != 0 && rt != 0 && rs == rt) {
11969 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11972 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11975 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11976 if (rs == 0 && rt != 0) {
11978 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11979 } else if (rs != 0 && rt != 0 && rs == rt) {
11981 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11984 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11987 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11988 if (rs == 0 && rt != 0) {
11990 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11991 } else if (rs != 0 && rt != 0 && rs == rt) {
11993 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11996 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11999 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12000 if (rs == 0 && rt != 0) {
12002 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12003 } else if (rs != 0 && rt != 0 && rs == rt) {
12005 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12008 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12011 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12012 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12014 /* OPC_BOVC, OPC_BNVC */
12015 TCGv t2 = tcg_temp_new();
12016 TCGv t3 = tcg_temp_new();
12017 TCGv t4 = tcg_temp_new();
12018 TCGv input_overflow = tcg_temp_new();
12020 gen_load_gpr(t0, rs);
12021 gen_load_gpr(t1, rt);
12022 tcg_gen_ext32s_tl(t2, t0);
12023 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12024 tcg_gen_ext32s_tl(t3, t1);
12025 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12026 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12028 tcg_gen_add_tl(t4, t2, t3);
12029 tcg_gen_ext32s_tl(t4, t4);
12030 tcg_gen_xor_tl(t2, t2, t3);
12031 tcg_gen_xor_tl(t3, t4, t3);
12032 tcg_gen_andc_tl(t2, t3, t2);
12033 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12034 tcg_gen_or_tl(t4, t4, input_overflow);
12035 if (opc == OPC_BOVC) {
12037 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12040 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12042 tcg_temp_free(input_overflow);
12046 } else if (rs < rt && rs == 0) {
12047 /* OPC_BEQZALC, OPC_BNEZALC */
12048 if (opc == OPC_BEQZALC) {
12050 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12053 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12056 /* OPC_BEQC, OPC_BNEC */
12057 if (opc == OPC_BEQC) {
12059 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12062 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12067 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12070 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12073 MIPS_INVAL("Compact conditional branch/jump");
12074 generate_exception_end(ctx, EXCP_RI);
12078 /* Generating branch here as compact branches don't have delay slot */
12079 gen_goto_tb(ctx, 1, ctx->btarget);
12082 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12090 /* ISA extensions (ASEs) */
12091 /* MIPS16 extension to MIPS32 */
12093 /* MIPS16 major opcodes */
12095 M16_OPC_ADDIUSP = 0x00,
12096 M16_OPC_ADDIUPC = 0x01,
12098 M16_OPC_JAL = 0x03,
12099 M16_OPC_BEQZ = 0x04,
12100 M16_OPC_BNEQZ = 0x05,
12101 M16_OPC_SHIFT = 0x06,
12103 M16_OPC_RRIA = 0x08,
12104 M16_OPC_ADDIU8 = 0x09,
12105 M16_OPC_SLTI = 0x0a,
12106 M16_OPC_SLTIU = 0x0b,
12109 M16_OPC_CMPI = 0x0e,
12113 M16_OPC_LWSP = 0x12,
12115 M16_OPC_LBU = 0x14,
12116 M16_OPC_LHU = 0x15,
12117 M16_OPC_LWPC = 0x16,
12118 M16_OPC_LWU = 0x17,
12121 M16_OPC_SWSP = 0x1a,
12123 M16_OPC_RRR = 0x1c,
12125 M16_OPC_EXTEND = 0x1e,
12129 /* I8 funct field */
12148 /* RR funct field */
12182 /* I64 funct field */
12190 I64_DADDIUPC = 0x6,
12194 /* RR ry field for CNVT */
12196 RR_RY_CNVT_ZEB = 0x0,
12197 RR_RY_CNVT_ZEH = 0x1,
12198 RR_RY_CNVT_ZEW = 0x2,
12199 RR_RY_CNVT_SEB = 0x4,
12200 RR_RY_CNVT_SEH = 0x5,
12201 RR_RY_CNVT_SEW = 0x6,
12204 static int xlat (int r)
12206 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12211 static void gen_mips16_save (DisasContext *ctx,
12212 int xsregs, int aregs,
12213 int do_ra, int do_s0, int do_s1,
12216 TCGv t0 = tcg_temp_new();
12217 TCGv t1 = tcg_temp_new();
12218 TCGv t2 = tcg_temp_new();
12248 generate_exception_end(ctx, EXCP_RI);
12254 gen_base_offset_addr(ctx, t0, 29, 12);
12255 gen_load_gpr(t1, 7);
12256 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12259 gen_base_offset_addr(ctx, t0, 29, 8);
12260 gen_load_gpr(t1, 6);
12261 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12264 gen_base_offset_addr(ctx, t0, 29, 4);
12265 gen_load_gpr(t1, 5);
12266 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12269 gen_base_offset_addr(ctx, t0, 29, 0);
12270 gen_load_gpr(t1, 4);
12271 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12274 gen_load_gpr(t0, 29);
12276 #define DECR_AND_STORE(reg) do { \
12277 tcg_gen_movi_tl(t2, -4); \
12278 gen_op_addr_add(ctx, t0, t0, t2); \
12279 gen_load_gpr(t1, reg); \
12280 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12284 DECR_AND_STORE(31);
12289 DECR_AND_STORE(30);
12292 DECR_AND_STORE(23);
12295 DECR_AND_STORE(22);
12298 DECR_AND_STORE(21);
12301 DECR_AND_STORE(20);
12304 DECR_AND_STORE(19);
12307 DECR_AND_STORE(18);
12311 DECR_AND_STORE(17);
12314 DECR_AND_STORE(16);
12344 generate_exception_end(ctx, EXCP_RI);
12360 #undef DECR_AND_STORE
12362 tcg_gen_movi_tl(t2, -framesize);
12363 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12369 static void gen_mips16_restore (DisasContext *ctx,
12370 int xsregs, int aregs,
12371 int do_ra, int do_s0, int do_s1,
12375 TCGv t0 = tcg_temp_new();
12376 TCGv t1 = tcg_temp_new();
12377 TCGv t2 = tcg_temp_new();
12379 tcg_gen_movi_tl(t2, framesize);
12380 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
12382 #define DECR_AND_LOAD(reg) do { \
12383 tcg_gen_movi_tl(t2, -4); \
12384 gen_op_addr_add(ctx, t0, t0, t2); \
12385 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12386 gen_store_gpr(t1, reg); \
12450 generate_exception_end(ctx, EXCP_RI);
12466 #undef DECR_AND_LOAD
12468 tcg_gen_movi_tl(t2, framesize);
12469 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12475 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
12476 int is_64_bit, int extended)
12480 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12481 generate_exception_end(ctx, EXCP_RI);
12485 t0 = tcg_temp_new();
12487 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12488 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12490 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12496 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12499 TCGv_i32 t0 = tcg_const_i32(op);
12500 TCGv t1 = tcg_temp_new();
12501 gen_base_offset_addr(ctx, t1, base, offset);
12502 gen_helper_cache(cpu_env, t1, t0);
12505 #if defined(TARGET_MIPS64)
12506 static void decode_i64_mips16 (DisasContext *ctx,
12507 int ry, int funct, int16_t offset,
12512 check_insn(ctx, ISA_MIPS3);
12513 check_mips_64(ctx);
12514 offset = extended ? offset : offset << 3;
12515 gen_ld(ctx, OPC_LD, ry, 29, offset);
12518 check_insn(ctx, ISA_MIPS3);
12519 check_mips_64(ctx);
12520 offset = extended ? offset : offset << 3;
12521 gen_st(ctx, OPC_SD, ry, 29, offset);
12524 check_insn(ctx, ISA_MIPS3);
12525 check_mips_64(ctx);
12526 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
12527 gen_st(ctx, OPC_SD, 31, 29, offset);
12530 check_insn(ctx, ISA_MIPS3);
12531 check_mips_64(ctx);
12532 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
12533 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
12536 check_insn(ctx, ISA_MIPS3);
12537 check_mips_64(ctx);
12538 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12539 generate_exception_end(ctx, EXCP_RI);
12541 offset = extended ? offset : offset << 3;
12542 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
12546 check_insn(ctx, ISA_MIPS3);
12547 check_mips_64(ctx);
12548 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
12549 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
12552 check_insn(ctx, ISA_MIPS3);
12553 check_mips_64(ctx);
12554 offset = extended ? offset : offset << 2;
12555 gen_addiupc(ctx, ry, offset, 1, extended);
12558 check_insn(ctx, ISA_MIPS3);
12559 check_mips_64(ctx);
12560 offset = extended ? offset : offset << 2;
12561 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
12567 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
12569 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
12570 int op, rx, ry, funct, sa;
12571 int16_t imm, offset;
12573 ctx->opcode = (ctx->opcode << 16) | extend;
12574 op = (ctx->opcode >> 11) & 0x1f;
12575 sa = (ctx->opcode >> 22) & 0x1f;
12576 funct = (ctx->opcode >> 8) & 0x7;
12577 rx = xlat((ctx->opcode >> 8) & 0x7);
12578 ry = xlat((ctx->opcode >> 5) & 0x7);
12579 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
12580 | ((ctx->opcode >> 21) & 0x3f) << 5
12581 | (ctx->opcode & 0x1f));
12583 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
12586 case M16_OPC_ADDIUSP:
12587 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12589 case M16_OPC_ADDIUPC:
12590 gen_addiupc(ctx, rx, imm, 0, 1);
12593 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
12594 /* No delay slot, so just process as a normal instruction */
12597 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
12598 /* No delay slot, so just process as a normal instruction */
12600 case M16_OPC_BNEQZ:
12601 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
12602 /* No delay slot, so just process as a normal instruction */
12604 case M16_OPC_SHIFT:
12605 switch (ctx->opcode & 0x3) {
12607 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12610 #if defined(TARGET_MIPS64)
12611 check_mips_64(ctx);
12612 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12614 generate_exception_end(ctx, EXCP_RI);
12618 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12621 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12625 #if defined(TARGET_MIPS64)
12627 check_insn(ctx, ISA_MIPS3);
12628 check_mips_64(ctx);
12629 gen_ld(ctx, OPC_LD, ry, rx, offset);
12633 imm = ctx->opcode & 0xf;
12634 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
12635 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
12636 imm = (int16_t) (imm << 1) >> 1;
12637 if ((ctx->opcode >> 4) & 0x1) {
12638 #if defined(TARGET_MIPS64)
12639 check_mips_64(ctx);
12640 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12642 generate_exception_end(ctx, EXCP_RI);
12645 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12648 case M16_OPC_ADDIU8:
12649 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12652 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12654 case M16_OPC_SLTIU:
12655 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12660 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
12663 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
12666 gen_st(ctx, OPC_SW, 31, 29, imm);
12669 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
12672 check_insn(ctx, ISA_MIPS32);
12674 int xsregs = (ctx->opcode >> 24) & 0x7;
12675 int aregs = (ctx->opcode >> 16) & 0xf;
12676 int do_ra = (ctx->opcode >> 6) & 0x1;
12677 int do_s0 = (ctx->opcode >> 5) & 0x1;
12678 int do_s1 = (ctx->opcode >> 4) & 0x1;
12679 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
12680 | (ctx->opcode & 0xf)) << 3;
12682 if (ctx->opcode & (1 << 7)) {
12683 gen_mips16_save(ctx, xsregs, aregs,
12684 do_ra, do_s0, do_s1,
12687 gen_mips16_restore(ctx, xsregs, aregs,
12688 do_ra, do_s0, do_s1,
12694 generate_exception_end(ctx, EXCP_RI);
12699 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
12702 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
12704 #if defined(TARGET_MIPS64)
12706 check_insn(ctx, ISA_MIPS3);
12707 check_mips_64(ctx);
12708 gen_st(ctx, OPC_SD, ry, rx, offset);
12712 gen_ld(ctx, OPC_LB, ry, rx, offset);
12715 gen_ld(ctx, OPC_LH, ry, rx, offset);
12718 gen_ld(ctx, OPC_LW, rx, 29, offset);
12721 gen_ld(ctx, OPC_LW, ry, rx, offset);
12724 gen_ld(ctx, OPC_LBU, ry, rx, offset);
12727 gen_ld(ctx, OPC_LHU, ry, rx, offset);
12730 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
12732 #if defined(TARGET_MIPS64)
12734 check_insn(ctx, ISA_MIPS3);
12735 check_mips_64(ctx);
12736 gen_ld(ctx, OPC_LWU, ry, rx, offset);
12740 gen_st(ctx, OPC_SB, ry, rx, offset);
12743 gen_st(ctx, OPC_SH, ry, rx, offset);
12746 gen_st(ctx, OPC_SW, rx, 29, offset);
12749 gen_st(ctx, OPC_SW, ry, rx, offset);
12751 #if defined(TARGET_MIPS64)
12753 decode_i64_mips16(ctx, ry, funct, offset, 1);
12757 generate_exception_end(ctx, EXCP_RI);
12764 static inline bool is_uhi(int sdbbp_code)
12766 #ifdef CONFIG_USER_ONLY
12769 return semihosting_enabled() && sdbbp_code == 1;
12773 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
12777 int op, cnvt_op, op1, offset;
12781 op = (ctx->opcode >> 11) & 0x1f;
12782 sa = (ctx->opcode >> 2) & 0x7;
12783 sa = sa == 0 ? 8 : sa;
12784 rx = xlat((ctx->opcode >> 8) & 0x7);
12785 cnvt_op = (ctx->opcode >> 5) & 0x7;
12786 ry = xlat((ctx->opcode >> 5) & 0x7);
12787 op1 = offset = ctx->opcode & 0x1f;
12792 case M16_OPC_ADDIUSP:
12794 int16_t imm = ((uint8_t) ctx->opcode) << 2;
12796 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12799 case M16_OPC_ADDIUPC:
12800 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
12803 offset = (ctx->opcode & 0x7ff) << 1;
12804 offset = (int16_t)(offset << 4) >> 4;
12805 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
12806 /* No delay slot, so just process as a normal instruction */
12809 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
12810 offset = (((ctx->opcode & 0x1f) << 21)
12811 | ((ctx->opcode >> 5) & 0x1f) << 16
12813 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
12814 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
12818 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
12819 ((int8_t)ctx->opcode) << 1, 0);
12820 /* No delay slot, so just process as a normal instruction */
12822 case M16_OPC_BNEQZ:
12823 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
12824 ((int8_t)ctx->opcode) << 1, 0);
12825 /* No delay slot, so just process as a normal instruction */
12827 case M16_OPC_SHIFT:
12828 switch (ctx->opcode & 0x3) {
12830 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12833 #if defined(TARGET_MIPS64)
12834 check_insn(ctx, ISA_MIPS3);
12835 check_mips_64(ctx);
12836 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12838 generate_exception_end(ctx, EXCP_RI);
12842 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12845 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12849 #if defined(TARGET_MIPS64)
12851 check_insn(ctx, ISA_MIPS3);
12852 check_mips_64(ctx);
12853 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
12858 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
12860 if ((ctx->opcode >> 4) & 1) {
12861 #if defined(TARGET_MIPS64)
12862 check_insn(ctx, ISA_MIPS3);
12863 check_mips_64(ctx);
12864 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12866 generate_exception_end(ctx, EXCP_RI);
12869 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12873 case M16_OPC_ADDIU8:
12875 int16_t imm = (int8_t) ctx->opcode;
12877 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12882 int16_t imm = (uint8_t) ctx->opcode;
12883 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12886 case M16_OPC_SLTIU:
12888 int16_t imm = (uint8_t) ctx->opcode;
12889 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12896 funct = (ctx->opcode >> 8) & 0x7;
12899 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
12900 ((int8_t)ctx->opcode) << 1, 0);
12903 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
12904 ((int8_t)ctx->opcode) << 1, 0);
12907 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
12910 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
12911 ((int8_t)ctx->opcode) << 3);
12914 check_insn(ctx, ISA_MIPS32);
12916 int do_ra = ctx->opcode & (1 << 6);
12917 int do_s0 = ctx->opcode & (1 << 5);
12918 int do_s1 = ctx->opcode & (1 << 4);
12919 int framesize = ctx->opcode & 0xf;
12921 if (framesize == 0) {
12924 framesize = framesize << 3;
12927 if (ctx->opcode & (1 << 7)) {
12928 gen_mips16_save(ctx, 0, 0,
12929 do_ra, do_s0, do_s1, framesize);
12931 gen_mips16_restore(ctx, 0, 0,
12932 do_ra, do_s0, do_s1, framesize);
12938 int rz = xlat(ctx->opcode & 0x7);
12940 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
12941 ((ctx->opcode >> 5) & 0x7);
12942 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
12946 reg32 = ctx->opcode & 0x1f;
12947 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
12950 generate_exception_end(ctx, EXCP_RI);
12957 int16_t imm = (uint8_t) ctx->opcode;
12959 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
12964 int16_t imm = (uint8_t) ctx->opcode;
12965 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
12968 #if defined(TARGET_MIPS64)
12970 check_insn(ctx, ISA_MIPS3);
12971 check_mips_64(ctx);
12972 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
12976 gen_ld(ctx, OPC_LB, ry, rx, offset);
12979 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
12982 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
12985 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
12988 gen_ld(ctx, OPC_LBU, ry, rx, offset);
12991 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
12994 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
12996 #if defined (TARGET_MIPS64)
12998 check_insn(ctx, ISA_MIPS3);
12999 check_mips_64(ctx);
13000 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13004 gen_st(ctx, OPC_SB, ry, rx, offset);
13007 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13010 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13013 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13017 int rz = xlat((ctx->opcode >> 2) & 0x7);
13020 switch (ctx->opcode & 0x3) {
13022 mips32_op = OPC_ADDU;
13025 mips32_op = OPC_SUBU;
13027 #if defined(TARGET_MIPS64)
13029 mips32_op = OPC_DADDU;
13030 check_insn(ctx, ISA_MIPS3);
13031 check_mips_64(ctx);
13034 mips32_op = OPC_DSUBU;
13035 check_insn(ctx, ISA_MIPS3);
13036 check_mips_64(ctx);
13040 generate_exception_end(ctx, EXCP_RI);
13044 gen_arith(ctx, mips32_op, rz, rx, ry);
13053 int nd = (ctx->opcode >> 7) & 0x1;
13054 int link = (ctx->opcode >> 6) & 0x1;
13055 int ra = (ctx->opcode >> 5) & 0x1;
13058 check_insn(ctx, ISA_MIPS32);
13067 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13072 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13073 gen_helper_do_semihosting(cpu_env);
13075 /* XXX: not clear which exception should be raised
13076 * when in debug mode...
13078 check_insn(ctx, ISA_MIPS32);
13079 generate_exception_end(ctx, EXCP_DBp);
13083 gen_slt(ctx, OPC_SLT, 24, rx, ry);
13086 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13089 generate_exception_end(ctx, EXCP_BREAK);
13092 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13095 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13098 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13100 #if defined (TARGET_MIPS64)
13102 check_insn(ctx, ISA_MIPS3);
13103 check_mips_64(ctx);
13104 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13108 gen_logic(ctx, OPC_XOR, 24, rx, ry);
13111 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13114 gen_logic(ctx, OPC_AND, rx, rx, ry);
13117 gen_logic(ctx, OPC_OR, rx, rx, ry);
13120 gen_logic(ctx, OPC_XOR, rx, rx, ry);
13123 gen_logic(ctx, OPC_NOR, rx, ry, 0);
13126 gen_HILO(ctx, OPC_MFHI, 0, rx);
13129 check_insn(ctx, ISA_MIPS32);
13131 case RR_RY_CNVT_ZEB:
13132 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13134 case RR_RY_CNVT_ZEH:
13135 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13137 case RR_RY_CNVT_SEB:
13138 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13140 case RR_RY_CNVT_SEH:
13141 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13143 #if defined (TARGET_MIPS64)
13144 case RR_RY_CNVT_ZEW:
13145 check_insn(ctx, ISA_MIPS64);
13146 check_mips_64(ctx);
13147 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13149 case RR_RY_CNVT_SEW:
13150 check_insn(ctx, ISA_MIPS64);
13151 check_mips_64(ctx);
13152 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13156 generate_exception_end(ctx, EXCP_RI);
13161 gen_HILO(ctx, OPC_MFLO, 0, rx);
13163 #if defined (TARGET_MIPS64)
13165 check_insn(ctx, ISA_MIPS3);
13166 check_mips_64(ctx);
13167 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13170 check_insn(ctx, ISA_MIPS3);
13171 check_mips_64(ctx);
13172 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
13175 check_insn(ctx, ISA_MIPS3);
13176 check_mips_64(ctx);
13177 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
13180 check_insn(ctx, ISA_MIPS3);
13181 check_mips_64(ctx);
13182 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
13186 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
13189 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
13192 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
13195 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
13197 #if defined (TARGET_MIPS64)
13199 check_insn(ctx, ISA_MIPS3);
13200 check_mips_64(ctx);
13201 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
13204 check_insn(ctx, ISA_MIPS3);
13205 check_mips_64(ctx);
13206 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
13209 check_insn(ctx, ISA_MIPS3);
13210 check_mips_64(ctx);
13211 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
13214 check_insn(ctx, ISA_MIPS3);
13215 check_mips_64(ctx);
13216 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
13220 generate_exception_end(ctx, EXCP_RI);
13224 case M16_OPC_EXTEND:
13225 decode_extended_mips16_opc(env, ctx);
13228 #if defined(TARGET_MIPS64)
13230 funct = (ctx->opcode >> 8) & 0x7;
13231 decode_i64_mips16(ctx, ry, funct, offset, 0);
13235 generate_exception_end(ctx, EXCP_RI);
13242 /* microMIPS extension to MIPS32/MIPS64 */
13245 * microMIPS32/microMIPS64 major opcodes
13247 * 1. MIPS Architecture for Programmers Volume II-B:
13248 * The microMIPS32 Instruction Set (Revision 3.05)
13250 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13252 * 2. MIPS Architecture For Programmers Volume II-A:
13253 * The MIPS64 Instruction Set (Revision 3.51)
13283 POOL32S = 0x16, /* MIPS64 */
13284 DADDIU32 = 0x17, /* MIPS64 */
13313 /* 0x29 is reserved */
13326 /* 0x31 is reserved */
13339 SD32 = 0x36, /* MIPS64 */
13340 LD32 = 0x37, /* MIPS64 */
13342 /* 0x39 is reserved */
13358 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13380 /* POOL32A encoding of minor opcode field */
13383 /* These opcodes are distinguished only by bits 9..6; those bits are
13384 * what are recorded below. */
13421 /* The following can be distinguished by their lower 6 bits. */
13431 /* POOL32AXF encoding of minor opcode field extension */
13434 * 1. MIPS Architecture for Programmers Volume II-B:
13435 * The microMIPS32 Instruction Set (Revision 3.05)
13437 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13439 * 2. MIPS Architecture for Programmers VolumeIV-e:
13440 * The MIPS DSP Application-Specific Extension
13441 * to the microMIPS32 Architecture (Revision 2.34)
13443 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13458 /* begin of microMIPS32 DSP */
13460 /* bits 13..12 for 0x01 */
13466 /* bits 13..12 for 0x2a */
13472 /* bits 13..12 for 0x32 */
13476 /* end of microMIPS32 DSP */
13478 /* bits 15..12 for 0x2c */
13495 /* bits 15..12 for 0x34 */
13503 /* bits 15..12 for 0x3c */
13505 JR = 0x0, /* alias */
13513 /* bits 15..12 for 0x05 */
13517 /* bits 15..12 for 0x0d */
13529 /* bits 15..12 for 0x15 */
13535 /* bits 15..12 for 0x1d */
13539 /* bits 15..12 for 0x2d */
13544 /* bits 15..12 for 0x35 */
13551 /* POOL32B encoding of minor opcode field (bits 15..12) */
13567 /* POOL32C encoding of minor opcode field (bits 15..12) */
13588 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13601 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13614 /* POOL32F encoding of minor opcode field (bits 5..0) */
13617 /* These are the bit 7..6 values */
13626 /* These are the bit 8..6 values */
13651 MOVZ_FMT_05 = 0x05,
13685 CABS_COND_FMT = 0x1c, /* MIPS3D */
13692 /* POOL32Fxf encoding of minor opcode extension field */
13730 /* POOL32I encoding of minor opcode field (bits 25..21) */
13760 /* These overlap and are distinguished by bit16 of the instruction */
13769 /* POOL16A encoding of minor opcode field */
13776 /* POOL16B encoding of minor opcode field */
13783 /* POOL16C encoding of minor opcode field */
13803 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
13827 /* POOL16D encoding of minor opcode field */
13834 /* POOL16E encoding of minor opcode field */
13841 static int mmreg (int r)
13843 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13848 /* Used for 16-bit store instructions. */
13849 static int mmreg2 (int r)
13851 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
13856 #define uMIPS_RD(op) ((op >> 7) & 0x7)
13857 #define uMIPS_RS(op) ((op >> 4) & 0x7)
13858 #define uMIPS_RS2(op) uMIPS_RS(op)
13859 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
13860 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
13861 #define uMIPS_RS5(op) (op & 0x1f)
13863 /* Signed immediate */
13864 #define SIMM(op, start, width) \
13865 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
13868 /* Zero-extended immediate */
13869 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
13871 static void gen_addiur1sp(DisasContext *ctx)
13873 int rd = mmreg(uMIPS_RD(ctx->opcode));
13875 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
13878 static void gen_addiur2(DisasContext *ctx)
13880 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
13881 int rd = mmreg(uMIPS_RD(ctx->opcode));
13882 int rs = mmreg(uMIPS_RS(ctx->opcode));
13884 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
13887 static void gen_addiusp(DisasContext *ctx)
13889 int encoded = ZIMM(ctx->opcode, 1, 9);
13892 if (encoded <= 1) {
13893 decoded = 256 + encoded;
13894 } else if (encoded <= 255) {
13896 } else if (encoded <= 509) {
13897 decoded = encoded - 512;
13899 decoded = encoded - 768;
13902 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
13905 static void gen_addius5(DisasContext *ctx)
13907 int imm = SIMM(ctx->opcode, 1, 4);
13908 int rd = (ctx->opcode >> 5) & 0x1f;
13910 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
13913 static void gen_andi16(DisasContext *ctx)
13915 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13916 31, 32, 63, 64, 255, 32768, 65535 };
13917 int rd = mmreg(uMIPS_RD(ctx->opcode));
13918 int rs = mmreg(uMIPS_RS(ctx->opcode));
13919 int encoded = ZIMM(ctx->opcode, 0, 4);
13921 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
13924 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
13925 int base, int16_t offset)
13930 if (ctx->hflags & MIPS_HFLAG_BMASK) {
13931 generate_exception_end(ctx, EXCP_RI);
13935 t0 = tcg_temp_new();
13937 gen_base_offset_addr(ctx, t0, base, offset);
13939 t1 = tcg_const_tl(reglist);
13940 t2 = tcg_const_i32(ctx->mem_idx);
13942 save_cpu_state(ctx, 1);
13945 gen_helper_lwm(cpu_env, t0, t1, t2);
13948 gen_helper_swm(cpu_env, t0, t1, t2);
13950 #ifdef TARGET_MIPS64
13952 gen_helper_ldm(cpu_env, t0, t1, t2);
13955 gen_helper_sdm(cpu_env, t0, t1, t2);
13961 tcg_temp_free_i32(t2);
13965 static void gen_pool16c_insn(DisasContext *ctx)
13967 int rd = mmreg((ctx->opcode >> 3) & 0x7);
13968 int rs = mmreg(ctx->opcode & 0x7);
13970 switch (((ctx->opcode) >> 4) & 0x3f) {
13975 gen_logic(ctx, OPC_NOR, rd, rs, 0);
13981 gen_logic(ctx, OPC_XOR, rd, rd, rs);
13987 gen_logic(ctx, OPC_AND, rd, rd, rs);
13993 gen_logic(ctx, OPC_OR, rd, rd, rs);
14000 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14001 int offset = ZIMM(ctx->opcode, 0, 4);
14003 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14012 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14013 int offset = ZIMM(ctx->opcode, 0, 4);
14015 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14022 int reg = ctx->opcode & 0x1f;
14024 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14030 int reg = ctx->opcode & 0x1f;
14031 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14032 /* Let normal delay slot handling in our caller take us
14033 to the branch target. */
14038 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14039 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14043 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14044 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14048 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14052 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14055 generate_exception_end(ctx, EXCP_BREAK);
14058 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14059 gen_helper_do_semihosting(cpu_env);
14061 /* XXX: not clear which exception should be raised
14062 * when in debug mode...
14064 check_insn(ctx, ISA_MIPS32);
14065 generate_exception_end(ctx, EXCP_DBp);
14068 case JRADDIUSP + 0:
14069 case JRADDIUSP + 1:
14071 int imm = ZIMM(ctx->opcode, 0, 5);
14072 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14073 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14074 /* Let normal delay slot handling in our caller take us
14075 to the branch target. */
14079 generate_exception_end(ctx, EXCP_RI);
14084 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14087 int rd, rs, re, rt;
14088 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14089 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14090 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14091 rd = rd_enc[enc_dest];
14092 re = re_enc[enc_dest];
14093 rs = rs_rt_enc[enc_rs];
14094 rt = rs_rt_enc[enc_rt];
14096 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14098 tcg_gen_movi_tl(cpu_gpr[rd], 0);
14101 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14103 tcg_gen_movi_tl(cpu_gpr[re], 0);
14107 static void gen_pool16c_r6_insn(DisasContext *ctx)
14109 int rt = mmreg((ctx->opcode >> 7) & 0x7);
14110 int rs = mmreg((ctx->opcode >> 4) & 0x7);
14112 switch (ctx->opcode & 0xf) {
14114 gen_logic(ctx, OPC_NOR, rt, rs, 0);
14117 gen_logic(ctx, OPC_AND, rt, rt, rs);
14121 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14122 int offset = extract32(ctx->opcode, 4, 4);
14123 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14126 case R6_JRC16: /* JRCADDIUSP */
14127 if ((ctx->opcode >> 4) & 1) {
14129 int imm = extract32(ctx->opcode, 5, 5);
14130 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14131 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14134 rs = extract32(ctx->opcode, 5, 5);
14135 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14147 int enc_dest = uMIPS_RD(ctx->opcode);
14148 int enc_rt = uMIPS_RS2(ctx->opcode);
14149 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14150 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14154 gen_logic(ctx, OPC_XOR, rt, rt, rs);
14157 gen_logic(ctx, OPC_OR, rt, rt, rs);
14161 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14162 int offset = extract32(ctx->opcode, 4, 4);
14163 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14166 case JALRC16: /* BREAK16, SDBBP16 */
14167 switch (ctx->opcode & 0x3f) {
14169 case JALRC16 + 0x20:
14171 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14176 generate_exception(ctx, EXCP_BREAK);
14180 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14181 gen_helper_do_semihosting(cpu_env);
14183 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14184 generate_exception(ctx, EXCP_RI);
14186 generate_exception(ctx, EXCP_DBp);
14193 generate_exception(ctx, EXCP_RI);
14198 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14200 TCGv t0 = tcg_temp_new();
14201 TCGv t1 = tcg_temp_new();
14203 gen_load_gpr(t0, base);
14206 gen_load_gpr(t1, index);
14207 tcg_gen_shli_tl(t1, t1, 2);
14208 gen_op_addr_add(ctx, t0, t1, t0);
14211 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14212 gen_store_gpr(t1, rd);
14218 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14219 int base, int16_t offset)
14223 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
14224 generate_exception_end(ctx, EXCP_RI);
14228 t0 = tcg_temp_new();
14229 t1 = tcg_temp_new();
14231 gen_base_offset_addr(ctx, t0, base, offset);
14236 generate_exception_end(ctx, EXCP_RI);
14239 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14240 gen_store_gpr(t1, rd);
14241 tcg_gen_movi_tl(t1, 4);
14242 gen_op_addr_add(ctx, t0, t0, t1);
14243 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14244 gen_store_gpr(t1, rd+1);
14247 gen_load_gpr(t1, rd);
14248 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14249 tcg_gen_movi_tl(t1, 4);
14250 gen_op_addr_add(ctx, t0, t0, t1);
14251 gen_load_gpr(t1, rd+1);
14252 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14254 #ifdef TARGET_MIPS64
14257 generate_exception_end(ctx, EXCP_RI);
14260 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14261 gen_store_gpr(t1, rd);
14262 tcg_gen_movi_tl(t1, 8);
14263 gen_op_addr_add(ctx, t0, t0, t1);
14264 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14265 gen_store_gpr(t1, rd+1);
14268 gen_load_gpr(t1, rd);
14269 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14270 tcg_gen_movi_tl(t1, 8);
14271 gen_op_addr_add(ctx, t0, t0, t1);
14272 gen_load_gpr(t1, rd+1);
14273 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14281 static void gen_sync(int stype)
14283 TCGBar tcg_mo = TCG_BAR_SC;
14286 case 0x4: /* SYNC_WMB */
14287 tcg_mo |= TCG_MO_ST_ST;
14289 case 0x10: /* SYNC_MB */
14290 tcg_mo |= TCG_MO_ALL;
14292 case 0x11: /* SYNC_ACQUIRE */
14293 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14295 case 0x12: /* SYNC_RELEASE */
14296 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14298 case 0x13: /* SYNC_RMB */
14299 tcg_mo |= TCG_MO_LD_LD;
14302 tcg_mo |= TCG_MO_ALL;
14306 tcg_gen_mb(tcg_mo);
14309 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
14311 int extension = (ctx->opcode >> 6) & 0x3f;
14312 int minor = (ctx->opcode >> 12) & 0xf;
14313 uint32_t mips32_op;
14315 switch (extension) {
14317 mips32_op = OPC_TEQ;
14320 mips32_op = OPC_TGE;
14323 mips32_op = OPC_TGEU;
14326 mips32_op = OPC_TLT;
14329 mips32_op = OPC_TLTU;
14332 mips32_op = OPC_TNE;
14334 gen_trap(ctx, mips32_op, rs, rt, -1);
14336 #ifndef CONFIG_USER_ONLY
14339 check_cp0_enabled(ctx);
14341 /* Treat as NOP. */
14344 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
14348 check_cp0_enabled(ctx);
14350 TCGv t0 = tcg_temp_new();
14352 gen_load_gpr(t0, rt);
14353 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
14359 switch (minor & 3) {
14361 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
14364 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
14367 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
14370 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
14373 goto pool32axf_invalid;
14377 switch (minor & 3) {
14379 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
14382 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
14385 goto pool32axf_invalid;
14391 check_insn(ctx, ISA_MIPS32R6);
14392 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
14395 gen_bshfl(ctx, OPC_SEB, rs, rt);
14398 gen_bshfl(ctx, OPC_SEH, rs, rt);
14401 mips32_op = OPC_CLO;
14404 mips32_op = OPC_CLZ;
14406 check_insn(ctx, ISA_MIPS32);
14407 gen_cl(ctx, mips32_op, rt, rs);
14410 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14411 gen_rdhwr(ctx, rt, rs, 0);
14414 gen_bshfl(ctx, OPC_WSBH, rs, rt);
14417 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14418 mips32_op = OPC_MULT;
14421 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14422 mips32_op = OPC_MULTU;
14425 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14426 mips32_op = OPC_DIV;
14429 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14430 mips32_op = OPC_DIVU;
14433 check_insn(ctx, ISA_MIPS32);
14434 gen_muldiv(ctx, mips32_op, 0, rs, rt);
14437 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14438 mips32_op = OPC_MADD;
14441 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14442 mips32_op = OPC_MADDU;
14445 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14446 mips32_op = OPC_MSUB;
14449 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14450 mips32_op = OPC_MSUBU;
14452 check_insn(ctx, ISA_MIPS32);
14453 gen_muldiv(ctx, mips32_op, 0, rs, rt);
14456 goto pool32axf_invalid;
14467 generate_exception_err(ctx, EXCP_CpU, 2);
14470 goto pool32axf_invalid;
14475 case JALR: /* JALRC */
14476 case JALR_HB: /* JALRC_HB */
14477 if (ctx->insn_flags & ISA_MIPS32R6) {
14478 /* JALRC, JALRC_HB */
14479 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
14481 /* JALR, JALR_HB */
14482 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
14483 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14488 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14489 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
14490 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14493 goto pool32axf_invalid;
14499 check_cp0_enabled(ctx);
14500 check_insn(ctx, ISA_MIPS32R2);
14501 gen_load_srsgpr(rs, rt);
14504 check_cp0_enabled(ctx);
14505 check_insn(ctx, ISA_MIPS32R2);
14506 gen_store_srsgpr(rs, rt);
14509 goto pool32axf_invalid;
14512 #ifndef CONFIG_USER_ONLY
14516 mips32_op = OPC_TLBP;
14519 mips32_op = OPC_TLBR;
14522 mips32_op = OPC_TLBWI;
14525 mips32_op = OPC_TLBWR;
14528 mips32_op = OPC_TLBINV;
14531 mips32_op = OPC_TLBINVF;
14534 mips32_op = OPC_WAIT;
14537 mips32_op = OPC_DERET;
14540 mips32_op = OPC_ERET;
14542 gen_cp0(env, ctx, mips32_op, rt, rs);
14545 goto pool32axf_invalid;
14551 check_cp0_enabled(ctx);
14553 TCGv t0 = tcg_temp_new();
14555 save_cpu_state(ctx, 1);
14556 gen_helper_di(t0, cpu_env);
14557 gen_store_gpr(t0, rs);
14558 /* Stop translation as we may have switched the execution mode */
14559 ctx->base.is_jmp = DISAS_STOP;
14564 check_cp0_enabled(ctx);
14566 TCGv t0 = tcg_temp_new();
14568 save_cpu_state(ctx, 1);
14569 gen_helper_ei(t0, cpu_env);
14570 gen_store_gpr(t0, rs);
14571 /* DISAS_STOP isn't sufficient, we need to ensure we break out
14572 of translated code to check for pending interrupts. */
14573 gen_save_pc(ctx->base.pc_next + 4);
14574 ctx->base.is_jmp = DISAS_EXIT;
14579 goto pool32axf_invalid;
14586 gen_sync(extract32(ctx->opcode, 16, 5));
14589 generate_exception_end(ctx, EXCP_SYSCALL);
14592 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
14593 gen_helper_do_semihosting(cpu_env);
14595 check_insn(ctx, ISA_MIPS32);
14596 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14597 generate_exception_end(ctx, EXCP_RI);
14599 generate_exception_end(ctx, EXCP_DBp);
14604 goto pool32axf_invalid;
14608 switch (minor & 3) {
14610 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
14613 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
14616 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
14619 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
14622 goto pool32axf_invalid;
14626 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14629 gen_HILO(ctx, OPC_MFHI, 0, rs);
14632 gen_HILO(ctx, OPC_MFLO, 0, rs);
14635 gen_HILO(ctx, OPC_MTHI, 0, rs);
14638 gen_HILO(ctx, OPC_MTLO, 0, rs);
14641 goto pool32axf_invalid;
14646 MIPS_INVAL("pool32axf");
14647 generate_exception_end(ctx, EXCP_RI);
14652 /* Values for microMIPS fmt field. Variable-width, depending on which
14653 formats the instruction supports. */
14672 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
14674 int extension = (ctx->opcode >> 6) & 0x3ff;
14675 uint32_t mips32_op;
14677 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
14678 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
14679 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
14681 switch (extension) {
14682 case FLOAT_1BIT_FMT(CFC1, 0):
14683 mips32_op = OPC_CFC1;
14685 case FLOAT_1BIT_FMT(CTC1, 0):
14686 mips32_op = OPC_CTC1;
14688 case FLOAT_1BIT_FMT(MFC1, 0):
14689 mips32_op = OPC_MFC1;
14691 case FLOAT_1BIT_FMT(MTC1, 0):
14692 mips32_op = OPC_MTC1;
14694 case FLOAT_1BIT_FMT(MFHC1, 0):
14695 mips32_op = OPC_MFHC1;
14697 case FLOAT_1BIT_FMT(MTHC1, 0):
14698 mips32_op = OPC_MTHC1;
14700 gen_cp1(ctx, mips32_op, rt, rs);
14703 /* Reciprocal square root */
14704 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
14705 mips32_op = OPC_RSQRT_S;
14707 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
14708 mips32_op = OPC_RSQRT_D;
14712 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
14713 mips32_op = OPC_SQRT_S;
14715 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
14716 mips32_op = OPC_SQRT_D;
14720 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
14721 mips32_op = OPC_RECIP_S;
14723 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
14724 mips32_op = OPC_RECIP_D;
14728 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
14729 mips32_op = OPC_FLOOR_L_S;
14731 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
14732 mips32_op = OPC_FLOOR_L_D;
14734 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
14735 mips32_op = OPC_FLOOR_W_S;
14737 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
14738 mips32_op = OPC_FLOOR_W_D;
14742 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
14743 mips32_op = OPC_CEIL_L_S;
14745 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
14746 mips32_op = OPC_CEIL_L_D;
14748 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
14749 mips32_op = OPC_CEIL_W_S;
14751 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
14752 mips32_op = OPC_CEIL_W_D;
14756 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
14757 mips32_op = OPC_TRUNC_L_S;
14759 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
14760 mips32_op = OPC_TRUNC_L_D;
14762 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
14763 mips32_op = OPC_TRUNC_W_S;
14765 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
14766 mips32_op = OPC_TRUNC_W_D;
14770 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
14771 mips32_op = OPC_ROUND_L_S;
14773 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
14774 mips32_op = OPC_ROUND_L_D;
14776 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
14777 mips32_op = OPC_ROUND_W_S;
14779 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
14780 mips32_op = OPC_ROUND_W_D;
14783 /* Integer to floating-point conversion */
14784 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
14785 mips32_op = OPC_CVT_L_S;
14787 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
14788 mips32_op = OPC_CVT_L_D;
14790 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
14791 mips32_op = OPC_CVT_W_S;
14793 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
14794 mips32_op = OPC_CVT_W_D;
14797 /* Paired-foo conversions */
14798 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
14799 mips32_op = OPC_CVT_S_PL;
14801 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
14802 mips32_op = OPC_CVT_S_PU;
14804 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
14805 mips32_op = OPC_CVT_PW_PS;
14807 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
14808 mips32_op = OPC_CVT_PS_PW;
14811 /* Floating-point moves */
14812 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
14813 mips32_op = OPC_MOV_S;
14815 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
14816 mips32_op = OPC_MOV_D;
14818 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
14819 mips32_op = OPC_MOV_PS;
14822 /* Absolute value */
14823 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
14824 mips32_op = OPC_ABS_S;
14826 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
14827 mips32_op = OPC_ABS_D;
14829 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
14830 mips32_op = OPC_ABS_PS;
14834 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
14835 mips32_op = OPC_NEG_S;
14837 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
14838 mips32_op = OPC_NEG_D;
14840 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
14841 mips32_op = OPC_NEG_PS;
14844 /* Reciprocal square root step */
14845 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
14846 mips32_op = OPC_RSQRT1_S;
14848 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
14849 mips32_op = OPC_RSQRT1_D;
14851 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
14852 mips32_op = OPC_RSQRT1_PS;
14855 /* Reciprocal step */
14856 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
14857 mips32_op = OPC_RECIP1_S;
14859 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
14860 mips32_op = OPC_RECIP1_S;
14862 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
14863 mips32_op = OPC_RECIP1_PS;
14866 /* Conversions from double */
14867 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
14868 mips32_op = OPC_CVT_D_S;
14870 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
14871 mips32_op = OPC_CVT_D_W;
14873 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
14874 mips32_op = OPC_CVT_D_L;
14877 /* Conversions from single */
14878 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
14879 mips32_op = OPC_CVT_S_D;
14881 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
14882 mips32_op = OPC_CVT_S_W;
14884 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
14885 mips32_op = OPC_CVT_S_L;
14887 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
14890 /* Conditional moves on floating-point codes */
14891 case COND_FLOAT_MOV(MOVT, 0):
14892 case COND_FLOAT_MOV(MOVT, 1):
14893 case COND_FLOAT_MOV(MOVT, 2):
14894 case COND_FLOAT_MOV(MOVT, 3):
14895 case COND_FLOAT_MOV(MOVT, 4):
14896 case COND_FLOAT_MOV(MOVT, 5):
14897 case COND_FLOAT_MOV(MOVT, 6):
14898 case COND_FLOAT_MOV(MOVT, 7):
14899 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14900 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
14902 case COND_FLOAT_MOV(MOVF, 0):
14903 case COND_FLOAT_MOV(MOVF, 1):
14904 case COND_FLOAT_MOV(MOVF, 2):
14905 case COND_FLOAT_MOV(MOVF, 3):
14906 case COND_FLOAT_MOV(MOVF, 4):
14907 case COND_FLOAT_MOV(MOVF, 5):
14908 case COND_FLOAT_MOV(MOVF, 6):
14909 case COND_FLOAT_MOV(MOVF, 7):
14910 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14911 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
14914 MIPS_INVAL("pool32fxf");
14915 generate_exception_end(ctx, EXCP_RI);
14920 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
14924 int rt, rs, rd, rr;
14926 uint32_t op, minor, minor2, mips32_op;
14927 uint32_t cond, fmt, cc;
14929 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
14930 ctx->opcode = (ctx->opcode << 16) | insn;
14932 rt = (ctx->opcode >> 21) & 0x1f;
14933 rs = (ctx->opcode >> 16) & 0x1f;
14934 rd = (ctx->opcode >> 11) & 0x1f;
14935 rr = (ctx->opcode >> 6) & 0x1f;
14936 imm = (int16_t) ctx->opcode;
14938 op = (ctx->opcode >> 26) & 0x3f;
14941 minor = ctx->opcode & 0x3f;
14944 minor = (ctx->opcode >> 6) & 0xf;
14947 mips32_op = OPC_SLL;
14950 mips32_op = OPC_SRA;
14953 mips32_op = OPC_SRL;
14956 mips32_op = OPC_ROTR;
14958 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
14961 check_insn(ctx, ISA_MIPS32R6);
14962 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
14965 check_insn(ctx, ISA_MIPS32R6);
14966 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
14969 check_insn(ctx, ISA_MIPS32R6);
14970 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
14973 goto pool32a_invalid;
14977 minor = (ctx->opcode >> 6) & 0xf;
14981 mips32_op = OPC_ADD;
14984 mips32_op = OPC_ADDU;
14987 mips32_op = OPC_SUB;
14990 mips32_op = OPC_SUBU;
14993 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14994 mips32_op = OPC_MUL;
14996 gen_arith(ctx, mips32_op, rd, rs, rt);
15000 mips32_op = OPC_SLLV;
15003 mips32_op = OPC_SRLV;
15006 mips32_op = OPC_SRAV;
15009 mips32_op = OPC_ROTRV;
15011 gen_shift(ctx, mips32_op, rd, rs, rt);
15013 /* Logical operations */
15015 mips32_op = OPC_AND;
15018 mips32_op = OPC_OR;
15021 mips32_op = OPC_NOR;
15024 mips32_op = OPC_XOR;
15026 gen_logic(ctx, mips32_op, rd, rs, rt);
15028 /* Set less than */
15030 mips32_op = OPC_SLT;
15033 mips32_op = OPC_SLTU;
15035 gen_slt(ctx, mips32_op, rd, rs, rt);
15038 goto pool32a_invalid;
15042 minor = (ctx->opcode >> 6) & 0xf;
15044 /* Conditional moves */
15045 case MOVN: /* MUL */
15046 if (ctx->insn_flags & ISA_MIPS32R6) {
15048 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15051 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15054 case MOVZ: /* MUH */
15055 if (ctx->insn_flags & ISA_MIPS32R6) {
15057 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15060 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15064 check_insn(ctx, ISA_MIPS32R6);
15065 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15068 check_insn(ctx, ISA_MIPS32R6);
15069 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15071 case LWXS: /* DIV */
15072 if (ctx->insn_flags & ISA_MIPS32R6) {
15074 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15077 gen_ldxs(ctx, rs, rt, rd);
15081 check_insn(ctx, ISA_MIPS32R6);
15082 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15085 check_insn(ctx, ISA_MIPS32R6);
15086 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15089 check_insn(ctx, ISA_MIPS32R6);
15090 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15093 goto pool32a_invalid;
15097 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15100 check_insn(ctx, ISA_MIPS32R6);
15101 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15102 extract32(ctx->opcode, 9, 2));
15105 check_insn(ctx, ISA_MIPS32R6);
15106 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15109 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15112 gen_pool32axf(env, ctx, rt, rs);
15115 generate_exception_end(ctx, EXCP_BREAK);
15118 check_insn(ctx, ISA_MIPS32R6);
15119 generate_exception_end(ctx, EXCP_RI);
15123 MIPS_INVAL("pool32a");
15124 generate_exception_end(ctx, EXCP_RI);
15129 minor = (ctx->opcode >> 12) & 0xf;
15132 check_cp0_enabled(ctx);
15133 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15134 gen_cache_operation(ctx, rt, rs, imm);
15139 /* COP2: Not implemented. */
15140 generate_exception_err(ctx, EXCP_CpU, 2);
15142 #ifdef TARGET_MIPS64
15145 check_insn(ctx, ISA_MIPS3);
15146 check_mips_64(ctx);
15151 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15153 #ifdef TARGET_MIPS64
15156 check_insn(ctx, ISA_MIPS3);
15157 check_mips_64(ctx);
15162 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15165 MIPS_INVAL("pool32b");
15166 generate_exception_end(ctx, EXCP_RI);
15171 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15172 minor = ctx->opcode & 0x3f;
15173 check_cp1_enabled(ctx);
15176 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15177 mips32_op = OPC_ALNV_PS;
15180 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15181 mips32_op = OPC_MADD_S;
15184 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15185 mips32_op = OPC_MADD_D;
15188 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15189 mips32_op = OPC_MADD_PS;
15192 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15193 mips32_op = OPC_MSUB_S;
15196 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15197 mips32_op = OPC_MSUB_D;
15200 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15201 mips32_op = OPC_MSUB_PS;
15204 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15205 mips32_op = OPC_NMADD_S;
15208 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15209 mips32_op = OPC_NMADD_D;
15212 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15213 mips32_op = OPC_NMADD_PS;
15216 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15217 mips32_op = OPC_NMSUB_S;
15220 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15221 mips32_op = OPC_NMSUB_D;
15224 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15225 mips32_op = OPC_NMSUB_PS;
15227 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15229 case CABS_COND_FMT:
15230 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15231 cond = (ctx->opcode >> 6) & 0xf;
15232 cc = (ctx->opcode >> 13) & 0x7;
15233 fmt = (ctx->opcode >> 10) & 0x3;
15236 gen_cmpabs_s(ctx, cond, rt, rs, cc);
15239 gen_cmpabs_d(ctx, cond, rt, rs, cc);
15242 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15245 goto pool32f_invalid;
15249 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15250 cond = (ctx->opcode >> 6) & 0xf;
15251 cc = (ctx->opcode >> 13) & 0x7;
15252 fmt = (ctx->opcode >> 10) & 0x3;
15255 gen_cmp_s(ctx, cond, rt, rs, cc);
15258 gen_cmp_d(ctx, cond, rt, rs, cc);
15261 gen_cmp_ps(ctx, cond, rt, rs, cc);
15264 goto pool32f_invalid;
15268 check_insn(ctx, ISA_MIPS32R6);
15269 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15272 check_insn(ctx, ISA_MIPS32R6);
15273 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15276 gen_pool32fxf(ctx, rt, rs);
15280 switch ((ctx->opcode >> 6) & 0x7) {
15282 mips32_op = OPC_PLL_PS;
15285 mips32_op = OPC_PLU_PS;
15288 mips32_op = OPC_PUL_PS;
15291 mips32_op = OPC_PUU_PS;
15294 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15295 mips32_op = OPC_CVT_PS_S;
15297 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15300 goto pool32f_invalid;
15304 check_insn(ctx, ISA_MIPS32R6);
15305 switch ((ctx->opcode >> 9) & 0x3) {
15307 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15310 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15313 goto pool32f_invalid;
15318 switch ((ctx->opcode >> 6) & 0x7) {
15320 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15321 mips32_op = OPC_LWXC1;
15324 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15325 mips32_op = OPC_SWXC1;
15328 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15329 mips32_op = OPC_LDXC1;
15332 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15333 mips32_op = OPC_SDXC1;
15336 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15337 mips32_op = OPC_LUXC1;
15340 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15341 mips32_op = OPC_SUXC1;
15343 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
15346 goto pool32f_invalid;
15350 check_insn(ctx, ISA_MIPS32R6);
15351 switch ((ctx->opcode >> 9) & 0x3) {
15353 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
15356 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
15359 goto pool32f_invalid;
15364 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15365 fmt = (ctx->opcode >> 9) & 0x3;
15366 switch ((ctx->opcode >> 6) & 0x7) {
15370 mips32_op = OPC_RSQRT2_S;
15373 mips32_op = OPC_RSQRT2_D;
15376 mips32_op = OPC_RSQRT2_PS;
15379 goto pool32f_invalid;
15385 mips32_op = OPC_RECIP2_S;
15388 mips32_op = OPC_RECIP2_D;
15391 mips32_op = OPC_RECIP2_PS;
15394 goto pool32f_invalid;
15398 mips32_op = OPC_ADDR_PS;
15401 mips32_op = OPC_MULR_PS;
15403 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15406 goto pool32f_invalid;
15410 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15411 cc = (ctx->opcode >> 13) & 0x7;
15412 fmt = (ctx->opcode >> 9) & 0x3;
15413 switch ((ctx->opcode >> 6) & 0x7) {
15414 case MOVF_FMT: /* RINT_FMT */
15415 if (ctx->insn_flags & ISA_MIPS32R6) {
15419 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
15422 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
15425 goto pool32f_invalid;
15431 gen_movcf_s(ctx, rs, rt, cc, 0);
15434 gen_movcf_d(ctx, rs, rt, cc, 0);
15438 gen_movcf_ps(ctx, rs, rt, cc, 0);
15441 goto pool32f_invalid;
15445 case MOVT_FMT: /* CLASS_FMT */
15446 if (ctx->insn_flags & ISA_MIPS32R6) {
15450 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
15453 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
15456 goto pool32f_invalid;
15462 gen_movcf_s(ctx, rs, rt, cc, 1);
15465 gen_movcf_d(ctx, rs, rt, cc, 1);
15469 gen_movcf_ps(ctx, rs, rt, cc, 1);
15472 goto pool32f_invalid;
15477 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15480 goto pool32f_invalid;
15483 #define FINSN_3ARG_SDPS(prfx) \
15484 switch ((ctx->opcode >> 8) & 0x3) { \
15486 mips32_op = OPC_##prfx##_S; \
15489 mips32_op = OPC_##prfx##_D; \
15491 case FMT_SDPS_PS: \
15493 mips32_op = OPC_##prfx##_PS; \
15496 goto pool32f_invalid; \
15499 check_insn(ctx, ISA_MIPS32R6);
15500 switch ((ctx->opcode >> 9) & 0x3) {
15502 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
15505 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
15508 goto pool32f_invalid;
15512 check_insn(ctx, ISA_MIPS32R6);
15513 switch ((ctx->opcode >> 9) & 0x3) {
15515 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
15518 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
15521 goto pool32f_invalid;
15525 /* regular FP ops */
15526 switch ((ctx->opcode >> 6) & 0x3) {
15528 FINSN_3ARG_SDPS(ADD);
15531 FINSN_3ARG_SDPS(SUB);
15534 FINSN_3ARG_SDPS(MUL);
15537 fmt = (ctx->opcode >> 8) & 0x3;
15539 mips32_op = OPC_DIV_D;
15540 } else if (fmt == 0) {
15541 mips32_op = OPC_DIV_S;
15543 goto pool32f_invalid;
15547 goto pool32f_invalid;
15552 switch ((ctx->opcode >> 6) & 0x7) {
15553 case MOVN_FMT: /* SELNEZ_FMT */
15554 if (ctx->insn_flags & ISA_MIPS32R6) {
15556 switch ((ctx->opcode >> 9) & 0x3) {
15558 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
15561 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
15564 goto pool32f_invalid;
15568 FINSN_3ARG_SDPS(MOVN);
15572 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15573 FINSN_3ARG_SDPS(MOVN);
15575 case MOVZ_FMT: /* SELEQZ_FMT */
15576 if (ctx->insn_flags & ISA_MIPS32R6) {
15578 switch ((ctx->opcode >> 9) & 0x3) {
15580 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
15583 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
15586 goto pool32f_invalid;
15590 FINSN_3ARG_SDPS(MOVZ);
15594 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15595 FINSN_3ARG_SDPS(MOVZ);
15598 check_insn(ctx, ISA_MIPS32R6);
15599 switch ((ctx->opcode >> 9) & 0x3) {
15601 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
15604 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
15607 goto pool32f_invalid;
15611 check_insn(ctx, ISA_MIPS32R6);
15612 switch ((ctx->opcode >> 9) & 0x3) {
15614 mips32_op = OPC_MADDF_S;
15617 mips32_op = OPC_MADDF_D;
15620 goto pool32f_invalid;
15624 check_insn(ctx, ISA_MIPS32R6);
15625 switch ((ctx->opcode >> 9) & 0x3) {
15627 mips32_op = OPC_MSUBF_S;
15630 mips32_op = OPC_MSUBF_D;
15633 goto pool32f_invalid;
15637 goto pool32f_invalid;
15641 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15645 MIPS_INVAL("pool32f");
15646 generate_exception_end(ctx, EXCP_RI);
15650 generate_exception_err(ctx, EXCP_CpU, 1);
15654 minor = (ctx->opcode >> 21) & 0x1f;
15657 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15658 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
15661 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15662 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
15663 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15666 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15667 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
15668 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15671 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15672 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
15675 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15676 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
15677 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15680 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15681 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
15682 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15685 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15686 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
15689 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15690 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
15694 case TLTI: /* BC1EQZC */
15695 if (ctx->insn_flags & ISA_MIPS32R6) {
15697 check_cp1_enabled(ctx);
15698 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
15701 mips32_op = OPC_TLTI;
15705 case TGEI: /* BC1NEZC */
15706 if (ctx->insn_flags & ISA_MIPS32R6) {
15708 check_cp1_enabled(ctx);
15709 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
15712 mips32_op = OPC_TGEI;
15717 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15718 mips32_op = OPC_TLTIU;
15721 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15722 mips32_op = OPC_TGEIU;
15724 case TNEI: /* SYNCI */
15725 if (ctx->insn_flags & ISA_MIPS32R6) {
15727 /* Break the TB to be able to sync copied instructions
15729 ctx->base.is_jmp = DISAS_STOP;
15732 mips32_op = OPC_TNEI;
15737 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15738 mips32_op = OPC_TEQI;
15740 gen_trap(ctx, mips32_op, rs, -1, imm);
15745 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15746 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
15747 4, rs, 0, imm << 1, 0);
15748 /* Compact branches don't have a delay slot, so just let
15749 the normal delay slot handling take us to the branch
15753 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15754 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
15757 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15758 /* Break the TB to be able to sync copied instructions
15760 ctx->base.is_jmp = DISAS_STOP;
15764 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15765 /* COP2: Not implemented. */
15766 generate_exception_err(ctx, EXCP_CpU, 2);
15769 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15770 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
15773 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15774 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
15777 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15778 mips32_op = OPC_BC1FANY4;
15781 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15782 mips32_op = OPC_BC1TANY4;
15785 check_insn(ctx, ASE_MIPS3D);
15788 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15789 check_cp1_enabled(ctx);
15790 gen_compute_branch1(ctx, mips32_op,
15791 (ctx->opcode >> 18) & 0x7, imm << 1);
15793 generate_exception_err(ctx, EXCP_CpU, 1);
15798 /* MIPS DSP: not implemented */
15801 MIPS_INVAL("pool32i");
15802 generate_exception_end(ctx, EXCP_RI);
15807 minor = (ctx->opcode >> 12) & 0xf;
15808 offset = sextract32(ctx->opcode, 0,
15809 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
15812 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15813 mips32_op = OPC_LWL;
15816 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15817 mips32_op = OPC_SWL;
15820 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15821 mips32_op = OPC_LWR;
15824 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15825 mips32_op = OPC_SWR;
15827 #if defined(TARGET_MIPS64)
15829 check_insn(ctx, ISA_MIPS3);
15830 check_mips_64(ctx);
15831 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15832 mips32_op = OPC_LDL;
15835 check_insn(ctx, ISA_MIPS3);
15836 check_mips_64(ctx);
15837 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15838 mips32_op = OPC_SDL;
15841 check_insn(ctx, ISA_MIPS3);
15842 check_mips_64(ctx);
15843 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15844 mips32_op = OPC_LDR;
15847 check_insn(ctx, ISA_MIPS3);
15848 check_mips_64(ctx);
15849 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15850 mips32_op = OPC_SDR;
15853 check_insn(ctx, ISA_MIPS3);
15854 check_mips_64(ctx);
15855 mips32_op = OPC_LWU;
15858 check_insn(ctx, ISA_MIPS3);
15859 check_mips_64(ctx);
15860 mips32_op = OPC_LLD;
15864 mips32_op = OPC_LL;
15867 gen_ld(ctx, mips32_op, rt, rs, offset);
15870 gen_st(ctx, mips32_op, rt, rs, offset);
15873 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
15875 #if defined(TARGET_MIPS64)
15877 check_insn(ctx, ISA_MIPS3);
15878 check_mips_64(ctx);
15879 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
15884 MIPS_INVAL("pool32c ld-eva");
15885 generate_exception_end(ctx, EXCP_RI);
15888 check_cp0_enabled(ctx);
15890 minor2 = (ctx->opcode >> 9) & 0x7;
15891 offset = sextract32(ctx->opcode, 0, 9);
15894 mips32_op = OPC_LBUE;
15897 mips32_op = OPC_LHUE;
15900 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15901 mips32_op = OPC_LWLE;
15904 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15905 mips32_op = OPC_LWRE;
15908 mips32_op = OPC_LBE;
15911 mips32_op = OPC_LHE;
15914 mips32_op = OPC_LLE;
15917 mips32_op = OPC_LWE;
15923 MIPS_INVAL("pool32c st-eva");
15924 generate_exception_end(ctx, EXCP_RI);
15927 check_cp0_enabled(ctx);
15929 minor2 = (ctx->opcode >> 9) & 0x7;
15930 offset = sextract32(ctx->opcode, 0, 9);
15933 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15934 mips32_op = OPC_SWLE;
15937 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15938 mips32_op = OPC_SWRE;
15941 /* Treat as no-op */
15942 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15943 /* hint codes 24-31 are reserved and signal RI */
15944 generate_exception(ctx, EXCP_RI);
15948 /* Treat as no-op */
15949 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15950 gen_cache_operation(ctx, rt, rs, offset);
15954 mips32_op = OPC_SBE;
15957 mips32_op = OPC_SHE;
15960 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
15963 mips32_op = OPC_SWE;
15968 /* Treat as no-op */
15969 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15970 /* hint codes 24-31 are reserved and signal RI */
15971 generate_exception(ctx, EXCP_RI);
15975 MIPS_INVAL("pool32c");
15976 generate_exception_end(ctx, EXCP_RI);
15980 case ADDI32: /* AUI, LUI */
15981 if (ctx->insn_flags & ISA_MIPS32R6) {
15983 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
15986 mips32_op = OPC_ADDI;
15991 mips32_op = OPC_ADDIU;
15993 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
15996 /* Logical operations */
15998 mips32_op = OPC_ORI;
16001 mips32_op = OPC_XORI;
16004 mips32_op = OPC_ANDI;
16006 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16009 /* Set less than immediate */
16011 mips32_op = OPC_SLTI;
16014 mips32_op = OPC_SLTIU;
16016 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16019 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16020 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16021 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16022 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16024 case JALS32: /* BOVC, BEQC, BEQZALC */
16025 if (ctx->insn_flags & ISA_MIPS32R6) {
16028 mips32_op = OPC_BOVC;
16029 } else if (rs < rt && rs == 0) {
16031 mips32_op = OPC_BEQZALC;
16034 mips32_op = OPC_BEQC;
16036 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16039 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16040 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16041 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16044 case BEQ32: /* BC */
16045 if (ctx->insn_flags & ISA_MIPS32R6) {
16047 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16048 sextract32(ctx->opcode << 1, 0, 27));
16051 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16054 case BNE32: /* BALC */
16055 if (ctx->insn_flags & ISA_MIPS32R6) {
16057 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16058 sextract32(ctx->opcode << 1, 0, 27));
16061 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16064 case J32: /* BGTZC, BLTZC, BLTC */
16065 if (ctx->insn_flags & ISA_MIPS32R6) {
16066 if (rs == 0 && rt != 0) {
16068 mips32_op = OPC_BGTZC;
16069 } else if (rs != 0 && rt != 0 && rs == rt) {
16071 mips32_op = OPC_BLTZC;
16074 mips32_op = OPC_BLTC;
16076 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16079 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16080 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16083 case JAL32: /* BLEZC, BGEZC, BGEC */
16084 if (ctx->insn_flags & ISA_MIPS32R6) {
16085 if (rs == 0 && rt != 0) {
16087 mips32_op = OPC_BLEZC;
16088 } else if (rs != 0 && rt != 0 && rs == rt) {
16090 mips32_op = OPC_BGEZC;
16093 mips32_op = OPC_BGEC;
16095 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16098 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16099 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16100 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16103 /* Floating point (COP1) */
16105 mips32_op = OPC_LWC1;
16108 mips32_op = OPC_LDC1;
16111 mips32_op = OPC_SWC1;
16114 mips32_op = OPC_SDC1;
16116 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16118 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16119 if (ctx->insn_flags & ISA_MIPS32R6) {
16120 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16121 switch ((ctx->opcode >> 16) & 0x1f) {
16130 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16133 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16136 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16146 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16149 generate_exception(ctx, EXCP_RI);
16154 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16155 offset = SIMM(ctx->opcode, 0, 23) << 2;
16157 gen_addiupc(ctx, reg, offset, 0, 0);
16160 case BNVC: /* BNEC, BNEZALC */
16161 check_insn(ctx, ISA_MIPS32R6);
16164 mips32_op = OPC_BNVC;
16165 } else if (rs < rt && rs == 0) {
16167 mips32_op = OPC_BNEZALC;
16170 mips32_op = OPC_BNEC;
16172 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16174 case R6_BNEZC: /* JIALC */
16175 check_insn(ctx, ISA_MIPS32R6);
16178 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16179 sextract32(ctx->opcode << 1, 0, 22));
16182 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16185 case R6_BEQZC: /* JIC */
16186 check_insn(ctx, ISA_MIPS32R6);
16189 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16190 sextract32(ctx->opcode << 1, 0, 22));
16193 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16196 case BLEZALC: /* BGEZALC, BGEUC */
16197 check_insn(ctx, ISA_MIPS32R6);
16198 if (rs == 0 && rt != 0) {
16200 mips32_op = OPC_BLEZALC;
16201 } else if (rs != 0 && rt != 0 && rs == rt) {
16203 mips32_op = OPC_BGEZALC;
16206 mips32_op = OPC_BGEUC;
16208 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16210 case BGTZALC: /* BLTZALC, BLTUC */
16211 check_insn(ctx, ISA_MIPS32R6);
16212 if (rs == 0 && rt != 0) {
16214 mips32_op = OPC_BGTZALC;
16215 } else if (rs != 0 && rt != 0 && rs == rt) {
16217 mips32_op = OPC_BLTZALC;
16220 mips32_op = OPC_BLTUC;
16222 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16224 /* Loads and stores */
16226 mips32_op = OPC_LB;
16229 mips32_op = OPC_LBU;
16232 mips32_op = OPC_LH;
16235 mips32_op = OPC_LHU;
16238 mips32_op = OPC_LW;
16240 #ifdef TARGET_MIPS64
16242 check_insn(ctx, ISA_MIPS3);
16243 check_mips_64(ctx);
16244 mips32_op = OPC_LD;
16247 check_insn(ctx, ISA_MIPS3);
16248 check_mips_64(ctx);
16249 mips32_op = OPC_SD;
16253 mips32_op = OPC_SB;
16256 mips32_op = OPC_SH;
16259 mips32_op = OPC_SW;
16262 gen_ld(ctx, mips32_op, rt, rs, imm);
16265 gen_st(ctx, mips32_op, rt, rs, imm);
16268 generate_exception_end(ctx, EXCP_RI);
16273 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
16277 /* make sure instructions are on a halfword boundary */
16278 if (ctx->base.pc_next & 0x1) {
16279 env->CP0_BadVAddr = ctx->base.pc_next;
16280 generate_exception_end(ctx, EXCP_AdEL);
16284 op = (ctx->opcode >> 10) & 0x3f;
16285 /* Enforce properly-sized instructions in a delay slot */
16286 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16287 switch (op & 0x7) { /* MSB-3..MSB-5 */
16289 /* POOL32A, POOL32B, POOL32I, POOL32C */
16291 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16293 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16295 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16297 /* LB32, LH32, LWC132, LDC132, LW32 */
16298 if (ctx->hflags & MIPS_HFLAG_BDS16) {
16299 generate_exception_end(ctx, EXCP_RI);
16304 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16306 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16308 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16309 if (ctx->hflags & MIPS_HFLAG_BDS32) {
16310 generate_exception_end(ctx, EXCP_RI);
16320 int rd = mmreg(uMIPS_RD(ctx->opcode));
16321 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16322 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16325 switch (ctx->opcode & 0x1) {
16333 if (ctx->insn_flags & ISA_MIPS32R6) {
16334 /* In the Release 6 the register number location in
16335 * the instruction encoding has changed.
16337 gen_arith(ctx, opc, rs1, rd, rs2);
16339 gen_arith(ctx, opc, rd, rs1, rs2);
16345 int rd = mmreg(uMIPS_RD(ctx->opcode));
16346 int rs = mmreg(uMIPS_RS(ctx->opcode));
16347 int amount = (ctx->opcode >> 1) & 0x7;
16349 amount = amount == 0 ? 8 : amount;
16351 switch (ctx->opcode & 0x1) {
16360 gen_shift_imm(ctx, opc, rd, rs, amount);
16364 if (ctx->insn_flags & ISA_MIPS32R6) {
16365 gen_pool16c_r6_insn(ctx);
16367 gen_pool16c_insn(ctx);
16372 int rd = mmreg(uMIPS_RD(ctx->opcode));
16373 int rb = 28; /* GP */
16374 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
16376 gen_ld(ctx, OPC_LW, rd, rb, offset);
16380 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16381 if (ctx->opcode & 1) {
16382 generate_exception_end(ctx, EXCP_RI);
16385 int enc_dest = uMIPS_RD(ctx->opcode);
16386 int enc_rt = uMIPS_RS2(ctx->opcode);
16387 int enc_rs = uMIPS_RS1(ctx->opcode);
16388 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
16393 int rd = mmreg(uMIPS_RD(ctx->opcode));
16394 int rb = mmreg(uMIPS_RS(ctx->opcode));
16395 int16_t offset = ZIMM(ctx->opcode, 0, 4);
16396 offset = (offset == 0xf ? -1 : offset);
16398 gen_ld(ctx, OPC_LBU, rd, rb, offset);
16403 int rd = mmreg(uMIPS_RD(ctx->opcode));
16404 int rb = mmreg(uMIPS_RS(ctx->opcode));
16405 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16407 gen_ld(ctx, OPC_LHU, rd, rb, offset);
16412 int rd = (ctx->opcode >> 5) & 0x1f;
16413 int rb = 29; /* SP */
16414 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16416 gen_ld(ctx, OPC_LW, rd, rb, offset);
16421 int rd = mmreg(uMIPS_RD(ctx->opcode));
16422 int rb = mmreg(uMIPS_RS(ctx->opcode));
16423 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16425 gen_ld(ctx, OPC_LW, rd, rb, offset);
16430 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16431 int rb = mmreg(uMIPS_RS(ctx->opcode));
16432 int16_t offset = ZIMM(ctx->opcode, 0, 4);
16434 gen_st(ctx, OPC_SB, rd, rb, offset);
16439 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16440 int rb = mmreg(uMIPS_RS(ctx->opcode));
16441 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16443 gen_st(ctx, OPC_SH, rd, rb, offset);
16448 int rd = (ctx->opcode >> 5) & 0x1f;
16449 int rb = 29; /* SP */
16450 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16452 gen_st(ctx, OPC_SW, rd, rb, offset);
16457 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16458 int rb = mmreg(uMIPS_RS(ctx->opcode));
16459 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16461 gen_st(ctx, OPC_SW, rd, rb, offset);
16466 int rd = uMIPS_RD5(ctx->opcode);
16467 int rs = uMIPS_RS5(ctx->opcode);
16469 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
16476 switch (ctx->opcode & 0x1) {
16486 switch (ctx->opcode & 0x1) {
16491 gen_addiur1sp(ctx);
16495 case B16: /* BC16 */
16496 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
16497 sextract32(ctx->opcode, 0, 10) << 1,
16498 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16500 case BNEZ16: /* BNEZC16 */
16501 case BEQZ16: /* BEQZC16 */
16502 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
16503 mmreg(uMIPS_RD(ctx->opcode)),
16504 0, sextract32(ctx->opcode, 0, 7) << 1,
16505 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16510 int reg = mmreg(uMIPS_RD(ctx->opcode));
16511 int imm = ZIMM(ctx->opcode, 0, 7);
16513 imm = (imm == 0x7f ? -1 : imm);
16514 tcg_gen_movi_tl(cpu_gpr[reg], imm);
16520 generate_exception_end(ctx, EXCP_RI);
16523 decode_micromips32_opc(env, ctx);
16536 /* MAJOR, P16, and P32 pools opcodes */
16540 NM_MOVE_BALC = 0x02,
16548 NM_P16_SHIFT = 0x0c,
16566 NM_P_LS_U12 = 0x21,
16576 NM_P16_ADDU = 0x2c,
16590 NM_MOVEPREV = 0x3f,
16593 /* POOL32A instruction pool */
16595 NM_POOL32A0 = 0x00,
16596 NM_SPECIAL2 = 0x01,
16599 NM_POOL32A5 = 0x05,
16600 NM_POOL32A7 = 0x07,
16603 /* P.GP.W instruction pool */
16605 NM_ADDIUGP_W = 0x00,
16610 /* P48I instruction pool */
16614 NM_ADDIUGP48 = 0x02,
16615 NM_ADDIUPC48 = 0x03,
16620 /* P.U12 instruction pool */
16629 NM_ADDIUNEG = 0x08,
16636 /* POOL32F instruction pool */
16638 NM_POOL32F_0 = 0x00,
16639 NM_POOL32F_3 = 0x03,
16640 NM_POOL32F_5 = 0x05,
16643 /* POOL32S instruction pool */
16645 NM_POOL32S_0 = 0x00,
16646 NM_POOL32S_4 = 0x04,
16649 /* P.LUI instruction pool */
16655 /* P.GP.BH instruction pool */
16660 NM_ADDIUGP_B = 0x03,
16663 NM_P_GP_CP1 = 0x06,
16666 /* P.LS.U12 instruction pool */
16671 NM_P_PREFU12 = 0x03,
16684 /* P.LS.S9 instruction pool */
16690 NM_P_LS_UAWM = 0x05,
16693 /* P.BAL instruction pool */
16699 /* P.J instruction pool */
16702 NM_JALRC_HB = 0x01,
16703 NM_P_BALRSC = 0x08,
16706 /* P.BR1 instruction pool */
16714 /* P.BR2 instruction pool */
16721 /* P.BRI instruction pool */
16733 /* P16.SHIFT instruction pool */
16739 /* POOL16C instruction pool */
16741 NM_POOL16C_0 = 0x00,
16745 /* P16.A1 instruction pool */
16747 NM_ADDIUR1SP = 0x01,
16750 /* P16.A2 instruction pool */
16753 NM_P_ADDIURS5 = 0x01,
16756 /* P16.ADDU instruction pool */
16762 /* P16.SR instruction pool */
16765 NM_RESTORE_JRC16 = 0x01,
16768 /* P16.4X4 instruction pool */
16774 /* P16.LB instruction pool */
16781 /* P16.LH instruction pool */
16788 /* P.RI instruction pool */
16791 NM_P_SYSCALL = 0x01,
16796 /* POOL32A0 instruction pool */
16831 NM_D_E_MT_VPE = 0x56,
16839 /* POOL32A5 instruction pool */
16841 NM_CMP_EQ_PH = 0x00,
16842 NM_CMP_LT_PH = 0x08,
16843 NM_CMP_LE_PH = 0x10,
16844 NM_CMPGU_EQ_QB = 0x18,
16845 NM_CMPGU_LT_QB = 0x20,
16846 NM_CMPGU_LE_QB = 0x28,
16847 NM_CMPGDU_EQ_QB = 0x30,
16848 NM_CMPGDU_LT_QB = 0x38,
16849 NM_CMPGDU_LE_QB = 0x40,
16850 NM_CMPU_EQ_QB = 0x48,
16851 NM_CMPU_LT_QB = 0x50,
16852 NM_CMPU_LE_QB = 0x58,
16853 NM_ADDQ_S_W = 0x60,
16854 NM_SUBQ_S_W = 0x68,
16858 NM_ADDQ_S_PH = 0x01,
16859 NM_ADDQH_R_PH = 0x09,
16860 NM_ADDQH_R_W = 0x11,
16861 NM_ADDU_S_QB = 0x19,
16862 NM_ADDU_S_PH = 0x21,
16863 NM_ADDUH_R_QB = 0x29,
16864 NM_SHRAV_R_PH = 0x31,
16865 NM_SHRAV_R_QB = 0x39,
16866 NM_SUBQ_S_PH = 0x41,
16867 NM_SUBQH_R_PH = 0x49,
16868 NM_SUBQH_R_W = 0x51,
16869 NM_SUBU_S_QB = 0x59,
16870 NM_SUBU_S_PH = 0x61,
16871 NM_SUBUH_R_QB = 0x69,
16872 NM_SHLLV_S_PH = 0x71,
16873 NM_PRECR_SRA_R_PH_W = 0x79,
16875 NM_MULEU_S_PH_QBL = 0x12,
16876 NM_MULEU_S_PH_QBR = 0x1a,
16877 NM_MULQ_RS_PH = 0x22,
16878 NM_MULQ_S_PH = 0x2a,
16879 NM_MULQ_RS_W = 0x32,
16880 NM_MULQ_S_W = 0x3a,
16883 NM_SHRAV_R_W = 0x5a,
16884 NM_SHRLV_PH = 0x62,
16885 NM_SHRLV_QB = 0x6a,
16886 NM_SHLLV_QB = 0x72,
16887 NM_SHLLV_S_W = 0x7a,
16891 NM_MULEQ_S_W_PHL = 0x04,
16892 NM_MULEQ_S_W_PHR = 0x0c,
16894 NM_MUL_S_PH = 0x05,
16895 NM_PRECR_QB_PH = 0x0d,
16896 NM_PRECRQ_QB_PH = 0x15,
16897 NM_PRECRQ_PH_W = 0x1d,
16898 NM_PRECRQ_RS_PH_W = 0x25,
16899 NM_PRECRQU_S_QB_PH = 0x2d,
16900 NM_PACKRL_PH = 0x35,
16904 NM_SHRA_R_W = 0x5e,
16905 NM_SHRA_R_PH = 0x66,
16906 NM_SHLL_S_PH = 0x76,
16907 NM_SHLL_S_W = 0x7e,
16912 /* POOL32A7 instruction pool */
16917 NM_POOL32AXF = 0x07,
16920 /* P.SR instruction pool */
16926 /* P.SHIFT instruction pool */
16934 /* P.ROTX instruction pool */
16939 /* P.INS instruction pool */
16944 /* P.EXT instruction pool */
16949 /* POOL32F_0 (fmt) instruction pool */
16954 NM_SELEQZ_S = 0x07,
16955 NM_SELEQZ_D = 0x47,
16959 NM_SELNEZ_S = 0x0f,
16960 NM_SELNEZ_D = 0x4f,
16975 /* POOL32F_3 instruction pool */
16979 NM_MINA_FMT = 0x04,
16980 NM_MAXA_FMT = 0x05,
16981 NM_POOL32FXF = 0x07,
16984 /* POOL32F_5 instruction pool */
16986 NM_CMP_CONDN_S = 0x00,
16987 NM_CMP_CONDN_D = 0x02,
16990 /* P.GP.LH instruction pool */
16996 /* P.GP.SH instruction pool */
17001 /* P.GP.CP1 instruction pool */
17009 /* P.LS.S0 instruction pool */
17026 NM_P_PREFS9 = 0x03,
17032 /* P.LS.S1 instruction pool */
17034 NM_ASET_ACLR = 0x02,
17042 /* P.LS.WM instruction pool */
17048 /* P.LS.UAWM instruction pool */
17054 /* P.BR3A instruction pool */
17060 NM_BPOSGE32C = 0x04,
17063 /* P16.RI instruction pool */
17065 NM_P16_SYSCALL = 0x01,
17070 /* POOL16C_0 instruction pool */
17072 NM_POOL16C_00 = 0x00,
17075 /* P16.JRC instruction pool */
17081 /* P.SYSCALL instruction pool */
17087 /* P.TRAP instruction pool */
17093 /* P.CMOVE instruction pool */
17099 /* POOL32Axf instruction pool */
17101 NM_POOL32AXF_1 = 0x01,
17102 NM_POOL32AXF_2 = 0x02,
17103 NM_POOL32AXF_4 = 0x04,
17104 NM_POOL32AXF_5 = 0x05,
17105 NM_POOL32AXF_7 = 0x07,
17108 /* POOL32Axf_1 instruction pool */
17110 NM_POOL32AXF_1_0 = 0x00,
17111 NM_POOL32AXF_1_1 = 0x01,
17112 NM_POOL32AXF_1_3 = 0x03,
17113 NM_POOL32AXF_1_4 = 0x04,
17114 NM_POOL32AXF_1_5 = 0x05,
17115 NM_POOL32AXF_1_7 = 0x07,
17118 /* POOL32Axf_2 instruction pool */
17120 NM_POOL32AXF_2_0_7 = 0x00,
17121 NM_POOL32AXF_2_8_15 = 0x01,
17122 NM_POOL32AXF_2_16_23 = 0x02,
17123 NM_POOL32AXF_2_24_31 = 0x03,
17126 /* POOL32Axf_7 instruction pool */
17128 NM_SHRA_R_QB = 0x0,
17133 /* POOL32Axf_1_0 instruction pool */
17141 /* POOL32Axf_1_1 instruction pool */
17147 /* POOL32Axf_1_3 instruction pool */
17155 /* POOL32Axf_1_4 instruction pool */
17161 /* POOL32Axf_1_5 instruction pool */
17163 NM_MAQ_S_W_PHR = 0x0,
17164 NM_MAQ_S_W_PHL = 0x1,
17165 NM_MAQ_SA_W_PHR = 0x2,
17166 NM_MAQ_SA_W_PHL = 0x3,
17169 /* POOL32Axf_1_7 instruction pool */
17173 NM_EXTR_RS_W = 0x2,
17177 /* POOL32Axf_2_0_7 instruction pool */
17180 NM_DPAQ_S_W_PH = 0x1,
17182 NM_DPSQ_S_W_PH = 0x3,
17189 /* POOL32Axf_2_8_15 instruction pool */
17191 NM_DPAX_W_PH = 0x0,
17192 NM_DPAQ_SA_L_W = 0x1,
17193 NM_DPSX_W_PH = 0x2,
17194 NM_DPSQ_SA_L_W = 0x3,
17197 NM_EXTRV_R_W = 0x7,
17200 /* POOL32Axf_2_16_23 instruction pool */
17202 NM_DPAU_H_QBL = 0x0,
17203 NM_DPAQX_S_W_PH = 0x1,
17204 NM_DPSU_H_QBL = 0x2,
17205 NM_DPSQX_S_W_PH = 0x3,
17208 NM_MULSA_W_PH = 0x6,
17209 NM_EXTRV_RS_W = 0x7,
17212 /* POOL32Axf_2_24_31 instruction pool */
17214 NM_DPAU_H_QBR = 0x0,
17215 NM_DPAQX_SA_W_PH = 0x1,
17216 NM_DPSU_H_QBR = 0x2,
17217 NM_DPSQX_SA_W_PH = 0x3,
17220 NM_MULSAQ_S_W_PH = 0x6,
17221 NM_EXTRV_S_H = 0x7,
17224 /* POOL32Axf_{4, 5} instruction pool */
17243 /* nanoMIPS DSP instructions */
17244 NM_ABSQ_S_QB = 0x00,
17245 NM_ABSQ_S_PH = 0x08,
17246 NM_ABSQ_S_W = 0x10,
17247 NM_PRECEQ_W_PHL = 0x28,
17248 NM_PRECEQ_W_PHR = 0x30,
17249 NM_PRECEQU_PH_QBL = 0x38,
17250 NM_PRECEQU_PH_QBR = 0x48,
17251 NM_PRECEU_PH_QBL = 0x58,
17252 NM_PRECEU_PH_QBR = 0x68,
17253 NM_PRECEQU_PH_QBLA = 0x39,
17254 NM_PRECEQU_PH_QBRA = 0x49,
17255 NM_PRECEU_PH_QBLA = 0x59,
17256 NM_PRECEU_PH_QBRA = 0x69,
17257 NM_REPLV_PH = 0x01,
17258 NM_REPLV_QB = 0x09,
17261 NM_RADDU_W_QB = 0x78,
17267 /* PP.SR instruction pool */
17271 NM_RESTORE_JRC = 0x03,
17274 /* P.SR.F instruction pool */
17277 NM_RESTOREF = 0x01,
17280 /* P16.SYSCALL instruction pool */
17282 NM_SYSCALL16 = 0x00,
17283 NM_HYPCALL16 = 0x01,
17286 /* POOL16C_00 instruction pool */
17294 /* PP.LSX and PP.LSXS instruction pool */
17332 /* ERETx instruction pool */
17338 /* POOL32FxF_{0, 1} insturction pool */
17347 NM_CVT_S_PL = 0x84,
17348 NM_CVT_S_PU = 0xa4,
17350 NM_CVT_L_S = 0x004,
17351 NM_CVT_L_D = 0x104,
17352 NM_CVT_W_S = 0x024,
17353 NM_CVT_W_D = 0x124,
17355 NM_RSQRT_S = 0x008,
17356 NM_RSQRT_D = 0x108,
17361 NM_RECIP_S = 0x048,
17362 NM_RECIP_D = 0x148,
17364 NM_FLOOR_L_S = 0x00c,
17365 NM_FLOOR_L_D = 0x10c,
17367 NM_FLOOR_W_S = 0x02c,
17368 NM_FLOOR_W_D = 0x12c,
17370 NM_CEIL_L_S = 0x04c,
17371 NM_CEIL_L_D = 0x14c,
17372 NM_CEIL_W_S = 0x06c,
17373 NM_CEIL_W_D = 0x16c,
17374 NM_TRUNC_L_S = 0x08c,
17375 NM_TRUNC_L_D = 0x18c,
17376 NM_TRUNC_W_S = 0x0ac,
17377 NM_TRUNC_W_D = 0x1ac,
17378 NM_ROUND_L_S = 0x0cc,
17379 NM_ROUND_L_D = 0x1cc,
17380 NM_ROUND_W_S = 0x0ec,
17381 NM_ROUND_W_D = 0x1ec,
17389 NM_CVT_D_S = 0x04d,
17390 NM_CVT_D_W = 0x0cd,
17391 NM_CVT_D_L = 0x14d,
17392 NM_CVT_S_D = 0x06d,
17393 NM_CVT_S_W = 0x0ed,
17394 NM_CVT_S_L = 0x16d,
17397 /* P.LL instruction pool */
17403 /* P.SC instruction pool */
17409 /* P.DVP instruction pool */
17418 * nanoMIPS decoding engine
17423 /* extraction utilities */
17425 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17426 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17427 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17428 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17429 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17430 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17432 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17433 static inline int decode_gpr_gpr3(int r)
17435 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17437 return map[r & 0x7];
17440 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17441 static inline int decode_gpr_gpr3_src_store(int r)
17443 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
17445 return map[r & 0x7];
17448 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17449 static inline int decode_gpr_gpr4(int r)
17451 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
17452 16, 17, 18, 19, 20, 21, 22, 23 };
17454 return map[r & 0xf];
17457 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17458 static inline int decode_gpr_gpr4_zero(int r)
17460 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
17461 16, 17, 18, 19, 20, 21, 22, 23 };
17463 return map[r & 0xf];
17467 /* extraction utilities */
17469 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17470 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17471 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17472 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17473 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17474 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17477 static void gen_adjust_sp(DisasContext *ctx, int u)
17479 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
17482 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
17483 uint8_t gp, uint16_t u)
17486 TCGv va = tcg_temp_new();
17487 TCGv t0 = tcg_temp_new();
17489 while (counter != count) {
17490 bool use_gp = gp && (counter == count - 1);
17491 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17492 int this_offset = -((counter + 1) << 2);
17493 gen_base_offset_addr(ctx, va, 29, this_offset);
17494 gen_load_gpr(t0, this_rt);
17495 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
17496 (MO_TEUL | ctx->default_tcg_memop_mask));
17500 /* adjust stack pointer */
17501 gen_adjust_sp(ctx, -u);
17507 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
17508 uint8_t gp, uint16_t u)
17511 TCGv va = tcg_temp_new();
17512 TCGv t0 = tcg_temp_new();
17514 while (counter != count) {
17515 bool use_gp = gp && (counter == count - 1);
17516 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17517 int this_offset = u - ((counter + 1) << 2);
17518 gen_base_offset_addr(ctx, va, 29, this_offset);
17519 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
17520 ctx->default_tcg_memop_mask);
17521 tcg_gen_ext32s_tl(t0, t0);
17522 gen_store_gpr(t0, this_rt);
17526 /* adjust stack pointer */
17527 gen_adjust_sp(ctx, u);
17533 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
17535 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
17536 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
17538 switch (extract32(ctx->opcode, 2, 2)) {
17540 gen_logic(ctx, OPC_NOR, rt, rs, 0);
17543 gen_logic(ctx, OPC_AND, rt, rt, rs);
17546 gen_logic(ctx, OPC_XOR, rt, rt, rs);
17549 gen_logic(ctx, OPC_OR, rt, rt, rs);
17554 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
17556 int rt = extract32(ctx->opcode, 21, 5);
17557 int rs = extract32(ctx->opcode, 16, 5);
17558 int rd = extract32(ctx->opcode, 11, 5);
17560 switch (extract32(ctx->opcode, 3, 7)) {
17562 switch (extract32(ctx->opcode, 10, 1)) {
17565 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
17569 gen_trap(ctx, OPC_TNE, rs, rt, -1);
17575 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
17579 gen_bshfl(ctx, OPC_SEB, rs, rt);
17582 gen_bshfl(ctx, OPC_SEH, rs, rt);
17585 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
17588 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
17591 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
17594 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
17597 gen_arith(ctx, OPC_ADD, rd, rs, rt);
17600 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
17604 gen_arith(ctx, OPC_SUB, rd, rs, rt);
17607 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
17610 switch (extract32(ctx->opcode, 10, 1)) {
17612 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
17615 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
17620 gen_logic(ctx, OPC_AND, rd, rs, rt);
17623 gen_logic(ctx, OPC_OR, rd, rs, rt);
17626 gen_logic(ctx, OPC_NOR, rd, rs, rt);
17629 gen_logic(ctx, OPC_XOR, rd, rs, rt);
17632 gen_slt(ctx, OPC_SLT, rd, rs, rt);
17637 #ifndef CONFIG_USER_ONLY
17638 TCGv t0 = tcg_temp_new();
17639 switch (extract32(ctx->opcode, 10, 1)) {
17642 check_cp0_enabled(ctx);
17643 gen_helper_dvp(t0, cpu_env);
17644 gen_store_gpr(t0, rt);
17649 check_cp0_enabled(ctx);
17650 gen_helper_evp(t0, cpu_env);
17651 gen_store_gpr(t0, rt);
17658 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
17663 TCGv t0 = tcg_temp_new();
17664 TCGv t1 = tcg_temp_new();
17665 TCGv t2 = tcg_temp_new();
17667 gen_load_gpr(t1, rs);
17668 gen_load_gpr(t2, rt);
17669 tcg_gen_add_tl(t0, t1, t2);
17670 tcg_gen_ext32s_tl(t0, t0);
17671 tcg_gen_xor_tl(t1, t1, t2);
17672 tcg_gen_xor_tl(t2, t0, t2);
17673 tcg_gen_andc_tl(t1, t2, t1);
17675 /* operands of same sign, result different sign */
17676 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
17677 gen_store_gpr(t0, rd);
17685 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
17688 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
17691 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
17694 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
17697 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
17700 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
17703 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
17706 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
17708 #ifndef CONFIG_USER_ONLY
17710 check_cp0_enabled(ctx);
17712 /* Treat as NOP. */
17715 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
17718 check_cp0_enabled(ctx);
17720 TCGv t0 = tcg_temp_new();
17722 gen_load_gpr(t0, rt);
17723 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
17727 case NM_D_E_MT_VPE:
17729 uint8_t sc = extract32(ctx->opcode, 10, 1);
17730 TCGv t0 = tcg_temp_new();
17737 gen_helper_dmt(t0);
17738 gen_store_gpr(t0, rt);
17739 } else if (rs == 0) {
17742 gen_helper_dvpe(t0, cpu_env);
17743 gen_store_gpr(t0, rt);
17745 generate_exception_end(ctx, EXCP_RI);
17752 gen_helper_emt(t0);
17753 gen_store_gpr(t0, rt);
17754 } else if (rs == 0) {
17757 gen_helper_evpe(t0, cpu_env);
17758 gen_store_gpr(t0, rt);
17760 generate_exception_end(ctx, EXCP_RI);
17771 TCGv t0 = tcg_temp_new();
17772 TCGv t1 = tcg_temp_new();
17774 gen_load_gpr(t0, rt);
17775 gen_load_gpr(t1, rs);
17776 gen_helper_fork(t0, t1);
17783 check_cp0_enabled(ctx);
17785 /* Treat as NOP. */
17788 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17789 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17793 check_cp0_enabled(ctx);
17794 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17795 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17800 TCGv t0 = tcg_temp_new();
17802 gen_load_gpr(t0, rs);
17803 gen_helper_yield(t0, cpu_env, t0);
17804 gen_store_gpr(t0, rt);
17810 generate_exception_end(ctx, EXCP_RI);
17816 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
17817 int ret, int v1, int v2)
17823 t0 = tcg_temp_new_i32();
17825 v0_t = tcg_temp_new();
17826 v1_t = tcg_temp_new();
17828 tcg_gen_movi_i32(t0, v2 >> 3);
17830 gen_load_gpr(v0_t, ret);
17831 gen_load_gpr(v1_t, v1);
17834 case NM_MAQ_S_W_PHR:
17836 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
17838 case NM_MAQ_S_W_PHL:
17840 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
17842 case NM_MAQ_SA_W_PHR:
17844 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
17846 case NM_MAQ_SA_W_PHL:
17848 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
17851 generate_exception_end(ctx, EXCP_RI);
17855 tcg_temp_free_i32(t0);
17857 tcg_temp_free(v0_t);
17858 tcg_temp_free(v1_t);
17862 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
17863 int ret, int v1, int v2)
17866 TCGv t0 = tcg_temp_new();
17867 TCGv t1 = tcg_temp_new();
17868 TCGv v0_t = tcg_temp_new();
17870 gen_load_gpr(v0_t, v1);
17873 case NM_POOL32AXF_1_0:
17875 switch (extract32(ctx->opcode, 12, 2)) {
17877 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
17880 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
17883 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
17886 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
17890 case NM_POOL32AXF_1_1:
17892 switch (extract32(ctx->opcode, 12, 2)) {
17894 tcg_gen_movi_tl(t0, v2);
17895 gen_helper_mthlip(t0, v0_t, cpu_env);
17898 tcg_gen_movi_tl(t0, v2 >> 3);
17899 gen_helper_shilo(t0, v0_t, cpu_env);
17902 generate_exception_end(ctx, EXCP_RI);
17906 case NM_POOL32AXF_1_3:
17908 imm = extract32(ctx->opcode, 14, 7);
17909 switch (extract32(ctx->opcode, 12, 2)) {
17911 tcg_gen_movi_tl(t0, imm);
17912 gen_helper_rddsp(t0, t0, cpu_env);
17913 gen_store_gpr(t0, ret);
17916 gen_load_gpr(t0, ret);
17917 tcg_gen_movi_tl(t1, imm);
17918 gen_helper_wrdsp(t0, t1, cpu_env);
17921 tcg_gen_movi_tl(t0, v2 >> 3);
17922 tcg_gen_movi_tl(t1, v1);
17923 gen_helper_extp(t0, t0, t1, cpu_env);
17924 gen_store_gpr(t0, ret);
17927 tcg_gen_movi_tl(t0, v2 >> 3);
17928 tcg_gen_movi_tl(t1, v1);
17929 gen_helper_extpdp(t0, t0, t1, cpu_env);
17930 gen_store_gpr(t0, ret);
17934 case NM_POOL32AXF_1_4:
17936 tcg_gen_movi_tl(t0, v2 >> 2);
17937 switch (extract32(ctx->opcode, 12, 1)) {
17939 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
17940 gen_store_gpr(t0, ret);
17943 gen_helper_shrl_qb(t0, t0, v0_t);
17944 gen_store_gpr(t0, ret);
17948 case NM_POOL32AXF_1_5:
17949 opc = extract32(ctx->opcode, 12, 2);
17950 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
17952 case NM_POOL32AXF_1_7:
17954 tcg_gen_movi_tl(t0, v2 >> 3);
17955 tcg_gen_movi_tl(t1, v1);
17956 switch (extract32(ctx->opcode, 12, 2)) {
17958 gen_helper_extr_w(t0, t0, t1, cpu_env);
17959 gen_store_gpr(t0, ret);
17962 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
17963 gen_store_gpr(t0, ret);
17966 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
17967 gen_store_gpr(t0, ret);
17970 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
17971 gen_store_gpr(t0, ret);
17976 generate_exception_end(ctx, EXCP_RI);
17982 tcg_temp_free(v0_t);
17985 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
17986 TCGv v0, TCGv v1, int rd)
17990 t0 = tcg_temp_new_i32();
17992 tcg_gen_movi_i32(t0, rd >> 3);
17995 case NM_POOL32AXF_2_0_7:
17996 switch (extract32(ctx->opcode, 9, 3)) {
17999 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18001 case NM_DPAQ_S_W_PH:
18003 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18007 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18009 case NM_DPSQ_S_W_PH:
18011 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18014 generate_exception_end(ctx, EXCP_RI);
18018 case NM_POOL32AXF_2_8_15:
18019 switch (extract32(ctx->opcode, 9, 3)) {
18022 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18024 case NM_DPAQ_SA_L_W:
18026 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18030 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18032 case NM_DPSQ_SA_L_W:
18034 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18037 generate_exception_end(ctx, EXCP_RI);
18041 case NM_POOL32AXF_2_16_23:
18042 switch (extract32(ctx->opcode, 9, 3)) {
18043 case NM_DPAU_H_QBL:
18045 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18047 case NM_DPAQX_S_W_PH:
18049 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18051 case NM_DPSU_H_QBL:
18053 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18055 case NM_DPSQX_S_W_PH:
18057 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18059 case NM_MULSA_W_PH:
18061 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18064 generate_exception_end(ctx, EXCP_RI);
18068 case NM_POOL32AXF_2_24_31:
18069 switch (extract32(ctx->opcode, 9, 3)) {
18070 case NM_DPAU_H_QBR:
18072 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18074 case NM_DPAQX_SA_W_PH:
18076 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18078 case NM_DPSU_H_QBR:
18080 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18082 case NM_DPSQX_SA_W_PH:
18084 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18086 case NM_MULSAQ_S_W_PH:
18088 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18091 generate_exception_end(ctx, EXCP_RI);
18096 generate_exception_end(ctx, EXCP_RI);
18100 tcg_temp_free_i32(t0);
18103 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18104 int rt, int rs, int rd)
18107 TCGv t0 = tcg_temp_new();
18108 TCGv t1 = tcg_temp_new();
18109 TCGv v0_t = tcg_temp_new();
18110 TCGv v1_t = tcg_temp_new();
18112 gen_load_gpr(v0_t, rt);
18113 gen_load_gpr(v1_t, rs);
18116 case NM_POOL32AXF_2_0_7:
18117 switch (extract32(ctx->opcode, 9, 3)) {
18119 case NM_DPAQ_S_W_PH:
18121 case NM_DPSQ_S_W_PH:
18122 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18127 gen_load_gpr(t0, rs);
18129 if (rd != 0 && rd != 2) {
18130 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18131 tcg_gen_ext32u_tl(t0, t0);
18132 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18133 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18135 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18141 int acc = extract32(ctx->opcode, 14, 2);
18142 TCGv_i64 t2 = tcg_temp_new_i64();
18143 TCGv_i64 t3 = tcg_temp_new_i64();
18145 gen_load_gpr(t0, rt);
18146 gen_load_gpr(t1, rs);
18147 tcg_gen_ext_tl_i64(t2, t0);
18148 tcg_gen_ext_tl_i64(t3, t1);
18149 tcg_gen_mul_i64(t2, t2, t3);
18150 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18151 tcg_gen_add_i64(t2, t2, t3);
18152 tcg_temp_free_i64(t3);
18153 gen_move_low32(cpu_LO[acc], t2);
18154 gen_move_high32(cpu_HI[acc], t2);
18155 tcg_temp_free_i64(t2);
18161 int acc = extract32(ctx->opcode, 14, 2);
18162 TCGv_i32 t2 = tcg_temp_new_i32();
18163 TCGv_i32 t3 = tcg_temp_new_i32();
18165 gen_load_gpr(t0, rs);
18166 gen_load_gpr(t1, rt);
18167 tcg_gen_trunc_tl_i32(t2, t0);
18168 tcg_gen_trunc_tl_i32(t3, t1);
18169 tcg_gen_muls2_i32(t2, t3, t2, t3);
18170 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18171 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18172 tcg_temp_free_i32(t2);
18173 tcg_temp_free_i32(t3);
18178 gen_load_gpr(v1_t, rs);
18179 tcg_gen_movi_tl(t0, rd >> 3);
18180 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18181 gen_store_gpr(t0, ret);
18185 case NM_POOL32AXF_2_8_15:
18186 switch (extract32(ctx->opcode, 9, 3)) {
18188 case NM_DPAQ_SA_L_W:
18190 case NM_DPSQ_SA_L_W:
18191 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18196 int acc = extract32(ctx->opcode, 14, 2);
18197 TCGv_i64 t2 = tcg_temp_new_i64();
18198 TCGv_i64 t3 = tcg_temp_new_i64();
18200 gen_load_gpr(t0, rs);
18201 gen_load_gpr(t1, rt);
18202 tcg_gen_ext32u_tl(t0, t0);
18203 tcg_gen_ext32u_tl(t1, t1);
18204 tcg_gen_extu_tl_i64(t2, t0);
18205 tcg_gen_extu_tl_i64(t3, t1);
18206 tcg_gen_mul_i64(t2, t2, t3);
18207 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18208 tcg_gen_add_i64(t2, t2, t3);
18209 tcg_temp_free_i64(t3);
18210 gen_move_low32(cpu_LO[acc], t2);
18211 gen_move_high32(cpu_HI[acc], t2);
18212 tcg_temp_free_i64(t2);
18218 int acc = extract32(ctx->opcode, 14, 2);
18219 TCGv_i32 t2 = tcg_temp_new_i32();
18220 TCGv_i32 t3 = tcg_temp_new_i32();
18222 gen_load_gpr(t0, rs);
18223 gen_load_gpr(t1, rt);
18224 tcg_gen_trunc_tl_i32(t2, t0);
18225 tcg_gen_trunc_tl_i32(t3, t1);
18226 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18227 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18228 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18229 tcg_temp_free_i32(t2);
18230 tcg_temp_free_i32(t3);
18235 tcg_gen_movi_tl(t0, rd >> 3);
18236 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18237 gen_store_gpr(t0, ret);
18240 generate_exception_end(ctx, EXCP_RI);
18244 case NM_POOL32AXF_2_16_23:
18245 switch (extract32(ctx->opcode, 9, 3)) {
18246 case NM_DPAU_H_QBL:
18247 case NM_DPAQX_S_W_PH:
18248 case NM_DPSU_H_QBL:
18249 case NM_DPSQX_S_W_PH:
18250 case NM_MULSA_W_PH:
18251 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18255 tcg_gen_movi_tl(t0, rd >> 3);
18256 gen_helper_extp(t0, t0, v1_t, cpu_env);
18257 gen_store_gpr(t0, ret);
18262 int acc = extract32(ctx->opcode, 14, 2);
18263 TCGv_i64 t2 = tcg_temp_new_i64();
18264 TCGv_i64 t3 = tcg_temp_new_i64();
18266 gen_load_gpr(t0, rs);
18267 gen_load_gpr(t1, rt);
18268 tcg_gen_ext_tl_i64(t2, t0);
18269 tcg_gen_ext_tl_i64(t3, t1);
18270 tcg_gen_mul_i64(t2, t2, t3);
18271 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18272 tcg_gen_sub_i64(t2, t3, t2);
18273 tcg_temp_free_i64(t3);
18274 gen_move_low32(cpu_LO[acc], t2);
18275 gen_move_high32(cpu_HI[acc], t2);
18276 tcg_temp_free_i64(t2);
18279 case NM_EXTRV_RS_W:
18281 tcg_gen_movi_tl(t0, rd >> 3);
18282 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18283 gen_store_gpr(t0, ret);
18287 case NM_POOL32AXF_2_24_31:
18288 switch (extract32(ctx->opcode, 9, 3)) {
18289 case NM_DPAU_H_QBR:
18290 case NM_DPAQX_SA_W_PH:
18291 case NM_DPSU_H_QBR:
18292 case NM_DPSQX_SA_W_PH:
18293 case NM_MULSAQ_S_W_PH:
18294 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18298 tcg_gen_movi_tl(t0, rd >> 3);
18299 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
18300 gen_store_gpr(t0, ret);
18305 int acc = extract32(ctx->opcode, 14, 2);
18306 TCGv_i64 t2 = tcg_temp_new_i64();
18307 TCGv_i64 t3 = tcg_temp_new_i64();
18309 gen_load_gpr(t0, rs);
18310 gen_load_gpr(t1, rt);
18311 tcg_gen_ext32u_tl(t0, t0);
18312 tcg_gen_ext32u_tl(t1, t1);
18313 tcg_gen_extu_tl_i64(t2, t0);
18314 tcg_gen_extu_tl_i64(t3, t1);
18315 tcg_gen_mul_i64(t2, t2, t3);
18316 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18317 tcg_gen_sub_i64(t2, t3, t2);
18318 tcg_temp_free_i64(t3);
18319 gen_move_low32(cpu_LO[acc], t2);
18320 gen_move_high32(cpu_HI[acc], t2);
18321 tcg_temp_free_i64(t2);
18326 tcg_gen_movi_tl(t0, rd >> 3);
18327 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
18328 gen_store_gpr(t0, ret);
18333 generate_exception_end(ctx, EXCP_RI);
18340 tcg_temp_free(v0_t);
18341 tcg_temp_free(v1_t);
18344 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
18348 TCGv t0 = tcg_temp_new();
18349 TCGv v0_t = tcg_temp_new();
18351 gen_load_gpr(v0_t, rs);
18356 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
18357 gen_store_gpr(v0_t, ret);
18361 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
18362 gen_store_gpr(v0_t, ret);
18366 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
18367 gen_store_gpr(v0_t, ret);
18369 case NM_PRECEQ_W_PHL:
18371 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
18372 tcg_gen_ext32s_tl(v0_t, v0_t);
18373 gen_store_gpr(v0_t, ret);
18375 case NM_PRECEQ_W_PHR:
18377 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
18378 tcg_gen_shli_tl(v0_t, v0_t, 16);
18379 tcg_gen_ext32s_tl(v0_t, v0_t);
18380 gen_store_gpr(v0_t, ret);
18382 case NM_PRECEQU_PH_QBL:
18384 gen_helper_precequ_ph_qbl(v0_t, v0_t);
18385 gen_store_gpr(v0_t, ret);
18387 case NM_PRECEQU_PH_QBR:
18389 gen_helper_precequ_ph_qbr(v0_t, v0_t);
18390 gen_store_gpr(v0_t, ret);
18392 case NM_PRECEQU_PH_QBLA:
18394 gen_helper_precequ_ph_qbla(v0_t, v0_t);
18395 gen_store_gpr(v0_t, ret);
18397 case NM_PRECEQU_PH_QBRA:
18399 gen_helper_precequ_ph_qbra(v0_t, v0_t);
18400 gen_store_gpr(v0_t, ret);
18402 case NM_PRECEU_PH_QBL:
18404 gen_helper_preceu_ph_qbl(v0_t, v0_t);
18405 gen_store_gpr(v0_t, ret);
18407 case NM_PRECEU_PH_QBR:
18409 gen_helper_preceu_ph_qbr(v0_t, v0_t);
18410 gen_store_gpr(v0_t, ret);
18412 case NM_PRECEU_PH_QBLA:
18414 gen_helper_preceu_ph_qbla(v0_t, v0_t);
18415 gen_store_gpr(v0_t, ret);
18417 case NM_PRECEU_PH_QBRA:
18419 gen_helper_preceu_ph_qbra(v0_t, v0_t);
18420 gen_store_gpr(v0_t, ret);
18424 tcg_gen_ext16u_tl(v0_t, v0_t);
18425 tcg_gen_shli_tl(t0, v0_t, 16);
18426 tcg_gen_or_tl(v0_t, v0_t, t0);
18427 tcg_gen_ext32s_tl(v0_t, v0_t);
18428 gen_store_gpr(v0_t, ret);
18432 tcg_gen_ext8u_tl(v0_t, v0_t);
18433 tcg_gen_shli_tl(t0, v0_t, 8);
18434 tcg_gen_or_tl(v0_t, v0_t, t0);
18435 tcg_gen_shli_tl(t0, v0_t, 16);
18436 tcg_gen_or_tl(v0_t, v0_t, t0);
18437 tcg_gen_ext32s_tl(v0_t, v0_t);
18438 gen_store_gpr(v0_t, ret);
18442 gen_helper_bitrev(v0_t, v0_t);
18443 gen_store_gpr(v0_t, ret);
18448 TCGv tv0 = tcg_temp_new();
18450 gen_load_gpr(tv0, rt);
18451 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
18452 gen_store_gpr(v0_t, ret);
18453 tcg_temp_free(tv0);
18456 case NM_RADDU_W_QB:
18458 gen_helper_raddu_w_qb(v0_t, v0_t);
18459 gen_store_gpr(v0_t, ret);
18462 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
18466 gen_cl(ctx, OPC_CLO, ret, rs);
18470 gen_cl(ctx, OPC_CLZ, ret, rs);
18473 gen_bshfl(ctx, OPC_WSBH, ret, rs);
18476 generate_exception_end(ctx, EXCP_RI);
18480 tcg_temp_free(v0_t);
18484 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
18485 int rt, int rs, int rd)
18487 TCGv t0 = tcg_temp_new();
18488 TCGv rs_t = tcg_temp_new();
18490 gen_load_gpr(rs_t, rs);
18495 tcg_gen_movi_tl(t0, rd >> 2);
18496 switch (extract32(ctx->opcode, 12, 1)) {
18499 gen_helper_shra_qb(t0, t0, rs_t);
18500 gen_store_gpr(t0, rt);
18504 gen_helper_shra_r_qb(t0, t0, rs_t);
18505 gen_store_gpr(t0, rt);
18511 tcg_gen_movi_tl(t0, rd >> 1);
18512 gen_helper_shrl_ph(t0, t0, rs_t);
18513 gen_store_gpr(t0, rt);
18519 target_long result;
18520 imm = extract32(ctx->opcode, 13, 8);
18521 result = (uint32_t)imm << 24 |
18522 (uint32_t)imm << 16 |
18523 (uint32_t)imm << 8 |
18525 result = (int32_t)result;
18526 tcg_gen_movi_tl(t0, result);
18527 gen_store_gpr(t0, rt);
18531 generate_exception_end(ctx, EXCP_RI);
18535 tcg_temp_free(rs_t);
18539 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18541 int rt = extract32(ctx->opcode, 21, 5);
18542 int rs = extract32(ctx->opcode, 16, 5);
18543 int rd = extract32(ctx->opcode, 11, 5);
18545 switch (extract32(ctx->opcode, 6, 3)) {
18546 case NM_POOL32AXF_1:
18548 int32_t op1 = extract32(ctx->opcode, 9, 3);
18549 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
18552 case NM_POOL32AXF_2:
18554 int32_t op1 = extract32(ctx->opcode, 12, 2);
18555 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
18558 case NM_POOL32AXF_4:
18560 int32_t op1 = extract32(ctx->opcode, 9, 7);
18561 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
18564 case NM_POOL32AXF_5:
18565 switch (extract32(ctx->opcode, 9, 7)) {
18566 #ifndef CONFIG_USER_ONLY
18568 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
18571 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
18574 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
18577 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
18580 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
18583 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
18586 check_cp0_enabled(ctx);
18588 TCGv t0 = tcg_temp_new();
18590 save_cpu_state(ctx, 1);
18591 gen_helper_di(t0, cpu_env);
18592 gen_store_gpr(t0, rt);
18593 /* Stop translation as we may have switched the execution mode */
18594 ctx->base.is_jmp = DISAS_STOP;
18599 check_cp0_enabled(ctx);
18601 TCGv t0 = tcg_temp_new();
18603 save_cpu_state(ctx, 1);
18604 gen_helper_ei(t0, cpu_env);
18605 gen_store_gpr(t0, rt);
18606 /* Stop translation as we may have switched the execution mode */
18607 ctx->base.is_jmp = DISAS_STOP;
18612 gen_load_srsgpr(rs, rt);
18615 gen_store_srsgpr(rs, rt);
18618 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
18621 gen_cp0(env, ctx, OPC_DERET, 0, 0);
18624 gen_cp0(env, ctx, OPC_ERET, 0, 0);
18628 generate_exception_end(ctx, EXCP_RI);
18632 case NM_POOL32AXF_7:
18634 int32_t op1 = extract32(ctx->opcode, 9, 3);
18635 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
18639 generate_exception_end(ctx, EXCP_RI);
18644 /* Immediate Value Compact Branches */
18645 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
18646 int rt, int32_t imm, int32_t offset)
18649 int bcond_compute = 0;
18650 TCGv t0 = tcg_temp_new();
18651 TCGv t1 = tcg_temp_new();
18653 gen_load_gpr(t0, rt);
18654 tcg_gen_movi_tl(t1, imm);
18655 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18657 /* Load needed operands and calculate btarget */
18660 if (rt == 0 && imm == 0) {
18661 /* Unconditional branch */
18662 } else if (rt == 0 && imm != 0) {
18667 cond = TCG_COND_EQ;
18673 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
18674 generate_exception_end(ctx, EXCP_RI);
18676 } else if (rt == 0 && opc == NM_BBEQZC) {
18677 /* Unconditional branch */
18678 } else if (rt == 0 && opc == NM_BBNEZC) {
18682 tcg_gen_shri_tl(t0, t0, imm);
18683 tcg_gen_andi_tl(t0, t0, 1);
18684 tcg_gen_movi_tl(t1, 0);
18686 if (opc == NM_BBEQZC) {
18687 cond = TCG_COND_EQ;
18689 cond = TCG_COND_NE;
18694 if (rt == 0 && imm == 0) {
18697 } else if (rt == 0 && imm != 0) {
18698 /* Unconditional branch */
18701 cond = TCG_COND_NE;
18705 if (rt == 0 && imm == 0) {
18706 /* Unconditional branch */
18709 cond = TCG_COND_GE;
18714 cond = TCG_COND_LT;
18717 if (rt == 0 && imm == 0) {
18718 /* Unconditional branch */
18721 cond = TCG_COND_GEU;
18726 cond = TCG_COND_LTU;
18729 MIPS_INVAL("Immediate Value Compact branch");
18730 generate_exception_end(ctx, EXCP_RI);
18734 if (bcond_compute == 0) {
18735 /* Uncoditional compact branch */
18736 gen_goto_tb(ctx, 0, ctx->btarget);
18738 /* Conditional compact branch */
18739 TCGLabel *fs = gen_new_label();
18741 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
18743 gen_goto_tb(ctx, 1, ctx->btarget);
18746 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
18754 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
18755 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
18758 TCGv t0 = tcg_temp_new();
18759 TCGv t1 = tcg_temp_new();
18762 gen_load_gpr(t0, rs);
18766 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
18769 /* calculate btarget */
18770 tcg_gen_shli_tl(t0, t0, 1);
18771 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
18772 gen_op_addr_add(ctx, btarget, t1, t0);
18774 /* unconditional branch to register */
18775 tcg_gen_mov_tl(cpu_PC, btarget);
18776 tcg_gen_lookup_and_goto_ptr();
18782 /* nanoMIPS Branches */
18783 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
18784 int rs, int rt, int32_t offset)
18786 int bcond_compute = 0;
18787 TCGv t0 = tcg_temp_new();
18788 TCGv t1 = tcg_temp_new();
18790 /* Load needed operands and calculate btarget */
18792 /* compact branch */
18795 gen_load_gpr(t0, rs);
18796 gen_load_gpr(t1, rt);
18798 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18802 if (rs == 0 || rs == rt) {
18803 /* OPC_BLEZALC, OPC_BGEZALC */
18804 /* OPC_BGTZALC, OPC_BLTZALC */
18805 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
18807 gen_load_gpr(t0, rs);
18808 gen_load_gpr(t1, rt);
18810 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18813 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18817 /* OPC_BEQZC, OPC_BNEZC */
18818 gen_load_gpr(t0, rs);
18820 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18822 /* OPC_JIC, OPC_JIALC */
18823 TCGv tbase = tcg_temp_new();
18824 TCGv toffset = tcg_temp_new();
18826 gen_load_gpr(tbase, rt);
18827 tcg_gen_movi_tl(toffset, offset);
18828 gen_op_addr_add(ctx, btarget, tbase, toffset);
18829 tcg_temp_free(tbase);
18830 tcg_temp_free(toffset);
18834 MIPS_INVAL("Compact branch/jump");
18835 generate_exception_end(ctx, EXCP_RI);
18839 if (bcond_compute == 0) {
18840 /* Uncoditional compact branch */
18843 gen_goto_tb(ctx, 0, ctx->btarget);
18846 MIPS_INVAL("Compact branch/jump");
18847 generate_exception_end(ctx, EXCP_RI);
18851 /* Conditional compact branch */
18852 TCGLabel *fs = gen_new_label();
18856 if (rs == 0 && rt != 0) {
18858 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18859 } else if (rs != 0 && rt != 0 && rs == rt) {
18861 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18864 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
18868 if (rs == 0 && rt != 0) {
18870 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18871 } else if (rs != 0 && rt != 0 && rs == rt) {
18873 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
18876 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
18880 if (rs == 0 && rt != 0) {
18882 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18883 } else if (rs != 0 && rt != 0 && rs == rt) {
18885 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18888 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
18892 if (rs == 0 && rt != 0) {
18894 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18895 } else if (rs != 0 && rt != 0 && rs == rt) {
18897 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
18900 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
18904 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
18907 MIPS_INVAL("Compact conditional branch/jump");
18908 generate_exception_end(ctx, EXCP_RI);
18912 /* Generating branch here as compact branches don't have delay slot */
18913 gen_goto_tb(ctx, 1, ctx->btarget);
18916 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
18925 /* nanoMIPS CP1 Branches */
18926 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
18927 int32_t ft, int32_t offset)
18929 target_ulong btarget;
18930 TCGv_i64 t0 = tcg_temp_new_i64();
18932 gen_load_fpr64(ctx, t0, ft);
18933 tcg_gen_andi_i64(t0, t0, 1);
18935 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18939 tcg_gen_xori_i64(t0, t0, 1);
18940 ctx->hflags |= MIPS_HFLAG_BC;
18943 /* t0 already set */
18944 ctx->hflags |= MIPS_HFLAG_BC;
18947 MIPS_INVAL("cp1 cond branch");
18948 generate_exception_end(ctx, EXCP_RI);
18952 tcg_gen_trunc_i64_tl(bcond, t0);
18954 ctx->btarget = btarget;
18957 tcg_temp_free_i64(t0);
18961 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
18964 t0 = tcg_temp_new();
18965 t1 = tcg_temp_new();
18967 gen_load_gpr(t0, rs);
18968 gen_load_gpr(t1, rt);
18970 if ((extract32(ctx->opcode, 6, 1)) == 1) {
18971 /* PP.LSXS instructions require shifting */
18972 switch (extract32(ctx->opcode, 7, 4)) {
18977 tcg_gen_shli_tl(t0, t0, 1);
18984 tcg_gen_shli_tl(t0, t0, 2);
18988 tcg_gen_shli_tl(t0, t0, 3);
18992 gen_op_addr_add(ctx, t0, t0, t1);
18994 switch (extract32(ctx->opcode, 7, 4)) {
18996 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
18998 gen_store_gpr(t0, rd);
19002 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19004 gen_store_gpr(t0, rd);
19008 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19010 gen_store_gpr(t0, rd);
19013 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19015 gen_store_gpr(t0, rd);
19019 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19021 gen_store_gpr(t0, rd);
19025 gen_load_gpr(t1, rd);
19026 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19032 gen_load_gpr(t1, rd);
19033 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19039 gen_load_gpr(t1, rd);
19040 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19044 /*case NM_LWC1XS:*/
19046 /*case NM_LDC1XS:*/
19048 /*case NM_SWC1XS:*/
19050 /*case NM_SDC1XS:*/
19051 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19052 check_cp1_enabled(ctx);
19053 switch (extract32(ctx->opcode, 7, 4)) {
19055 /*case NM_LWC1XS:*/
19056 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19059 /*case NM_LDC1XS:*/
19060 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19063 /*case NM_SWC1XS:*/
19064 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19067 /*case NM_SDC1XS:*/
19068 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19072 generate_exception_err(ctx, EXCP_CpU, 1);
19076 generate_exception_end(ctx, EXCP_RI);
19084 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19088 rt = extract32(ctx->opcode, 21, 5);
19089 rs = extract32(ctx->opcode, 16, 5);
19090 rd = extract32(ctx->opcode, 11, 5);
19092 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19093 generate_exception_end(ctx, EXCP_RI);
19096 check_cp1_enabled(ctx);
19097 switch (extract32(ctx->opcode, 0, 3)) {
19099 switch (extract32(ctx->opcode, 3, 7)) {
19101 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19104 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19107 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19110 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19113 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19116 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19119 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19122 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19125 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19128 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19131 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19134 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19137 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19140 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19143 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19146 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19149 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19152 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19155 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19158 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19161 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19164 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19167 generate_exception_end(ctx, EXCP_RI);
19172 switch (extract32(ctx->opcode, 3, 3)) {
19174 switch (extract32(ctx->opcode, 9, 1)) {
19176 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19179 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19184 switch (extract32(ctx->opcode, 9, 1)) {
19186 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19189 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19194 switch (extract32(ctx->opcode, 9, 1)) {
19196 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19199 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19204 switch (extract32(ctx->opcode, 9, 1)) {
19206 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19209 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19214 switch (extract32(ctx->opcode, 6, 8)) {
19216 gen_cp1(ctx, OPC_CFC1, rt, rs);
19219 gen_cp1(ctx, OPC_CTC1, rt, rs);
19222 gen_cp1(ctx, OPC_MFC1, rt, rs);
19225 gen_cp1(ctx, OPC_MTC1, rt, rs);
19228 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19231 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19234 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19237 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19240 switch (extract32(ctx->opcode, 6, 9)) {
19242 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19245 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19248 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19251 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19254 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19257 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19260 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19263 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19266 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19269 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19272 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19275 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19278 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19281 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19284 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19287 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
19290 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
19293 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
19296 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
19299 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
19302 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
19305 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
19308 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
19311 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
19314 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
19317 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
19320 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
19323 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
19326 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
19329 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
19332 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
19335 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
19338 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
19341 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
19344 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
19347 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
19350 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
19353 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
19356 generate_exception_end(ctx, EXCP_RI);
19365 switch (extract32(ctx->opcode, 3, 3)) {
19366 case NM_CMP_CONDN_S:
19367 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19369 case NM_CMP_CONDN_D:
19370 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19373 generate_exception_end(ctx, EXCP_RI);
19378 generate_exception_end(ctx, EXCP_RI);
19383 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
19384 int rd, int rs, int rt)
19387 TCGv t0 = tcg_temp_new();
19388 TCGv v1_t = tcg_temp_new();
19389 TCGv v2_t = tcg_temp_new();
19391 gen_load_gpr(v1_t, rs);
19392 gen_load_gpr(v2_t, rt);
19397 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
19401 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
19405 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
19407 case NM_CMPU_EQ_QB:
19409 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
19411 case NM_CMPU_LT_QB:
19413 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
19415 case NM_CMPU_LE_QB:
19417 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
19419 case NM_CMPGU_EQ_QB:
19421 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19422 gen_store_gpr(v1_t, ret);
19424 case NM_CMPGU_LT_QB:
19426 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19427 gen_store_gpr(v1_t, ret);
19429 case NM_CMPGU_LE_QB:
19431 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19432 gen_store_gpr(v1_t, ret);
19434 case NM_CMPGDU_EQ_QB:
19436 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19437 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19438 gen_store_gpr(v1_t, ret);
19440 case NM_CMPGDU_LT_QB:
19442 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19443 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19444 gen_store_gpr(v1_t, ret);
19446 case NM_CMPGDU_LE_QB:
19448 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19449 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19450 gen_store_gpr(v1_t, ret);
19454 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
19455 gen_store_gpr(v1_t, ret);
19459 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
19460 gen_store_gpr(v1_t, ret);
19464 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
19465 gen_store_gpr(v1_t, ret);
19469 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
19470 gen_store_gpr(v1_t, ret);
19474 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
19475 gen_store_gpr(v1_t, ret);
19479 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
19480 gen_store_gpr(v1_t, ret);
19484 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
19485 gen_store_gpr(v1_t, ret);
19489 switch (extract32(ctx->opcode, 10, 1)) {
19492 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
19493 gen_store_gpr(v1_t, ret);
19497 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19498 gen_store_gpr(v1_t, ret);
19502 case NM_ADDQH_R_PH:
19504 switch (extract32(ctx->opcode, 10, 1)) {
19507 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
19508 gen_store_gpr(v1_t, ret);
19512 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
19513 gen_store_gpr(v1_t, ret);
19519 switch (extract32(ctx->opcode, 10, 1)) {
19522 gen_helper_addqh_w(v1_t, v1_t, v2_t);
19523 gen_store_gpr(v1_t, ret);
19527 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
19528 gen_store_gpr(v1_t, ret);
19534 switch (extract32(ctx->opcode, 10, 1)) {
19537 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
19538 gen_store_gpr(v1_t, ret);
19542 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19543 gen_store_gpr(v1_t, ret);
19549 switch (extract32(ctx->opcode, 10, 1)) {
19552 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
19553 gen_store_gpr(v1_t, ret);
19557 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19558 gen_store_gpr(v1_t, ret);
19562 case NM_ADDUH_R_QB:
19564 switch (extract32(ctx->opcode, 10, 1)) {
19567 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
19568 gen_store_gpr(v1_t, ret);
19572 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
19573 gen_store_gpr(v1_t, ret);
19577 case NM_SHRAV_R_PH:
19579 switch (extract32(ctx->opcode, 10, 1)) {
19582 gen_helper_shra_ph(v1_t, v1_t, v2_t);
19583 gen_store_gpr(v1_t, ret);
19587 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
19588 gen_store_gpr(v1_t, ret);
19592 case NM_SHRAV_R_QB:
19594 switch (extract32(ctx->opcode, 10, 1)) {
19597 gen_helper_shra_qb(v1_t, v1_t, v2_t);
19598 gen_store_gpr(v1_t, ret);
19602 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
19603 gen_store_gpr(v1_t, ret);
19609 switch (extract32(ctx->opcode, 10, 1)) {
19612 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
19613 gen_store_gpr(v1_t, ret);
19617 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19618 gen_store_gpr(v1_t, ret);
19622 case NM_SUBQH_R_PH:
19624 switch (extract32(ctx->opcode, 10, 1)) {
19627 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
19628 gen_store_gpr(v1_t, ret);
19632 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
19633 gen_store_gpr(v1_t, ret);
19639 switch (extract32(ctx->opcode, 10, 1)) {
19642 gen_helper_subqh_w(v1_t, v1_t, v2_t);
19643 gen_store_gpr(v1_t, ret);
19647 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
19648 gen_store_gpr(v1_t, ret);
19654 switch (extract32(ctx->opcode, 10, 1)) {
19657 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
19658 gen_store_gpr(v1_t, ret);
19662 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19663 gen_store_gpr(v1_t, ret);
19669 switch (extract32(ctx->opcode, 10, 1)) {
19672 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
19673 gen_store_gpr(v1_t, ret);
19677 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19678 gen_store_gpr(v1_t, ret);
19682 case NM_SUBUH_R_QB:
19684 switch (extract32(ctx->opcode, 10, 1)) {
19687 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
19688 gen_store_gpr(v1_t, ret);
19692 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
19693 gen_store_gpr(v1_t, ret);
19697 case NM_SHLLV_S_PH:
19699 switch (extract32(ctx->opcode, 10, 1)) {
19702 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
19703 gen_store_gpr(v1_t, ret);
19707 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
19708 gen_store_gpr(v1_t, ret);
19712 case NM_PRECR_SRA_R_PH_W:
19714 switch (extract32(ctx->opcode, 10, 1)) {
19716 /* PRECR_SRA_PH_W */
19718 TCGv_i32 sa_t = tcg_const_i32(rd);
19719 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
19721 gen_store_gpr(v1_t, rt);
19722 tcg_temp_free_i32(sa_t);
19726 /* PRECR_SRA_R_PH_W */
19728 TCGv_i32 sa_t = tcg_const_i32(rd);
19729 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
19731 gen_store_gpr(v1_t, rt);
19732 tcg_temp_free_i32(sa_t);
19737 case NM_MULEU_S_PH_QBL:
19739 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
19740 gen_store_gpr(v1_t, ret);
19742 case NM_MULEU_S_PH_QBR:
19744 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
19745 gen_store_gpr(v1_t, ret);
19747 case NM_MULQ_RS_PH:
19749 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
19750 gen_store_gpr(v1_t, ret);
19754 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19755 gen_store_gpr(v1_t, ret);
19759 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
19760 gen_store_gpr(v1_t, ret);
19764 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
19765 gen_store_gpr(v1_t, ret);
19769 gen_load_gpr(t0, rs);
19771 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
19773 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
19777 gen_helper_modsub(v1_t, v1_t, v2_t);
19778 gen_store_gpr(v1_t, ret);
19782 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
19783 gen_store_gpr(v1_t, ret);
19787 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
19788 gen_store_gpr(v1_t, ret);
19792 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
19793 gen_store_gpr(v1_t, ret);
19797 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
19798 gen_store_gpr(v1_t, ret);
19802 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
19803 gen_store_gpr(v1_t, ret);
19808 TCGv tv0 = tcg_temp_new();
19809 TCGv tv1 = tcg_temp_new();
19810 int16_t imm = extract32(ctx->opcode, 16, 7);
19812 tcg_gen_movi_tl(tv0, rd >> 3);
19813 tcg_gen_movi_tl(tv1, imm);
19814 gen_helper_shilo(tv0, tv1, cpu_env);
19817 case NM_MULEQ_S_W_PHL:
19819 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
19820 gen_store_gpr(v1_t, ret);
19822 case NM_MULEQ_S_W_PHR:
19824 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
19825 gen_store_gpr(v1_t, ret);
19829 switch (extract32(ctx->opcode, 10, 1)) {
19832 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
19833 gen_store_gpr(v1_t, ret);
19837 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
19838 gen_store_gpr(v1_t, ret);
19842 case NM_PRECR_QB_PH:
19844 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
19845 gen_store_gpr(v1_t, ret);
19847 case NM_PRECRQ_QB_PH:
19849 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
19850 gen_store_gpr(v1_t, ret);
19852 case NM_PRECRQ_PH_W:
19854 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
19855 gen_store_gpr(v1_t, ret);
19857 case NM_PRECRQ_RS_PH_W:
19859 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
19860 gen_store_gpr(v1_t, ret);
19862 case NM_PRECRQU_S_QB_PH:
19864 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
19865 gen_store_gpr(v1_t, ret);
19869 tcg_gen_movi_tl(t0, rd);
19870 gen_helper_shra_r_w(v1_t, t0, v1_t);
19871 gen_store_gpr(v1_t, rt);
19875 tcg_gen_movi_tl(t0, rd >> 1);
19876 switch (extract32(ctx->opcode, 10, 1)) {
19879 gen_helper_shra_ph(v1_t, t0, v1_t);
19881 gen_store_gpr(v1_t, rt);
19884 gen_helper_shra_r_ph(v1_t, t0, v1_t);
19885 gen_store_gpr(v1_t, rt);
19891 tcg_gen_movi_tl(t0, rd >> 1);
19892 switch (extract32(ctx->opcode, 10, 2)) {
19895 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
19896 gen_store_gpr(v1_t, rt);
19900 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
19901 gen_store_gpr(v1_t, rt);
19904 generate_exception_end(ctx, EXCP_RI);
19910 tcg_gen_movi_tl(t0, rd);
19911 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
19912 gen_store_gpr(v1_t, rt);
19918 imm = sextract32(ctx->opcode, 11, 11);
19919 imm = (int16_t)(imm << 6) >> 6;
19921 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
19926 generate_exception_end(ctx, EXCP_RI);
19931 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
19939 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
19940 ctx->opcode = (ctx->opcode << 16) | insn;
19942 rt = extract32(ctx->opcode, 21, 5);
19943 rs = extract32(ctx->opcode, 16, 5);
19944 rd = extract32(ctx->opcode, 11, 5);
19946 op = extract32(ctx->opcode, 26, 6);
19951 switch (extract32(ctx->opcode, 19, 2)) {
19954 generate_exception_end(ctx, EXCP_RI);
19957 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
19958 generate_exception_end(ctx, EXCP_SYSCALL);
19960 generate_exception_end(ctx, EXCP_RI);
19964 generate_exception_end(ctx, EXCP_BREAK);
19967 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
19968 gen_helper_do_semihosting(cpu_env);
19970 if (ctx->hflags & MIPS_HFLAG_SBRI) {
19971 generate_exception_end(ctx, EXCP_RI);
19973 generate_exception_end(ctx, EXCP_DBp);
19980 imm = extract32(ctx->opcode, 0, 16);
19982 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
19984 tcg_gen_movi_tl(cpu_gpr[rt], imm);
19986 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
19991 offset = sextract32(ctx->opcode, 0, 1) << 21 |
19992 extract32(ctx->opcode, 1, 20) << 1;
19993 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
19994 tcg_gen_movi_tl(cpu_gpr[rt], addr);
19998 switch (ctx->opcode & 0x07) {
20000 gen_pool32a0_nanomips_insn(env, ctx);
20004 int32_t op1 = extract32(ctx->opcode, 3, 7);
20005 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20009 switch (extract32(ctx->opcode, 3, 3)) {
20011 gen_p_lsx(ctx, rd, rs, rt);
20014 /* In nanoMIPS, the shift field directly encodes the shift
20015 * amount, meaning that the supported shift values are in
20016 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20017 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20018 extract32(ctx->opcode, 9, 2) - 1);
20021 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20024 gen_pool32axf_nanomips_insn(env, ctx);
20027 generate_exception_end(ctx, EXCP_RI);
20032 generate_exception_end(ctx, EXCP_RI);
20037 switch (ctx->opcode & 0x03) {
20040 offset = extract32(ctx->opcode, 0, 21);
20041 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20045 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20048 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20051 generate_exception_end(ctx, EXCP_RI);
20057 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20058 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20059 switch (extract32(ctx->opcode, 16, 5)) {
20063 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20069 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20070 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20076 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20082 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20085 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20092 t0 = tcg_temp_new();
20094 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20097 tcg_gen_movi_tl(t0, addr);
20098 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20106 t0 = tcg_temp_new();
20107 t1 = tcg_temp_new();
20109 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20112 tcg_gen_movi_tl(t0, addr);
20113 gen_load_gpr(t1, rt);
20115 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20122 generate_exception_end(ctx, EXCP_RI);
20128 switch (extract32(ctx->opcode, 12, 4)) {
20130 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20133 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20136 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20139 switch (extract32(ctx->opcode, 20, 1)) {
20141 switch (ctx->opcode & 3) {
20143 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20144 extract32(ctx->opcode, 2, 1),
20145 extract32(ctx->opcode, 3, 9) << 3);
20148 case NM_RESTORE_JRC:
20149 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20150 extract32(ctx->opcode, 2, 1),
20151 extract32(ctx->opcode, 3, 9) << 3);
20152 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20153 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20157 generate_exception_end(ctx, EXCP_RI);
20162 generate_exception_end(ctx, EXCP_RI);
20167 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20170 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20174 TCGv t0 = tcg_temp_new();
20176 imm = extract32(ctx->opcode, 0, 12);
20177 gen_load_gpr(t0, rs);
20178 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20179 gen_store_gpr(t0, rt);
20185 imm = (int16_t) extract32(ctx->opcode, 0, 12);
20186 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20190 int shift = extract32(ctx->opcode, 0, 5);
20191 switch (extract32(ctx->opcode, 5, 4)) {
20193 if (rt == 0 && shift == 0) {
20195 } else if (rt == 0 && shift == 3) {
20196 /* EHB - treat as NOP */
20197 } else if (rt == 0 && shift == 5) {
20198 /* PAUSE - treat as NOP */
20199 } else if (rt == 0 && shift == 6) {
20201 gen_sync(extract32(ctx->opcode, 16, 5));
20204 gen_shift_imm(ctx, OPC_SLL, rt, rs,
20205 extract32(ctx->opcode, 0, 5));
20209 gen_shift_imm(ctx, OPC_SRL, rt, rs,
20210 extract32(ctx->opcode, 0, 5));
20213 gen_shift_imm(ctx, OPC_SRA, rt, rs,
20214 extract32(ctx->opcode, 0, 5));
20217 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20218 extract32(ctx->opcode, 0, 5));
20226 TCGv t0 = tcg_temp_new();
20227 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20228 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20230 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20232 gen_load_gpr(t0, rs);
20233 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20236 tcg_temp_free_i32(shift);
20237 tcg_temp_free_i32(shiftx);
20238 tcg_temp_free_i32(stripe);
20242 switch (((ctx->opcode >> 10) & 2) |
20243 (extract32(ctx->opcode, 5, 1))) {
20246 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20247 extract32(ctx->opcode, 6, 5));
20250 generate_exception_end(ctx, EXCP_RI);
20255 switch (((ctx->opcode >> 10) & 2) |
20256 (extract32(ctx->opcode, 5, 1))) {
20259 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20260 extract32(ctx->opcode, 6, 5));
20263 generate_exception_end(ctx, EXCP_RI);
20268 generate_exception_end(ctx, EXCP_RI);
20273 gen_pool32f_nanomips_insn(ctx);
20278 switch (extract32(ctx->opcode, 1, 1)) {
20281 tcg_gen_movi_tl(cpu_gpr[rt],
20282 sextract32(ctx->opcode, 0, 1) << 31 |
20283 extract32(ctx->opcode, 2, 10) << 21 |
20284 extract32(ctx->opcode, 12, 9) << 12);
20289 offset = sextract32(ctx->opcode, 0, 1) << 31 |
20290 extract32(ctx->opcode, 2, 10) << 21 |
20291 extract32(ctx->opcode, 12, 9) << 12;
20293 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
20294 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20301 uint32_t u = extract32(ctx->opcode, 0, 18);
20303 switch (extract32(ctx->opcode, 18, 3)) {
20305 gen_ld(ctx, OPC_LB, rt, 28, u);
20308 gen_st(ctx, OPC_SB, rt, 28, u);
20311 gen_ld(ctx, OPC_LBU, rt, 28, u);
20315 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
20320 switch (ctx->opcode & 1) {
20322 gen_ld(ctx, OPC_LH, rt, 28, u);
20325 gen_ld(ctx, OPC_LHU, rt, 28, u);
20331 switch (ctx->opcode & 1) {
20333 gen_st(ctx, OPC_SH, rt, 28, u);
20336 generate_exception_end(ctx, EXCP_RI);
20342 switch (ctx->opcode & 0x3) {
20344 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
20347 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
20350 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
20353 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
20358 generate_exception_end(ctx, EXCP_RI);
20365 uint32_t u = extract32(ctx->opcode, 0, 12);
20367 switch (extract32(ctx->opcode, 12, 4)) {
20371 /* Break the TB to be able to sync copied instructions
20373 ctx->base.is_jmp = DISAS_STOP;
20376 /* Treat as NOP. */
20380 gen_ld(ctx, OPC_LB, rt, rs, u);
20383 gen_ld(ctx, OPC_LH, rt, rs, u);
20386 gen_ld(ctx, OPC_LW, rt, rs, u);
20389 gen_ld(ctx, OPC_LBU, rt, rs, u);
20392 gen_ld(ctx, OPC_LHU, rt, rs, u);
20395 gen_st(ctx, OPC_SB, rt, rs, u);
20398 gen_st(ctx, OPC_SH, rt, rs, u);
20401 gen_st(ctx, OPC_SW, rt, rs, u);
20404 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
20407 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
20410 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
20413 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
20416 generate_exception_end(ctx, EXCP_RI);
20423 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
20424 extract32(ctx->opcode, 0, 8);
20426 switch (extract32(ctx->opcode, 8, 3)) {
20428 switch (extract32(ctx->opcode, 11, 4)) {
20430 gen_ld(ctx, OPC_LB, rt, rs, s);
20433 gen_ld(ctx, OPC_LH, rt, rs, s);
20436 gen_ld(ctx, OPC_LW, rt, rs, s);
20439 gen_ld(ctx, OPC_LBU, rt, rs, s);
20442 gen_ld(ctx, OPC_LHU, rt, rs, s);
20445 gen_st(ctx, OPC_SB, rt, rs, s);
20448 gen_st(ctx, OPC_SH, rt, rs, s);
20451 gen_st(ctx, OPC_SW, rt, rs, s);
20454 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
20457 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
20460 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
20463 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
20468 /* Break the TB to be able to sync copied instructions
20470 ctx->base.is_jmp = DISAS_STOP;
20473 /* Treat as NOP. */
20477 generate_exception_end(ctx, EXCP_RI);
20482 switch (extract32(ctx->opcode, 11, 4)) {
20487 TCGv t0 = tcg_temp_new();
20488 TCGv t1 = tcg_temp_new();
20490 gen_base_offset_addr(ctx, t0, rs, s);
20492 switch (extract32(ctx->opcode, 11, 4)) {
20494 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
20496 gen_store_gpr(t0, rt);
20499 gen_load_gpr(t1, rt);
20500 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
20509 switch (ctx->opcode & 0x03) {
20511 gen_ld(ctx, OPC_LL, rt, rs, s);
20515 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20520 switch (ctx->opcode & 0x03) {
20522 gen_st_cond(ctx, OPC_SC, rt, rs, s);
20526 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20531 check_cp0_enabled(ctx);
20532 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
20533 gen_cache_operation(ctx, rt, rs, s);
20542 int count = extract32(ctx->opcode, 12, 3);
20545 offset = sextract32(ctx->opcode, 15, 1) << 8 |
20546 extract32(ctx->opcode, 0, 8);
20547 TCGv va = tcg_temp_new();
20548 TCGv t1 = tcg_temp_new();
20549 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
20550 NM_P_LS_UAWM ? MO_UNALN : 0;
20552 count = (count == 0) ? 8 : count;
20553 while (counter != count) {
20554 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
20555 int this_offset = offset + (counter << 2);
20557 gen_base_offset_addr(ctx, va, rs, this_offset);
20559 switch (extract32(ctx->opcode, 11, 1)) {
20561 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
20563 gen_store_gpr(t1, this_rt);
20564 if ((this_rt == rs) &&
20565 (counter != (count - 1))) {
20566 /* UNPREDICTABLE */
20570 this_rt = (rt == 0) ? 0 : this_rt;
20571 gen_load_gpr(t1, this_rt);
20572 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
20583 generate_exception_end(ctx, EXCP_RI);
20591 TCGv t0 = tcg_temp_new();
20592 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
20593 extract32(ctx->opcode, 1, 20) << 1;
20594 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
20595 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
20596 extract32(ctx->opcode, 21, 3));
20597 gen_load_gpr(t0, rt);
20598 tcg_gen_mov_tl(cpu_gpr[rd], t0);
20599 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20605 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
20606 extract32(ctx->opcode, 1, 24) << 1;
20608 if ((extract32(ctx->opcode, 25, 1)) == 0) {
20610 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
20613 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20618 switch (extract32(ctx->opcode, 12, 4)) {
20621 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
20624 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
20627 generate_exception_end(ctx, EXCP_RI);
20633 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20634 extract32(ctx->opcode, 1, 13) << 1;
20635 switch (extract32(ctx->opcode, 14, 2)) {
20638 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
20641 s = sextract32(ctx->opcode, 0, 1) << 14 |
20642 extract32(ctx->opcode, 1, 13) << 1;
20643 check_cp1_enabled(ctx);
20644 switch (extract32(ctx->opcode, 16, 5)) {
20646 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
20649 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
20654 int32_t imm = extract32(ctx->opcode, 1, 13) |
20655 extract32(ctx->opcode, 0, 1) << 13;
20657 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
20662 generate_exception_end(ctx, EXCP_RI);
20668 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
20670 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
20674 if (rs == rt || rt == 0) {
20675 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
20676 } else if (rs == 0) {
20677 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
20679 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
20687 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20688 extract32(ctx->opcode, 1, 13) << 1;
20689 switch (extract32(ctx->opcode, 14, 2)) {
20692 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
20695 if (rs != 0 && rt != 0 && rs == rt) {
20697 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20699 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
20703 if (rs == 0 || rs == rt) {
20705 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20707 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
20711 generate_exception_end(ctx, EXCP_RI);
20718 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
20719 extract32(ctx->opcode, 1, 10) << 1;
20720 uint32_t u = extract32(ctx->opcode, 11, 7);
20722 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
20727 generate_exception_end(ctx, EXCP_RI);
20733 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
20736 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
20737 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
20738 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
20742 /* make sure instructions are on a halfword boundary */
20743 if (ctx->base.pc_next & 0x1) {
20744 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
20745 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
20746 tcg_temp_free(tmp);
20747 generate_exception_end(ctx, EXCP_AdEL);
20751 op = extract32(ctx->opcode, 10, 6);
20754 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20757 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
20758 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
20761 switch (extract32(ctx->opcode, 3, 2)) {
20762 case NM_P16_SYSCALL:
20763 if (extract32(ctx->opcode, 2, 1) == 0) {
20764 generate_exception_end(ctx, EXCP_SYSCALL);
20766 generate_exception_end(ctx, EXCP_RI);
20770 generate_exception_end(ctx, EXCP_BREAK);
20773 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
20774 gen_helper_do_semihosting(cpu_env);
20776 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20777 generate_exception_end(ctx, EXCP_RI);
20779 generate_exception_end(ctx, EXCP_DBp);
20784 generate_exception_end(ctx, EXCP_RI);
20791 int shift = extract32(ctx->opcode, 0, 3);
20793 shift = (shift == 0) ? 8 : shift;
20795 switch (extract32(ctx->opcode, 3, 1)) {
20803 gen_shift_imm(ctx, opc, rt, rs, shift);
20807 switch (ctx->opcode & 1) {
20809 gen_pool16c_nanomips_insn(ctx);
20812 gen_ldxs(ctx, rt, rs, rd);
20817 switch (extract32(ctx->opcode, 6, 1)) {
20819 imm = extract32(ctx->opcode, 0, 6) << 2;
20820 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
20823 generate_exception_end(ctx, EXCP_RI);
20828 switch (extract32(ctx->opcode, 3, 1)) {
20830 imm = extract32(ctx->opcode, 0, 3) << 2;
20831 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
20833 case NM_P_ADDIURS5:
20834 rt = extract32(ctx->opcode, 5, 5);
20836 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
20837 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
20838 (extract32(ctx->opcode, 0, 3));
20839 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
20845 switch (ctx->opcode & 0x1) {
20847 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
20850 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
20855 rt = (extract32(ctx->opcode, 9, 1) << 3) |
20856 extract32(ctx->opcode, 5, 3);
20857 rs = (extract32(ctx->opcode, 4, 1) << 3) |
20858 extract32(ctx->opcode, 0, 3);
20859 rt = decode_gpr_gpr4(rt);
20860 rs = decode_gpr_gpr4(rs);
20861 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
20862 (extract32(ctx->opcode, 3, 1))) {
20865 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
20869 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
20872 generate_exception_end(ctx, EXCP_RI);
20878 int imm = extract32(ctx->opcode, 0, 7);
20879 imm = (imm == 0x7f ? -1 : imm);
20881 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20887 uint32_t u = extract32(ctx->opcode, 0, 4);
20888 u = (u == 12) ? 0xff :
20889 (u == 13) ? 0xffff : u;
20890 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
20894 offset = extract32(ctx->opcode, 0, 2);
20895 switch (extract32(ctx->opcode, 2, 2)) {
20897 gen_ld(ctx, OPC_LB, rt, rs, offset);
20900 rt = decode_gpr_gpr3_src_store(
20901 NANOMIPS_EXTRACT_RD(ctx->opcode));
20902 gen_st(ctx, OPC_SB, rt, rs, offset);
20905 gen_ld(ctx, OPC_LBU, rt, rs, offset);
20908 generate_exception_end(ctx, EXCP_RI);
20913 offset = extract32(ctx->opcode, 1, 2) << 1;
20914 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
20916 gen_ld(ctx, OPC_LH, rt, rs, offset);
20919 rt = decode_gpr_gpr3_src_store(
20920 NANOMIPS_EXTRACT_RD(ctx->opcode));
20921 gen_st(ctx, OPC_SH, rt, rs, offset);
20924 gen_ld(ctx, OPC_LHU, rt, rs, offset);
20927 generate_exception_end(ctx, EXCP_RI);
20932 offset = extract32(ctx->opcode, 0, 4) << 2;
20933 gen_ld(ctx, OPC_LW, rt, rs, offset);
20936 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20937 offset = extract32(ctx->opcode, 0, 5) << 2;
20938 gen_ld(ctx, OPC_LW, rt, 29, offset);
20942 rt = (extract32(ctx->opcode, 9, 1) << 3) |
20943 extract32(ctx->opcode, 5, 3);
20944 rs = (extract32(ctx->opcode, 4, 1) << 3) |
20945 extract32(ctx->opcode, 0, 3);
20946 offset = (extract32(ctx->opcode, 3, 1) << 3) |
20947 (extract32(ctx->opcode, 8, 1) << 2);
20948 rt = decode_gpr_gpr4(rt);
20949 rs = decode_gpr_gpr4(rs);
20950 gen_ld(ctx, OPC_LW, rt, rs, offset);
20954 rt = (extract32(ctx->opcode, 9, 1) << 3) |
20955 extract32(ctx->opcode, 5, 3);
20956 rs = (extract32(ctx->opcode, 4, 1) << 3) |
20957 extract32(ctx->opcode, 0, 3);
20958 offset = (extract32(ctx->opcode, 3, 1) << 3) |
20959 (extract32(ctx->opcode, 8, 1) << 2);
20960 rt = decode_gpr_gpr4_zero(rt);
20961 rs = decode_gpr_gpr4(rs);
20962 gen_st(ctx, OPC_SW, rt, rs, offset);
20965 offset = extract32(ctx->opcode, 0, 7) << 2;
20966 gen_ld(ctx, OPC_LW, rt, 28, offset);
20969 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20970 offset = extract32(ctx->opcode, 0, 5) << 2;
20971 gen_st(ctx, OPC_SW, rt, 29, offset);
20974 rt = decode_gpr_gpr3_src_store(
20975 NANOMIPS_EXTRACT_RD(ctx->opcode));
20976 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
20977 offset = extract32(ctx->opcode, 0, 4) << 2;
20978 gen_st(ctx, OPC_SW, rt, rs, offset);
20981 rt = decode_gpr_gpr3_src_store(
20982 NANOMIPS_EXTRACT_RD(ctx->opcode));
20983 offset = extract32(ctx->opcode, 0, 7) << 2;
20984 gen_st(ctx, OPC_SW, rt, 28, offset);
20987 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
20988 (sextract32(ctx->opcode, 0, 1) << 10) |
20989 (extract32(ctx->opcode, 1, 9) << 1));
20992 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
20993 (sextract32(ctx->opcode, 0, 1) << 10) |
20994 (extract32(ctx->opcode, 1, 9) << 1));
20997 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
20998 (sextract32(ctx->opcode, 0, 1) << 7) |
20999 (extract32(ctx->opcode, 1, 6) << 1));
21002 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21003 (sextract32(ctx->opcode, 0, 1) << 7) |
21004 (extract32(ctx->opcode, 1, 6) << 1));
21007 switch (ctx->opcode & 0xf) {
21010 switch (extract32(ctx->opcode, 4, 1)) {
21012 gen_compute_branch_nm(ctx, OPC_JR, 2,
21013 extract32(ctx->opcode, 5, 5), 0, 0);
21016 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21017 extract32(ctx->opcode, 5, 5), 31, 0);
21024 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21025 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21026 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21027 extract32(ctx->opcode, 0, 4) << 1);
21034 int count = extract32(ctx->opcode, 0, 4);
21035 int u = extract32(ctx->opcode, 4, 4) << 4;
21037 rt = 30 + extract32(ctx->opcode, 9, 1);
21038 switch (extract32(ctx->opcode, 8, 1)) {
21040 gen_save(ctx, rt, count, 0, u);
21042 case NM_RESTORE_JRC16:
21043 gen_restore(ctx, rt, count, 0, u);
21044 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21053 static const int gpr2reg1[] = {4, 5, 6, 7};
21054 static const int gpr2reg2[] = {5, 6, 7, 8};
21056 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21057 extract32(ctx->opcode, 8, 1);
21058 int r1 = gpr2reg1[rd2];
21059 int r2 = gpr2reg2[rd2];
21060 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21061 extract32(ctx->opcode, 0, 3);
21062 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21063 extract32(ctx->opcode, 5, 3);
21064 TCGv t0 = tcg_temp_new();
21065 TCGv t1 = tcg_temp_new();
21066 if (op == NM_MOVEP) {
21069 rs = decode_gpr_gpr4_zero(r3);
21070 rt = decode_gpr_gpr4_zero(r4);
21072 rd = decode_gpr_gpr4(r3);
21073 re = decode_gpr_gpr4(r4);
21077 gen_load_gpr(t0, rs);
21078 gen_load_gpr(t1, rt);
21079 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21080 tcg_gen_mov_tl(cpu_gpr[re], t1);
21086 return decode_nanomips_32_48_opc(env, ctx);
21093 /* SmartMIPS extension to MIPS32 */
21095 #if defined(TARGET_MIPS64)
21097 /* MDMX extension to MIPS64 */
21101 /* MIPSDSP functions. */
21102 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
21103 int rd, int base, int offset)
21108 t0 = tcg_temp_new();
21111 gen_load_gpr(t0, offset);
21112 } else if (offset == 0) {
21113 gen_load_gpr(t0, base);
21115 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21120 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
21121 gen_store_gpr(t0, rd);
21124 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
21125 gen_store_gpr(t0, rd);
21128 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
21129 gen_store_gpr(t0, rd);
21131 #if defined(TARGET_MIPS64)
21133 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
21134 gen_store_gpr(t0, rd);
21141 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21142 int ret, int v1, int v2)
21148 /* Treat as NOP. */
21152 v1_t = tcg_temp_new();
21153 v2_t = tcg_temp_new();
21155 gen_load_gpr(v1_t, v1);
21156 gen_load_gpr(v2_t, v2);
21159 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21160 case OPC_MULT_G_2E:
21164 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21166 case OPC_ADDUH_R_QB:
21167 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21170 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21172 case OPC_ADDQH_R_PH:
21173 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21176 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21178 case OPC_ADDQH_R_W:
21179 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21182 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21184 case OPC_SUBUH_R_QB:
21185 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21188 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
21190 case OPC_SUBQH_R_PH:
21191 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21194 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
21196 case OPC_SUBQH_R_W:
21197 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21201 case OPC_ABSQ_S_PH_DSP:
21203 case OPC_ABSQ_S_QB:
21205 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
21207 case OPC_ABSQ_S_PH:
21209 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
21213 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
21215 case OPC_PRECEQ_W_PHL:
21217 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
21218 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21220 case OPC_PRECEQ_W_PHR:
21222 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
21223 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
21224 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21226 case OPC_PRECEQU_PH_QBL:
21228 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
21230 case OPC_PRECEQU_PH_QBR:
21232 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
21234 case OPC_PRECEQU_PH_QBLA:
21236 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
21238 case OPC_PRECEQU_PH_QBRA:
21240 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
21242 case OPC_PRECEU_PH_QBL:
21244 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
21246 case OPC_PRECEU_PH_QBR:
21248 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
21250 case OPC_PRECEU_PH_QBLA:
21252 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
21254 case OPC_PRECEU_PH_QBRA:
21256 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
21260 case OPC_ADDU_QB_DSP:
21264 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21266 case OPC_ADDQ_S_PH:
21268 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21272 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21276 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21278 case OPC_ADDU_S_QB:
21280 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21284 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21286 case OPC_ADDU_S_PH:
21288 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21292 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21294 case OPC_SUBQ_S_PH:
21296 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21300 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21304 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21306 case OPC_SUBU_S_QB:
21308 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21312 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21314 case OPC_SUBU_S_PH:
21316 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21320 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21324 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21328 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
21330 case OPC_RADDU_W_QB:
21332 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
21336 case OPC_CMPU_EQ_QB_DSP:
21338 case OPC_PRECR_QB_PH:
21340 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21342 case OPC_PRECRQ_QB_PH:
21344 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21346 case OPC_PRECR_SRA_PH_W:
21349 TCGv_i32 sa_t = tcg_const_i32(v2);
21350 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
21352 tcg_temp_free_i32(sa_t);
21355 case OPC_PRECR_SRA_R_PH_W:
21358 TCGv_i32 sa_t = tcg_const_i32(v2);
21359 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
21361 tcg_temp_free_i32(sa_t);
21364 case OPC_PRECRQ_PH_W:
21366 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
21368 case OPC_PRECRQ_RS_PH_W:
21370 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21372 case OPC_PRECRQU_S_QB_PH:
21374 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21378 #ifdef TARGET_MIPS64
21379 case OPC_ABSQ_S_QH_DSP:
21381 case OPC_PRECEQ_L_PWL:
21383 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
21385 case OPC_PRECEQ_L_PWR:
21387 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
21389 case OPC_PRECEQ_PW_QHL:
21391 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
21393 case OPC_PRECEQ_PW_QHR:
21395 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
21397 case OPC_PRECEQ_PW_QHLA:
21399 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
21401 case OPC_PRECEQ_PW_QHRA:
21403 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
21405 case OPC_PRECEQU_QH_OBL:
21407 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
21409 case OPC_PRECEQU_QH_OBR:
21411 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
21413 case OPC_PRECEQU_QH_OBLA:
21415 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
21417 case OPC_PRECEQU_QH_OBRA:
21419 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
21421 case OPC_PRECEU_QH_OBL:
21423 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
21425 case OPC_PRECEU_QH_OBR:
21427 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
21429 case OPC_PRECEU_QH_OBLA:
21431 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
21433 case OPC_PRECEU_QH_OBRA:
21435 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
21437 case OPC_ABSQ_S_OB:
21439 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
21441 case OPC_ABSQ_S_PW:
21443 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
21445 case OPC_ABSQ_S_QH:
21447 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
21451 case OPC_ADDU_OB_DSP:
21453 case OPC_RADDU_L_OB:
21455 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
21459 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21461 case OPC_SUBQ_S_PW:
21463 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21467 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21469 case OPC_SUBQ_S_QH:
21471 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21475 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21477 case OPC_SUBU_S_OB:
21479 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21483 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21485 case OPC_SUBU_S_QH:
21487 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21491 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
21493 case OPC_SUBUH_R_OB:
21495 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21499 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21501 case OPC_ADDQ_S_PW:
21503 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21507 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21509 case OPC_ADDQ_S_QH:
21511 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21515 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21517 case OPC_ADDU_S_OB:
21519 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21523 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21525 case OPC_ADDU_S_QH:
21527 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21531 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
21533 case OPC_ADDUH_R_OB:
21535 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21539 case OPC_CMPU_EQ_OB_DSP:
21541 case OPC_PRECR_OB_QH:
21543 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21545 case OPC_PRECR_SRA_QH_PW:
21548 TCGv_i32 ret_t = tcg_const_i32(ret);
21549 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
21550 tcg_temp_free_i32(ret_t);
21553 case OPC_PRECR_SRA_R_QH_PW:
21556 TCGv_i32 sa_v = tcg_const_i32(ret);
21557 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
21558 tcg_temp_free_i32(sa_v);
21561 case OPC_PRECRQ_OB_QH:
21563 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21565 case OPC_PRECRQ_PW_L:
21567 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
21569 case OPC_PRECRQ_QH_PW:
21571 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
21573 case OPC_PRECRQ_RS_QH_PW:
21575 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21577 case OPC_PRECRQU_S_OB_QH:
21579 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21586 tcg_temp_free(v1_t);
21587 tcg_temp_free(v2_t);
21590 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
21591 int ret, int v1, int v2)
21599 /* Treat as NOP. */
21603 t0 = tcg_temp_new();
21604 v1_t = tcg_temp_new();
21605 v2_t = tcg_temp_new();
21607 tcg_gen_movi_tl(t0, v1);
21608 gen_load_gpr(v1_t, v1);
21609 gen_load_gpr(v2_t, v2);
21612 case OPC_SHLL_QB_DSP:
21614 op2 = MASK_SHLL_QB(ctx->opcode);
21618 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
21622 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21626 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21630 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21632 case OPC_SHLL_S_PH:
21634 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21636 case OPC_SHLLV_S_PH:
21638 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21642 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
21644 case OPC_SHLLV_S_W:
21646 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21650 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
21654 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
21658 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
21662 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
21666 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
21668 case OPC_SHRA_R_QB:
21670 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
21674 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
21676 case OPC_SHRAV_R_QB:
21678 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
21682 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
21684 case OPC_SHRA_R_PH:
21686 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
21690 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
21692 case OPC_SHRAV_R_PH:
21694 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
21698 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
21700 case OPC_SHRAV_R_W:
21702 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
21704 default: /* Invalid */
21705 MIPS_INVAL("MASK SHLL.QB");
21706 generate_exception_end(ctx, EXCP_RI);
21711 #ifdef TARGET_MIPS64
21712 case OPC_SHLL_OB_DSP:
21713 op2 = MASK_SHLL_OB(ctx->opcode);
21717 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21721 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21723 case OPC_SHLL_S_PW:
21725 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21727 case OPC_SHLLV_S_PW:
21729 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21733 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
21737 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21741 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21745 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21747 case OPC_SHLL_S_QH:
21749 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21751 case OPC_SHLLV_S_QH:
21753 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21757 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
21761 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
21763 case OPC_SHRA_R_OB:
21765 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
21767 case OPC_SHRAV_R_OB:
21769 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
21773 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
21777 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
21779 case OPC_SHRA_R_PW:
21781 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
21783 case OPC_SHRAV_R_PW:
21785 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
21789 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
21793 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
21795 case OPC_SHRA_R_QH:
21797 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
21799 case OPC_SHRAV_R_QH:
21801 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
21805 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
21809 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
21813 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
21817 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
21819 default: /* Invalid */
21820 MIPS_INVAL("MASK SHLL.OB");
21821 generate_exception_end(ctx, EXCP_RI);
21829 tcg_temp_free(v1_t);
21830 tcg_temp_free(v2_t);
21833 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
21834 int ret, int v1, int v2, int check_ret)
21840 if ((ret == 0) && (check_ret == 1)) {
21841 /* Treat as NOP. */
21845 t0 = tcg_temp_new_i32();
21846 v1_t = tcg_temp_new();
21847 v2_t = tcg_temp_new();
21849 tcg_gen_movi_i32(t0, ret);
21850 gen_load_gpr(v1_t, v1);
21851 gen_load_gpr(v2_t, v2);
21854 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
21855 * the same mask and op1. */
21856 case OPC_MULT_G_2E:
21860 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21863 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21866 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21868 case OPC_MULQ_RS_W:
21869 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21873 case OPC_DPA_W_PH_DSP:
21875 case OPC_DPAU_H_QBL:
21877 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
21879 case OPC_DPAU_H_QBR:
21881 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
21883 case OPC_DPSU_H_QBL:
21885 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
21887 case OPC_DPSU_H_QBR:
21889 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
21893 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
21895 case OPC_DPAX_W_PH:
21897 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
21899 case OPC_DPAQ_S_W_PH:
21901 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21903 case OPC_DPAQX_S_W_PH:
21905 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
21907 case OPC_DPAQX_SA_W_PH:
21909 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
21913 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
21915 case OPC_DPSX_W_PH:
21917 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
21919 case OPC_DPSQ_S_W_PH:
21921 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21923 case OPC_DPSQX_S_W_PH:
21925 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
21927 case OPC_DPSQX_SA_W_PH:
21929 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
21931 case OPC_MULSAQ_S_W_PH:
21933 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21935 case OPC_DPAQ_SA_L_W:
21937 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
21939 case OPC_DPSQ_SA_L_W:
21941 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
21943 case OPC_MAQ_S_W_PHL:
21945 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
21947 case OPC_MAQ_S_W_PHR:
21949 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
21951 case OPC_MAQ_SA_W_PHL:
21953 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
21955 case OPC_MAQ_SA_W_PHR:
21957 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
21959 case OPC_MULSA_W_PH:
21961 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
21965 #ifdef TARGET_MIPS64
21966 case OPC_DPAQ_W_QH_DSP:
21968 int ac = ret & 0x03;
21969 tcg_gen_movi_i32(t0, ac);
21974 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
21978 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
21982 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
21986 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
21990 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
21992 case OPC_DPAQ_S_W_QH:
21994 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
21996 case OPC_DPAQ_SA_L_PW:
21998 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22000 case OPC_DPAU_H_OBL:
22002 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22004 case OPC_DPAU_H_OBR:
22006 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22010 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22012 case OPC_DPSQ_S_W_QH:
22014 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22016 case OPC_DPSQ_SA_L_PW:
22018 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22020 case OPC_DPSU_H_OBL:
22022 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22024 case OPC_DPSU_H_OBR:
22026 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22028 case OPC_MAQ_S_L_PWL:
22030 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22032 case OPC_MAQ_S_L_PWR:
22034 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22036 case OPC_MAQ_S_W_QHLL:
22038 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22040 case OPC_MAQ_SA_W_QHLL:
22042 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22044 case OPC_MAQ_S_W_QHLR:
22046 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22048 case OPC_MAQ_SA_W_QHLR:
22050 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22052 case OPC_MAQ_S_W_QHRL:
22054 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22056 case OPC_MAQ_SA_W_QHRL:
22058 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22060 case OPC_MAQ_S_W_QHRR:
22062 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22064 case OPC_MAQ_SA_W_QHRR:
22066 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22068 case OPC_MULSAQ_S_L_PW:
22070 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22072 case OPC_MULSAQ_S_W_QH:
22074 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22080 case OPC_ADDU_QB_DSP:
22082 case OPC_MULEU_S_PH_QBL:
22084 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22086 case OPC_MULEU_S_PH_QBR:
22088 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22090 case OPC_MULQ_RS_PH:
22092 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22094 case OPC_MULEQ_S_W_PHL:
22096 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22098 case OPC_MULEQ_S_W_PHR:
22100 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22102 case OPC_MULQ_S_PH:
22104 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22108 #ifdef TARGET_MIPS64
22109 case OPC_ADDU_OB_DSP:
22111 case OPC_MULEQ_S_PW_QHL:
22113 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22115 case OPC_MULEQ_S_PW_QHR:
22117 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22119 case OPC_MULEU_S_QH_OBL:
22121 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22123 case OPC_MULEU_S_QH_OBR:
22125 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22127 case OPC_MULQ_RS_QH:
22129 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22136 tcg_temp_free_i32(t0);
22137 tcg_temp_free(v1_t);
22138 tcg_temp_free(v2_t);
22141 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22149 /* Treat as NOP. */
22153 t0 = tcg_temp_new();
22154 val_t = tcg_temp_new();
22155 gen_load_gpr(val_t, val);
22158 case OPC_ABSQ_S_PH_DSP:
22162 gen_helper_bitrev(cpu_gpr[ret], val_t);
22167 target_long result;
22168 imm = (ctx->opcode >> 16) & 0xFF;
22169 result = (uint32_t)imm << 24 |
22170 (uint32_t)imm << 16 |
22171 (uint32_t)imm << 8 |
22173 result = (int32_t)result;
22174 tcg_gen_movi_tl(cpu_gpr[ret], result);
22179 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22180 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22181 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22182 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22183 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22184 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22189 imm = (ctx->opcode >> 16) & 0x03FF;
22190 imm = (int16_t)(imm << 6) >> 6;
22191 tcg_gen_movi_tl(cpu_gpr[ret], \
22192 (target_long)((int32_t)imm << 16 | \
22198 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22199 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22200 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22201 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22205 #ifdef TARGET_MIPS64
22206 case OPC_ABSQ_S_QH_DSP:
22213 imm = (ctx->opcode >> 16) & 0xFF;
22214 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
22215 temp = (temp << 16) | temp;
22216 temp = (temp << 32) | temp;
22217 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22225 imm = (ctx->opcode >> 16) & 0x03FF;
22226 imm = (int16_t)(imm << 6) >> 6;
22227 temp = ((target_long)imm << 32) \
22228 | ((target_long)imm & 0xFFFFFFFF);
22229 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22237 imm = (ctx->opcode >> 16) & 0x03FF;
22238 imm = (int16_t)(imm << 6) >> 6;
22240 temp = ((uint64_t)(uint16_t)imm << 48) |
22241 ((uint64_t)(uint16_t)imm << 32) |
22242 ((uint64_t)(uint16_t)imm << 16) |
22243 (uint64_t)(uint16_t)imm;
22244 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22249 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22250 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22251 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22252 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22253 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22254 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22255 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22259 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
22260 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22261 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22265 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22266 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22267 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22268 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22269 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22276 tcg_temp_free(val_t);
22279 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
22280 uint32_t op1, uint32_t op2,
22281 int ret, int v1, int v2, int check_ret)
22287 if ((ret == 0) && (check_ret == 1)) {
22288 /* Treat as NOP. */
22292 t1 = tcg_temp_new();
22293 v1_t = tcg_temp_new();
22294 v2_t = tcg_temp_new();
22296 gen_load_gpr(v1_t, v1);
22297 gen_load_gpr(v2_t, v2);
22300 case OPC_CMPU_EQ_QB_DSP:
22302 case OPC_CMPU_EQ_QB:
22304 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
22306 case OPC_CMPU_LT_QB:
22308 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
22310 case OPC_CMPU_LE_QB:
22312 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
22314 case OPC_CMPGU_EQ_QB:
22316 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
22318 case OPC_CMPGU_LT_QB:
22320 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
22322 case OPC_CMPGU_LE_QB:
22324 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
22326 case OPC_CMPGDU_EQ_QB:
22328 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
22329 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22330 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22331 tcg_gen_shli_tl(t1, t1, 24);
22332 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22334 case OPC_CMPGDU_LT_QB:
22336 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
22337 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22338 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22339 tcg_gen_shli_tl(t1, t1, 24);
22340 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22342 case OPC_CMPGDU_LE_QB:
22344 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
22345 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22346 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22347 tcg_gen_shli_tl(t1, t1, 24);
22348 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22350 case OPC_CMP_EQ_PH:
22352 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
22354 case OPC_CMP_LT_PH:
22356 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
22358 case OPC_CMP_LE_PH:
22360 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
22364 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22368 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22370 case OPC_PACKRL_PH:
22372 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
22376 #ifdef TARGET_MIPS64
22377 case OPC_CMPU_EQ_OB_DSP:
22379 case OPC_CMP_EQ_PW:
22381 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
22383 case OPC_CMP_LT_PW:
22385 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
22387 case OPC_CMP_LE_PW:
22389 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
22391 case OPC_CMP_EQ_QH:
22393 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
22395 case OPC_CMP_LT_QH:
22397 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
22399 case OPC_CMP_LE_QH:
22401 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
22403 case OPC_CMPGDU_EQ_OB:
22405 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22407 case OPC_CMPGDU_LT_OB:
22409 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22411 case OPC_CMPGDU_LE_OB:
22413 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22415 case OPC_CMPGU_EQ_OB:
22417 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
22419 case OPC_CMPGU_LT_OB:
22421 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
22423 case OPC_CMPGU_LE_OB:
22425 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
22427 case OPC_CMPU_EQ_OB:
22429 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
22431 case OPC_CMPU_LT_OB:
22433 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
22435 case OPC_CMPU_LE_OB:
22437 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
22439 case OPC_PACKRL_PW:
22441 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
22445 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22449 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22453 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22461 tcg_temp_free(v1_t);
22462 tcg_temp_free(v2_t);
22465 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
22466 uint32_t op1, int rt, int rs, int sa)
22473 /* Treat as NOP. */
22477 t0 = tcg_temp_new();
22478 gen_load_gpr(t0, rs);
22481 case OPC_APPEND_DSP:
22482 switch (MASK_APPEND(ctx->opcode)) {
22485 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
22487 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22491 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
22492 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22493 tcg_gen_shli_tl(t0, t0, 32 - sa);
22494 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22496 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22500 if (sa != 0 && sa != 2) {
22501 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22502 tcg_gen_ext32u_tl(t0, t0);
22503 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
22504 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22506 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22508 default: /* Invalid */
22509 MIPS_INVAL("MASK APPEND");
22510 generate_exception_end(ctx, EXCP_RI);
22514 #ifdef TARGET_MIPS64
22515 case OPC_DAPPEND_DSP:
22516 switch (MASK_DAPPEND(ctx->opcode)) {
22519 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
22523 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
22524 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
22525 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
22529 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22530 tcg_gen_shli_tl(t0, t0, 64 - sa);
22531 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22536 if (sa != 0 && sa != 2 && sa != 4) {
22537 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22538 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
22539 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22542 default: /* Invalid */
22543 MIPS_INVAL("MASK DAPPEND");
22544 generate_exception_end(ctx, EXCP_RI);
22553 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22554 int ret, int v1, int v2, int check_ret)
22563 if ((ret == 0) && (check_ret == 1)) {
22564 /* Treat as NOP. */
22568 t0 = tcg_temp_new();
22569 t1 = tcg_temp_new();
22570 v1_t = tcg_temp_new();
22571 v2_t = tcg_temp_new();
22573 gen_load_gpr(v1_t, v1);
22574 gen_load_gpr(v2_t, v2);
22577 case OPC_EXTR_W_DSP:
22581 tcg_gen_movi_tl(t0, v2);
22582 tcg_gen_movi_tl(t1, v1);
22583 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
22586 tcg_gen_movi_tl(t0, v2);
22587 tcg_gen_movi_tl(t1, v1);
22588 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22590 case OPC_EXTR_RS_W:
22591 tcg_gen_movi_tl(t0, v2);
22592 tcg_gen_movi_tl(t1, v1);
22593 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22596 tcg_gen_movi_tl(t0, v2);
22597 tcg_gen_movi_tl(t1, v1);
22598 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22600 case OPC_EXTRV_S_H:
22601 tcg_gen_movi_tl(t0, v2);
22602 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
22605 tcg_gen_movi_tl(t0, v2);
22606 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22608 case OPC_EXTRV_R_W:
22609 tcg_gen_movi_tl(t0, v2);
22610 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22612 case OPC_EXTRV_RS_W:
22613 tcg_gen_movi_tl(t0, v2);
22614 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22617 tcg_gen_movi_tl(t0, v2);
22618 tcg_gen_movi_tl(t1, v1);
22619 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
22622 tcg_gen_movi_tl(t0, v2);
22623 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
22626 tcg_gen_movi_tl(t0, v2);
22627 tcg_gen_movi_tl(t1, v1);
22628 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
22631 tcg_gen_movi_tl(t0, v2);
22632 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22635 imm = (ctx->opcode >> 20) & 0x3F;
22636 tcg_gen_movi_tl(t0, ret);
22637 tcg_gen_movi_tl(t1, imm);
22638 gen_helper_shilo(t0, t1, cpu_env);
22641 tcg_gen_movi_tl(t0, ret);
22642 gen_helper_shilo(t0, v1_t, cpu_env);
22645 tcg_gen_movi_tl(t0, ret);
22646 gen_helper_mthlip(t0, v1_t, cpu_env);
22649 imm = (ctx->opcode >> 11) & 0x3FF;
22650 tcg_gen_movi_tl(t0, imm);
22651 gen_helper_wrdsp(v1_t, t0, cpu_env);
22654 imm = (ctx->opcode >> 16) & 0x03FF;
22655 tcg_gen_movi_tl(t0, imm);
22656 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
22660 #ifdef TARGET_MIPS64
22661 case OPC_DEXTR_W_DSP:
22665 tcg_gen_movi_tl(t0, ret);
22666 gen_helper_dmthlip(v1_t, t0, cpu_env);
22670 int shift = (ctx->opcode >> 19) & 0x7F;
22671 int ac = (ctx->opcode >> 11) & 0x03;
22672 tcg_gen_movi_tl(t0, shift);
22673 tcg_gen_movi_tl(t1, ac);
22674 gen_helper_dshilo(t0, t1, cpu_env);
22679 int ac = (ctx->opcode >> 11) & 0x03;
22680 tcg_gen_movi_tl(t0, ac);
22681 gen_helper_dshilo(v1_t, t0, cpu_env);
22685 tcg_gen_movi_tl(t0, v2);
22686 tcg_gen_movi_tl(t1, v1);
22688 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
22691 tcg_gen_movi_tl(t0, v2);
22692 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
22695 tcg_gen_movi_tl(t0, v2);
22696 tcg_gen_movi_tl(t1, v1);
22697 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
22700 tcg_gen_movi_tl(t0, v2);
22701 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22704 tcg_gen_movi_tl(t0, v2);
22705 tcg_gen_movi_tl(t1, v1);
22706 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
22708 case OPC_DEXTR_R_L:
22709 tcg_gen_movi_tl(t0, v2);
22710 tcg_gen_movi_tl(t1, v1);
22711 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
22713 case OPC_DEXTR_RS_L:
22714 tcg_gen_movi_tl(t0, v2);
22715 tcg_gen_movi_tl(t1, v1);
22716 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
22719 tcg_gen_movi_tl(t0, v2);
22720 tcg_gen_movi_tl(t1, v1);
22721 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
22723 case OPC_DEXTR_R_W:
22724 tcg_gen_movi_tl(t0, v2);
22725 tcg_gen_movi_tl(t1, v1);
22726 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22728 case OPC_DEXTR_RS_W:
22729 tcg_gen_movi_tl(t0, v2);
22730 tcg_gen_movi_tl(t1, v1);
22731 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22733 case OPC_DEXTR_S_H:
22734 tcg_gen_movi_tl(t0, v2);
22735 tcg_gen_movi_tl(t1, v1);
22736 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22738 case OPC_DEXTRV_S_H:
22739 tcg_gen_movi_tl(t0, v2);
22740 tcg_gen_movi_tl(t1, v1);
22741 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22744 tcg_gen_movi_tl(t0, v2);
22745 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22747 case OPC_DEXTRV_R_L:
22748 tcg_gen_movi_tl(t0, v2);
22749 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22751 case OPC_DEXTRV_RS_L:
22752 tcg_gen_movi_tl(t0, v2);
22753 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22756 tcg_gen_movi_tl(t0, v2);
22757 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22759 case OPC_DEXTRV_R_W:
22760 tcg_gen_movi_tl(t0, v2);
22761 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22763 case OPC_DEXTRV_RS_W:
22764 tcg_gen_movi_tl(t0, v2);
22765 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22774 tcg_temp_free(v1_t);
22775 tcg_temp_free(v2_t);
22778 /* End MIPSDSP functions. */
22780 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
22782 int rs, rt, rd, sa;
22785 rs = (ctx->opcode >> 21) & 0x1f;
22786 rt = (ctx->opcode >> 16) & 0x1f;
22787 rd = (ctx->opcode >> 11) & 0x1f;
22788 sa = (ctx->opcode >> 6) & 0x1f;
22790 op1 = MASK_SPECIAL(ctx->opcode);
22793 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
22799 op2 = MASK_R6_MULDIV(ctx->opcode);
22809 gen_r6_muldiv(ctx, op2, rd, rs, rt);
22812 MIPS_INVAL("special_r6 muldiv");
22813 generate_exception_end(ctx, EXCP_RI);
22819 gen_cond_move(ctx, op1, rd, rs, rt);
22823 if (rt == 0 && sa == 1) {
22824 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22825 We need additionally to check other fields */
22826 gen_cl(ctx, op1, rd, rs);
22828 generate_exception_end(ctx, EXCP_RI);
22832 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
22833 gen_helper_do_semihosting(cpu_env);
22835 if (ctx->hflags & MIPS_HFLAG_SBRI) {
22836 generate_exception_end(ctx, EXCP_RI);
22838 generate_exception_end(ctx, EXCP_DBp);
22842 #if defined(TARGET_MIPS64)
22844 check_mips_64(ctx);
22845 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
22849 if (rt == 0 && sa == 1) {
22850 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22851 We need additionally to check other fields */
22852 check_mips_64(ctx);
22853 gen_cl(ctx, op1, rd, rs);
22855 generate_exception_end(ctx, EXCP_RI);
22863 op2 = MASK_R6_MULDIV(ctx->opcode);
22873 check_mips_64(ctx);
22874 gen_r6_muldiv(ctx, op2, rd, rs, rt);
22877 MIPS_INVAL("special_r6 muldiv");
22878 generate_exception_end(ctx, EXCP_RI);
22883 default: /* Invalid */
22884 MIPS_INVAL("special_r6");
22885 generate_exception_end(ctx, EXCP_RI);
22890 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
22892 int rs, rt, rd, sa;
22895 rs = (ctx->opcode >> 21) & 0x1f;
22896 rt = (ctx->opcode >> 16) & 0x1f;
22897 rd = (ctx->opcode >> 11) & 0x1f;
22898 sa = (ctx->opcode >> 6) & 0x1f;
22900 op1 = MASK_SPECIAL(ctx->opcode);
22902 case OPC_MOVN: /* Conditional move */
22904 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
22905 INSN_LOONGSON2E | INSN_LOONGSON2F);
22906 gen_cond_move(ctx, op1, rd, rs, rt);
22908 case OPC_MFHI: /* Move from HI/LO */
22910 gen_HILO(ctx, op1, rs & 3, rd);
22913 case OPC_MTLO: /* Move to HI/LO */
22914 gen_HILO(ctx, op1, rd & 3, rs);
22917 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
22918 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
22919 check_cp1_enabled(ctx);
22920 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
22921 (ctx->opcode >> 16) & 1);
22923 generate_exception_err(ctx, EXCP_CpU, 1);
22929 check_insn(ctx, INSN_VR54XX);
22930 op1 = MASK_MUL_VR54XX(ctx->opcode);
22931 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
22933 gen_muldiv(ctx, op1, rd & 3, rs, rt);
22938 gen_muldiv(ctx, op1, 0, rs, rt);
22940 #if defined(TARGET_MIPS64)
22945 check_insn(ctx, ISA_MIPS3);
22946 check_mips_64(ctx);
22947 gen_muldiv(ctx, op1, 0, rs, rt);
22951 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
22954 #ifdef MIPS_STRICT_STANDARD
22955 MIPS_INVAL("SPIM");
22956 generate_exception_end(ctx, EXCP_RI);
22958 /* Implemented as RI exception for now. */
22959 MIPS_INVAL("spim (unofficial)");
22960 generate_exception_end(ctx, EXCP_RI);
22963 default: /* Invalid */
22964 MIPS_INVAL("special_legacy");
22965 generate_exception_end(ctx, EXCP_RI);
22970 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
22972 int rs, rt, rd, sa;
22975 rs = (ctx->opcode >> 21) & 0x1f;
22976 rt = (ctx->opcode >> 16) & 0x1f;
22977 rd = (ctx->opcode >> 11) & 0x1f;
22978 sa = (ctx->opcode >> 6) & 0x1f;
22980 op1 = MASK_SPECIAL(ctx->opcode);
22982 case OPC_SLL: /* Shift with immediate */
22983 if (sa == 5 && rd == 0 &&
22984 rs == 0 && rt == 0) { /* PAUSE */
22985 if ((ctx->insn_flags & ISA_MIPS32R6) &&
22986 (ctx->hflags & MIPS_HFLAG_BMASK)) {
22987 generate_exception_end(ctx, EXCP_RI);
22993 gen_shift_imm(ctx, op1, rd, rt, sa);
22996 switch ((ctx->opcode >> 21) & 0x1f) {
22998 /* rotr is decoded as srl on non-R2 CPUs */
22999 if (ctx->insn_flags & ISA_MIPS32R2) {
23004 gen_shift_imm(ctx, op1, rd, rt, sa);
23007 generate_exception_end(ctx, EXCP_RI);
23015 gen_arith(ctx, op1, rd, rs, rt);
23017 case OPC_SLLV: /* Shifts */
23019 gen_shift(ctx, op1, rd, rs, rt);
23022 switch ((ctx->opcode >> 6) & 0x1f) {
23024 /* rotrv is decoded as srlv on non-R2 CPUs */
23025 if (ctx->insn_flags & ISA_MIPS32R2) {
23030 gen_shift(ctx, op1, rd, rs, rt);
23033 generate_exception_end(ctx, EXCP_RI);
23037 case OPC_SLT: /* Set on less than */
23039 gen_slt(ctx, op1, rd, rs, rt);
23041 case OPC_AND: /* Logic*/
23045 gen_logic(ctx, op1, rd, rs, rt);
23048 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23050 case OPC_TGE: /* Traps */
23056 check_insn(ctx, ISA_MIPS2);
23057 gen_trap(ctx, op1, rs, rt, -1);
23059 case OPC_LSA: /* OPC_PMON */
23060 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23061 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23062 decode_opc_special_r6(env, ctx);
23064 /* Pmon entry point, also R4010 selsl */
23065 #ifdef MIPS_STRICT_STANDARD
23066 MIPS_INVAL("PMON / selsl");
23067 generate_exception_end(ctx, EXCP_RI);
23069 gen_helper_0e0i(pmon, sa);
23074 generate_exception_end(ctx, EXCP_SYSCALL);
23077 generate_exception_end(ctx, EXCP_BREAK);
23080 check_insn(ctx, ISA_MIPS2);
23081 gen_sync(extract32(ctx->opcode, 6, 5));
23084 #if defined(TARGET_MIPS64)
23085 /* MIPS64 specific opcodes */
23090 check_insn(ctx, ISA_MIPS3);
23091 check_mips_64(ctx);
23092 gen_shift_imm(ctx, op1, rd, rt, sa);
23095 switch ((ctx->opcode >> 21) & 0x1f) {
23097 /* drotr is decoded as dsrl on non-R2 CPUs */
23098 if (ctx->insn_flags & ISA_MIPS32R2) {
23103 check_insn(ctx, ISA_MIPS3);
23104 check_mips_64(ctx);
23105 gen_shift_imm(ctx, op1, rd, rt, sa);
23108 generate_exception_end(ctx, EXCP_RI);
23113 switch ((ctx->opcode >> 21) & 0x1f) {
23115 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23116 if (ctx->insn_flags & ISA_MIPS32R2) {
23121 check_insn(ctx, ISA_MIPS3);
23122 check_mips_64(ctx);
23123 gen_shift_imm(ctx, op1, rd, rt, sa);
23126 generate_exception_end(ctx, EXCP_RI);
23134 check_insn(ctx, ISA_MIPS3);
23135 check_mips_64(ctx);
23136 gen_arith(ctx, op1, rd, rs, rt);
23140 check_insn(ctx, ISA_MIPS3);
23141 check_mips_64(ctx);
23142 gen_shift(ctx, op1, rd, rs, rt);
23145 switch ((ctx->opcode >> 6) & 0x1f) {
23147 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23148 if (ctx->insn_flags & ISA_MIPS32R2) {
23153 check_insn(ctx, ISA_MIPS3);
23154 check_mips_64(ctx);
23155 gen_shift(ctx, op1, rd, rs, rt);
23158 generate_exception_end(ctx, EXCP_RI);
23163 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23164 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23165 decode_opc_special_r6(env, ctx);
23170 if (ctx->insn_flags & ISA_MIPS32R6) {
23171 decode_opc_special_r6(env, ctx);
23173 decode_opc_special_legacy(env, ctx);
23178 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
23183 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23185 rs = (ctx->opcode >> 21) & 0x1f;
23186 rt = (ctx->opcode >> 16) & 0x1f;
23187 rd = (ctx->opcode >> 11) & 0x1f;
23189 op1 = MASK_SPECIAL2(ctx->opcode);
23191 case OPC_MADD: /* Multiply and add/sub */
23195 check_insn(ctx, ISA_MIPS32);
23196 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23199 gen_arith(ctx, op1, rd, rs, rt);
23202 case OPC_DIVU_G_2F:
23203 case OPC_MULT_G_2F:
23204 case OPC_MULTU_G_2F:
23206 case OPC_MODU_G_2F:
23207 check_insn(ctx, INSN_LOONGSON2F);
23208 gen_loongson_integer(ctx, op1, rd, rs, rt);
23212 check_insn(ctx, ISA_MIPS32);
23213 gen_cl(ctx, op1, rd, rs);
23216 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23217 gen_helper_do_semihosting(cpu_env);
23219 /* XXX: not clear which exception should be raised
23220 * when in debug mode...
23222 check_insn(ctx, ISA_MIPS32);
23223 generate_exception_end(ctx, EXCP_DBp);
23226 #if defined(TARGET_MIPS64)
23229 check_insn(ctx, ISA_MIPS64);
23230 check_mips_64(ctx);
23231 gen_cl(ctx, op1, rd, rs);
23233 case OPC_DMULT_G_2F:
23234 case OPC_DMULTU_G_2F:
23235 case OPC_DDIV_G_2F:
23236 case OPC_DDIVU_G_2F:
23237 case OPC_DMOD_G_2F:
23238 case OPC_DMODU_G_2F:
23239 check_insn(ctx, INSN_LOONGSON2F);
23240 gen_loongson_integer(ctx, op1, rd, rs, rt);
23243 default: /* Invalid */
23244 MIPS_INVAL("special2_legacy");
23245 generate_exception_end(ctx, EXCP_RI);
23250 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
23252 int rs, rt, rd, sa;
23256 rs = (ctx->opcode >> 21) & 0x1f;
23257 rt = (ctx->opcode >> 16) & 0x1f;
23258 rd = (ctx->opcode >> 11) & 0x1f;
23259 sa = (ctx->opcode >> 6) & 0x1f;
23260 imm = (int16_t)ctx->opcode >> 7;
23262 op1 = MASK_SPECIAL3(ctx->opcode);
23266 /* hint codes 24-31 are reserved and signal RI */
23267 generate_exception_end(ctx, EXCP_RI);
23269 /* Treat as NOP. */
23272 check_cp0_enabled(ctx);
23273 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23274 gen_cache_operation(ctx, rt, rs, imm);
23278 gen_st_cond(ctx, op1, rt, rs, imm);
23281 gen_ld(ctx, op1, rt, rs, imm);
23286 /* Treat as NOP. */
23289 op2 = MASK_BSHFL(ctx->opcode);
23292 case OPC_ALIGN_END:
23293 gen_align(ctx, 32, rd, rs, rt, sa & 3);
23296 gen_bitswap(ctx, op2, rd, rt);
23301 #if defined(TARGET_MIPS64)
23303 gen_st_cond(ctx, op1, rt, rs, imm);
23306 gen_ld(ctx, op1, rt, rs, imm);
23309 check_mips_64(ctx);
23312 /* Treat as NOP. */
23315 op2 = MASK_DBSHFL(ctx->opcode);
23318 case OPC_DALIGN_END:
23319 gen_align(ctx, 64, rd, rs, rt, sa & 7);
23322 gen_bitswap(ctx, op2, rd, rt);
23329 default: /* Invalid */
23330 MIPS_INVAL("special3_r6");
23331 generate_exception_end(ctx, EXCP_RI);
23336 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
23341 rs = (ctx->opcode >> 21) & 0x1f;
23342 rt = (ctx->opcode >> 16) & 0x1f;
23343 rd = (ctx->opcode >> 11) & 0x1f;
23345 op1 = MASK_SPECIAL3(ctx->opcode);
23348 case OPC_DIVU_G_2E:
23350 case OPC_MODU_G_2E:
23351 case OPC_MULT_G_2E:
23352 case OPC_MULTU_G_2E:
23353 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23354 * the same mask and op1. */
23355 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
23356 op2 = MASK_ADDUH_QB(ctx->opcode);
23359 case OPC_ADDUH_R_QB:
23361 case OPC_ADDQH_R_PH:
23363 case OPC_ADDQH_R_W:
23365 case OPC_SUBUH_R_QB:
23367 case OPC_SUBQH_R_PH:
23369 case OPC_SUBQH_R_W:
23370 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23375 case OPC_MULQ_RS_W:
23376 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23379 MIPS_INVAL("MASK ADDUH.QB");
23380 generate_exception_end(ctx, EXCP_RI);
23383 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
23384 gen_loongson_integer(ctx, op1, rd, rs, rt);
23386 generate_exception_end(ctx, EXCP_RI);
23390 op2 = MASK_LX(ctx->opcode);
23392 #if defined(TARGET_MIPS64)
23398 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
23400 default: /* Invalid */
23401 MIPS_INVAL("MASK LX");
23402 generate_exception_end(ctx, EXCP_RI);
23406 case OPC_ABSQ_S_PH_DSP:
23407 op2 = MASK_ABSQ_S_PH(ctx->opcode);
23409 case OPC_ABSQ_S_QB:
23410 case OPC_ABSQ_S_PH:
23412 case OPC_PRECEQ_W_PHL:
23413 case OPC_PRECEQ_W_PHR:
23414 case OPC_PRECEQU_PH_QBL:
23415 case OPC_PRECEQU_PH_QBR:
23416 case OPC_PRECEQU_PH_QBLA:
23417 case OPC_PRECEQU_PH_QBRA:
23418 case OPC_PRECEU_PH_QBL:
23419 case OPC_PRECEU_PH_QBR:
23420 case OPC_PRECEU_PH_QBLA:
23421 case OPC_PRECEU_PH_QBRA:
23422 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23429 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23432 MIPS_INVAL("MASK ABSQ_S.PH");
23433 generate_exception_end(ctx, EXCP_RI);
23437 case OPC_ADDU_QB_DSP:
23438 op2 = MASK_ADDU_QB(ctx->opcode);
23441 case OPC_ADDQ_S_PH:
23444 case OPC_ADDU_S_QB:
23446 case OPC_ADDU_S_PH:
23448 case OPC_SUBQ_S_PH:
23451 case OPC_SUBU_S_QB:
23453 case OPC_SUBU_S_PH:
23457 case OPC_RADDU_W_QB:
23458 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23460 case OPC_MULEU_S_PH_QBL:
23461 case OPC_MULEU_S_PH_QBR:
23462 case OPC_MULQ_RS_PH:
23463 case OPC_MULEQ_S_W_PHL:
23464 case OPC_MULEQ_S_W_PHR:
23465 case OPC_MULQ_S_PH:
23466 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23468 default: /* Invalid */
23469 MIPS_INVAL("MASK ADDU.QB");
23470 generate_exception_end(ctx, EXCP_RI);
23475 case OPC_CMPU_EQ_QB_DSP:
23476 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
23478 case OPC_PRECR_SRA_PH_W:
23479 case OPC_PRECR_SRA_R_PH_W:
23480 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
23482 case OPC_PRECR_QB_PH:
23483 case OPC_PRECRQ_QB_PH:
23484 case OPC_PRECRQ_PH_W:
23485 case OPC_PRECRQ_RS_PH_W:
23486 case OPC_PRECRQU_S_QB_PH:
23487 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23489 case OPC_CMPU_EQ_QB:
23490 case OPC_CMPU_LT_QB:
23491 case OPC_CMPU_LE_QB:
23492 case OPC_CMP_EQ_PH:
23493 case OPC_CMP_LT_PH:
23494 case OPC_CMP_LE_PH:
23495 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
23497 case OPC_CMPGU_EQ_QB:
23498 case OPC_CMPGU_LT_QB:
23499 case OPC_CMPGU_LE_QB:
23500 case OPC_CMPGDU_EQ_QB:
23501 case OPC_CMPGDU_LT_QB:
23502 case OPC_CMPGDU_LE_QB:
23505 case OPC_PACKRL_PH:
23506 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23508 default: /* Invalid */
23509 MIPS_INVAL("MASK CMPU.EQ.QB");
23510 generate_exception_end(ctx, EXCP_RI);
23514 case OPC_SHLL_QB_DSP:
23515 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23517 case OPC_DPA_W_PH_DSP:
23518 op2 = MASK_DPA_W_PH(ctx->opcode);
23520 case OPC_DPAU_H_QBL:
23521 case OPC_DPAU_H_QBR:
23522 case OPC_DPSU_H_QBL:
23523 case OPC_DPSU_H_QBR:
23525 case OPC_DPAX_W_PH:
23526 case OPC_DPAQ_S_W_PH:
23527 case OPC_DPAQX_S_W_PH:
23528 case OPC_DPAQX_SA_W_PH:
23530 case OPC_DPSX_W_PH:
23531 case OPC_DPSQ_S_W_PH:
23532 case OPC_DPSQX_S_W_PH:
23533 case OPC_DPSQX_SA_W_PH:
23534 case OPC_MULSAQ_S_W_PH:
23535 case OPC_DPAQ_SA_L_W:
23536 case OPC_DPSQ_SA_L_W:
23537 case OPC_MAQ_S_W_PHL:
23538 case OPC_MAQ_S_W_PHR:
23539 case OPC_MAQ_SA_W_PHL:
23540 case OPC_MAQ_SA_W_PHR:
23541 case OPC_MULSA_W_PH:
23542 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23544 default: /* Invalid */
23545 MIPS_INVAL("MASK DPAW.PH");
23546 generate_exception_end(ctx, EXCP_RI);
23551 op2 = MASK_INSV(ctx->opcode);
23562 t0 = tcg_temp_new();
23563 t1 = tcg_temp_new();
23565 gen_load_gpr(t0, rt);
23566 gen_load_gpr(t1, rs);
23568 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
23574 default: /* Invalid */
23575 MIPS_INVAL("MASK INSV");
23576 generate_exception_end(ctx, EXCP_RI);
23580 case OPC_APPEND_DSP:
23581 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23583 case OPC_EXTR_W_DSP:
23584 op2 = MASK_EXTR_W(ctx->opcode);
23588 case OPC_EXTR_RS_W:
23590 case OPC_EXTRV_S_H:
23592 case OPC_EXTRV_R_W:
23593 case OPC_EXTRV_RS_W:
23598 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23601 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
23607 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23609 default: /* Invalid */
23610 MIPS_INVAL("MASK EXTR.W");
23611 generate_exception_end(ctx, EXCP_RI);
23615 #if defined(TARGET_MIPS64)
23616 case OPC_DDIV_G_2E:
23617 case OPC_DDIVU_G_2E:
23618 case OPC_DMULT_G_2E:
23619 case OPC_DMULTU_G_2E:
23620 case OPC_DMOD_G_2E:
23621 case OPC_DMODU_G_2E:
23622 check_insn(ctx, INSN_LOONGSON2E);
23623 gen_loongson_integer(ctx, op1, rd, rs, rt);
23625 case OPC_ABSQ_S_QH_DSP:
23626 op2 = MASK_ABSQ_S_QH(ctx->opcode);
23628 case OPC_PRECEQ_L_PWL:
23629 case OPC_PRECEQ_L_PWR:
23630 case OPC_PRECEQ_PW_QHL:
23631 case OPC_PRECEQ_PW_QHR:
23632 case OPC_PRECEQ_PW_QHLA:
23633 case OPC_PRECEQ_PW_QHRA:
23634 case OPC_PRECEQU_QH_OBL:
23635 case OPC_PRECEQU_QH_OBR:
23636 case OPC_PRECEQU_QH_OBLA:
23637 case OPC_PRECEQU_QH_OBRA:
23638 case OPC_PRECEU_QH_OBL:
23639 case OPC_PRECEU_QH_OBR:
23640 case OPC_PRECEU_QH_OBLA:
23641 case OPC_PRECEU_QH_OBRA:
23642 case OPC_ABSQ_S_OB:
23643 case OPC_ABSQ_S_PW:
23644 case OPC_ABSQ_S_QH:
23645 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23653 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23655 default: /* Invalid */
23656 MIPS_INVAL("MASK ABSQ_S.QH");
23657 generate_exception_end(ctx, EXCP_RI);
23661 case OPC_ADDU_OB_DSP:
23662 op2 = MASK_ADDU_OB(ctx->opcode);
23664 case OPC_RADDU_L_OB:
23666 case OPC_SUBQ_S_PW:
23668 case OPC_SUBQ_S_QH:
23670 case OPC_SUBU_S_OB:
23672 case OPC_SUBU_S_QH:
23674 case OPC_SUBUH_R_OB:
23676 case OPC_ADDQ_S_PW:
23678 case OPC_ADDQ_S_QH:
23680 case OPC_ADDU_S_OB:
23682 case OPC_ADDU_S_QH:
23684 case OPC_ADDUH_R_OB:
23685 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23687 case OPC_MULEQ_S_PW_QHL:
23688 case OPC_MULEQ_S_PW_QHR:
23689 case OPC_MULEU_S_QH_OBL:
23690 case OPC_MULEU_S_QH_OBR:
23691 case OPC_MULQ_RS_QH:
23692 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23694 default: /* Invalid */
23695 MIPS_INVAL("MASK ADDU.OB");
23696 generate_exception_end(ctx, EXCP_RI);
23700 case OPC_CMPU_EQ_OB_DSP:
23701 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
23703 case OPC_PRECR_SRA_QH_PW:
23704 case OPC_PRECR_SRA_R_QH_PW:
23705 /* Return value is rt. */
23706 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
23708 case OPC_PRECR_OB_QH:
23709 case OPC_PRECRQ_OB_QH:
23710 case OPC_PRECRQ_PW_L:
23711 case OPC_PRECRQ_QH_PW:
23712 case OPC_PRECRQ_RS_QH_PW:
23713 case OPC_PRECRQU_S_OB_QH:
23714 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23716 case OPC_CMPU_EQ_OB:
23717 case OPC_CMPU_LT_OB:
23718 case OPC_CMPU_LE_OB:
23719 case OPC_CMP_EQ_QH:
23720 case OPC_CMP_LT_QH:
23721 case OPC_CMP_LE_QH:
23722 case OPC_CMP_EQ_PW:
23723 case OPC_CMP_LT_PW:
23724 case OPC_CMP_LE_PW:
23725 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
23727 case OPC_CMPGDU_EQ_OB:
23728 case OPC_CMPGDU_LT_OB:
23729 case OPC_CMPGDU_LE_OB:
23730 case OPC_CMPGU_EQ_OB:
23731 case OPC_CMPGU_LT_OB:
23732 case OPC_CMPGU_LE_OB:
23733 case OPC_PACKRL_PW:
23737 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23739 default: /* Invalid */
23740 MIPS_INVAL("MASK CMPU_EQ.OB");
23741 generate_exception_end(ctx, EXCP_RI);
23745 case OPC_DAPPEND_DSP:
23746 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23748 case OPC_DEXTR_W_DSP:
23749 op2 = MASK_DEXTR_W(ctx->opcode);
23756 case OPC_DEXTR_R_L:
23757 case OPC_DEXTR_RS_L:
23759 case OPC_DEXTR_R_W:
23760 case OPC_DEXTR_RS_W:
23761 case OPC_DEXTR_S_H:
23763 case OPC_DEXTRV_R_L:
23764 case OPC_DEXTRV_RS_L:
23765 case OPC_DEXTRV_S_H:
23767 case OPC_DEXTRV_R_W:
23768 case OPC_DEXTRV_RS_W:
23769 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23774 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23776 default: /* Invalid */
23777 MIPS_INVAL("MASK EXTR.W");
23778 generate_exception_end(ctx, EXCP_RI);
23782 case OPC_DPAQ_W_QH_DSP:
23783 op2 = MASK_DPAQ_W_QH(ctx->opcode);
23785 case OPC_DPAU_H_OBL:
23786 case OPC_DPAU_H_OBR:
23787 case OPC_DPSU_H_OBL:
23788 case OPC_DPSU_H_OBR:
23790 case OPC_DPAQ_S_W_QH:
23792 case OPC_DPSQ_S_W_QH:
23793 case OPC_MULSAQ_S_W_QH:
23794 case OPC_DPAQ_SA_L_PW:
23795 case OPC_DPSQ_SA_L_PW:
23796 case OPC_MULSAQ_S_L_PW:
23797 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23799 case OPC_MAQ_S_W_QHLL:
23800 case OPC_MAQ_S_W_QHLR:
23801 case OPC_MAQ_S_W_QHRL:
23802 case OPC_MAQ_S_W_QHRR:
23803 case OPC_MAQ_SA_W_QHLL:
23804 case OPC_MAQ_SA_W_QHLR:
23805 case OPC_MAQ_SA_W_QHRL:
23806 case OPC_MAQ_SA_W_QHRR:
23807 case OPC_MAQ_S_L_PWL:
23808 case OPC_MAQ_S_L_PWR:
23813 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23815 default: /* Invalid */
23816 MIPS_INVAL("MASK DPAQ.W.QH");
23817 generate_exception_end(ctx, EXCP_RI);
23821 case OPC_DINSV_DSP:
23822 op2 = MASK_INSV(ctx->opcode);
23833 t0 = tcg_temp_new();
23834 t1 = tcg_temp_new();
23836 gen_load_gpr(t0, rt);
23837 gen_load_gpr(t1, rs);
23839 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
23845 default: /* Invalid */
23846 MIPS_INVAL("MASK DINSV");
23847 generate_exception_end(ctx, EXCP_RI);
23851 case OPC_SHLL_OB_DSP:
23852 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23855 default: /* Invalid */
23856 MIPS_INVAL("special3_legacy");
23857 generate_exception_end(ctx, EXCP_RI);
23862 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
23864 int rs, rt, rd, sa;
23868 rs = (ctx->opcode >> 21) & 0x1f;
23869 rt = (ctx->opcode >> 16) & 0x1f;
23870 rd = (ctx->opcode >> 11) & 0x1f;
23871 sa = (ctx->opcode >> 6) & 0x1f;
23872 imm = sextract32(ctx->opcode, 7, 9);
23874 op1 = MASK_SPECIAL3(ctx->opcode);
23877 * EVA loads and stores overlap Loongson 2E instructions decoded by
23878 * decode_opc_special3_legacy(), so be careful to allow their decoding when
23885 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23893 check_cp0_enabled(ctx);
23894 gen_ld(ctx, op1, rt, rs, imm);
23898 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23903 check_cp0_enabled(ctx);
23904 gen_st(ctx, op1, rt, rs, imm);
23907 check_cp0_enabled(ctx);
23908 gen_st_cond(ctx, op1, rt, rs, imm);
23911 check_cp0_enabled(ctx);
23912 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23913 gen_cache_operation(ctx, rt, rs, imm);
23915 /* Treat as NOP. */
23918 check_cp0_enabled(ctx);
23919 /* Treat as NOP. */
23927 check_insn(ctx, ISA_MIPS32R2);
23928 gen_bitops(ctx, op1, rt, rs, sa, rd);
23931 op2 = MASK_BSHFL(ctx->opcode);
23934 case OPC_ALIGN_END:
23936 check_insn(ctx, ISA_MIPS32R6);
23937 decode_opc_special3_r6(env, ctx);
23940 check_insn(ctx, ISA_MIPS32R2);
23941 gen_bshfl(ctx, op2, rt, rd);
23945 #if defined(TARGET_MIPS64)
23952 check_insn(ctx, ISA_MIPS64R2);
23953 check_mips_64(ctx);
23954 gen_bitops(ctx, op1, rt, rs, sa, rd);
23957 op2 = MASK_DBSHFL(ctx->opcode);
23960 case OPC_DALIGN_END:
23962 check_insn(ctx, ISA_MIPS32R6);
23963 decode_opc_special3_r6(env, ctx);
23966 check_insn(ctx, ISA_MIPS64R2);
23967 check_mips_64(ctx);
23968 op2 = MASK_DBSHFL(ctx->opcode);
23969 gen_bshfl(ctx, op2, rt, rd);
23975 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
23980 TCGv t0 = tcg_temp_new();
23981 TCGv t1 = tcg_temp_new();
23983 gen_load_gpr(t0, rt);
23984 gen_load_gpr(t1, rs);
23985 gen_helper_fork(t0, t1);
23993 TCGv t0 = tcg_temp_new();
23995 gen_load_gpr(t0, rs);
23996 gen_helper_yield(t0, cpu_env, t0);
23997 gen_store_gpr(t0, rd);
24002 if (ctx->insn_flags & ISA_MIPS32R6) {
24003 decode_opc_special3_r6(env, ctx);
24005 decode_opc_special3_legacy(env, ctx);
24010 /* MIPS SIMD Architecture (MSA) */
24011 static inline int check_msa_access(DisasContext *ctx)
24013 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
24014 !(ctx->hflags & MIPS_HFLAG_F64))) {
24015 generate_exception_end(ctx, EXCP_RI);
24019 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
24020 if (ctx->insn_flags & ASE_MSA) {
24021 generate_exception_end(ctx, EXCP_MSADIS);
24024 generate_exception_end(ctx, EXCP_RI);
24031 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
24033 /* generates tcg ops to check if any element is 0 */
24034 /* Note this function only works with MSA_WRLEN = 128 */
24035 uint64_t eval_zero_or_big = 0;
24036 uint64_t eval_big = 0;
24037 TCGv_i64 t0 = tcg_temp_new_i64();
24038 TCGv_i64 t1 = tcg_temp_new_i64();
24041 eval_zero_or_big = 0x0101010101010101ULL;
24042 eval_big = 0x8080808080808080ULL;
24045 eval_zero_or_big = 0x0001000100010001ULL;
24046 eval_big = 0x8000800080008000ULL;
24049 eval_zero_or_big = 0x0000000100000001ULL;
24050 eval_big = 0x8000000080000000ULL;
24053 eval_zero_or_big = 0x0000000000000001ULL;
24054 eval_big = 0x8000000000000000ULL;
24057 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
24058 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
24059 tcg_gen_andi_i64(t0, t0, eval_big);
24060 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
24061 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
24062 tcg_gen_andi_i64(t1, t1, eval_big);
24063 tcg_gen_or_i64(t0, t0, t1);
24064 /* if all bits are zero then all elements are not zero */
24065 /* if some bit is non-zero then some element is zero */
24066 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
24067 tcg_gen_trunc_i64_tl(tresult, t0);
24068 tcg_temp_free_i64(t0);
24069 tcg_temp_free_i64(t1);
24072 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
24074 uint8_t df = (ctx->opcode >> 21) & 0x3;
24075 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24076 int64_t s16 = (int16_t)ctx->opcode;
24078 check_msa_access(ctx);
24080 if (ctx->hflags & MIPS_HFLAG_BMASK) {
24081 generate_exception_end(ctx, EXCP_RI);
24088 TCGv_i64 t0 = tcg_temp_new_i64();
24089 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
24090 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
24091 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
24092 tcg_gen_trunc_i64_tl(bcond, t0);
24093 tcg_temp_free_i64(t0);
24100 gen_check_zero_element(bcond, df, wt);
24106 gen_check_zero_element(bcond, df, wt);
24107 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
24111 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
24113 ctx->hflags |= MIPS_HFLAG_BC;
24114 ctx->hflags |= MIPS_HFLAG_BDS32;
24117 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
24119 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
24120 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
24121 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24122 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24124 TCGv_i32 twd = tcg_const_i32(wd);
24125 TCGv_i32 tws = tcg_const_i32(ws);
24126 TCGv_i32 ti8 = tcg_const_i32(i8);
24128 switch (MASK_MSA_I8(ctx->opcode)) {
24130 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
24133 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
24136 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
24139 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
24142 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
24145 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
24148 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
24154 uint8_t df = (ctx->opcode >> 24) & 0x3;
24155 if (df == DF_DOUBLE) {
24156 generate_exception_end(ctx, EXCP_RI);
24158 TCGv_i32 tdf = tcg_const_i32(df);
24159 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
24160 tcg_temp_free_i32(tdf);
24165 MIPS_INVAL("MSA instruction");
24166 generate_exception_end(ctx, EXCP_RI);
24170 tcg_temp_free_i32(twd);
24171 tcg_temp_free_i32(tws);
24172 tcg_temp_free_i32(ti8);
24175 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
24177 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24178 uint8_t df = (ctx->opcode >> 21) & 0x3;
24179 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
24180 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
24181 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24182 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24184 TCGv_i32 tdf = tcg_const_i32(df);
24185 TCGv_i32 twd = tcg_const_i32(wd);
24186 TCGv_i32 tws = tcg_const_i32(ws);
24187 TCGv_i32 timm = tcg_temp_new_i32();
24188 tcg_gen_movi_i32(timm, u5);
24190 switch (MASK_MSA_I5(ctx->opcode)) {
24192 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
24195 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
24197 case OPC_MAXI_S_df:
24198 tcg_gen_movi_i32(timm, s5);
24199 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
24201 case OPC_MAXI_U_df:
24202 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
24204 case OPC_MINI_S_df:
24205 tcg_gen_movi_i32(timm, s5);
24206 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
24208 case OPC_MINI_U_df:
24209 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
24212 tcg_gen_movi_i32(timm, s5);
24213 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
24215 case OPC_CLTI_S_df:
24216 tcg_gen_movi_i32(timm, s5);
24217 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
24219 case OPC_CLTI_U_df:
24220 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
24222 case OPC_CLEI_S_df:
24223 tcg_gen_movi_i32(timm, s5);
24224 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
24226 case OPC_CLEI_U_df:
24227 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
24231 int32_t s10 = sextract32(ctx->opcode, 11, 10);
24232 tcg_gen_movi_i32(timm, s10);
24233 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
24237 MIPS_INVAL("MSA instruction");
24238 generate_exception_end(ctx, EXCP_RI);
24242 tcg_temp_free_i32(tdf);
24243 tcg_temp_free_i32(twd);
24244 tcg_temp_free_i32(tws);
24245 tcg_temp_free_i32(timm);
24248 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
24250 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24251 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
24252 uint32_t df = 0, m = 0;
24253 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24254 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24261 if ((dfm & 0x40) == 0x00) {
24264 } else if ((dfm & 0x60) == 0x40) {
24267 } else if ((dfm & 0x70) == 0x60) {
24270 } else if ((dfm & 0x78) == 0x70) {
24274 generate_exception_end(ctx, EXCP_RI);
24278 tdf = tcg_const_i32(df);
24279 tm = tcg_const_i32(m);
24280 twd = tcg_const_i32(wd);
24281 tws = tcg_const_i32(ws);
24283 switch (MASK_MSA_BIT(ctx->opcode)) {
24285 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
24288 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
24291 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
24294 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
24297 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
24300 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
24302 case OPC_BINSLI_df:
24303 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
24305 case OPC_BINSRI_df:
24306 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
24309 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
24312 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
24315 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
24318 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
24321 MIPS_INVAL("MSA instruction");
24322 generate_exception_end(ctx, EXCP_RI);
24326 tcg_temp_free_i32(tdf);
24327 tcg_temp_free_i32(tm);
24328 tcg_temp_free_i32(twd);
24329 tcg_temp_free_i32(tws);
24332 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
24334 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24335 uint8_t df = (ctx->opcode >> 21) & 0x3;
24336 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24337 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24338 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24340 TCGv_i32 tdf = tcg_const_i32(df);
24341 TCGv_i32 twd = tcg_const_i32(wd);
24342 TCGv_i32 tws = tcg_const_i32(ws);
24343 TCGv_i32 twt = tcg_const_i32(wt);
24345 switch (MASK_MSA_3R(ctx->opcode)) {
24347 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
24350 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
24353 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
24356 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
24358 case OPC_SUBS_S_df:
24359 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
24362 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
24365 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
24368 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
24371 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
24374 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
24376 case OPC_ADDS_A_df:
24377 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
24379 case OPC_SUBS_U_df:
24380 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
24383 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
24386 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
24389 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
24392 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
24395 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
24398 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
24400 case OPC_ADDS_S_df:
24401 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
24403 case OPC_SUBSUS_U_df:
24404 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
24407 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
24410 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
24413 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
24416 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
24419 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
24422 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
24424 case OPC_ADDS_U_df:
24425 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
24427 case OPC_SUBSUU_S_df:
24428 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
24431 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
24434 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
24437 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
24440 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
24443 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
24445 case OPC_ASUB_S_df:
24446 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
24449 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
24452 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
24455 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
24458 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
24461 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
24464 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
24466 case OPC_ASUB_U_df:
24467 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
24470 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
24473 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
24476 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
24479 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
24481 case OPC_AVER_S_df:
24482 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
24485 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
24488 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
24491 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
24494 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
24496 case OPC_AVER_U_df:
24497 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
24500 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
24503 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
24506 case OPC_DOTP_S_df:
24507 case OPC_DOTP_U_df:
24508 case OPC_DPADD_S_df:
24509 case OPC_DPADD_U_df:
24510 case OPC_DPSUB_S_df:
24511 case OPC_HADD_S_df:
24512 case OPC_DPSUB_U_df:
24513 case OPC_HADD_U_df:
24514 case OPC_HSUB_S_df:
24515 case OPC_HSUB_U_df:
24516 if (df == DF_BYTE) {
24517 generate_exception_end(ctx, EXCP_RI);
24520 switch (MASK_MSA_3R(ctx->opcode)) {
24521 case OPC_DOTP_S_df:
24522 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
24524 case OPC_DOTP_U_df:
24525 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
24527 case OPC_DPADD_S_df:
24528 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
24530 case OPC_DPADD_U_df:
24531 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
24533 case OPC_DPSUB_S_df:
24534 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
24536 case OPC_HADD_S_df:
24537 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
24539 case OPC_DPSUB_U_df:
24540 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
24542 case OPC_HADD_U_df:
24543 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
24545 case OPC_HSUB_S_df:
24546 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
24548 case OPC_HSUB_U_df:
24549 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
24554 MIPS_INVAL("MSA instruction");
24555 generate_exception_end(ctx, EXCP_RI);
24558 tcg_temp_free_i32(twd);
24559 tcg_temp_free_i32(tws);
24560 tcg_temp_free_i32(twt);
24561 tcg_temp_free_i32(tdf);
24564 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
24566 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
24567 uint8_t source = (ctx->opcode >> 11) & 0x1f;
24568 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
24569 TCGv telm = tcg_temp_new();
24570 TCGv_i32 tsr = tcg_const_i32(source);
24571 TCGv_i32 tdt = tcg_const_i32(dest);
24573 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
24575 gen_load_gpr(telm, source);
24576 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
24579 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
24580 gen_store_gpr(telm, dest);
24583 gen_helper_msa_move_v(cpu_env, tdt, tsr);
24586 MIPS_INVAL("MSA instruction");
24587 generate_exception_end(ctx, EXCP_RI);
24591 tcg_temp_free(telm);
24592 tcg_temp_free_i32(tdt);
24593 tcg_temp_free_i32(tsr);
24596 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
24599 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24600 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24601 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24603 TCGv_i32 tws = tcg_const_i32(ws);
24604 TCGv_i32 twd = tcg_const_i32(wd);
24605 TCGv_i32 tn = tcg_const_i32(n);
24606 TCGv_i32 tdf = tcg_const_i32(df);
24608 switch (MASK_MSA_ELM(ctx->opcode)) {
24610 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
24612 case OPC_SPLATI_df:
24613 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
24616 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
24618 case OPC_COPY_S_df:
24619 case OPC_COPY_U_df:
24620 case OPC_INSERT_df:
24621 #if !defined(TARGET_MIPS64)
24622 /* Double format valid only for MIPS64 */
24623 if (df == DF_DOUBLE) {
24624 generate_exception_end(ctx, EXCP_RI);
24628 switch (MASK_MSA_ELM(ctx->opcode)) {
24629 case OPC_COPY_S_df:
24630 if (likely(wd != 0)) {
24631 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
24634 case OPC_COPY_U_df:
24635 if (likely(wd != 0)) {
24636 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
24639 case OPC_INSERT_df:
24640 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
24645 MIPS_INVAL("MSA instruction");
24646 generate_exception_end(ctx, EXCP_RI);
24648 tcg_temp_free_i32(twd);
24649 tcg_temp_free_i32(tws);
24650 tcg_temp_free_i32(tn);
24651 tcg_temp_free_i32(tdf);
24654 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
24656 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
24657 uint32_t df = 0, n = 0;
24659 if ((dfn & 0x30) == 0x00) {
24662 } else if ((dfn & 0x38) == 0x20) {
24665 } else if ((dfn & 0x3c) == 0x30) {
24668 } else if ((dfn & 0x3e) == 0x38) {
24671 } else if (dfn == 0x3E) {
24672 /* CTCMSA, CFCMSA, MOVE.V */
24673 gen_msa_elm_3e(env, ctx);
24676 generate_exception_end(ctx, EXCP_RI);
24680 gen_msa_elm_df(env, ctx, df, n);
24683 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
24685 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24686 uint8_t df = (ctx->opcode >> 21) & 0x1;
24687 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24688 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24689 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24691 TCGv_i32 twd = tcg_const_i32(wd);
24692 TCGv_i32 tws = tcg_const_i32(ws);
24693 TCGv_i32 twt = tcg_const_i32(wt);
24694 TCGv_i32 tdf = tcg_temp_new_i32();
24696 /* adjust df value for floating-point instruction */
24697 tcg_gen_movi_i32(tdf, df + 2);
24699 switch (MASK_MSA_3RF(ctx->opcode)) {
24701 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
24704 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
24707 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
24710 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
24713 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
24716 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
24719 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
24722 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
24725 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
24728 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
24731 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
24734 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
24737 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
24740 tcg_gen_movi_i32(tdf, df + 1);
24741 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
24744 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
24747 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
24749 case OPC_MADD_Q_df:
24750 tcg_gen_movi_i32(tdf, df + 1);
24751 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
24754 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
24756 case OPC_MSUB_Q_df:
24757 tcg_gen_movi_i32(tdf, df + 1);
24758 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
24761 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
24764 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
24767 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
24770 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
24773 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
24776 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
24779 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
24782 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
24785 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
24788 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
24791 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
24794 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
24797 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
24799 case OPC_MULR_Q_df:
24800 tcg_gen_movi_i32(tdf, df + 1);
24801 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
24804 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
24806 case OPC_FMIN_A_df:
24807 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
24809 case OPC_MADDR_Q_df:
24810 tcg_gen_movi_i32(tdf, df + 1);
24811 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
24814 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
24817 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
24819 case OPC_MSUBR_Q_df:
24820 tcg_gen_movi_i32(tdf, df + 1);
24821 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
24824 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
24826 case OPC_FMAX_A_df:
24827 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
24830 MIPS_INVAL("MSA instruction");
24831 generate_exception_end(ctx, EXCP_RI);
24835 tcg_temp_free_i32(twd);
24836 tcg_temp_free_i32(tws);
24837 tcg_temp_free_i32(twt);
24838 tcg_temp_free_i32(tdf);
24841 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
24843 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24844 (op & (0x7 << 18)))
24845 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24846 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24847 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24848 uint8_t df = (ctx->opcode >> 16) & 0x3;
24849 TCGv_i32 twd = tcg_const_i32(wd);
24850 TCGv_i32 tws = tcg_const_i32(ws);
24851 TCGv_i32 twt = tcg_const_i32(wt);
24852 TCGv_i32 tdf = tcg_const_i32(df);
24854 switch (MASK_MSA_2R(ctx->opcode)) {
24856 #if !defined(TARGET_MIPS64)
24857 /* Double format valid only for MIPS64 */
24858 if (df == DF_DOUBLE) {
24859 generate_exception_end(ctx, EXCP_RI);
24863 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
24866 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
24869 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
24872 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
24875 MIPS_INVAL("MSA instruction");
24876 generate_exception_end(ctx, EXCP_RI);
24880 tcg_temp_free_i32(twd);
24881 tcg_temp_free_i32(tws);
24882 tcg_temp_free_i32(twt);
24883 tcg_temp_free_i32(tdf);
24886 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
24888 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24889 (op & (0xf << 17)))
24890 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24891 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24892 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24893 uint8_t df = (ctx->opcode >> 16) & 0x1;
24894 TCGv_i32 twd = tcg_const_i32(wd);
24895 TCGv_i32 tws = tcg_const_i32(ws);
24896 TCGv_i32 twt = tcg_const_i32(wt);
24897 /* adjust df value for floating-point instruction */
24898 TCGv_i32 tdf = tcg_const_i32(df + 2);
24900 switch (MASK_MSA_2RF(ctx->opcode)) {
24901 case OPC_FCLASS_df:
24902 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
24904 case OPC_FTRUNC_S_df:
24905 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
24907 case OPC_FTRUNC_U_df:
24908 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
24911 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
24913 case OPC_FRSQRT_df:
24914 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
24917 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
24920 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
24923 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
24925 case OPC_FEXUPL_df:
24926 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
24928 case OPC_FEXUPR_df:
24929 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
24932 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
24935 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
24937 case OPC_FTINT_S_df:
24938 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
24940 case OPC_FTINT_U_df:
24941 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
24943 case OPC_FFINT_S_df:
24944 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
24946 case OPC_FFINT_U_df:
24947 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
24951 tcg_temp_free_i32(twd);
24952 tcg_temp_free_i32(tws);
24953 tcg_temp_free_i32(twt);
24954 tcg_temp_free_i32(tdf);
24957 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
24959 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
24960 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24961 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24962 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24963 TCGv_i32 twd = tcg_const_i32(wd);
24964 TCGv_i32 tws = tcg_const_i32(ws);
24965 TCGv_i32 twt = tcg_const_i32(wt);
24967 switch (MASK_MSA_VEC(ctx->opcode)) {
24969 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
24972 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
24975 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
24978 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
24981 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
24984 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
24987 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
24990 MIPS_INVAL("MSA instruction");
24991 generate_exception_end(ctx, EXCP_RI);
24995 tcg_temp_free_i32(twd);
24996 tcg_temp_free_i32(tws);
24997 tcg_temp_free_i32(twt);
25000 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
25002 switch (MASK_MSA_VEC(ctx->opcode)) {
25010 gen_msa_vec_v(env, ctx);
25013 gen_msa_2r(env, ctx);
25016 gen_msa_2rf(env, ctx);
25019 MIPS_INVAL("MSA instruction");
25020 generate_exception_end(ctx, EXCP_RI);
25025 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
25027 uint32_t opcode = ctx->opcode;
25028 check_insn(ctx, ASE_MSA);
25029 check_msa_access(ctx);
25031 switch (MASK_MSA_MINOR(opcode)) {
25032 case OPC_MSA_I8_00:
25033 case OPC_MSA_I8_01:
25034 case OPC_MSA_I8_02:
25035 gen_msa_i8(env, ctx);
25037 case OPC_MSA_I5_06:
25038 case OPC_MSA_I5_07:
25039 gen_msa_i5(env, ctx);
25041 case OPC_MSA_BIT_09:
25042 case OPC_MSA_BIT_0A:
25043 gen_msa_bit(env, ctx);
25045 case OPC_MSA_3R_0D:
25046 case OPC_MSA_3R_0E:
25047 case OPC_MSA_3R_0F:
25048 case OPC_MSA_3R_10:
25049 case OPC_MSA_3R_11:
25050 case OPC_MSA_3R_12:
25051 case OPC_MSA_3R_13:
25052 case OPC_MSA_3R_14:
25053 case OPC_MSA_3R_15:
25054 gen_msa_3r(env, ctx);
25057 gen_msa_elm(env, ctx);
25059 case OPC_MSA_3RF_1A:
25060 case OPC_MSA_3RF_1B:
25061 case OPC_MSA_3RF_1C:
25062 gen_msa_3rf(env, ctx);
25065 gen_msa_vec(env, ctx);
25076 int32_t s10 = sextract32(ctx->opcode, 16, 10);
25077 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
25078 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25079 uint8_t df = (ctx->opcode >> 0) & 0x3;
25081 TCGv_i32 twd = tcg_const_i32(wd);
25082 TCGv taddr = tcg_temp_new();
25083 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
25085 switch (MASK_MSA_MINOR(opcode)) {
25087 gen_helper_msa_ld_b(cpu_env, twd, taddr);
25090 gen_helper_msa_ld_h(cpu_env, twd, taddr);
25093 gen_helper_msa_ld_w(cpu_env, twd, taddr);
25096 gen_helper_msa_ld_d(cpu_env, twd, taddr);
25099 gen_helper_msa_st_b(cpu_env, twd, taddr);
25102 gen_helper_msa_st_h(cpu_env, twd, taddr);
25105 gen_helper_msa_st_w(cpu_env, twd, taddr);
25108 gen_helper_msa_st_d(cpu_env, twd, taddr);
25112 tcg_temp_free_i32(twd);
25113 tcg_temp_free(taddr);
25117 MIPS_INVAL("MSA instruction");
25118 generate_exception_end(ctx, EXCP_RI);
25124 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
25127 int rs, rt, rd, sa;
25131 /* make sure instructions are on a word boundary */
25132 if (ctx->base.pc_next & 0x3) {
25133 env->CP0_BadVAddr = ctx->base.pc_next;
25134 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
25138 /* Handle blikely not taken case */
25139 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
25140 TCGLabel *l1 = gen_new_label();
25142 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
25143 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
25144 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
25148 op = MASK_OP_MAJOR(ctx->opcode);
25149 rs = (ctx->opcode >> 21) & 0x1f;
25150 rt = (ctx->opcode >> 16) & 0x1f;
25151 rd = (ctx->opcode >> 11) & 0x1f;
25152 sa = (ctx->opcode >> 6) & 0x1f;
25153 imm = (int16_t)ctx->opcode;
25156 decode_opc_special(env, ctx);
25159 decode_opc_special2_legacy(env, ctx);
25162 decode_opc_special3(env, ctx);
25165 op1 = MASK_REGIMM(ctx->opcode);
25167 case OPC_BLTZL: /* REGIMM branches */
25171 check_insn(ctx, ISA_MIPS2);
25172 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25176 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25180 if (ctx->insn_flags & ISA_MIPS32R6) {
25182 /* OPC_NAL, OPC_BAL */
25183 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
25185 generate_exception_end(ctx, EXCP_RI);
25188 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25191 case OPC_TGEI: /* REGIMM traps */
25198 check_insn(ctx, ISA_MIPS2);
25199 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25200 gen_trap(ctx, op1, rs, -1, imm);
25203 check_insn(ctx, ISA_MIPS32R6);
25204 generate_exception_end(ctx, EXCP_RI);
25207 check_insn(ctx, ISA_MIPS32R2);
25208 /* Break the TB to be able to sync copied instructions
25210 ctx->base.is_jmp = DISAS_STOP;
25212 case OPC_BPOSGE32: /* MIPS DSP branch */
25213 #if defined(TARGET_MIPS64)
25217 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
25219 #if defined(TARGET_MIPS64)
25221 check_insn(ctx, ISA_MIPS32R6);
25222 check_mips_64(ctx);
25224 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
25228 check_insn(ctx, ISA_MIPS32R6);
25229 check_mips_64(ctx);
25231 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
25235 default: /* Invalid */
25236 MIPS_INVAL("regimm");
25237 generate_exception_end(ctx, EXCP_RI);
25242 check_cp0_enabled(ctx);
25243 op1 = MASK_CP0(ctx->opcode);
25251 #if defined(TARGET_MIPS64)
25255 #ifndef CONFIG_USER_ONLY
25256 gen_cp0(env, ctx, op1, rt, rd);
25257 #endif /* !CONFIG_USER_ONLY */
25275 #ifndef CONFIG_USER_ONLY
25276 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
25277 #endif /* !CONFIG_USER_ONLY */
25280 #ifndef CONFIG_USER_ONLY
25283 TCGv t0 = tcg_temp_new();
25285 op2 = MASK_MFMC0(ctx->opcode);
25289 gen_helper_dmt(t0);
25290 gen_store_gpr(t0, rt);
25294 gen_helper_emt(t0);
25295 gen_store_gpr(t0, rt);
25299 gen_helper_dvpe(t0, cpu_env);
25300 gen_store_gpr(t0, rt);
25304 gen_helper_evpe(t0, cpu_env);
25305 gen_store_gpr(t0, rt);
25308 check_insn(ctx, ISA_MIPS32R6);
25310 gen_helper_dvp(t0, cpu_env);
25311 gen_store_gpr(t0, rt);
25315 check_insn(ctx, ISA_MIPS32R6);
25317 gen_helper_evp(t0, cpu_env);
25318 gen_store_gpr(t0, rt);
25322 check_insn(ctx, ISA_MIPS32R2);
25323 save_cpu_state(ctx, 1);
25324 gen_helper_di(t0, cpu_env);
25325 gen_store_gpr(t0, rt);
25326 /* Stop translation as we may have switched
25327 the execution mode. */
25328 ctx->base.is_jmp = DISAS_STOP;
25331 check_insn(ctx, ISA_MIPS32R2);
25332 save_cpu_state(ctx, 1);
25333 gen_helper_ei(t0, cpu_env);
25334 gen_store_gpr(t0, rt);
25335 /* DISAS_STOP isn't sufficient, we need to ensure we break
25336 out of translated code to check for pending interrupts */
25337 gen_save_pc(ctx->base.pc_next + 4);
25338 ctx->base.is_jmp = DISAS_EXIT;
25340 default: /* Invalid */
25341 MIPS_INVAL("mfmc0");
25342 generate_exception_end(ctx, EXCP_RI);
25347 #endif /* !CONFIG_USER_ONLY */
25350 check_insn(ctx, ISA_MIPS32R2);
25351 gen_load_srsgpr(rt, rd);
25354 check_insn(ctx, ISA_MIPS32R2);
25355 gen_store_srsgpr(rt, rd);
25359 generate_exception_end(ctx, EXCP_RI);
25363 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
25364 if (ctx->insn_flags & ISA_MIPS32R6) {
25365 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
25366 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25369 /* Arithmetic with immediate opcode */
25370 gen_arith_imm(ctx, op, rt, rs, imm);
25374 gen_arith_imm(ctx, op, rt, rs, imm);
25376 case OPC_SLTI: /* Set on less than with immediate opcode */
25378 gen_slt_imm(ctx, op, rt, rs, imm);
25380 case OPC_ANDI: /* Arithmetic with immediate opcode */
25381 case OPC_LUI: /* OPC_AUI */
25384 gen_logic_imm(ctx, op, rt, rs, imm);
25386 case OPC_J: /* Jump */
25388 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25389 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25392 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
25393 if (ctx->insn_flags & ISA_MIPS32R6) {
25395 generate_exception_end(ctx, EXCP_RI);
25398 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
25399 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25402 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25405 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
25406 if (ctx->insn_flags & ISA_MIPS32R6) {
25408 generate_exception_end(ctx, EXCP_RI);
25411 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
25412 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25415 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25418 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
25421 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25423 check_insn(ctx, ISA_MIPS32R6);
25424 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
25425 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25428 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
25431 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25433 check_insn(ctx, ISA_MIPS32R6);
25434 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
25435 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25440 check_insn(ctx, ISA_MIPS2);
25441 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25445 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25447 case OPC_LL: /* Load and stores */
25448 check_insn(ctx, ISA_MIPS2);
25452 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25460 gen_ld(ctx, op, rt, rs, imm);
25464 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25469 gen_st(ctx, op, rt, rs, imm);
25472 check_insn(ctx, ISA_MIPS2);
25473 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25474 gen_st_cond(ctx, op, rt, rs, imm);
25477 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25478 check_cp0_enabled(ctx);
25479 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
25480 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25481 gen_cache_operation(ctx, rt, rs, imm);
25483 /* Treat as NOP. */
25486 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25487 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
25488 /* Treat as NOP. */
25491 /* Floating point (COP1). */
25496 gen_cop1_ldst(ctx, op, rt, rs, imm);
25500 op1 = MASK_CP1(ctx->opcode);
25505 check_cp1_enabled(ctx);
25506 check_insn(ctx, ISA_MIPS32R2);
25512 check_cp1_enabled(ctx);
25513 gen_cp1(ctx, op1, rt, rd);
25515 #if defined(TARGET_MIPS64)
25518 check_cp1_enabled(ctx);
25519 check_insn(ctx, ISA_MIPS3);
25520 check_mips_64(ctx);
25521 gen_cp1(ctx, op1, rt, rd);
25524 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
25525 check_cp1_enabled(ctx);
25526 if (ctx->insn_flags & ISA_MIPS32R6) {
25528 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25533 check_insn(ctx, ASE_MIPS3D);
25534 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25535 (rt >> 2) & 0x7, imm << 2);
25539 check_cp1_enabled(ctx);
25540 check_insn(ctx, ISA_MIPS32R6);
25541 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25545 check_cp1_enabled(ctx);
25546 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25548 check_insn(ctx, ASE_MIPS3D);
25551 check_cp1_enabled(ctx);
25552 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25553 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25554 (rt >> 2) & 0x7, imm << 2);
25561 check_cp1_enabled(ctx);
25562 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25568 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
25569 check_cp1_enabled(ctx);
25570 if (ctx->insn_flags & ISA_MIPS32R6) {
25572 case R6_OPC_CMP_AF_S:
25573 case R6_OPC_CMP_UN_S:
25574 case R6_OPC_CMP_EQ_S:
25575 case R6_OPC_CMP_UEQ_S:
25576 case R6_OPC_CMP_LT_S:
25577 case R6_OPC_CMP_ULT_S:
25578 case R6_OPC_CMP_LE_S:
25579 case R6_OPC_CMP_ULE_S:
25580 case R6_OPC_CMP_SAF_S:
25581 case R6_OPC_CMP_SUN_S:
25582 case R6_OPC_CMP_SEQ_S:
25583 case R6_OPC_CMP_SEUQ_S:
25584 case R6_OPC_CMP_SLT_S:
25585 case R6_OPC_CMP_SULT_S:
25586 case R6_OPC_CMP_SLE_S:
25587 case R6_OPC_CMP_SULE_S:
25588 case R6_OPC_CMP_OR_S:
25589 case R6_OPC_CMP_UNE_S:
25590 case R6_OPC_CMP_NE_S:
25591 case R6_OPC_CMP_SOR_S:
25592 case R6_OPC_CMP_SUNE_S:
25593 case R6_OPC_CMP_SNE_S:
25594 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25596 case R6_OPC_CMP_AF_D:
25597 case R6_OPC_CMP_UN_D:
25598 case R6_OPC_CMP_EQ_D:
25599 case R6_OPC_CMP_UEQ_D:
25600 case R6_OPC_CMP_LT_D:
25601 case R6_OPC_CMP_ULT_D:
25602 case R6_OPC_CMP_LE_D:
25603 case R6_OPC_CMP_ULE_D:
25604 case R6_OPC_CMP_SAF_D:
25605 case R6_OPC_CMP_SUN_D:
25606 case R6_OPC_CMP_SEQ_D:
25607 case R6_OPC_CMP_SEUQ_D:
25608 case R6_OPC_CMP_SLT_D:
25609 case R6_OPC_CMP_SULT_D:
25610 case R6_OPC_CMP_SLE_D:
25611 case R6_OPC_CMP_SULE_D:
25612 case R6_OPC_CMP_OR_D:
25613 case R6_OPC_CMP_UNE_D:
25614 case R6_OPC_CMP_NE_D:
25615 case R6_OPC_CMP_SOR_D:
25616 case R6_OPC_CMP_SUNE_D:
25617 case R6_OPC_CMP_SNE_D:
25618 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25621 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
25622 rt, rd, sa, (imm >> 8) & 0x7);
25627 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25642 check_insn(ctx, ASE_MSA);
25643 gen_msa_branch(env, ctx, op1);
25647 generate_exception_end(ctx, EXCP_RI);
25652 /* Compact branches [R6] and COP2 [non-R6] */
25653 case OPC_BC: /* OPC_LWC2 */
25654 case OPC_BALC: /* OPC_SWC2 */
25655 if (ctx->insn_flags & ISA_MIPS32R6) {
25656 /* OPC_BC, OPC_BALC */
25657 gen_compute_compact_branch(ctx, op, 0, 0,
25658 sextract32(ctx->opcode << 2, 0, 28));
25660 /* OPC_LWC2, OPC_SWC2 */
25661 /* COP2: Not implemented. */
25662 generate_exception_err(ctx, EXCP_CpU, 2);
25665 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
25666 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
25667 if (ctx->insn_flags & ISA_MIPS32R6) {
25669 /* OPC_BEQZC, OPC_BNEZC */
25670 gen_compute_compact_branch(ctx, op, rs, 0,
25671 sextract32(ctx->opcode << 2, 0, 23));
25673 /* OPC_JIC, OPC_JIALC */
25674 gen_compute_compact_branch(ctx, op, 0, rt, imm);
25677 /* OPC_LWC2, OPC_SWC2 */
25678 /* COP2: Not implemented. */
25679 generate_exception_err(ctx, EXCP_CpU, 2);
25683 check_insn(ctx, INSN_LOONGSON2F);
25684 /* Note that these instructions use different fields. */
25685 gen_loongson_multimedia(ctx, sa, rd, rt);
25689 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25690 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
25691 check_cp1_enabled(ctx);
25692 op1 = MASK_CP3(ctx->opcode);
25696 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25702 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25703 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
25706 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25707 /* Treat as NOP. */
25710 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25724 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25725 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
25729 generate_exception_end(ctx, EXCP_RI);
25733 generate_exception_err(ctx, EXCP_CpU, 1);
25737 #if defined(TARGET_MIPS64)
25738 /* MIPS64 opcodes */
25742 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25746 check_insn(ctx, ISA_MIPS3);
25747 check_mips_64(ctx);
25748 gen_ld(ctx, op, rt, rs, imm);
25752 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25755 check_insn(ctx, ISA_MIPS3);
25756 check_mips_64(ctx);
25757 gen_st(ctx, op, rt, rs, imm);
25760 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25761 check_insn(ctx, ISA_MIPS3);
25762 check_mips_64(ctx);
25763 gen_st_cond(ctx, op, rt, rs, imm);
25765 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25766 if (ctx->insn_flags & ISA_MIPS32R6) {
25767 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25768 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25771 check_insn(ctx, ISA_MIPS3);
25772 check_mips_64(ctx);
25773 gen_arith_imm(ctx, op, rt, rs, imm);
25777 check_insn(ctx, ISA_MIPS3);
25778 check_mips_64(ctx);
25779 gen_arith_imm(ctx, op, rt, rs, imm);
25782 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
25783 if (ctx->insn_flags & ISA_MIPS32R6) {
25784 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25786 MIPS_INVAL("major opcode");
25787 generate_exception_end(ctx, EXCP_RI);
25791 case OPC_DAUI: /* OPC_JALX */
25792 if (ctx->insn_flags & ISA_MIPS32R6) {
25793 #if defined(TARGET_MIPS64)
25795 check_mips_64(ctx);
25797 generate_exception(ctx, EXCP_RI);
25798 } else if (rt != 0) {
25799 TCGv t0 = tcg_temp_new();
25800 gen_load_gpr(t0, rs);
25801 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
25805 generate_exception_end(ctx, EXCP_RI);
25806 MIPS_INVAL("major opcode");
25810 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
25811 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25812 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25815 case OPC_MSA: /* OPC_MDMX */
25816 /* MDMX: Not implemented. */
25820 check_insn(ctx, ISA_MIPS32R6);
25821 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
25823 default: /* Invalid */
25824 MIPS_INVAL("major opcode");
25825 generate_exception_end(ctx, EXCP_RI);
25830 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
25832 DisasContext *ctx = container_of(dcbase, DisasContext, base);
25833 CPUMIPSState *env = cs->env_ptr;
25835 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
25836 ctx->saved_pc = -1;
25837 ctx->insn_flags = env->insn_flags;
25838 ctx->CP0_Config1 = env->CP0_Config1;
25839 ctx->CP0_Config2 = env->CP0_Config2;
25840 ctx->CP0_Config3 = env->CP0_Config3;
25841 ctx->CP0_Config5 = env->CP0_Config5;
25843 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
25844 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
25845 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
25846 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
25847 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
25848 ctx->PAMask = env->PAMask;
25849 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
25850 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
25851 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
25852 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
25853 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
25854 /* Restore delay slot state from the tb context. */
25855 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
25856 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
25857 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
25858 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
25859 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
25860 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
25861 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
25862 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
25863 restore_cpu_state(env, ctx);
25864 #ifdef CONFIG_USER_ONLY
25865 ctx->mem_idx = MIPS_HFLAG_UM;
25867 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
25869 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
25870 MO_UNALN : MO_ALIGN;
25872 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
25876 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
25880 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
25882 DisasContext *ctx = container_of(dcbase, DisasContext, base);
25884 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
25888 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
25889 const CPUBreakpoint *bp)
25891 DisasContext *ctx = container_of(dcbase, DisasContext, base);
25893 save_cpu_state(ctx, 1);
25894 ctx->base.is_jmp = DISAS_NORETURN;
25895 gen_helper_raise_exception_debug(cpu_env);
25896 /* The address covered by the breakpoint must be included in
25897 [tb->pc, tb->pc + tb->size) in order to for it to be
25898 properly cleared -- thus we increment the PC here so that
25899 the logic setting tb->size below does the right thing. */
25900 ctx->base.pc_next += 4;
25904 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
25906 CPUMIPSState *env = cs->env_ptr;
25907 DisasContext *ctx = container_of(dcbase, DisasContext, base);
25911 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
25912 if (ctx->insn_flags & ISA_NANOMIPS32) {
25913 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
25914 insn_bytes = decode_nanomips_opc(env, ctx);
25915 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
25916 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
25918 decode_opc(env, ctx);
25919 } else if (ctx->insn_flags & ASE_MICROMIPS) {
25920 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
25921 insn_bytes = decode_micromips_opc(env, ctx);
25922 } else if (ctx->insn_flags & ASE_MIPS16) {
25923 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
25924 insn_bytes = decode_mips16_opc(env, ctx);
25926 generate_exception_end(ctx, EXCP_RI);
25927 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
25931 if (ctx->hflags & MIPS_HFLAG_BMASK) {
25932 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
25933 MIPS_HFLAG_FBNSLOT))) {
25934 /* force to generate branch as there is neither delay nor
25938 if ((ctx->hflags & MIPS_HFLAG_M16) &&
25939 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
25940 /* Force to generate branch as microMIPS R6 doesn't restrict
25941 branches in the forbidden slot. */
25946 gen_branch(ctx, insn_bytes);
25948 ctx->base.pc_next += insn_bytes;
25950 if (ctx->base.is_jmp != DISAS_NEXT) {
25953 /* Execute a branch and its delay slot as a single instruction.
25954 This is what GDB expects and is consistent with what the
25955 hardware does (e.g. if a delay slot instruction faults, the
25956 reported PC is the PC of the branch). */
25957 if (ctx->base.singlestep_enabled &&
25958 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
25959 ctx->base.is_jmp = DISAS_TOO_MANY;
25961 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
25962 ctx->base.is_jmp = DISAS_TOO_MANY;
25966 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
25968 DisasContext *ctx = container_of(dcbase, DisasContext, base);
25970 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
25971 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
25972 gen_helper_raise_exception_debug(cpu_env);
25974 switch (ctx->base.is_jmp) {
25976 gen_save_pc(ctx->base.pc_next);
25977 tcg_gen_lookup_and_goto_ptr();
25980 case DISAS_TOO_MANY:
25981 save_cpu_state(ctx, 0);
25982 gen_goto_tb(ctx, 0, ctx->base.pc_next);
25985 tcg_gen_exit_tb(NULL, 0);
25987 case DISAS_NORETURN:
25990 g_assert_not_reached();
25995 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
25997 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
25998 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
26001 static const TranslatorOps mips_tr_ops = {
26002 .init_disas_context = mips_tr_init_disas_context,
26003 .tb_start = mips_tr_tb_start,
26004 .insn_start = mips_tr_insn_start,
26005 .breakpoint_check = mips_tr_breakpoint_check,
26006 .translate_insn = mips_tr_translate_insn,
26007 .tb_stop = mips_tr_tb_stop,
26008 .disas_log = mips_tr_disas_log,
26011 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
26015 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
26018 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
26022 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
26024 #define printfpr(fp) \
26027 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
26028 " fd:%13g fs:%13g psu: %13g\n", \
26029 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
26030 (double)(fp)->fd, \
26031 (double)(fp)->fs[FP_ENDIAN_IDX], \
26032 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
26035 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
26036 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
26037 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
26038 " fd:%13g fs:%13g psu:%13g\n", \
26039 tmp.w[FP_ENDIAN_IDX], tmp.d, \
26041 (double)tmp.fs[FP_ENDIAN_IDX], \
26042 (double)tmp.fs[!FP_ENDIAN_IDX]); \
26047 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
26048 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
26049 get_float_exception_flags(&env->active_fpu.fp_status));
26050 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
26051 fpu_fprintf(f, "%3s: ", fregnames[i]);
26052 printfpr(&env->active_fpu.fpr[i]);
26058 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
26061 MIPSCPU *cpu = MIPS_CPU(cs);
26062 CPUMIPSState *env = &cpu->env;
26065 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
26066 " LO=0x" TARGET_FMT_lx " ds %04x "
26067 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
26068 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
26069 env->hflags, env->btarget, env->bcond);
26070 for (i = 0; i < 32; i++) {
26072 cpu_fprintf(f, "GPR%02d:", i);
26073 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
26075 cpu_fprintf(f, "\n");
26078 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
26079 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
26080 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
26082 env->CP0_Config0, env->CP0_Config1, env->lladdr);
26083 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
26084 env->CP0_Config2, env->CP0_Config3);
26085 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
26086 env->CP0_Config4, env->CP0_Config5);
26087 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
26088 fpu_dump_state(env, f, cpu_fprintf, flags);
26092 void mips_tcg_init(void)
26097 for (i = 1; i < 32; i++)
26098 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
26099 offsetof(CPUMIPSState, active_tc.gpr[i]),
26102 for (i = 0; i < 32; i++) {
26103 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
26105 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
26106 /* The scalar floating-point unit (FPU) registers are mapped on
26107 * the MSA vector registers. */
26108 fpu_f64[i] = msa_wr_d[i * 2];
26109 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
26110 msa_wr_d[i * 2 + 1] =
26111 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
26114 cpu_PC = tcg_global_mem_new(cpu_env,
26115 offsetof(CPUMIPSState, active_tc.PC), "PC");
26116 for (i = 0; i < MIPS_DSP_ACC; i++) {
26117 cpu_HI[i] = tcg_global_mem_new(cpu_env,
26118 offsetof(CPUMIPSState, active_tc.HI[i]),
26120 cpu_LO[i] = tcg_global_mem_new(cpu_env,
26121 offsetof(CPUMIPSState, active_tc.LO[i]),
26124 cpu_dspctrl = tcg_global_mem_new(cpu_env,
26125 offsetof(CPUMIPSState, active_tc.DSPControl),
26127 bcond = tcg_global_mem_new(cpu_env,
26128 offsetof(CPUMIPSState, bcond), "bcond");
26129 btarget = tcg_global_mem_new(cpu_env,
26130 offsetof(CPUMIPSState, btarget), "btarget");
26131 hflags = tcg_global_mem_new_i32(cpu_env,
26132 offsetof(CPUMIPSState, hflags), "hflags");
26134 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
26135 offsetof(CPUMIPSState, active_fpu.fcr0),
26137 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
26138 offsetof(CPUMIPSState, active_fpu.fcr31),
26142 #include "translate_init.inc.c"
26144 void cpu_mips_realize_env(CPUMIPSState *env)
26146 env->exception_base = (int32_t)0xBFC00000;
26148 #ifndef CONFIG_USER_ONLY
26149 mmu_init(env, env->cpu_model);
26151 fpu_init(env, env->cpu_model);
26152 mvp_init(env, env->cpu_model);
26155 bool cpu_supports_cps_smp(const char *cpu_type)
26157 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26158 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
26161 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
26163 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26164 return (mcc->cpu_def->insn_flags & isa) != 0;
26167 void cpu_set_exception_base(int vp_index, target_ulong address)
26169 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
26170 vp->env.exception_base = address;
26173 void cpu_state_reset(CPUMIPSState *env)
26175 MIPSCPU *cpu = mips_env_get_cpu(env);
26176 CPUState *cs = CPU(cpu);
26178 /* Reset registers to their default values */
26179 env->CP0_PRid = env->cpu_model->CP0_PRid;
26180 env->CP0_Config0 = env->cpu_model->CP0_Config0;
26181 #ifdef TARGET_WORDS_BIGENDIAN
26182 env->CP0_Config0 |= (1 << CP0C0_BE);
26184 env->CP0_Config1 = env->cpu_model->CP0_Config1;
26185 env->CP0_Config2 = env->cpu_model->CP0_Config2;
26186 env->CP0_Config3 = env->cpu_model->CP0_Config3;
26187 env->CP0_Config4 = env->cpu_model->CP0_Config4;
26188 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
26189 env->CP0_Config5 = env->cpu_model->CP0_Config5;
26190 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
26191 env->CP0_Config6 = env->cpu_model->CP0_Config6;
26192 env->CP0_Config7 = env->cpu_model->CP0_Config7;
26193 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
26194 << env->cpu_model->CP0_LLAddr_shift;
26195 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
26196 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
26197 env->CCRes = env->cpu_model->CCRes;
26198 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
26199 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
26200 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
26201 env->current_tc = 0;
26202 env->SEGBITS = env->cpu_model->SEGBITS;
26203 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
26204 #if defined(TARGET_MIPS64)
26205 if (env->cpu_model->insn_flags & ISA_MIPS3) {
26206 env->SEGMask |= 3ULL << 62;
26209 env->PABITS = env->cpu_model->PABITS;
26210 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
26211 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
26212 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
26213 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
26214 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
26215 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
26216 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
26217 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
26218 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
26219 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
26220 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
26221 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
26222 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
26223 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
26224 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
26225 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
26226 env->msair = env->cpu_model->MSAIR;
26227 env->insn_flags = env->cpu_model->insn_flags;
26229 #if defined(CONFIG_USER_ONLY)
26230 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
26231 # ifdef TARGET_MIPS64
26232 /* Enable 64-bit register mode. */
26233 env->CP0_Status |= (1 << CP0St_PX);
26235 # ifdef TARGET_ABI_MIPSN64
26236 /* Enable 64-bit address mode. */
26237 env->CP0_Status |= (1 << CP0St_UX);
26239 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
26240 hardware registers. */
26241 env->CP0_HWREna |= 0x0000000F;
26242 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
26243 env->CP0_Status |= (1 << CP0St_CU1);
26245 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
26246 env->CP0_Status |= (1 << CP0St_MX);
26248 # if defined(TARGET_MIPS64)
26249 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
26250 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
26251 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
26252 env->CP0_Status |= (1 << CP0St_FR);
26256 if (env->hflags & MIPS_HFLAG_BMASK) {
26257 /* If the exception was raised from a delay slot,
26258 come back to the jump. */
26259 env->CP0_ErrorEPC = (env->active_tc.PC
26260 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
26262 env->CP0_ErrorEPC = env->active_tc.PC;
26264 env->active_tc.PC = env->exception_base;
26265 env->CP0_Random = env->tlb->nb_tlb - 1;
26266 env->tlb->tlb_in_use = env->tlb->nb_tlb;
26267 env->CP0_Wired = 0;
26268 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
26269 env->CP0_EBase = (cs->cpu_index & 0x3FF);
26270 if (mips_um_ksegs_enabled()) {
26271 env->CP0_EBase |= 0x40000000;
26273 env->CP0_EBase |= (int32_t)0x80000000;
26275 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
26276 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
26278 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
26280 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
26281 /* vectored interrupts not implemented, timer on int 7,
26282 no performance counters. */
26283 env->CP0_IntCtl = 0xe0000000;
26287 for (i = 0; i < 7; i++) {
26288 env->CP0_WatchLo[i] = 0;
26289 env->CP0_WatchHi[i] = 0x80000000;
26291 env->CP0_WatchLo[7] = 0;
26292 env->CP0_WatchHi[7] = 0;
26294 /* Count register increments in debug mode, EJTAG version 1 */
26295 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
26297 cpu_mips_store_count(env, 1);
26299 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
26302 /* Only TC0 on VPE 0 starts as active. */
26303 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
26304 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
26305 env->tcs[i].CP0_TCHalt = 1;
26307 env->active_tc.CP0_TCHalt = 1;
26310 if (cs->cpu_index == 0) {
26311 /* VPE0 starts up enabled. */
26312 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
26313 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
26315 /* TC0 starts up unhalted. */
26317 env->active_tc.CP0_TCHalt = 0;
26318 env->tcs[0].CP0_TCHalt = 0;
26319 /* With thread 0 active. */
26320 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
26321 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
26326 * Configure default legacy segmentation control. We use this regardless of
26327 * whether segmentation control is presented to the guest.
26329 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
26330 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
26331 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
26332 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
26333 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
26334 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26336 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
26337 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26338 (3 << CP0SC_C)) << 16;
26339 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
26340 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26341 (1 << CP0SC_EU) | (2 << CP0SC_C);
26342 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
26343 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26344 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
26345 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
26346 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
26348 if ((env->insn_flags & ISA_MIPS32R6) &&
26349 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
26350 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
26351 env->CP0_Status |= (1 << CP0St_FR);
26354 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
26355 /* microMIPS on reset when Config3.ISA is 3 */
26356 env->hflags |= MIPS_HFLAG_M16;
26360 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
26364 compute_hflags(env);
26365 restore_fp_status(env);
26366 restore_pamask(env);
26367 cs->exception_index = EXCP_NONE;
26369 if (semihosting_get_argc()) {
26370 /* UHI interface can be used to obtain argc and argv */
26371 env->active_tc.gpr[4] = -1;
26375 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
26376 target_ulong *data)
26378 env->active_tc.PC = data[0];
26379 env->hflags &= ~MIPS_HFLAG_BMASK;
26380 env->hflags |= data[1];
26381 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
26382 case MIPS_HFLAG_BR:
26384 case MIPS_HFLAG_BC:
26385 case MIPS_HFLAG_BL:
26387 env->btarget = data[2];