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 * Overview of the TX79-specific instruction set
1932 * =============================================
1934 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1935 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1936 * instructions and certain multimedia instructions (MMIs). These MMIs
1937 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1938 * or sixteen 8-bit paths.
1942 * The Toshiba TX System RISC TX79 Core Architecture manual,
1943 * https://wiki.qemu.org/File:C790.pdf
1945 * Three-Operand Multiply and Multiply-Add (4 instructions)
1946 * --------------------------------------------------------
1947 * MADD [rd,] rs, rt Multiply/Add
1948 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1949 * MULT [rd,] rs, rt Multiply (3-operand)
1950 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1952 * Multiply Instructions for Pipeline 1 (10 instructions)
1953 * ------------------------------------------------------
1954 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1955 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1956 * DIV1 rs, rt Divide Pipeline 1
1957 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1958 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1959 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1960 * MFHI1 rd Move From HI1 Register
1961 * MFLO1 rd Move From LO1 Register
1962 * MTHI1 rs Move To HI1 Register
1963 * MTLO1 rs Move To LO1 Register
1965 * Arithmetic (19 instructions)
1966 * ----------------------------
1967 * PADDB rd, rs, rt Parallel Add Byte
1968 * PSUBB rd, rs, rt Parallel Subtract Byte
1969 * PADDH rd, rs, rt Parallel Add Halfword
1970 * PSUBH rd, rs, rt Parallel Subtract Halfword
1971 * PADDW rd, rs, rt Parallel Add Word
1972 * PSUBW rd, rs, rt Parallel Subtract Word
1973 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1974 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1975 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1976 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1977 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1978 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1979 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1980 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1981 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1982 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1983 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1984 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1985 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1987 * Min/Max (4 instructions)
1988 * ------------------------
1989 * PMAXH rd, rs, rt Parallel Maximum Halfword
1990 * PMINH rd, rs, rt Parallel Minimum Halfword
1991 * PMAXW rd, rs, rt Parallel Maximum Word
1992 * PMINW rd, rs, rt Parallel Minimum Word
1994 * Absolute (2 instructions)
1995 * -------------------------
1996 * PABSH rd, rt Parallel Absolute Halfword
1997 * PABSW rd, rt Parallel Absolute Word
1999 * Logical (4 instructions)
2000 * ------------------------
2001 * PAND rd, rs, rt Parallel AND
2002 * POR rd, rs, rt Parallel OR
2003 * PXOR rd, rs, rt Parallel XOR
2004 * PNOR rd, rs, rt Parallel NOR
2006 * Shift (9 instructions)
2007 * ----------------------
2008 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2009 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2010 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2011 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2012 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2013 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2014 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2015 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2016 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2018 * Compare (6 instructions)
2019 * ------------------------
2020 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2021 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2022 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2023 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2024 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2025 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2027 * LZC (1 instruction)
2028 * -------------------
2029 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2031 * Quadword Load and Store (2 instructions)
2032 * ----------------------------------------
2033 * LQ rt, offset(base) Load Quadword
2034 * SQ rt, offset(base) Store Quadword
2036 * Multiply and Divide (19 instructions)
2037 * -------------------------------------
2038 * PMULTW rd, rs, rt Parallel Multiply Word
2039 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2040 * PDIVW rs, rt Parallel Divide Word
2041 * PDIVUW rs, rt Parallel Divide Unsigned Word
2042 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2043 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2044 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2045 * PMULTH rd, rs, rt Parallel Multiply Halfword
2046 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2047 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2048 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2049 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2050 * PDIVBW rs, rt Parallel Divide Broadcast Word
2051 * PMFHI rd Parallel Move From HI Register
2052 * PMFLO rd Parallel Move From LO Register
2053 * PMTHI rs Parallel Move To HI Register
2054 * PMTLO rs Parallel Move To LO Register
2055 * PMFHL rd Parallel Move From HI/LO Register
2056 * PMTHL rs Parallel Move To HI/LO Register
2058 * Pack/Extend (11 instructions)
2059 * -----------------------------
2060 * PPAC5 rd, rt Parallel Pack to 5 bits
2061 * PPACB rd, rs, rt Parallel Pack to Byte
2062 * PPACH rd, rs, rt Parallel Pack to Halfword
2063 * PPACW rd, rs, rt Parallel Pack to Word
2064 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2065 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2066 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2067 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2068 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2069 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2070 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2072 * Others (16 instructions)
2073 * ------------------------
2074 * PCPYH rd, rt Parallel Copy Halfword
2075 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2076 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2077 * PREVH rd, rt Parallel Reverse Halfword
2078 * PINTH rd, rs, rt Parallel Interleave Halfword
2079 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2080 * PEXEH rd, rt Parallel Exchange Even Halfword
2081 * PEXCH rd, rt Parallel Exchange Center Halfword
2082 * PEXEW rd, rt Parallel Exchange Even Word
2083 * PEXCW rd, rt Parallel Exchange Center Word
2084 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2085 * MFSA rd Move from Shift Amount Register
2086 * MTSA rs Move to Shift Amount Register
2087 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2088 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2089 * PROT3W rd, rt Parallel Rotate 3 Words
2091 * The TX79-specific Multimedia Instruction encodings
2092 * ==================================================
2094 * TX79 Multimedia Instruction encoding table keys:
2096 * * This code is reserved for future use. An attempt to execute it
2097 * causes a Reserved Instruction exception.
2098 * % This code indicates an instruction class. The instruction word
2099 * must be further decoded by examining additional tables that show
2100 * the values for other instruction fields.
2101 * # This code is reserved for the unsupported instructions DMULT,
2102 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2103 * to execute it causes a Reserved Instruction exception.
2105 * TX79 Multimedia Instructions encoded by opcode field (MMI, LQ, SQ):
2108 * +--------+----------------------------------------+
2110 * +--------+----------------------------------------+
2112 * opcode bits 28..26
2113 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2114 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2115 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2116 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2117 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2118 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2119 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2120 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2121 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2122 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2123 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2127 TX79_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2128 TX79_LQ = 0x1E << 26, /* Same as OPC_MSA */
2129 TX79_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
2133 * TX79 Multimedia Instructions with opcode field = MMI:
2136 * +--------+-------------------------------+--------+
2137 * | MMI | |function|
2138 * +--------+-------------------------------+--------+
2140 * function bits 2..0
2141 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2142 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2143 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2144 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2145 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2146 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2147 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2148 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2149 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2150 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2151 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2154 #define MASK_TX79_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2156 TX79_MMI_MADD = 0x00 | TX79_CLASS_MMI, /* Same as OPC_MADD */
2157 TX79_MMI_MADDU = 0x01 | TX79_CLASS_MMI, /* Same as OPC_MADDU */
2158 TX79_MMI_PLZCW = 0x04 | TX79_CLASS_MMI,
2159 TX79_MMI_CLASS_MMI0 = 0x08 | TX79_CLASS_MMI,
2160 TX79_MMI_CLASS_MMI2 = 0x09 | TX79_CLASS_MMI,
2161 TX79_MMI_MFHI1 = 0x10 | TX79_CLASS_MMI, /* Same minor as OPC_MFHI */
2162 TX79_MMI_MTHI1 = 0x11 | TX79_CLASS_MMI, /* Same minor as OPC_MTHI */
2163 TX79_MMI_MFLO1 = 0x12 | TX79_CLASS_MMI, /* Same minor as OPC_MFLO */
2164 TX79_MMI_MTLO1 = 0x13 | TX79_CLASS_MMI, /* Same minor as OPC_MTLO */
2165 TX79_MMI_MULT1 = 0x18 | TX79_CLASS_MMI, /* Same minor as OPC_MULT */
2166 TX79_MMI_MULTU1 = 0x19 | TX79_CLASS_MMI, /* Same minor as OPC_MULTU */
2167 TX79_MMI_DIV1 = 0x1A | TX79_CLASS_MMI, /* Same minor as OPC_DIV */
2168 TX79_MMI_DIVU1 = 0x1B | TX79_CLASS_MMI, /* Same minor as OPC_DIVU */
2169 TX79_MMI_MADD1 = 0x20 | TX79_CLASS_MMI,
2170 TX79_MMI_MADDU1 = 0x21 | TX79_CLASS_MMI,
2171 TX79_MMI_CLASS_MMI1 = 0x28 | TX79_CLASS_MMI,
2172 TX79_MMI_CLASS_MMI3 = 0x29 | TX79_CLASS_MMI,
2173 TX79_MMI_PMFHL = 0x30 | TX79_CLASS_MMI,
2174 TX79_MMI_PMTHL = 0x31 | TX79_CLASS_MMI,
2175 TX79_MMI_PSLLH = 0x34 | TX79_CLASS_MMI,
2176 TX79_MMI_PSRLH = 0x36 | TX79_CLASS_MMI,
2177 TX79_MMI_PSRAH = 0x37 | TX79_CLASS_MMI,
2178 TX79_MMI_PSLLW = 0x3C | TX79_CLASS_MMI,
2179 TX79_MMI_PSRLW = 0x3E | TX79_CLASS_MMI,
2180 TX79_MMI_PSRAW = 0x3F | TX79_CLASS_MMI,
2184 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI0:
2187 * +--------+----------------------+--------+--------+
2188 * | MMI | |function| MMI0 |
2189 * +--------+----------------------+--------+--------+
2191 * function bits 7..6
2192 * bits | 0 | 1 | 2 | 3
2193 * 10..8 | 00 | 01 | 10 | 11
2194 * -------+-------+-------+-------+-------
2195 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2196 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2197 * 2 010 | PADDB | PSUBB | PCGTB | *
2198 * 3 011 | * | * | * | *
2199 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2200 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2201 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2202 * 7 111 | * | * | PEXT5 | PPAC5
2205 #define MASK_TX79_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2207 TX79_MMI0_PADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI0,
2208 TX79_MMI0_PSUBW = (0x01 << 6) | TX79_MMI_CLASS_MMI0,
2209 TX79_MMI0_PCGTW = (0x02 << 6) | TX79_MMI_CLASS_MMI0,
2210 TX79_MMI0_PMAXW = (0x03 << 6) | TX79_MMI_CLASS_MMI0,
2211 TX79_MMI0_PADDH = (0x04 << 6) | TX79_MMI_CLASS_MMI0,
2212 TX79_MMI0_PSUBH = (0x05 << 6) | TX79_MMI_CLASS_MMI0,
2213 TX79_MMI0_PCGTH = (0x06 << 6) | TX79_MMI_CLASS_MMI0,
2214 TX79_MMI0_PMAXH = (0x07 << 6) | TX79_MMI_CLASS_MMI0,
2215 TX79_MMI0_PADDB = (0x08 << 6) | TX79_MMI_CLASS_MMI0,
2216 TX79_MMI0_PSUBB = (0x09 << 6) | TX79_MMI_CLASS_MMI0,
2217 TX79_MMI0_PCGTB = (0x0A << 6) | TX79_MMI_CLASS_MMI0,
2218 TX79_MMI0_PADDSW = (0x10 << 6) | TX79_MMI_CLASS_MMI0,
2219 TX79_MMI0_PSUBSW = (0x11 << 6) | TX79_MMI_CLASS_MMI0,
2220 TX79_MMI0_PEXTLW = (0x12 << 6) | TX79_MMI_CLASS_MMI0,
2221 TX79_MMI0_PPACW = (0x13 << 6) | TX79_MMI_CLASS_MMI0,
2222 TX79_MMI0_PADDSH = (0x14 << 6) | TX79_MMI_CLASS_MMI0,
2223 TX79_MMI0_PSUBSH = (0x15 << 6) | TX79_MMI_CLASS_MMI0,
2224 TX79_MMI0_PEXTLH = (0x16 << 6) | TX79_MMI_CLASS_MMI0,
2225 TX79_MMI0_PPACH = (0x17 << 6) | TX79_MMI_CLASS_MMI0,
2226 TX79_MMI0_PADDSB = (0x18 << 6) | TX79_MMI_CLASS_MMI0,
2227 TX79_MMI0_PSUBSB = (0x19 << 6) | TX79_MMI_CLASS_MMI0,
2228 TX79_MMI0_PEXTLB = (0x1A << 6) | TX79_MMI_CLASS_MMI0,
2229 TX79_MMI0_PPACB = (0x1B << 6) | TX79_MMI_CLASS_MMI0,
2230 TX79_MMI0_PEXT5 = (0x1E << 6) | TX79_MMI_CLASS_MMI0,
2231 TX79_MMI0_PPAC5 = (0x1F << 6) | TX79_MMI_CLASS_MMI0,
2235 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI1:
2238 * +--------+----------------------+--------+--------+
2239 * | MMI | |function| MMI1 |
2240 * +--------+----------------------+--------+--------+
2242 * function bits 7..6
2243 * bits | 0 | 1 | 2 | 3
2244 * 10..8 | 00 | 01 | 10 | 11
2245 * -------+-------+-------+-------+-------
2246 * 0 000 | * | PABSW | PCEQW | PMINW
2247 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2248 * 2 010 | * | * | PCEQB | *
2249 * 3 011 | * | * | * | *
2250 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2251 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2252 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2253 * 7 111 | * | * | * | *
2256 #define MASK_TX79_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2258 TX79_MMI1_PABSW = (0x01 << 6) | TX79_MMI_CLASS_MMI1,
2259 TX79_MMI1_PCEQW = (0x02 << 6) | TX79_MMI_CLASS_MMI1,
2260 TX79_MMI1_PMINW = (0x03 << 6) | TX79_MMI_CLASS_MMI1,
2261 TX79_MMI1_PADSBH = (0x04 << 6) | TX79_MMI_CLASS_MMI1,
2262 TX79_MMI1_PABSH = (0x05 << 6) | TX79_MMI_CLASS_MMI1,
2263 TX79_MMI1_PCEQH = (0x06 << 6) | TX79_MMI_CLASS_MMI1,
2264 TX79_MMI1_PMINH = (0x07 << 6) | TX79_MMI_CLASS_MMI1,
2265 TX79_MMI1_PCEQB = (0x0A << 6) | TX79_MMI_CLASS_MMI1,
2266 TX79_MMI1_PADDUW = (0x10 << 6) | TX79_MMI_CLASS_MMI1,
2267 TX79_MMI1_PSUBUW = (0x11 << 6) | TX79_MMI_CLASS_MMI1,
2268 TX79_MMI1_PEXTUW = (0x12 << 6) | TX79_MMI_CLASS_MMI1,
2269 TX79_MMI1_PADDUH = (0x14 << 6) | TX79_MMI_CLASS_MMI1,
2270 TX79_MMI1_PSUBUH = (0x15 << 6) | TX79_MMI_CLASS_MMI1,
2271 TX79_MMI1_PEXTUH = (0x16 << 6) | TX79_MMI_CLASS_MMI1,
2272 TX79_MMI1_PADDUB = (0x18 << 6) | TX79_MMI_CLASS_MMI1,
2273 TX79_MMI1_PSUBUB = (0x19 << 6) | TX79_MMI_CLASS_MMI1,
2274 TX79_MMI1_PEXTUB = (0x1A << 6) | TX79_MMI_CLASS_MMI1,
2275 TX79_MMI1_QFSRV = (0x1B << 6) | TX79_MMI_CLASS_MMI1,
2279 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI2:
2282 * +--------+----------------------+--------+--------+
2283 * | MMI | |function| MMI2 |
2284 * +--------+----------------------+--------+--------+
2286 * function bits 7..6
2287 * bits | 0 | 1 | 2 | 3
2288 * 10..8 | 00 | 01 | 10 | 11
2289 * -------+-------+-------+-------+-------
2290 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2291 * 1 001 | PMSUBW| * | * | *
2292 * 2 010 | PMFHI | PMFLO | PINTH | *
2293 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2294 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2295 * 5 101 | PMSUBH| PHMSBH| * | *
2296 * 6 110 | * | * | PEXEH | PREVH
2297 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2300 #define MASK_TX79_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2302 TX79_MMI2_PMADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI2,
2303 TX79_MMI2_PSLLVW = (0x02 << 6) | TX79_MMI_CLASS_MMI2,
2304 TX79_MMI2_PSRLVW = (0x03 << 6) | TX79_MMI_CLASS_MMI2,
2305 TX79_MMI2_PMSUBW = (0x04 << 6) | TX79_MMI_CLASS_MMI2,
2306 TX79_MMI2_PMFHI = (0x08 << 6) | TX79_MMI_CLASS_MMI2,
2307 TX79_MMI2_PMFLO = (0x09 << 6) | TX79_MMI_CLASS_MMI2,
2308 TX79_MMI2_PINTH = (0x0A << 6) | TX79_MMI_CLASS_MMI2,
2309 TX79_MMI2_PMULTW = (0x0C << 6) | TX79_MMI_CLASS_MMI2,
2310 TX79_MMI2_PDIVW = (0x0D << 6) | TX79_MMI_CLASS_MMI2,
2311 TX79_MMI2_PCPYLD = (0x0E << 6) | TX79_MMI_CLASS_MMI2,
2312 TX79_MMI2_PMADDH = (0x10 << 6) | TX79_MMI_CLASS_MMI2,
2313 TX79_MMI2_PHMADH = (0x11 << 6) | TX79_MMI_CLASS_MMI2,
2314 TX79_MMI2_PAND = (0x12 << 6) | TX79_MMI_CLASS_MMI2,
2315 TX79_MMI2_PXOR = (0x13 << 6) | TX79_MMI_CLASS_MMI2,
2316 TX79_MMI2_PMSUBH = (0x14 << 6) | TX79_MMI_CLASS_MMI2,
2317 TX79_MMI2_PHMSBH = (0x15 << 6) | TX79_MMI_CLASS_MMI2,
2318 TX79_MMI2_PEXEH = (0x1A << 6) | TX79_MMI_CLASS_MMI2,
2319 TX79_MMI2_PREVH = (0x1B << 6) | TX79_MMI_CLASS_MMI2,
2320 TX79_MMI2_PMULTH = (0x1C << 6) | TX79_MMI_CLASS_MMI2,
2321 TX79_MMI2_PDIVBW = (0x1D << 6) | TX79_MMI_CLASS_MMI2,
2322 TX79_MMI2_PEXEW = (0x1E << 6) | TX79_MMI_CLASS_MMI2,
2323 TX79_MMI2_PROT3W = (0x1F << 6) | TX79_MMI_CLASS_MMI2,
2327 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI3:
2330 * +--------+----------------------+--------+--------+
2331 * | MMI | |function| MMI3 |
2332 * +--------+----------------------+--------+--------+
2334 * function bits 7..6
2335 * bits | 0 | 1 | 2 | 3
2336 * 10..8 | 00 | 01 | 10 | 11
2337 * -------+-------+-------+-------+-------
2338 * 0 000 |PMADDUW| * | * | PSRAVW
2339 * 1 001 | * | * | * | *
2340 * 2 010 | PMTHI | PMTLO | PINTEH| *
2341 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2342 * 4 100 | * | * | POR | PNOR
2343 * 5 101 | * | * | * | *
2344 * 6 110 | * | * | PEXCH | PCPYH
2345 * 7 111 | * | * | PEXCW | *
2348 #define MASK_TX79_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2350 TX79_MMI3_PMADDUW = (0x00 << 6) | TX79_MMI_CLASS_MMI3,
2351 TX79_MMI3_PSRAVW = (0x03 << 6) | TX79_MMI_CLASS_MMI3,
2352 TX79_MMI3_PMTHI = (0x08 << 6) | TX79_MMI_CLASS_MMI3,
2353 TX79_MMI3_PMTLO = (0x09 << 6) | TX79_MMI_CLASS_MMI3,
2354 TX79_MMI3_PINTEH = (0x0A << 6) | TX79_MMI_CLASS_MMI3,
2355 TX79_MMI3_PMULTUW = (0x0C << 6) | TX79_MMI_CLASS_MMI3,
2356 TX79_MMI3_PDIVUW = (0x0D << 6) | TX79_MMI_CLASS_MMI3,
2357 TX79_MMI3_PCPYUD = (0x0E << 6) | TX79_MMI_CLASS_MMI3,
2358 TX79_MMI3_POR = (0x12 << 6) | TX79_MMI_CLASS_MMI3,
2359 TX79_MMI3_PNOR = (0x13 << 6) | TX79_MMI_CLASS_MMI3,
2360 TX79_MMI3_PEXCH = (0x1A << 6) | TX79_MMI_CLASS_MMI3,
2361 TX79_MMI3_PCPYH = (0x1B << 6) | TX79_MMI_CLASS_MMI3,
2362 TX79_MMI3_PEXCW = (0x1E << 6) | TX79_MMI_CLASS_MMI3,
2365 /* global register indices */
2366 static TCGv cpu_gpr[32], cpu_PC;
2367 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2368 static TCGv cpu_dspctrl, btarget, bcond;
2369 static TCGv_i32 hflags;
2370 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2371 static TCGv_i64 fpu_f64[32];
2372 static TCGv_i64 msa_wr_d[64];
2374 #include "exec/gen-icount.h"
2376 #define gen_helper_0e0i(name, arg) do { \
2377 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2378 gen_helper_##name(cpu_env, helper_tmp); \
2379 tcg_temp_free_i32(helper_tmp); \
2382 #define gen_helper_0e1i(name, arg1, arg2) do { \
2383 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2384 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2385 tcg_temp_free_i32(helper_tmp); \
2388 #define gen_helper_1e0i(name, ret, arg1) do { \
2389 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2390 gen_helper_##name(ret, cpu_env, helper_tmp); \
2391 tcg_temp_free_i32(helper_tmp); \
2394 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2395 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2396 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2397 tcg_temp_free_i32(helper_tmp); \
2400 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2401 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2402 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2403 tcg_temp_free_i32(helper_tmp); \
2406 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2407 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2408 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2409 tcg_temp_free_i32(helper_tmp); \
2412 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2413 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2414 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2415 tcg_temp_free_i32(helper_tmp); \
2418 typedef struct DisasContext {
2419 DisasContextBase base;
2420 target_ulong saved_pc;
2421 target_ulong page_start;
2423 uint64_t insn_flags;
2424 int32_t CP0_Config1;
2425 int32_t CP0_Config2;
2426 int32_t CP0_Config3;
2427 int32_t CP0_Config5;
2428 /* Routine used to access memory */
2430 TCGMemOp default_tcg_memop_mask;
2431 uint32_t hflags, saved_hflags;
2432 target_ulong btarget;
2443 int CP0_LLAddr_shift;
2452 #define DISAS_STOP DISAS_TARGET_0
2453 #define DISAS_EXIT DISAS_TARGET_1
2455 static const char * const regnames[] = {
2456 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2457 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2458 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2459 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2462 static const char * const regnames_HI[] = {
2463 "HI0", "HI1", "HI2", "HI3",
2466 static const char * const regnames_LO[] = {
2467 "LO0", "LO1", "LO2", "LO3",
2470 static const char * const fregnames[] = {
2471 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2472 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2473 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2474 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2477 static const char * const msaregnames[] = {
2478 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2479 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2480 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2481 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2482 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2483 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2484 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2485 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2486 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2487 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2488 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2489 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2490 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2491 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2492 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2493 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2496 #define LOG_DISAS(...) \
2498 if (MIPS_DEBUG_DISAS) { \
2499 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2503 #define MIPS_INVAL(op) \
2505 if (MIPS_DEBUG_DISAS) { \
2506 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2507 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2508 ctx->base.pc_next, ctx->opcode, op, \
2509 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2510 ((ctx->opcode >> 16) & 0x1F)); \
2514 /* General purpose registers moves. */
2515 static inline void gen_load_gpr (TCGv t, int reg)
2518 tcg_gen_movi_tl(t, 0);
2520 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2523 static inline void gen_store_gpr (TCGv t, int reg)
2526 tcg_gen_mov_tl(cpu_gpr[reg], t);
2529 /* Moves to/from shadow registers. */
2530 static inline void gen_load_srsgpr (int from, int to)
2532 TCGv t0 = tcg_temp_new();
2535 tcg_gen_movi_tl(t0, 0);
2537 TCGv_i32 t2 = tcg_temp_new_i32();
2538 TCGv_ptr addr = tcg_temp_new_ptr();
2540 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2541 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2542 tcg_gen_andi_i32(t2, t2, 0xf);
2543 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2544 tcg_gen_ext_i32_ptr(addr, t2);
2545 tcg_gen_add_ptr(addr, cpu_env, addr);
2547 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2548 tcg_temp_free_ptr(addr);
2549 tcg_temp_free_i32(t2);
2551 gen_store_gpr(t0, to);
2555 static inline void gen_store_srsgpr (int from, int to)
2558 TCGv t0 = tcg_temp_new();
2559 TCGv_i32 t2 = tcg_temp_new_i32();
2560 TCGv_ptr addr = tcg_temp_new_ptr();
2562 gen_load_gpr(t0, from);
2563 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2564 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2565 tcg_gen_andi_i32(t2, t2, 0xf);
2566 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2567 tcg_gen_ext_i32_ptr(addr, t2);
2568 tcg_gen_add_ptr(addr, cpu_env, addr);
2570 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2571 tcg_temp_free_ptr(addr);
2572 tcg_temp_free_i32(t2);
2578 static inline void gen_save_pc(target_ulong pc)
2580 tcg_gen_movi_tl(cpu_PC, pc);
2583 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2585 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2586 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2587 gen_save_pc(ctx->base.pc_next);
2588 ctx->saved_pc = ctx->base.pc_next;
2590 if (ctx->hflags != ctx->saved_hflags) {
2591 tcg_gen_movi_i32(hflags, ctx->hflags);
2592 ctx->saved_hflags = ctx->hflags;
2593 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2599 tcg_gen_movi_tl(btarget, ctx->btarget);
2605 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2607 ctx->saved_hflags = ctx->hflags;
2608 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2614 ctx->btarget = env->btarget;
2619 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2621 TCGv_i32 texcp = tcg_const_i32(excp);
2622 TCGv_i32 terr = tcg_const_i32(err);
2623 save_cpu_state(ctx, 1);
2624 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2625 tcg_temp_free_i32(terr);
2626 tcg_temp_free_i32(texcp);
2627 ctx->base.is_jmp = DISAS_NORETURN;
2630 static inline void generate_exception(DisasContext *ctx, int excp)
2632 gen_helper_0e0i(raise_exception, excp);
2635 static inline void generate_exception_end(DisasContext *ctx, int excp)
2637 generate_exception_err(ctx, excp, 0);
2640 /* Floating point register moves. */
2641 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2643 if (ctx->hflags & MIPS_HFLAG_FRE) {
2644 generate_exception(ctx, EXCP_RI);
2646 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2649 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2652 if (ctx->hflags & MIPS_HFLAG_FRE) {
2653 generate_exception(ctx, EXCP_RI);
2655 t64 = tcg_temp_new_i64();
2656 tcg_gen_extu_i32_i64(t64, t);
2657 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2658 tcg_temp_free_i64(t64);
2661 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2663 if (ctx->hflags & MIPS_HFLAG_F64) {
2664 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2666 gen_load_fpr32(ctx, t, reg | 1);
2670 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2672 if (ctx->hflags & MIPS_HFLAG_F64) {
2673 TCGv_i64 t64 = tcg_temp_new_i64();
2674 tcg_gen_extu_i32_i64(t64, t);
2675 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2676 tcg_temp_free_i64(t64);
2678 gen_store_fpr32(ctx, t, reg | 1);
2682 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2684 if (ctx->hflags & MIPS_HFLAG_F64) {
2685 tcg_gen_mov_i64(t, fpu_f64[reg]);
2687 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2691 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2693 if (ctx->hflags & MIPS_HFLAG_F64) {
2694 tcg_gen_mov_i64(fpu_f64[reg], t);
2697 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2698 t0 = tcg_temp_new_i64();
2699 tcg_gen_shri_i64(t0, t, 32);
2700 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2701 tcg_temp_free_i64(t0);
2705 static inline int get_fp_bit (int cc)
2713 /* Addresses computation */
2714 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2716 tcg_gen_add_tl(ret, arg0, arg1);
2718 #if defined(TARGET_MIPS64)
2719 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2720 tcg_gen_ext32s_i64(ret, ret);
2725 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2728 tcg_gen_addi_tl(ret, base, ofs);
2730 #if defined(TARGET_MIPS64)
2731 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2732 tcg_gen_ext32s_i64(ret, ret);
2737 /* Addresses computation (translation time) */
2738 static target_long addr_add(DisasContext *ctx, target_long base,
2741 target_long sum = base + offset;
2743 #if defined(TARGET_MIPS64)
2744 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2751 /* Sign-extract the low 32-bits to a target_long. */
2752 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2754 #if defined(TARGET_MIPS64)
2755 tcg_gen_ext32s_i64(ret, arg);
2757 tcg_gen_extrl_i64_i32(ret, arg);
2761 /* Sign-extract the high 32-bits to a target_long. */
2762 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2764 #if defined(TARGET_MIPS64)
2765 tcg_gen_sari_i64(ret, arg, 32);
2767 tcg_gen_extrh_i64_i32(ret, arg);
2771 static inline void check_cp0_enabled(DisasContext *ctx)
2773 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2774 generate_exception_err(ctx, EXCP_CpU, 0);
2777 static inline void check_cp1_enabled(DisasContext *ctx)
2779 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2780 generate_exception_err(ctx, EXCP_CpU, 1);
2783 /* Verify that the processor is running with COP1X instructions enabled.
2784 This is associated with the nabla symbol in the MIPS32 and MIPS64
2787 static inline void check_cop1x(DisasContext *ctx)
2789 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2790 generate_exception_end(ctx, EXCP_RI);
2793 /* Verify that the processor is running with 64-bit floating-point
2794 operations enabled. */
2796 static inline void check_cp1_64bitmode(DisasContext *ctx)
2798 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2799 generate_exception_end(ctx, EXCP_RI);
2803 * Verify if floating point register is valid; an operation is not defined
2804 * if bit 0 of any register specification is set and the FR bit in the
2805 * Status register equals zero, since the register numbers specify an
2806 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2807 * in the Status register equals one, both even and odd register numbers
2808 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2810 * Multiple 64 bit wide registers can be checked by calling
2811 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2813 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2815 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2816 generate_exception_end(ctx, EXCP_RI);
2819 /* Verify that the processor is running with DSP instructions enabled.
2820 This is enabled by CP0 Status register MX(24) bit.
2823 static inline void check_dsp(DisasContext *ctx)
2825 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2826 if (ctx->insn_flags & ASE_DSP) {
2827 generate_exception_end(ctx, EXCP_DSPDIS);
2829 generate_exception_end(ctx, EXCP_RI);
2834 static inline void check_dsp_r2(DisasContext *ctx)
2836 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2837 if (ctx->insn_flags & ASE_DSP) {
2838 generate_exception_end(ctx, EXCP_DSPDIS);
2840 generate_exception_end(ctx, EXCP_RI);
2845 static inline void check_dsp_r3(DisasContext *ctx)
2847 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2848 if (ctx->insn_flags & ASE_DSP) {
2849 generate_exception_end(ctx, EXCP_DSPDIS);
2851 generate_exception_end(ctx, EXCP_RI);
2856 /* This code generates a "reserved instruction" exception if the
2857 CPU does not support the instruction set corresponding to flags. */
2858 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2860 if (unlikely(!(ctx->insn_flags & flags))) {
2861 generate_exception_end(ctx, EXCP_RI);
2865 /* This code generates a "reserved instruction" exception if the
2866 CPU has corresponding flag set which indicates that the instruction
2867 has been removed. */
2868 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2870 if (unlikely(ctx->insn_flags & flags)) {
2871 generate_exception_end(ctx, EXCP_RI);
2875 /* This code generates a "reserved instruction" exception if the
2876 CPU does not support 64-bit paired-single (PS) floating point data type */
2877 static inline void check_ps(DisasContext *ctx)
2879 if (unlikely(!ctx->ps)) {
2880 generate_exception(ctx, EXCP_RI);
2882 check_cp1_64bitmode(ctx);
2885 #ifdef TARGET_MIPS64
2886 /* This code generates a "reserved instruction" exception if 64-bit
2887 instructions are not enabled. */
2888 static inline void check_mips_64(DisasContext *ctx)
2890 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
2891 generate_exception_end(ctx, EXCP_RI);
2895 #ifndef CONFIG_USER_ONLY
2896 static inline void check_mvh(DisasContext *ctx)
2898 if (unlikely(!ctx->mvh)) {
2899 generate_exception(ctx, EXCP_RI);
2905 * This code generates a "reserved instruction" exception if the
2906 * Config5 XNP bit is set.
2908 static inline void check_xnp(DisasContext *ctx)
2910 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2911 generate_exception_end(ctx, EXCP_RI);
2915 #ifndef CONFIG_USER_ONLY
2917 * This code generates a "reserved instruction" exception if the
2918 * Config3 PW bit is NOT set.
2920 static inline void check_pw(DisasContext *ctx)
2922 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
2923 generate_exception_end(ctx, EXCP_RI);
2929 * This code generates a "reserved instruction" exception if the
2930 * Config3 MT bit is NOT set.
2932 static inline void check_mt(DisasContext *ctx)
2934 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2935 generate_exception_end(ctx, EXCP_RI);
2939 #ifndef CONFIG_USER_ONLY
2941 * This code generates a "coprocessor unusable" exception if CP0 is not
2942 * available, and, if that is not the case, generates a "reserved instruction"
2943 * exception if the Config5 MT bit is NOT set. This is needed for availability
2944 * control of some of MT ASE instructions.
2946 static inline void check_cp0_mt(DisasContext *ctx)
2948 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2949 generate_exception_err(ctx, EXCP_CpU, 0);
2951 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2952 generate_exception_err(ctx, EXCP_RI, 0);
2959 * This code generates a "reserved instruction" exception if the
2960 * Config5 NMS bit is set.
2962 static inline void check_nms(DisasContext *ctx)
2964 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2965 generate_exception_end(ctx, EXCP_RI);
2970 /* Define small wrappers for gen_load_fpr* so that we have a uniform
2971 calling interface for 32 and 64-bit FPRs. No sense in changing
2972 all callers for gen_load_fpr32 when we need the CTX parameter for
2974 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2975 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2976 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2977 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2978 int ft, int fs, int cc) \
2980 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
2981 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
2990 check_cp1_registers(ctx, fs | ft); \
2998 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
2999 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3001 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3002 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3003 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3004 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3005 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3006 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3007 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3008 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3009 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3010 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3011 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3012 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3013 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3014 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3015 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3016 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
3019 tcg_temp_free_i##bits (fp0); \
3020 tcg_temp_free_i##bits (fp1); \
3023 FOP_CONDS(, 0, d, FMT_D, 64)
3024 FOP_CONDS(abs, 1, d, FMT_D, 64)
3025 FOP_CONDS(, 0, s, FMT_S, 32)
3026 FOP_CONDS(abs, 1, s, FMT_S, 32)
3027 FOP_CONDS(, 0, ps, FMT_PS, 64)
3028 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3031 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3032 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3033 int ft, int fs, int fd) \
3035 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3036 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3037 if (ifmt == FMT_D) { \
3038 check_cp1_registers(ctx, fs | ft | fd); \
3040 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3041 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3044 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3047 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3050 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3053 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3056 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3059 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3062 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3065 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3068 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3071 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3074 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3077 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3080 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3083 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3086 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3089 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3092 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3095 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3098 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3101 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3104 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3107 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3113 tcg_temp_free_i ## bits (fp0); \
3114 tcg_temp_free_i ## bits (fp1); \
3117 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3118 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3120 #undef gen_ldcmp_fpr32
3121 #undef gen_ldcmp_fpr64
3123 /* load/store instructions. */
3124 #ifdef CONFIG_USER_ONLY
3125 #define OP_LD_ATOMIC(insn,fname) \
3126 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3127 DisasContext *ctx) \
3129 TCGv t0 = tcg_temp_new(); \
3130 tcg_gen_mov_tl(t0, arg1); \
3131 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3132 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3133 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3134 tcg_temp_free(t0); \
3137 #define OP_LD_ATOMIC(insn,fname) \
3138 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3139 DisasContext *ctx) \
3141 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3144 OP_LD_ATOMIC(ll,ld32s);
3145 #if defined(TARGET_MIPS64)
3146 OP_LD_ATOMIC(lld,ld64);
3150 #ifdef CONFIG_USER_ONLY
3151 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
3152 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3153 DisasContext *ctx) \
3155 TCGv t0 = tcg_temp_new(); \
3156 TCGLabel *l1 = gen_new_label(); \
3157 TCGLabel *l2 = gen_new_label(); \
3159 tcg_gen_andi_tl(t0, arg2, almask); \
3160 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
3161 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
3162 generate_exception(ctx, EXCP_AdES); \
3163 gen_set_label(l1); \
3164 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3165 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
3166 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
3167 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
3168 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
3169 generate_exception_end(ctx, EXCP_SC); \
3170 gen_set_label(l2); \
3171 tcg_gen_movi_tl(t0, 0); \
3172 gen_store_gpr(t0, rt); \
3173 tcg_temp_free(t0); \
3176 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
3177 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3178 DisasContext *ctx) \
3180 TCGv t0 = tcg_temp_new(); \
3181 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
3182 gen_store_gpr(t0, rt); \
3183 tcg_temp_free(t0); \
3186 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
3187 #if defined(TARGET_MIPS64)
3188 OP_ST_ATOMIC(scd,st64,ld64,0x7);
3192 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3193 int base, int offset)
3196 tcg_gen_movi_tl(addr, offset);
3197 } else if (offset == 0) {
3198 gen_load_gpr(addr, base);
3200 tcg_gen_movi_tl(addr, offset);
3201 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3205 static target_ulong pc_relative_pc (DisasContext *ctx)
3207 target_ulong pc = ctx->base.pc_next;
3209 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3210 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3215 pc &= ~(target_ulong)3;
3220 static void gen_ld(DisasContext *ctx, uint32_t opc,
3221 int rt, int base, int offset)
3224 int mem_idx = ctx->mem_idx;
3226 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3227 /* Loongson CPU uses a load to zero register for prefetch.
3228 We emulate it as a NOP. On other CPU we must perform the
3229 actual memory access. */
3233 t0 = tcg_temp_new();
3234 gen_base_offset_addr(ctx, t0, base, offset);
3237 #if defined(TARGET_MIPS64)
3239 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3240 ctx->default_tcg_memop_mask);
3241 gen_store_gpr(t0, rt);
3244 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3245 ctx->default_tcg_memop_mask);
3246 gen_store_gpr(t0, rt);
3250 op_ld_lld(t0, t0, mem_idx, ctx);
3251 gen_store_gpr(t0, rt);
3254 t1 = tcg_temp_new();
3255 /* Do a byte access to possibly trigger a page
3256 fault with the unaligned address. */
3257 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3258 tcg_gen_andi_tl(t1, t0, 7);
3259 #ifndef TARGET_WORDS_BIGENDIAN
3260 tcg_gen_xori_tl(t1, t1, 7);
3262 tcg_gen_shli_tl(t1, t1, 3);
3263 tcg_gen_andi_tl(t0, t0, ~7);
3264 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3265 tcg_gen_shl_tl(t0, t0, t1);
3266 t2 = tcg_const_tl(-1);
3267 tcg_gen_shl_tl(t2, t2, t1);
3268 gen_load_gpr(t1, rt);
3269 tcg_gen_andc_tl(t1, t1, t2);
3271 tcg_gen_or_tl(t0, t0, t1);
3273 gen_store_gpr(t0, rt);
3276 t1 = tcg_temp_new();
3277 /* Do a byte access to possibly trigger a page
3278 fault with the unaligned address. */
3279 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3280 tcg_gen_andi_tl(t1, t0, 7);
3281 #ifdef TARGET_WORDS_BIGENDIAN
3282 tcg_gen_xori_tl(t1, t1, 7);
3284 tcg_gen_shli_tl(t1, t1, 3);
3285 tcg_gen_andi_tl(t0, t0, ~7);
3286 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3287 tcg_gen_shr_tl(t0, t0, t1);
3288 tcg_gen_xori_tl(t1, t1, 63);
3289 t2 = tcg_const_tl(0xfffffffffffffffeull);
3290 tcg_gen_shl_tl(t2, t2, t1);
3291 gen_load_gpr(t1, rt);
3292 tcg_gen_and_tl(t1, t1, t2);
3294 tcg_gen_or_tl(t0, t0, t1);
3296 gen_store_gpr(t0, rt);
3299 t1 = tcg_const_tl(pc_relative_pc(ctx));
3300 gen_op_addr_add(ctx, t0, t0, t1);
3302 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3303 gen_store_gpr(t0, rt);
3307 t1 = tcg_const_tl(pc_relative_pc(ctx));
3308 gen_op_addr_add(ctx, t0, t0, t1);
3310 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3311 gen_store_gpr(t0, rt);
3314 mem_idx = MIPS_HFLAG_UM;
3317 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3318 ctx->default_tcg_memop_mask);
3319 gen_store_gpr(t0, rt);
3322 mem_idx = MIPS_HFLAG_UM;
3325 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3326 ctx->default_tcg_memop_mask);
3327 gen_store_gpr(t0, rt);
3330 mem_idx = MIPS_HFLAG_UM;
3333 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3334 ctx->default_tcg_memop_mask);
3335 gen_store_gpr(t0, rt);
3338 mem_idx = MIPS_HFLAG_UM;
3341 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3342 gen_store_gpr(t0, rt);
3345 mem_idx = MIPS_HFLAG_UM;
3348 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3349 gen_store_gpr(t0, rt);
3352 mem_idx = MIPS_HFLAG_UM;
3355 t1 = tcg_temp_new();
3356 /* Do a byte access to possibly trigger a page
3357 fault with the unaligned address. */
3358 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3359 tcg_gen_andi_tl(t1, t0, 3);
3360 #ifndef TARGET_WORDS_BIGENDIAN
3361 tcg_gen_xori_tl(t1, t1, 3);
3363 tcg_gen_shli_tl(t1, t1, 3);
3364 tcg_gen_andi_tl(t0, t0, ~3);
3365 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3366 tcg_gen_shl_tl(t0, t0, t1);
3367 t2 = tcg_const_tl(-1);
3368 tcg_gen_shl_tl(t2, t2, t1);
3369 gen_load_gpr(t1, rt);
3370 tcg_gen_andc_tl(t1, t1, t2);
3372 tcg_gen_or_tl(t0, t0, t1);
3374 tcg_gen_ext32s_tl(t0, t0);
3375 gen_store_gpr(t0, rt);
3378 mem_idx = MIPS_HFLAG_UM;
3381 t1 = tcg_temp_new();
3382 /* Do a byte access to possibly trigger a page
3383 fault with the unaligned address. */
3384 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3385 tcg_gen_andi_tl(t1, t0, 3);
3386 #ifdef TARGET_WORDS_BIGENDIAN
3387 tcg_gen_xori_tl(t1, t1, 3);
3389 tcg_gen_shli_tl(t1, t1, 3);
3390 tcg_gen_andi_tl(t0, t0, ~3);
3391 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3392 tcg_gen_shr_tl(t0, t0, t1);
3393 tcg_gen_xori_tl(t1, t1, 31);
3394 t2 = tcg_const_tl(0xfffffffeull);
3395 tcg_gen_shl_tl(t2, t2, t1);
3396 gen_load_gpr(t1, rt);
3397 tcg_gen_and_tl(t1, t1, t2);
3399 tcg_gen_or_tl(t0, t0, t1);
3401 tcg_gen_ext32s_tl(t0, t0);
3402 gen_store_gpr(t0, rt);
3405 mem_idx = MIPS_HFLAG_UM;
3409 op_ld_ll(t0, t0, mem_idx, ctx);
3410 gen_store_gpr(t0, rt);
3416 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3417 uint32_t reg1, uint32_t reg2)
3419 TCGv taddr = tcg_temp_new();
3420 TCGv_i64 tval = tcg_temp_new_i64();
3421 TCGv tmp1 = tcg_temp_new();
3422 TCGv tmp2 = tcg_temp_new();
3424 gen_base_offset_addr(ctx, taddr, base, offset);
3425 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3426 #ifdef TARGET_WORDS_BIGENDIAN
3427 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3429 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3431 gen_store_gpr(tmp1, reg1);
3432 tcg_temp_free(tmp1);
3433 gen_store_gpr(tmp2, reg2);
3434 tcg_temp_free(tmp2);
3435 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3436 tcg_temp_free_i64(tval);
3437 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3438 tcg_temp_free(taddr);
3442 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3443 int base, int offset)
3445 TCGv t0 = tcg_temp_new();
3446 TCGv t1 = tcg_temp_new();
3447 int mem_idx = ctx->mem_idx;
3449 gen_base_offset_addr(ctx, t0, base, offset);
3450 gen_load_gpr(t1, rt);
3452 #if defined(TARGET_MIPS64)
3454 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3455 ctx->default_tcg_memop_mask);
3458 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3461 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3465 mem_idx = MIPS_HFLAG_UM;
3468 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3469 ctx->default_tcg_memop_mask);
3472 mem_idx = MIPS_HFLAG_UM;
3475 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3476 ctx->default_tcg_memop_mask);
3479 mem_idx = MIPS_HFLAG_UM;
3482 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3485 mem_idx = MIPS_HFLAG_UM;
3488 gen_helper_0e2i(swl, t1, t0, mem_idx);
3491 mem_idx = MIPS_HFLAG_UM;
3494 gen_helper_0e2i(swr, t1, t0, mem_idx);
3502 /* Store conditional */
3503 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3504 int base, int16_t offset)
3507 int mem_idx = ctx->mem_idx;
3509 #ifdef CONFIG_USER_ONLY
3510 t0 = tcg_temp_local_new();
3511 t1 = tcg_temp_local_new();
3513 t0 = tcg_temp_new();
3514 t1 = tcg_temp_new();
3516 gen_base_offset_addr(ctx, t0, base, offset);
3517 gen_load_gpr(t1, rt);
3519 #if defined(TARGET_MIPS64)
3522 op_st_scd(t1, t0, rt, mem_idx, ctx);
3526 mem_idx = MIPS_HFLAG_UM;
3530 op_st_sc(t1, t0, rt, mem_idx, ctx);
3537 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3538 uint32_t reg1, uint32_t reg2)
3540 TCGv taddr = tcg_temp_local_new();
3541 TCGv lladdr = tcg_temp_local_new();
3542 TCGv_i64 tval = tcg_temp_new_i64();
3543 TCGv_i64 llval = tcg_temp_new_i64();
3544 TCGv_i64 val = tcg_temp_new_i64();
3545 TCGv tmp1 = tcg_temp_new();
3546 TCGv tmp2 = tcg_temp_new();
3547 TCGLabel *lab_fail = gen_new_label();
3548 TCGLabel *lab_done = gen_new_label();
3550 gen_base_offset_addr(ctx, taddr, base, offset);
3552 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3553 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3555 gen_load_gpr(tmp1, reg1);
3556 gen_load_gpr(tmp2, reg2);
3558 #ifdef TARGET_WORDS_BIGENDIAN
3559 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3561 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3564 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3565 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3566 ctx->mem_idx, MO_64);
3568 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3570 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3572 gen_set_label(lab_fail);
3575 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3577 gen_set_label(lab_done);
3578 tcg_gen_movi_tl(lladdr, -1);
3579 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3582 /* Load and store */
3583 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3586 /* Don't do NOP if destination is zero: we must perform the actual
3591 TCGv_i32 fp0 = tcg_temp_new_i32();
3592 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3593 ctx->default_tcg_memop_mask);
3594 gen_store_fpr32(ctx, fp0, ft);
3595 tcg_temp_free_i32(fp0);
3600 TCGv_i32 fp0 = tcg_temp_new_i32();
3601 gen_load_fpr32(ctx, fp0, ft);
3602 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3603 ctx->default_tcg_memop_mask);
3604 tcg_temp_free_i32(fp0);
3609 TCGv_i64 fp0 = tcg_temp_new_i64();
3610 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3611 ctx->default_tcg_memop_mask);
3612 gen_store_fpr64(ctx, fp0, ft);
3613 tcg_temp_free_i64(fp0);
3618 TCGv_i64 fp0 = tcg_temp_new_i64();
3619 gen_load_fpr64(ctx, fp0, ft);
3620 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3621 ctx->default_tcg_memop_mask);
3622 tcg_temp_free_i64(fp0);
3626 MIPS_INVAL("flt_ldst");
3627 generate_exception_end(ctx, EXCP_RI);
3632 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3633 int rs, int16_t imm)
3635 TCGv t0 = tcg_temp_new();
3637 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3638 check_cp1_enabled(ctx);
3642 check_insn(ctx, ISA_MIPS2);
3645 gen_base_offset_addr(ctx, t0, rs, imm);
3646 gen_flt_ldst(ctx, op, rt, t0);
3649 generate_exception_err(ctx, EXCP_CpU, 1);
3654 /* Arithmetic with immediate operand */
3655 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3656 int rt, int rs, int imm)
3658 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3660 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3661 /* If no destination, treat it as a NOP.
3662 For addi, we must generate the overflow exception when needed. */
3668 TCGv t0 = tcg_temp_local_new();
3669 TCGv t1 = tcg_temp_new();
3670 TCGv t2 = tcg_temp_new();
3671 TCGLabel *l1 = gen_new_label();
3673 gen_load_gpr(t1, rs);
3674 tcg_gen_addi_tl(t0, t1, uimm);
3675 tcg_gen_ext32s_tl(t0, t0);
3677 tcg_gen_xori_tl(t1, t1, ~uimm);
3678 tcg_gen_xori_tl(t2, t0, uimm);
3679 tcg_gen_and_tl(t1, t1, t2);
3681 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3683 /* operands of same sign, result different sign */
3684 generate_exception(ctx, EXCP_OVERFLOW);
3686 tcg_gen_ext32s_tl(t0, t0);
3687 gen_store_gpr(t0, rt);
3693 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3694 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3696 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3699 #if defined(TARGET_MIPS64)
3702 TCGv t0 = tcg_temp_local_new();
3703 TCGv t1 = tcg_temp_new();
3704 TCGv t2 = tcg_temp_new();
3705 TCGLabel *l1 = gen_new_label();
3707 gen_load_gpr(t1, rs);
3708 tcg_gen_addi_tl(t0, t1, uimm);
3710 tcg_gen_xori_tl(t1, t1, ~uimm);
3711 tcg_gen_xori_tl(t2, t0, uimm);
3712 tcg_gen_and_tl(t1, t1, t2);
3714 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3716 /* operands of same sign, result different sign */
3717 generate_exception(ctx, EXCP_OVERFLOW);
3719 gen_store_gpr(t0, rt);
3725 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3727 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3734 /* Logic with immediate operand */
3735 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3736 int rt, int rs, int16_t imm)
3741 /* If no destination, treat it as a NOP. */
3744 uimm = (uint16_t)imm;
3747 if (likely(rs != 0))
3748 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3750 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3754 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3756 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3759 if (likely(rs != 0))
3760 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3762 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3765 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3767 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3768 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3770 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3779 /* Set on less than with immediate operand */
3780 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3781 int rt, int rs, int16_t imm)
3783 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3787 /* If no destination, treat it as a NOP. */
3790 t0 = tcg_temp_new();
3791 gen_load_gpr(t0, rs);
3794 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3797 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3803 /* Shifts with immediate operand */
3804 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3805 int rt, int rs, int16_t imm)
3807 target_ulong uimm = ((uint16_t)imm) & 0x1f;
3811 /* If no destination, treat it as a NOP. */
3815 t0 = tcg_temp_new();
3816 gen_load_gpr(t0, rs);
3819 tcg_gen_shli_tl(t0, t0, uimm);
3820 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3823 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3827 tcg_gen_ext32u_tl(t0, t0);
3828 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3830 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3835 TCGv_i32 t1 = tcg_temp_new_i32();
3837 tcg_gen_trunc_tl_i32(t1, t0);
3838 tcg_gen_rotri_i32(t1, t1, uimm);
3839 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3840 tcg_temp_free_i32(t1);
3842 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3845 #if defined(TARGET_MIPS64)
3847 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3850 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3853 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3857 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3859 tcg_gen_mov_tl(cpu_gpr[rt], t0);
3863 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3866 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
3869 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
3872 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
3880 static void gen_arith(DisasContext *ctx, uint32_t opc,
3881 int rd, int rs, int rt)
3883 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3884 && opc != OPC_DADD && opc != OPC_DSUB) {
3885 /* If no destination, treat it as a NOP.
3886 For add & sub, we must generate the overflow exception when needed. */
3893 TCGv t0 = tcg_temp_local_new();
3894 TCGv t1 = tcg_temp_new();
3895 TCGv t2 = tcg_temp_new();
3896 TCGLabel *l1 = gen_new_label();
3898 gen_load_gpr(t1, rs);
3899 gen_load_gpr(t2, rt);
3900 tcg_gen_add_tl(t0, t1, t2);
3901 tcg_gen_ext32s_tl(t0, t0);
3902 tcg_gen_xor_tl(t1, t1, t2);
3903 tcg_gen_xor_tl(t2, t0, t2);
3904 tcg_gen_andc_tl(t1, t2, t1);
3906 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3908 /* operands of same sign, result different sign */
3909 generate_exception(ctx, EXCP_OVERFLOW);
3911 gen_store_gpr(t0, rd);
3916 if (rs != 0 && rt != 0) {
3917 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3918 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3919 } else if (rs == 0 && rt != 0) {
3920 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3921 } else if (rs != 0 && rt == 0) {
3922 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3924 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3929 TCGv t0 = tcg_temp_local_new();
3930 TCGv t1 = tcg_temp_new();
3931 TCGv t2 = tcg_temp_new();
3932 TCGLabel *l1 = gen_new_label();
3934 gen_load_gpr(t1, rs);
3935 gen_load_gpr(t2, rt);
3936 tcg_gen_sub_tl(t0, t1, t2);
3937 tcg_gen_ext32s_tl(t0, t0);
3938 tcg_gen_xor_tl(t2, t1, t2);
3939 tcg_gen_xor_tl(t1, t0, t1);
3940 tcg_gen_and_tl(t1, t1, t2);
3942 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3944 /* operands of different sign, first operand and result different sign */
3945 generate_exception(ctx, EXCP_OVERFLOW);
3947 gen_store_gpr(t0, rd);
3952 if (rs != 0 && rt != 0) {
3953 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3954 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3955 } else if (rs == 0 && rt != 0) {
3956 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3957 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3958 } else if (rs != 0 && rt == 0) {
3959 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3961 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3964 #if defined(TARGET_MIPS64)
3967 TCGv t0 = tcg_temp_local_new();
3968 TCGv t1 = tcg_temp_new();
3969 TCGv t2 = tcg_temp_new();
3970 TCGLabel *l1 = gen_new_label();
3972 gen_load_gpr(t1, rs);
3973 gen_load_gpr(t2, rt);
3974 tcg_gen_add_tl(t0, t1, t2);
3975 tcg_gen_xor_tl(t1, t1, t2);
3976 tcg_gen_xor_tl(t2, t0, t2);
3977 tcg_gen_andc_tl(t1, t2, t1);
3979 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3981 /* operands of same sign, result different sign */
3982 generate_exception(ctx, EXCP_OVERFLOW);
3984 gen_store_gpr(t0, rd);
3989 if (rs != 0 && rt != 0) {
3990 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3991 } else if (rs == 0 && rt != 0) {
3992 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3993 } else if (rs != 0 && rt == 0) {
3994 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3996 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4001 TCGv t0 = tcg_temp_local_new();
4002 TCGv t1 = tcg_temp_new();
4003 TCGv t2 = tcg_temp_new();
4004 TCGLabel *l1 = gen_new_label();
4006 gen_load_gpr(t1, rs);
4007 gen_load_gpr(t2, rt);
4008 tcg_gen_sub_tl(t0, t1, t2);
4009 tcg_gen_xor_tl(t2, t1, t2);
4010 tcg_gen_xor_tl(t1, t0, t1);
4011 tcg_gen_and_tl(t1, t1, t2);
4013 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4015 /* operands of different sign, first operand and result different sign */
4016 generate_exception(ctx, EXCP_OVERFLOW);
4018 gen_store_gpr(t0, rd);
4023 if (rs != 0 && rt != 0) {
4024 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4025 } else if (rs == 0 && rt != 0) {
4026 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4027 } else if (rs != 0 && rt == 0) {
4028 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4030 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4035 if (likely(rs != 0 && rt != 0)) {
4036 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4037 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4039 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4045 /* Conditional move */
4046 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4047 int rd, int rs, int rt)
4052 /* If no destination, treat it as a NOP. */
4056 t0 = tcg_temp_new();
4057 gen_load_gpr(t0, rt);
4058 t1 = tcg_const_tl(0);
4059 t2 = tcg_temp_new();
4060 gen_load_gpr(t2, rs);
4063 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4066 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4069 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4072 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4081 static void gen_logic(DisasContext *ctx, uint32_t opc,
4082 int rd, int rs, int rt)
4085 /* If no destination, treat it as a NOP. */
4091 if (likely(rs != 0 && rt != 0)) {
4092 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4094 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4098 if (rs != 0 && rt != 0) {
4099 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4100 } else if (rs == 0 && rt != 0) {
4101 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4102 } else if (rs != 0 && rt == 0) {
4103 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4105 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4109 if (likely(rs != 0 && rt != 0)) {
4110 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4111 } else if (rs == 0 && rt != 0) {
4112 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4113 } else if (rs != 0 && rt == 0) {
4114 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4116 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4120 if (likely(rs != 0 && rt != 0)) {
4121 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4122 } else if (rs == 0 && rt != 0) {
4123 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4124 } else if (rs != 0 && rt == 0) {
4125 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4127 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4133 /* Set on lower than */
4134 static void gen_slt(DisasContext *ctx, uint32_t opc,
4135 int rd, int rs, int rt)
4140 /* If no destination, treat it as a NOP. */
4144 t0 = tcg_temp_new();
4145 t1 = tcg_temp_new();
4146 gen_load_gpr(t0, rs);
4147 gen_load_gpr(t1, rt);
4150 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4153 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4161 static void gen_shift(DisasContext *ctx, uint32_t opc,
4162 int rd, int rs, int rt)
4167 /* If no destination, treat it as a NOP.
4168 For add & sub, we must generate the overflow exception when needed. */
4172 t0 = tcg_temp_new();
4173 t1 = tcg_temp_new();
4174 gen_load_gpr(t0, rs);
4175 gen_load_gpr(t1, rt);
4178 tcg_gen_andi_tl(t0, t0, 0x1f);
4179 tcg_gen_shl_tl(t0, t1, t0);
4180 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4183 tcg_gen_andi_tl(t0, t0, 0x1f);
4184 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4187 tcg_gen_ext32u_tl(t1, t1);
4188 tcg_gen_andi_tl(t0, t0, 0x1f);
4189 tcg_gen_shr_tl(t0, t1, t0);
4190 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4194 TCGv_i32 t2 = tcg_temp_new_i32();
4195 TCGv_i32 t3 = tcg_temp_new_i32();
4197 tcg_gen_trunc_tl_i32(t2, t0);
4198 tcg_gen_trunc_tl_i32(t3, t1);
4199 tcg_gen_andi_i32(t2, t2, 0x1f);
4200 tcg_gen_rotr_i32(t2, t3, t2);
4201 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4202 tcg_temp_free_i32(t2);
4203 tcg_temp_free_i32(t3);
4206 #if defined(TARGET_MIPS64)
4208 tcg_gen_andi_tl(t0, t0, 0x3f);
4209 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4212 tcg_gen_andi_tl(t0, t0, 0x3f);
4213 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4216 tcg_gen_andi_tl(t0, t0, 0x3f);
4217 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4220 tcg_gen_andi_tl(t0, t0, 0x3f);
4221 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4229 /* Arithmetic on HI/LO registers */
4230 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4232 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4243 #if defined(TARGET_MIPS64)
4245 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4249 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4253 #if defined(TARGET_MIPS64)
4255 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4259 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4264 #if defined(TARGET_MIPS64)
4266 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4270 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4273 tcg_gen_movi_tl(cpu_HI[acc], 0);
4278 #if defined(TARGET_MIPS64)
4280 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4284 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4287 tcg_gen_movi_tl(cpu_LO[acc], 0);
4293 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4296 TCGv t0 = tcg_const_tl(addr);
4297 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4298 gen_store_gpr(t0, reg);
4302 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4308 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4311 offset = sextract32(ctx->opcode << 2, 0, 21);
4312 addr = addr_add(ctx, pc, offset);
4313 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4317 offset = sextract32(ctx->opcode << 2, 0, 21);
4318 addr = addr_add(ctx, pc, offset);
4319 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4321 #if defined(TARGET_MIPS64)
4324 offset = sextract32(ctx->opcode << 2, 0, 21);
4325 addr = addr_add(ctx, pc, offset);
4326 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4330 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4333 offset = sextract32(ctx->opcode, 0, 16) << 16;
4334 addr = addr_add(ctx, pc, offset);
4335 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4340 offset = sextract32(ctx->opcode, 0, 16) << 16;
4341 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4342 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4345 #if defined(TARGET_MIPS64)
4346 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4347 case R6_OPC_LDPC + (1 << 16):
4348 case R6_OPC_LDPC + (2 << 16):
4349 case R6_OPC_LDPC + (3 << 16):
4351 offset = sextract32(ctx->opcode << 3, 0, 21);
4352 addr = addr_add(ctx, (pc & ~0x7), offset);
4353 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4357 MIPS_INVAL("OPC_PCREL");
4358 generate_exception_end(ctx, EXCP_RI);
4365 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4374 t0 = tcg_temp_new();
4375 t1 = tcg_temp_new();
4377 gen_load_gpr(t0, rs);
4378 gen_load_gpr(t1, rt);
4383 TCGv t2 = tcg_temp_new();
4384 TCGv t3 = tcg_temp_new();
4385 tcg_gen_ext32s_tl(t0, t0);
4386 tcg_gen_ext32s_tl(t1, t1);
4387 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4388 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4389 tcg_gen_and_tl(t2, t2, t3);
4390 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4391 tcg_gen_or_tl(t2, t2, t3);
4392 tcg_gen_movi_tl(t3, 0);
4393 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4394 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4395 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4402 TCGv t2 = tcg_temp_new();
4403 TCGv t3 = tcg_temp_new();
4404 tcg_gen_ext32s_tl(t0, t0);
4405 tcg_gen_ext32s_tl(t1, t1);
4406 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4407 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4408 tcg_gen_and_tl(t2, t2, t3);
4409 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4410 tcg_gen_or_tl(t2, t2, t3);
4411 tcg_gen_movi_tl(t3, 0);
4412 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4413 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4414 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4421 TCGv t2 = tcg_const_tl(0);
4422 TCGv t3 = tcg_const_tl(1);
4423 tcg_gen_ext32u_tl(t0, t0);
4424 tcg_gen_ext32u_tl(t1, t1);
4425 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4426 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4427 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4434 TCGv t2 = tcg_const_tl(0);
4435 TCGv t3 = tcg_const_tl(1);
4436 tcg_gen_ext32u_tl(t0, t0);
4437 tcg_gen_ext32u_tl(t1, t1);
4438 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4439 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4440 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4447 TCGv_i32 t2 = tcg_temp_new_i32();
4448 TCGv_i32 t3 = tcg_temp_new_i32();
4449 tcg_gen_trunc_tl_i32(t2, t0);
4450 tcg_gen_trunc_tl_i32(t3, t1);
4451 tcg_gen_mul_i32(t2, t2, t3);
4452 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4453 tcg_temp_free_i32(t2);
4454 tcg_temp_free_i32(t3);
4459 TCGv_i32 t2 = tcg_temp_new_i32();
4460 TCGv_i32 t3 = tcg_temp_new_i32();
4461 tcg_gen_trunc_tl_i32(t2, t0);
4462 tcg_gen_trunc_tl_i32(t3, t1);
4463 tcg_gen_muls2_i32(t2, t3, t2, t3);
4464 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4465 tcg_temp_free_i32(t2);
4466 tcg_temp_free_i32(t3);
4471 TCGv_i32 t2 = tcg_temp_new_i32();
4472 TCGv_i32 t3 = tcg_temp_new_i32();
4473 tcg_gen_trunc_tl_i32(t2, t0);
4474 tcg_gen_trunc_tl_i32(t3, t1);
4475 tcg_gen_mul_i32(t2, t2, t3);
4476 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4477 tcg_temp_free_i32(t2);
4478 tcg_temp_free_i32(t3);
4483 TCGv_i32 t2 = tcg_temp_new_i32();
4484 TCGv_i32 t3 = tcg_temp_new_i32();
4485 tcg_gen_trunc_tl_i32(t2, t0);
4486 tcg_gen_trunc_tl_i32(t3, t1);
4487 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4488 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4489 tcg_temp_free_i32(t2);
4490 tcg_temp_free_i32(t3);
4493 #if defined(TARGET_MIPS64)
4496 TCGv t2 = tcg_temp_new();
4497 TCGv t3 = tcg_temp_new();
4498 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4499 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4500 tcg_gen_and_tl(t2, t2, t3);
4501 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4502 tcg_gen_or_tl(t2, t2, t3);
4503 tcg_gen_movi_tl(t3, 0);
4504 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4505 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4512 TCGv t2 = tcg_temp_new();
4513 TCGv t3 = tcg_temp_new();
4514 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4515 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4516 tcg_gen_and_tl(t2, t2, t3);
4517 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4518 tcg_gen_or_tl(t2, t2, t3);
4519 tcg_gen_movi_tl(t3, 0);
4520 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4521 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4528 TCGv t2 = tcg_const_tl(0);
4529 TCGv t3 = tcg_const_tl(1);
4530 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4531 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4538 TCGv t2 = tcg_const_tl(0);
4539 TCGv t3 = tcg_const_tl(1);
4540 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4541 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4547 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4551 TCGv t2 = tcg_temp_new();
4552 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4557 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4561 TCGv t2 = tcg_temp_new();
4562 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4568 MIPS_INVAL("r6 mul/div");
4569 generate_exception_end(ctx, EXCP_RI);
4577 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4578 int acc, int rs, int rt)
4582 t0 = tcg_temp_new();
4583 t1 = tcg_temp_new();
4585 gen_load_gpr(t0, rs);
4586 gen_load_gpr(t1, rt);
4595 TCGv t2 = tcg_temp_new();
4596 TCGv t3 = tcg_temp_new();
4597 tcg_gen_ext32s_tl(t0, t0);
4598 tcg_gen_ext32s_tl(t1, t1);
4599 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4600 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4601 tcg_gen_and_tl(t2, t2, t3);
4602 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4603 tcg_gen_or_tl(t2, t2, t3);
4604 tcg_gen_movi_tl(t3, 0);
4605 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4606 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4607 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4608 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4609 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4616 TCGv t2 = tcg_const_tl(0);
4617 TCGv t3 = tcg_const_tl(1);
4618 tcg_gen_ext32u_tl(t0, t0);
4619 tcg_gen_ext32u_tl(t1, t1);
4620 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4621 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4622 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4623 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4624 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4631 TCGv_i32 t2 = tcg_temp_new_i32();
4632 TCGv_i32 t3 = tcg_temp_new_i32();
4633 tcg_gen_trunc_tl_i32(t2, t0);
4634 tcg_gen_trunc_tl_i32(t3, t1);
4635 tcg_gen_muls2_i32(t2, t3, t2, t3);
4636 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4637 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4638 tcg_temp_free_i32(t2);
4639 tcg_temp_free_i32(t3);
4644 TCGv_i32 t2 = tcg_temp_new_i32();
4645 TCGv_i32 t3 = tcg_temp_new_i32();
4646 tcg_gen_trunc_tl_i32(t2, t0);
4647 tcg_gen_trunc_tl_i32(t3, t1);
4648 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4649 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4650 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4651 tcg_temp_free_i32(t2);
4652 tcg_temp_free_i32(t3);
4655 #if defined(TARGET_MIPS64)
4658 TCGv t2 = tcg_temp_new();
4659 TCGv t3 = tcg_temp_new();
4660 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4661 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4662 tcg_gen_and_tl(t2, t2, t3);
4663 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4664 tcg_gen_or_tl(t2, t2, t3);
4665 tcg_gen_movi_tl(t3, 0);
4666 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4667 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4668 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4675 TCGv t2 = tcg_const_tl(0);
4676 TCGv t3 = tcg_const_tl(1);
4677 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4678 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4679 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4685 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4688 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4693 TCGv_i64 t2 = tcg_temp_new_i64();
4694 TCGv_i64 t3 = tcg_temp_new_i64();
4696 tcg_gen_ext_tl_i64(t2, t0);
4697 tcg_gen_ext_tl_i64(t3, t1);
4698 tcg_gen_mul_i64(t2, t2, t3);
4699 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4700 tcg_gen_add_i64(t2, t2, t3);
4701 tcg_temp_free_i64(t3);
4702 gen_move_low32(cpu_LO[acc], t2);
4703 gen_move_high32(cpu_HI[acc], t2);
4704 tcg_temp_free_i64(t2);
4709 TCGv_i64 t2 = tcg_temp_new_i64();
4710 TCGv_i64 t3 = tcg_temp_new_i64();
4712 tcg_gen_ext32u_tl(t0, t0);
4713 tcg_gen_ext32u_tl(t1, t1);
4714 tcg_gen_extu_tl_i64(t2, t0);
4715 tcg_gen_extu_tl_i64(t3, t1);
4716 tcg_gen_mul_i64(t2, t2, t3);
4717 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4718 tcg_gen_add_i64(t2, t2, t3);
4719 tcg_temp_free_i64(t3);
4720 gen_move_low32(cpu_LO[acc], t2);
4721 gen_move_high32(cpu_HI[acc], t2);
4722 tcg_temp_free_i64(t2);
4727 TCGv_i64 t2 = tcg_temp_new_i64();
4728 TCGv_i64 t3 = tcg_temp_new_i64();
4730 tcg_gen_ext_tl_i64(t2, t0);
4731 tcg_gen_ext_tl_i64(t3, t1);
4732 tcg_gen_mul_i64(t2, t2, t3);
4733 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4734 tcg_gen_sub_i64(t2, t3, t2);
4735 tcg_temp_free_i64(t3);
4736 gen_move_low32(cpu_LO[acc], t2);
4737 gen_move_high32(cpu_HI[acc], t2);
4738 tcg_temp_free_i64(t2);
4743 TCGv_i64 t2 = tcg_temp_new_i64();
4744 TCGv_i64 t3 = tcg_temp_new_i64();
4746 tcg_gen_ext32u_tl(t0, t0);
4747 tcg_gen_ext32u_tl(t1, t1);
4748 tcg_gen_extu_tl_i64(t2, t0);
4749 tcg_gen_extu_tl_i64(t3, t1);
4750 tcg_gen_mul_i64(t2, t2, t3);
4751 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4752 tcg_gen_sub_i64(t2, t3, t2);
4753 tcg_temp_free_i64(t3);
4754 gen_move_low32(cpu_LO[acc], t2);
4755 gen_move_high32(cpu_HI[acc], t2);
4756 tcg_temp_free_i64(t2);
4760 MIPS_INVAL("mul/div");
4761 generate_exception_end(ctx, EXCP_RI);
4769 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4770 int rd, int rs, int rt)
4772 TCGv t0 = tcg_temp_new();
4773 TCGv t1 = tcg_temp_new();
4775 gen_load_gpr(t0, rs);
4776 gen_load_gpr(t1, rt);
4779 case OPC_VR54XX_MULS:
4780 gen_helper_muls(t0, cpu_env, t0, t1);
4782 case OPC_VR54XX_MULSU:
4783 gen_helper_mulsu(t0, cpu_env, t0, t1);
4785 case OPC_VR54XX_MACC:
4786 gen_helper_macc(t0, cpu_env, t0, t1);
4788 case OPC_VR54XX_MACCU:
4789 gen_helper_maccu(t0, cpu_env, t0, t1);
4791 case OPC_VR54XX_MSAC:
4792 gen_helper_msac(t0, cpu_env, t0, t1);
4794 case OPC_VR54XX_MSACU:
4795 gen_helper_msacu(t0, cpu_env, t0, t1);
4797 case OPC_VR54XX_MULHI:
4798 gen_helper_mulhi(t0, cpu_env, t0, t1);
4800 case OPC_VR54XX_MULHIU:
4801 gen_helper_mulhiu(t0, cpu_env, t0, t1);
4803 case OPC_VR54XX_MULSHI:
4804 gen_helper_mulshi(t0, cpu_env, t0, t1);
4806 case OPC_VR54XX_MULSHIU:
4807 gen_helper_mulshiu(t0, cpu_env, t0, t1);
4809 case OPC_VR54XX_MACCHI:
4810 gen_helper_macchi(t0, cpu_env, t0, t1);
4812 case OPC_VR54XX_MACCHIU:
4813 gen_helper_macchiu(t0, cpu_env, t0, t1);
4815 case OPC_VR54XX_MSACHI:
4816 gen_helper_msachi(t0, cpu_env, t0, t1);
4818 case OPC_VR54XX_MSACHIU:
4819 gen_helper_msachiu(t0, cpu_env, t0, t1);
4822 MIPS_INVAL("mul vr54xx");
4823 generate_exception_end(ctx, EXCP_RI);
4826 gen_store_gpr(t0, rd);
4833 static void gen_cl (DisasContext *ctx, uint32_t opc,
4843 gen_load_gpr(t0, rs);
4848 #if defined(TARGET_MIPS64)
4852 tcg_gen_not_tl(t0, t0);
4861 tcg_gen_ext32u_tl(t0, t0);
4862 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
4863 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
4865 #if defined(TARGET_MIPS64)
4870 tcg_gen_clzi_i64(t0, t0, 64);
4876 /* Godson integer instructions */
4877 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
4878 int rd, int rs, int rt)
4890 case OPC_MULTU_G_2E:
4891 case OPC_MULTU_G_2F:
4892 #if defined(TARGET_MIPS64)
4893 case OPC_DMULT_G_2E:
4894 case OPC_DMULT_G_2F:
4895 case OPC_DMULTU_G_2E:
4896 case OPC_DMULTU_G_2F:
4898 t0 = tcg_temp_new();
4899 t1 = tcg_temp_new();
4902 t0 = tcg_temp_local_new();
4903 t1 = tcg_temp_local_new();
4907 gen_load_gpr(t0, rs);
4908 gen_load_gpr(t1, rt);
4913 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4914 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4916 case OPC_MULTU_G_2E:
4917 case OPC_MULTU_G_2F:
4918 tcg_gen_ext32u_tl(t0, t0);
4919 tcg_gen_ext32u_tl(t1, t1);
4920 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4921 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4926 TCGLabel *l1 = gen_new_label();
4927 TCGLabel *l2 = gen_new_label();
4928 TCGLabel *l3 = gen_new_label();
4929 tcg_gen_ext32s_tl(t0, t0);
4930 tcg_gen_ext32s_tl(t1, t1);
4931 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4932 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4935 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4936 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4937 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4940 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4941 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4948 TCGLabel *l1 = gen_new_label();
4949 TCGLabel *l2 = gen_new_label();
4950 tcg_gen_ext32u_tl(t0, t0);
4951 tcg_gen_ext32u_tl(t1, t1);
4952 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4953 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4956 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4957 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4964 TCGLabel *l1 = gen_new_label();
4965 TCGLabel *l2 = gen_new_label();
4966 TCGLabel *l3 = gen_new_label();
4967 tcg_gen_ext32u_tl(t0, t0);
4968 tcg_gen_ext32u_tl(t1, t1);
4969 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4970 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4971 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4973 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4976 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4977 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4984 TCGLabel *l1 = gen_new_label();
4985 TCGLabel *l2 = gen_new_label();
4986 tcg_gen_ext32u_tl(t0, t0);
4987 tcg_gen_ext32u_tl(t1, t1);
4988 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4989 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4992 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4993 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4997 #if defined(TARGET_MIPS64)
4998 case OPC_DMULT_G_2E:
4999 case OPC_DMULT_G_2F:
5000 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5002 case OPC_DMULTU_G_2E:
5003 case OPC_DMULTU_G_2F:
5004 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5009 TCGLabel *l1 = gen_new_label();
5010 TCGLabel *l2 = gen_new_label();
5011 TCGLabel *l3 = gen_new_label();
5012 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5013 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5016 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5017 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5018 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5021 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5025 case OPC_DDIVU_G_2E:
5026 case OPC_DDIVU_G_2F:
5028 TCGLabel *l1 = gen_new_label();
5029 TCGLabel *l2 = gen_new_label();
5030 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5031 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5034 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5041 TCGLabel *l1 = gen_new_label();
5042 TCGLabel *l2 = gen_new_label();
5043 TCGLabel *l3 = gen_new_label();
5044 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5045 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5046 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5048 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5051 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5055 case OPC_DMODU_G_2E:
5056 case OPC_DMODU_G_2F:
5058 TCGLabel *l1 = gen_new_label();
5059 TCGLabel *l2 = gen_new_label();
5060 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5061 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5064 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5075 /* Loongson multimedia instructions */
5076 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5078 uint32_t opc, shift_max;
5081 opc = MASK_LMI(ctx->opcode);
5087 t0 = tcg_temp_local_new_i64();
5088 t1 = tcg_temp_local_new_i64();
5091 t0 = tcg_temp_new_i64();
5092 t1 = tcg_temp_new_i64();
5096 check_cp1_enabled(ctx);
5097 gen_load_fpr64(ctx, t0, rs);
5098 gen_load_fpr64(ctx, t1, rt);
5100 #define LMI_HELPER(UP, LO) \
5101 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5102 #define LMI_HELPER_1(UP, LO) \
5103 case OPC_##UP: gen_helper_##LO(t0, t0); break
5104 #define LMI_DIRECT(UP, LO, OP) \
5105 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5108 LMI_HELPER(PADDSH, paddsh);
5109 LMI_HELPER(PADDUSH, paddush);
5110 LMI_HELPER(PADDH, paddh);
5111 LMI_HELPER(PADDW, paddw);
5112 LMI_HELPER(PADDSB, paddsb);
5113 LMI_HELPER(PADDUSB, paddusb);
5114 LMI_HELPER(PADDB, paddb);
5116 LMI_HELPER(PSUBSH, psubsh);
5117 LMI_HELPER(PSUBUSH, psubush);
5118 LMI_HELPER(PSUBH, psubh);
5119 LMI_HELPER(PSUBW, psubw);
5120 LMI_HELPER(PSUBSB, psubsb);
5121 LMI_HELPER(PSUBUSB, psubusb);
5122 LMI_HELPER(PSUBB, psubb);
5124 LMI_HELPER(PSHUFH, pshufh);
5125 LMI_HELPER(PACKSSWH, packsswh);
5126 LMI_HELPER(PACKSSHB, packsshb);
5127 LMI_HELPER(PACKUSHB, packushb);
5129 LMI_HELPER(PUNPCKLHW, punpcklhw);
5130 LMI_HELPER(PUNPCKHHW, punpckhhw);
5131 LMI_HELPER(PUNPCKLBH, punpcklbh);
5132 LMI_HELPER(PUNPCKHBH, punpckhbh);
5133 LMI_HELPER(PUNPCKLWD, punpcklwd);
5134 LMI_HELPER(PUNPCKHWD, punpckhwd);
5136 LMI_HELPER(PAVGH, pavgh);
5137 LMI_HELPER(PAVGB, pavgb);
5138 LMI_HELPER(PMAXSH, pmaxsh);
5139 LMI_HELPER(PMINSH, pminsh);
5140 LMI_HELPER(PMAXUB, pmaxub);
5141 LMI_HELPER(PMINUB, pminub);
5143 LMI_HELPER(PCMPEQW, pcmpeqw);
5144 LMI_HELPER(PCMPGTW, pcmpgtw);
5145 LMI_HELPER(PCMPEQH, pcmpeqh);
5146 LMI_HELPER(PCMPGTH, pcmpgth);
5147 LMI_HELPER(PCMPEQB, pcmpeqb);
5148 LMI_HELPER(PCMPGTB, pcmpgtb);
5150 LMI_HELPER(PSLLW, psllw);
5151 LMI_HELPER(PSLLH, psllh);
5152 LMI_HELPER(PSRLW, psrlw);
5153 LMI_HELPER(PSRLH, psrlh);
5154 LMI_HELPER(PSRAW, psraw);
5155 LMI_HELPER(PSRAH, psrah);
5157 LMI_HELPER(PMULLH, pmullh);
5158 LMI_HELPER(PMULHH, pmulhh);
5159 LMI_HELPER(PMULHUH, pmulhuh);
5160 LMI_HELPER(PMADDHW, pmaddhw);
5162 LMI_HELPER(PASUBUB, pasubub);
5163 LMI_HELPER_1(BIADD, biadd);
5164 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5166 LMI_DIRECT(PADDD, paddd, add);
5167 LMI_DIRECT(PSUBD, psubd, sub);
5168 LMI_DIRECT(XOR_CP2, xor, xor);
5169 LMI_DIRECT(NOR_CP2, nor, nor);
5170 LMI_DIRECT(AND_CP2, and, and);
5171 LMI_DIRECT(OR_CP2, or, or);
5174 tcg_gen_andc_i64(t0, t1, t0);
5178 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5181 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5184 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5187 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5191 tcg_gen_andi_i64(t1, t1, 3);
5192 tcg_gen_shli_i64(t1, t1, 4);
5193 tcg_gen_shr_i64(t0, t0, t1);
5194 tcg_gen_ext16u_i64(t0, t0);
5198 tcg_gen_add_i64(t0, t0, t1);
5199 tcg_gen_ext32s_i64(t0, t0);
5202 tcg_gen_sub_i64(t0, t0, t1);
5203 tcg_gen_ext32s_i64(t0, t0);
5225 /* Make sure shift count isn't TCG undefined behaviour. */
5226 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5231 tcg_gen_shl_i64(t0, t0, t1);
5235 /* Since SRA is UndefinedResult without sign-extended inputs,
5236 we can treat SRA and DSRA the same. */
5237 tcg_gen_sar_i64(t0, t0, t1);
5240 /* We want to shift in zeros for SRL; zero-extend first. */
5241 tcg_gen_ext32u_i64(t0, t0);
5244 tcg_gen_shr_i64(t0, t0, t1);
5248 if (shift_max == 32) {
5249 tcg_gen_ext32s_i64(t0, t0);
5252 /* Shifts larger than MAX produce zero. */
5253 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5254 tcg_gen_neg_i64(t1, t1);
5255 tcg_gen_and_i64(t0, t0, t1);
5261 TCGv_i64 t2 = tcg_temp_new_i64();
5262 TCGLabel *lab = gen_new_label();
5264 tcg_gen_mov_i64(t2, t0);
5265 tcg_gen_add_i64(t0, t1, t2);
5266 if (opc == OPC_ADD_CP2) {
5267 tcg_gen_ext32s_i64(t0, t0);
5269 tcg_gen_xor_i64(t1, t1, t2);
5270 tcg_gen_xor_i64(t2, t2, t0);
5271 tcg_gen_andc_i64(t1, t2, t1);
5272 tcg_temp_free_i64(t2);
5273 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5274 generate_exception(ctx, EXCP_OVERFLOW);
5282 TCGv_i64 t2 = tcg_temp_new_i64();
5283 TCGLabel *lab = gen_new_label();
5285 tcg_gen_mov_i64(t2, t0);
5286 tcg_gen_sub_i64(t0, t1, t2);
5287 if (opc == OPC_SUB_CP2) {
5288 tcg_gen_ext32s_i64(t0, t0);
5290 tcg_gen_xor_i64(t1, t1, t2);
5291 tcg_gen_xor_i64(t2, t2, t0);
5292 tcg_gen_and_i64(t1, t1, t2);
5293 tcg_temp_free_i64(t2);
5294 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5295 generate_exception(ctx, EXCP_OVERFLOW);
5301 tcg_gen_ext32u_i64(t0, t0);
5302 tcg_gen_ext32u_i64(t1, t1);
5303 tcg_gen_mul_i64(t0, t0, t1);
5312 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5313 FD field is the CC field? */
5315 MIPS_INVAL("loongson_cp2");
5316 generate_exception_end(ctx, EXCP_RI);
5323 gen_store_fpr64(ctx, t0, rd);
5325 tcg_temp_free_i64(t0);
5326 tcg_temp_free_i64(t1);
5330 static void gen_trap (DisasContext *ctx, uint32_t opc,
5331 int rs, int rt, int16_t imm)
5334 TCGv t0 = tcg_temp_new();
5335 TCGv t1 = tcg_temp_new();
5338 /* Load needed operands */
5346 /* Compare two registers */
5348 gen_load_gpr(t0, rs);
5349 gen_load_gpr(t1, rt);
5359 /* Compare register to immediate */
5360 if (rs != 0 || imm != 0) {
5361 gen_load_gpr(t0, rs);
5362 tcg_gen_movi_tl(t1, (int32_t)imm);
5369 case OPC_TEQ: /* rs == rs */
5370 case OPC_TEQI: /* r0 == 0 */
5371 case OPC_TGE: /* rs >= rs */
5372 case OPC_TGEI: /* r0 >= 0 */
5373 case OPC_TGEU: /* rs >= rs unsigned */
5374 case OPC_TGEIU: /* r0 >= 0 unsigned */
5376 generate_exception_end(ctx, EXCP_TRAP);
5378 case OPC_TLT: /* rs < rs */
5379 case OPC_TLTI: /* r0 < 0 */
5380 case OPC_TLTU: /* rs < rs unsigned */
5381 case OPC_TLTIU: /* r0 < 0 unsigned */
5382 case OPC_TNE: /* rs != rs */
5383 case OPC_TNEI: /* r0 != 0 */
5384 /* Never trap: treat as NOP. */
5388 TCGLabel *l1 = gen_new_label();
5393 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5397 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5401 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5405 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5409 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5413 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5416 generate_exception(ctx, EXCP_TRAP);
5423 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5425 if (unlikely(ctx->base.singlestep_enabled)) {
5429 #ifndef CONFIG_USER_ONLY
5430 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5436 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5438 if (use_goto_tb(ctx, dest)) {
5441 tcg_gen_exit_tb(ctx->base.tb, n);
5444 if (ctx->base.singlestep_enabled) {
5445 save_cpu_state(ctx, 0);
5446 gen_helper_raise_exception_debug(cpu_env);
5448 tcg_gen_lookup_and_goto_ptr();
5452 /* Branches (before delay slot) */
5453 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5455 int rs, int rt, int32_t offset,
5458 target_ulong btgt = -1;
5460 int bcond_compute = 0;
5461 TCGv t0 = tcg_temp_new();
5462 TCGv t1 = tcg_temp_new();
5464 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5465 #ifdef MIPS_DEBUG_DISAS
5466 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5467 TARGET_FMT_lx "\n", ctx->base.pc_next);
5469 generate_exception_end(ctx, EXCP_RI);
5473 /* Load needed operands */
5479 /* Compare two registers */
5481 gen_load_gpr(t0, rs);
5482 gen_load_gpr(t1, rt);
5485 btgt = ctx->base.pc_next + insn_bytes + offset;
5499 /* Compare to zero */
5501 gen_load_gpr(t0, rs);
5504 btgt = ctx->base.pc_next + insn_bytes + offset;
5507 #if defined(TARGET_MIPS64)
5509 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5511 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5514 btgt = ctx->base.pc_next + insn_bytes + offset;
5519 /* Jump to immediate */
5520 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5525 /* Jump to register */
5526 if (offset != 0 && offset != 16) {
5527 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5528 others are reserved. */
5529 MIPS_INVAL("jump hint");
5530 generate_exception_end(ctx, EXCP_RI);
5533 gen_load_gpr(btarget, rs);
5536 MIPS_INVAL("branch/jump");
5537 generate_exception_end(ctx, EXCP_RI);
5540 if (bcond_compute == 0) {
5541 /* No condition to be computed */
5543 case OPC_BEQ: /* rx == rx */
5544 case OPC_BEQL: /* rx == rx likely */
5545 case OPC_BGEZ: /* 0 >= 0 */
5546 case OPC_BGEZL: /* 0 >= 0 likely */
5547 case OPC_BLEZ: /* 0 <= 0 */
5548 case OPC_BLEZL: /* 0 <= 0 likely */
5550 ctx->hflags |= MIPS_HFLAG_B;
5552 case OPC_BGEZAL: /* 0 >= 0 */
5553 case OPC_BGEZALL: /* 0 >= 0 likely */
5554 /* Always take and link */
5556 ctx->hflags |= MIPS_HFLAG_B;
5558 case OPC_BNE: /* rx != rx */
5559 case OPC_BGTZ: /* 0 > 0 */
5560 case OPC_BLTZ: /* 0 < 0 */
5563 case OPC_BLTZAL: /* 0 < 0 */
5564 /* Handle as an unconditional branch to get correct delay
5567 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5568 ctx->hflags |= MIPS_HFLAG_B;
5570 case OPC_BLTZALL: /* 0 < 0 likely */
5571 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5572 /* Skip the instruction in the delay slot */
5573 ctx->base.pc_next += 4;
5575 case OPC_BNEL: /* rx != rx likely */
5576 case OPC_BGTZL: /* 0 > 0 likely */
5577 case OPC_BLTZL: /* 0 < 0 likely */
5578 /* Skip the instruction in the delay slot */
5579 ctx->base.pc_next += 4;
5582 ctx->hflags |= MIPS_HFLAG_B;
5585 ctx->hflags |= MIPS_HFLAG_BX;
5589 ctx->hflags |= MIPS_HFLAG_B;
5592 ctx->hflags |= MIPS_HFLAG_BR;
5596 ctx->hflags |= MIPS_HFLAG_BR;
5599 MIPS_INVAL("branch/jump");
5600 generate_exception_end(ctx, EXCP_RI);
5606 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5609 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5612 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5615 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5618 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5621 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5624 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5628 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5632 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5635 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5638 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5641 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5644 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5647 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5650 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5652 #if defined(TARGET_MIPS64)
5654 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5658 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5661 ctx->hflags |= MIPS_HFLAG_BC;
5664 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5667 ctx->hflags |= MIPS_HFLAG_BL;
5670 MIPS_INVAL("conditional branch/jump");
5671 generate_exception_end(ctx, EXCP_RI);
5676 ctx->btarget = btgt;
5678 switch (delayslot_size) {
5680 ctx->hflags |= MIPS_HFLAG_BDS16;
5683 ctx->hflags |= MIPS_HFLAG_BDS32;
5688 int post_delay = insn_bytes + delayslot_size;
5689 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5691 tcg_gen_movi_tl(cpu_gpr[blink],
5692 ctx->base.pc_next + post_delay + lowbit);
5696 if (insn_bytes == 2)
5697 ctx->hflags |= MIPS_HFLAG_B16;
5703 /* nanoMIPS Branches */
5704 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5706 int rs, int rt, int32_t offset)
5708 target_ulong btgt = -1;
5709 int bcond_compute = 0;
5710 TCGv t0 = tcg_temp_new();
5711 TCGv t1 = tcg_temp_new();
5713 /* Load needed operands */
5717 /* Compare two registers */
5719 gen_load_gpr(t0, rs);
5720 gen_load_gpr(t1, rt);
5723 btgt = ctx->base.pc_next + insn_bytes + offset;
5726 /* Compare to zero */
5728 gen_load_gpr(t0, rs);
5731 btgt = ctx->base.pc_next + insn_bytes + offset;
5734 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5736 btgt = ctx->base.pc_next + insn_bytes + offset;
5740 /* Jump to register */
5741 if (offset != 0 && offset != 16) {
5742 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5743 others are reserved. */
5744 MIPS_INVAL("jump hint");
5745 generate_exception_end(ctx, EXCP_RI);
5748 gen_load_gpr(btarget, rs);
5751 MIPS_INVAL("branch/jump");
5752 generate_exception_end(ctx, EXCP_RI);
5755 if (bcond_compute == 0) {
5756 /* No condition to be computed */
5758 case OPC_BEQ: /* rx == rx */
5760 ctx->hflags |= MIPS_HFLAG_B;
5762 case OPC_BGEZAL: /* 0 >= 0 */
5763 /* Always take and link */
5764 tcg_gen_movi_tl(cpu_gpr[31],
5765 ctx->base.pc_next + insn_bytes);
5766 ctx->hflags |= MIPS_HFLAG_B;
5768 case OPC_BNE: /* rx != rx */
5769 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5770 /* Skip the instruction in the delay slot */
5771 ctx->base.pc_next += 4;
5774 ctx->hflags |= MIPS_HFLAG_BR;
5778 tcg_gen_movi_tl(cpu_gpr[rt],
5779 ctx->base.pc_next + insn_bytes);
5781 ctx->hflags |= MIPS_HFLAG_BR;
5784 MIPS_INVAL("branch/jump");
5785 generate_exception_end(ctx, EXCP_RI);
5791 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5794 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5797 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5798 tcg_gen_movi_tl(cpu_gpr[31],
5799 ctx->base.pc_next + insn_bytes);
5802 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5804 ctx->hflags |= MIPS_HFLAG_BC;
5807 MIPS_INVAL("conditional branch/jump");
5808 generate_exception_end(ctx, EXCP_RI);
5813 ctx->btarget = btgt;
5816 if (insn_bytes == 2) {
5817 ctx->hflags |= MIPS_HFLAG_B16;
5824 /* special3 bitfield operations */
5825 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
5826 int rs, int lsb, int msb)
5828 TCGv t0 = tcg_temp_new();
5829 TCGv t1 = tcg_temp_new();
5831 gen_load_gpr(t1, rs);
5834 if (lsb + msb > 31) {
5838 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5840 /* The two checks together imply that lsb == 0,
5841 so this is a simple sign-extension. */
5842 tcg_gen_ext32s_tl(t0, t1);
5845 #if defined(TARGET_MIPS64)
5854 if (lsb + msb > 63) {
5857 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5864 gen_load_gpr(t0, rt);
5865 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5866 tcg_gen_ext32s_tl(t0, t0);
5868 #if defined(TARGET_MIPS64)
5879 gen_load_gpr(t0, rt);
5880 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5885 MIPS_INVAL("bitops");
5886 generate_exception_end(ctx, EXCP_RI);
5891 gen_store_gpr(t0, rt);
5896 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
5901 /* If no destination, treat it as a NOP. */
5905 t0 = tcg_temp_new();
5906 gen_load_gpr(t0, rt);
5910 TCGv t1 = tcg_temp_new();
5911 TCGv t2 = tcg_const_tl(0x00FF00FF);
5913 tcg_gen_shri_tl(t1, t0, 8);
5914 tcg_gen_and_tl(t1, t1, t2);
5915 tcg_gen_and_tl(t0, t0, t2);
5916 tcg_gen_shli_tl(t0, t0, 8);
5917 tcg_gen_or_tl(t0, t0, t1);
5920 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5924 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5927 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5929 #if defined(TARGET_MIPS64)
5932 TCGv t1 = tcg_temp_new();
5933 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5935 tcg_gen_shri_tl(t1, t0, 8);
5936 tcg_gen_and_tl(t1, t1, t2);
5937 tcg_gen_and_tl(t0, t0, t2);
5938 tcg_gen_shli_tl(t0, t0, 8);
5939 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5946 TCGv t1 = tcg_temp_new();
5947 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5949 tcg_gen_shri_tl(t1, t0, 16);
5950 tcg_gen_and_tl(t1, t1, t2);
5951 tcg_gen_and_tl(t0, t0, t2);
5952 tcg_gen_shli_tl(t0, t0, 16);
5953 tcg_gen_or_tl(t0, t0, t1);
5954 tcg_gen_shri_tl(t1, t0, 32);
5955 tcg_gen_shli_tl(t0, t0, 32);
5956 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5963 MIPS_INVAL("bsfhl");
5964 generate_exception_end(ctx, EXCP_RI);
5971 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
5980 t0 = tcg_temp_new();
5981 t1 = tcg_temp_new();
5982 gen_load_gpr(t0, rs);
5983 gen_load_gpr(t1, rt);
5984 tcg_gen_shli_tl(t0, t0, imm2 + 1);
5985 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
5986 if (opc == OPC_LSA) {
5987 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5996 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6004 t0 = tcg_temp_new();
6005 if (bits == 0 || bits == wordsz) {
6007 gen_load_gpr(t0, rt);
6009 gen_load_gpr(t0, rs);
6013 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6015 #if defined(TARGET_MIPS64)
6017 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6022 TCGv t1 = tcg_temp_new();
6023 gen_load_gpr(t0, rt);
6024 gen_load_gpr(t1, rs);
6028 TCGv_i64 t2 = tcg_temp_new_i64();
6029 tcg_gen_concat_tl_i64(t2, t1, t0);
6030 tcg_gen_shri_i64(t2, t2, 32 - bits);
6031 gen_move_low32(cpu_gpr[rd], t2);
6032 tcg_temp_free_i64(t2);
6035 #if defined(TARGET_MIPS64)
6037 tcg_gen_shli_tl(t0, t0, bits);
6038 tcg_gen_shri_tl(t1, t1, 64 - bits);
6039 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6049 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6052 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6055 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6058 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6061 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6068 t0 = tcg_temp_new();
6069 gen_load_gpr(t0, rt);
6072 gen_helper_bitswap(cpu_gpr[rd], t0);
6074 #if defined(TARGET_MIPS64)
6076 gen_helper_dbitswap(cpu_gpr[rd], t0);
6083 #ifndef CONFIG_USER_ONLY
6084 /* CP0 (MMU and control) */
6085 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6087 TCGv_i64 t0 = tcg_temp_new_i64();
6088 TCGv_i64 t1 = tcg_temp_new_i64();
6090 tcg_gen_ext_tl_i64(t0, arg);
6091 tcg_gen_ld_i64(t1, cpu_env, off);
6092 #if defined(TARGET_MIPS64)
6093 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6095 tcg_gen_concat32_i64(t1, t1, t0);
6097 tcg_gen_st_i64(t1, cpu_env, off);
6098 tcg_temp_free_i64(t1);
6099 tcg_temp_free_i64(t0);
6102 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6104 TCGv_i64 t0 = tcg_temp_new_i64();
6105 TCGv_i64 t1 = tcg_temp_new_i64();
6107 tcg_gen_ext_tl_i64(t0, arg);
6108 tcg_gen_ld_i64(t1, cpu_env, off);
6109 tcg_gen_concat32_i64(t1, t1, t0);
6110 tcg_gen_st_i64(t1, cpu_env, off);
6111 tcg_temp_free_i64(t1);
6112 tcg_temp_free_i64(t0);
6115 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6117 TCGv_i64 t0 = tcg_temp_new_i64();
6119 tcg_gen_ld_i64(t0, cpu_env, off);
6120 #if defined(TARGET_MIPS64)
6121 tcg_gen_shri_i64(t0, t0, 30);
6123 tcg_gen_shri_i64(t0, t0, 32);
6125 gen_move_low32(arg, t0);
6126 tcg_temp_free_i64(t0);
6129 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6131 TCGv_i64 t0 = tcg_temp_new_i64();
6133 tcg_gen_ld_i64(t0, cpu_env, off);
6134 tcg_gen_shri_i64(t0, t0, 32 + shift);
6135 gen_move_low32(arg, t0);
6136 tcg_temp_free_i64(t0);
6139 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6141 TCGv_i32 t0 = tcg_temp_new_i32();
6143 tcg_gen_ld_i32(t0, cpu_env, off);
6144 tcg_gen_ext_i32_tl(arg, t0);
6145 tcg_temp_free_i32(t0);
6148 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6150 tcg_gen_ld_tl(arg, cpu_env, off);
6151 tcg_gen_ext32s_tl(arg, arg);
6154 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6156 TCGv_i32 t0 = tcg_temp_new_i32();
6158 tcg_gen_trunc_tl_i32(t0, arg);
6159 tcg_gen_st_i32(t0, cpu_env, off);
6160 tcg_temp_free_i32(t0);
6163 #define CP0_CHECK(c) \
6166 goto cp0_unimplemented; \
6170 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6172 const char *rn = "invalid";
6178 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6179 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6183 goto cp0_unimplemented;
6189 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6190 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6194 goto cp0_unimplemented;
6200 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6201 ctx->CP0_LLAddr_shift);
6205 CP0_CHECK(ctx->mrp);
6206 gen_helper_mfhc0_maar(arg, cpu_env);
6210 goto cp0_unimplemented;
6219 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6223 goto cp0_unimplemented;
6227 goto cp0_unimplemented;
6229 trace_mips_translate_c0("mfhc0", rn, reg, sel);
6233 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
6234 tcg_gen_movi_tl(arg, 0);
6237 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6239 const char *rn = "invalid";
6240 uint64_t mask = ctx->PAMask >> 36;
6246 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6247 tcg_gen_andi_tl(arg, arg, mask);
6248 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6252 goto cp0_unimplemented;
6258 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6259 tcg_gen_andi_tl(arg, arg, mask);
6260 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6264 goto cp0_unimplemented;
6270 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6271 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6272 relevant for modern MIPS cores supporting MTHC0, therefore
6273 treating MTHC0 to LLAddr as NOP. */
6277 CP0_CHECK(ctx->mrp);
6278 gen_helper_mthc0_maar(cpu_env, arg);
6282 goto cp0_unimplemented;
6291 tcg_gen_andi_tl(arg, arg, mask);
6292 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6296 goto cp0_unimplemented;
6300 goto cp0_unimplemented;
6302 trace_mips_translate_c0("mthc0", rn, reg, sel);
6305 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
6308 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6310 if (ctx->insn_flags & ISA_MIPS32R6) {
6311 tcg_gen_movi_tl(arg, 0);
6313 tcg_gen_movi_tl(arg, ~0);
6317 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6319 const char *rn = "invalid";
6322 check_insn(ctx, ISA_MIPS32);
6328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6332 CP0_CHECK(ctx->insn_flags & ASE_MT);
6333 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6337 CP0_CHECK(ctx->insn_flags & ASE_MT);
6338 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6342 CP0_CHECK(ctx->insn_flags & ASE_MT);
6343 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6352 goto cp0_unimplemented;
6358 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6359 gen_helper_mfc0_random(arg, cpu_env);
6363 CP0_CHECK(ctx->insn_flags & ASE_MT);
6364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6368 CP0_CHECK(ctx->insn_flags & ASE_MT);
6369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6373 CP0_CHECK(ctx->insn_flags & ASE_MT);
6374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6378 CP0_CHECK(ctx->insn_flags & ASE_MT);
6379 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6383 CP0_CHECK(ctx->insn_flags & ASE_MT);
6384 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6388 CP0_CHECK(ctx->insn_flags & ASE_MT);
6389 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6390 rn = "VPEScheFBack";
6393 CP0_CHECK(ctx->insn_flags & ASE_MT);
6394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6398 goto cp0_unimplemented;
6405 TCGv_i64 tmp = tcg_temp_new_i64();
6406 tcg_gen_ld_i64(tmp, cpu_env,
6407 offsetof(CPUMIPSState, CP0_EntryLo0));
6408 #if defined(TARGET_MIPS64)
6410 /* Move RI/XI fields to bits 31:30 */
6411 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6412 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6415 gen_move_low32(arg, tmp);
6416 tcg_temp_free_i64(tmp);
6421 CP0_CHECK(ctx->insn_flags & ASE_MT);
6422 gen_helper_mfc0_tcstatus(arg, cpu_env);
6426 CP0_CHECK(ctx->insn_flags & ASE_MT);
6427 gen_helper_mfc0_tcbind(arg, cpu_env);
6431 CP0_CHECK(ctx->insn_flags & ASE_MT);
6432 gen_helper_mfc0_tcrestart(arg, cpu_env);
6436 CP0_CHECK(ctx->insn_flags & ASE_MT);
6437 gen_helper_mfc0_tchalt(arg, cpu_env);
6441 CP0_CHECK(ctx->insn_flags & ASE_MT);
6442 gen_helper_mfc0_tccontext(arg, cpu_env);
6446 CP0_CHECK(ctx->insn_flags & ASE_MT);
6447 gen_helper_mfc0_tcschedule(arg, cpu_env);
6451 CP0_CHECK(ctx->insn_flags & ASE_MT);
6452 gen_helper_mfc0_tcschefback(arg, cpu_env);
6456 goto cp0_unimplemented;
6463 TCGv_i64 tmp = tcg_temp_new_i64();
6464 tcg_gen_ld_i64(tmp, cpu_env,
6465 offsetof(CPUMIPSState, CP0_EntryLo1));
6466 #if defined(TARGET_MIPS64)
6468 /* Move RI/XI fields to bits 31:30 */
6469 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6470 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6473 gen_move_low32(arg, tmp);
6474 tcg_temp_free_i64(tmp);
6480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6481 rn = "GlobalNumber";
6484 goto cp0_unimplemented;
6490 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6491 tcg_gen_ext32s_tl(arg, arg);
6495 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6496 rn = "ContextConfig";
6497 goto cp0_unimplemented;
6499 CP0_CHECK(ctx->ulri);
6500 tcg_gen_ld_tl(arg, cpu_env,
6501 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6502 tcg_gen_ext32s_tl(arg, arg);
6506 goto cp0_unimplemented;
6512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6516 check_insn(ctx, ISA_MIPS32R2);
6517 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6522 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6523 tcg_gen_ext32s_tl(arg, arg);
6528 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6529 tcg_gen_ext32s_tl(arg, arg);
6534 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6535 tcg_gen_ext32s_tl(arg, arg);
6540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6550 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6554 goto cp0_unimplemented;
6560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6564 check_insn(ctx, ISA_MIPS32R2);
6565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6569 check_insn(ctx, ISA_MIPS32R2);
6570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6574 check_insn(ctx, ISA_MIPS32R2);
6575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6579 check_insn(ctx, ISA_MIPS32R2);
6580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6584 check_insn(ctx, ISA_MIPS32R2);
6585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6590 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6594 goto cp0_unimplemented;
6600 check_insn(ctx, ISA_MIPS32R2);
6601 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6605 goto cp0_unimplemented;
6611 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6612 tcg_gen_ext32s_tl(arg, arg);
6617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6627 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6628 tcg_gen_andi_tl(arg, arg, ~0xffff);
6632 goto cp0_unimplemented;
6638 /* Mark as an IO operation because we read the time. */
6639 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6642 gen_helper_mfc0_count(arg, cpu_env);
6643 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6646 /* Break the TB to be able to take timer interrupts immediately
6647 after reading count. DISAS_STOP isn't sufficient, we need to
6648 ensure we break completely out of translated code. */
6649 gen_save_pc(ctx->base.pc_next + 4);
6650 ctx->base.is_jmp = DISAS_EXIT;
6653 /* 6,7 are implementation dependent */
6655 goto cp0_unimplemented;
6661 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6662 tcg_gen_ext32s_tl(arg, arg);
6666 goto cp0_unimplemented;
6672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6675 /* 6,7 are implementation dependent */
6677 goto cp0_unimplemented;
6683 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6687 check_insn(ctx, ISA_MIPS32R2);
6688 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6692 check_insn(ctx, ISA_MIPS32R2);
6693 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6697 check_insn(ctx, ISA_MIPS32R2);
6698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6702 goto cp0_unimplemented;
6708 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6712 goto cp0_unimplemented;
6718 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6719 tcg_gen_ext32s_tl(arg, arg);
6723 goto cp0_unimplemented;
6729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6733 check_insn(ctx, ISA_MIPS32R2);
6734 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6735 tcg_gen_ext32s_tl(arg, arg);
6739 check_insn(ctx, ISA_MIPS32R2);
6740 CP0_CHECK(ctx->cmgcr);
6741 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6742 tcg_gen_ext32s_tl(arg, arg);
6746 goto cp0_unimplemented;
6752 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6756 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6760 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6764 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6772 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6775 /* 6,7 are implementation dependent */
6777 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6785 goto cp0_unimplemented;
6791 gen_helper_mfc0_lladdr(arg, cpu_env);
6795 CP0_CHECK(ctx->mrp);
6796 gen_helper_mfc0_maar(arg, cpu_env);
6800 CP0_CHECK(ctx->mrp);
6801 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6805 goto cp0_unimplemented;
6818 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6819 gen_helper_1e0i(mfc0_watchlo, arg, sel);
6823 goto cp0_unimplemented;
6836 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6837 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6841 goto cp0_unimplemented;
6847 #if defined(TARGET_MIPS64)
6848 check_insn(ctx, ISA_MIPS3);
6849 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6850 tcg_gen_ext32s_tl(arg, arg);
6855 goto cp0_unimplemented;
6859 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6860 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6863 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6867 goto cp0_unimplemented;
6871 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6872 rn = "'Diagnostic"; /* implementation dependent */
6877 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6881 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
6882 rn = "TraceControl";
6883 goto cp0_unimplemented;
6885 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
6886 rn = "TraceControl2";
6887 goto cp0_unimplemented;
6889 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
6890 rn = "UserTraceData";
6891 goto cp0_unimplemented;
6893 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
6895 goto cp0_unimplemented;
6897 goto cp0_unimplemented;
6904 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6905 tcg_gen_ext32s_tl(arg, arg);
6909 goto cp0_unimplemented;
6915 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6916 rn = "Performance0";
6919 // gen_helper_mfc0_performance1(arg);
6920 rn = "Performance1";
6921 goto cp0_unimplemented;
6923 // gen_helper_mfc0_performance2(arg);
6924 rn = "Performance2";
6925 goto cp0_unimplemented;
6927 // gen_helper_mfc0_performance3(arg);
6928 rn = "Performance3";
6929 goto cp0_unimplemented;
6931 // gen_helper_mfc0_performance4(arg);
6932 rn = "Performance4";
6933 goto cp0_unimplemented;
6935 // gen_helper_mfc0_performance5(arg);
6936 rn = "Performance5";
6937 goto cp0_unimplemented;
6939 // gen_helper_mfc0_performance6(arg);
6940 rn = "Performance6";
6941 goto cp0_unimplemented;
6943 // gen_helper_mfc0_performance7(arg);
6944 rn = "Performance7";
6945 goto cp0_unimplemented;
6947 goto cp0_unimplemented;
6953 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6957 goto cp0_unimplemented;
6966 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6970 goto cp0_unimplemented;
6980 TCGv_i64 tmp = tcg_temp_new_i64();
6981 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6982 gen_move_low32(arg, tmp);
6983 tcg_temp_free_i64(tmp);
6991 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6995 goto cp0_unimplemented;
7004 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7011 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7015 goto cp0_unimplemented;
7021 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7022 tcg_gen_ext32s_tl(arg, arg);
7026 goto cp0_unimplemented;
7033 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7042 CP0_CHECK(ctx->kscrexist & (1 << sel));
7043 tcg_gen_ld_tl(arg, cpu_env,
7044 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7045 tcg_gen_ext32s_tl(arg, arg);
7049 goto cp0_unimplemented;
7053 goto cp0_unimplemented;
7055 trace_mips_translate_c0("mfc0", rn, reg, sel);
7059 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
7060 gen_mfc0_unimplemented(ctx, arg);
7063 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7065 const char *rn = "invalid";
7068 check_insn(ctx, ISA_MIPS32);
7070 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7078 gen_helper_mtc0_index(cpu_env, arg);
7082 CP0_CHECK(ctx->insn_flags & ASE_MT);
7083 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7087 CP0_CHECK(ctx->insn_flags & ASE_MT);
7092 CP0_CHECK(ctx->insn_flags & ASE_MT);
7102 goto cp0_unimplemented;
7112 CP0_CHECK(ctx->insn_flags & ASE_MT);
7113 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7117 CP0_CHECK(ctx->insn_flags & ASE_MT);
7118 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7122 CP0_CHECK(ctx->insn_flags & ASE_MT);
7123 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7127 CP0_CHECK(ctx->insn_flags & ASE_MT);
7128 gen_helper_mtc0_yqmask(cpu_env, arg);
7132 CP0_CHECK(ctx->insn_flags & ASE_MT);
7133 tcg_gen_st_tl(arg, cpu_env,
7134 offsetof(CPUMIPSState, CP0_VPESchedule));
7138 CP0_CHECK(ctx->insn_flags & ASE_MT);
7139 tcg_gen_st_tl(arg, cpu_env,
7140 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7141 rn = "VPEScheFBack";
7144 CP0_CHECK(ctx->insn_flags & ASE_MT);
7145 gen_helper_mtc0_vpeopt(cpu_env, arg);
7149 goto cp0_unimplemented;
7155 gen_helper_mtc0_entrylo0(cpu_env, arg);
7159 CP0_CHECK(ctx->insn_flags & ASE_MT);
7160 gen_helper_mtc0_tcstatus(cpu_env, arg);
7164 CP0_CHECK(ctx->insn_flags & ASE_MT);
7165 gen_helper_mtc0_tcbind(cpu_env, arg);
7169 CP0_CHECK(ctx->insn_flags & ASE_MT);
7170 gen_helper_mtc0_tcrestart(cpu_env, arg);
7174 CP0_CHECK(ctx->insn_flags & ASE_MT);
7175 gen_helper_mtc0_tchalt(cpu_env, arg);
7179 CP0_CHECK(ctx->insn_flags & ASE_MT);
7180 gen_helper_mtc0_tccontext(cpu_env, arg);
7184 CP0_CHECK(ctx->insn_flags & ASE_MT);
7185 gen_helper_mtc0_tcschedule(cpu_env, arg);
7189 CP0_CHECK(ctx->insn_flags & ASE_MT);
7190 gen_helper_mtc0_tcschefback(cpu_env, arg);
7194 goto cp0_unimplemented;
7200 gen_helper_mtc0_entrylo1(cpu_env, arg);
7206 rn = "GlobalNumber";
7209 goto cp0_unimplemented;
7215 gen_helper_mtc0_context(cpu_env, arg);
7219 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7220 rn = "ContextConfig";
7221 goto cp0_unimplemented;
7223 CP0_CHECK(ctx->ulri);
7224 tcg_gen_st_tl(arg, cpu_env,
7225 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7229 goto cp0_unimplemented;
7235 gen_helper_mtc0_pagemask(cpu_env, arg);
7239 check_insn(ctx, ISA_MIPS32R2);
7240 gen_helper_mtc0_pagegrain(cpu_env, arg);
7242 ctx->base.is_jmp = DISAS_STOP;
7246 gen_helper_mtc0_segctl0(cpu_env, arg);
7251 gen_helper_mtc0_segctl1(cpu_env, arg);
7256 gen_helper_mtc0_segctl2(cpu_env, arg);
7261 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7266 gen_helper_mtc0_pwfield(cpu_env, arg);
7271 gen_helper_mtc0_pwsize(cpu_env, arg);
7275 goto cp0_unimplemented;
7281 gen_helper_mtc0_wired(cpu_env, arg);
7285 check_insn(ctx, ISA_MIPS32R2);
7286 gen_helper_mtc0_srsconf0(cpu_env, arg);
7290 check_insn(ctx, ISA_MIPS32R2);
7291 gen_helper_mtc0_srsconf1(cpu_env, arg);
7295 check_insn(ctx, ISA_MIPS32R2);
7296 gen_helper_mtc0_srsconf2(cpu_env, arg);
7300 check_insn(ctx, ISA_MIPS32R2);
7301 gen_helper_mtc0_srsconf3(cpu_env, arg);
7305 check_insn(ctx, ISA_MIPS32R2);
7306 gen_helper_mtc0_srsconf4(cpu_env, arg);
7311 gen_helper_mtc0_pwctl(cpu_env, arg);
7315 goto cp0_unimplemented;
7321 check_insn(ctx, ISA_MIPS32R2);
7322 gen_helper_mtc0_hwrena(cpu_env, arg);
7323 ctx->base.is_jmp = DISAS_STOP;
7327 goto cp0_unimplemented;
7349 goto cp0_unimplemented;
7355 gen_helper_mtc0_count(cpu_env, arg);
7358 /* 6,7 are implementation dependent */
7360 goto cp0_unimplemented;
7366 gen_helper_mtc0_entryhi(cpu_env, arg);
7370 goto cp0_unimplemented;
7376 gen_helper_mtc0_compare(cpu_env, arg);
7379 /* 6,7 are implementation dependent */
7381 goto cp0_unimplemented;
7387 save_cpu_state(ctx, 1);
7388 gen_helper_mtc0_status(cpu_env, arg);
7389 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7390 gen_save_pc(ctx->base.pc_next + 4);
7391 ctx->base.is_jmp = DISAS_EXIT;
7395 check_insn(ctx, ISA_MIPS32R2);
7396 gen_helper_mtc0_intctl(cpu_env, arg);
7397 /* Stop translation as we may have switched the execution mode */
7398 ctx->base.is_jmp = DISAS_STOP;
7402 check_insn(ctx, ISA_MIPS32R2);
7403 gen_helper_mtc0_srsctl(cpu_env, arg);
7404 /* Stop translation as we may have switched the execution mode */
7405 ctx->base.is_jmp = DISAS_STOP;
7409 check_insn(ctx, ISA_MIPS32R2);
7410 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7411 /* Stop translation as we may have switched the execution mode */
7412 ctx->base.is_jmp = DISAS_STOP;
7416 goto cp0_unimplemented;
7422 save_cpu_state(ctx, 1);
7423 gen_helper_mtc0_cause(cpu_env, arg);
7424 /* Stop translation as we may have triggered an interrupt.
7425 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7426 * translated code to check for pending interrupts. */
7427 gen_save_pc(ctx->base.pc_next + 4);
7428 ctx->base.is_jmp = DISAS_EXIT;
7432 goto cp0_unimplemented;
7438 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7442 goto cp0_unimplemented;
7452 check_insn(ctx, ISA_MIPS32R2);
7453 gen_helper_mtc0_ebase(cpu_env, arg);
7457 goto cp0_unimplemented;
7463 gen_helper_mtc0_config0(cpu_env, arg);
7465 /* Stop translation as we may have switched the execution mode */
7466 ctx->base.is_jmp = DISAS_STOP;
7469 /* ignored, read only */
7473 gen_helper_mtc0_config2(cpu_env, arg);
7475 /* Stop translation as we may have switched the execution mode */
7476 ctx->base.is_jmp = DISAS_STOP;
7479 gen_helper_mtc0_config3(cpu_env, arg);
7481 /* Stop translation as we may have switched the execution mode */
7482 ctx->base.is_jmp = DISAS_STOP;
7485 gen_helper_mtc0_config4(cpu_env, arg);
7487 ctx->base.is_jmp = DISAS_STOP;
7490 gen_helper_mtc0_config5(cpu_env, arg);
7492 /* Stop translation as we may have switched the execution mode */
7493 ctx->base.is_jmp = DISAS_STOP;
7495 /* 6,7 are implementation dependent */
7505 rn = "Invalid config selector";
7506 goto cp0_unimplemented;
7512 gen_helper_mtc0_lladdr(cpu_env, arg);
7516 CP0_CHECK(ctx->mrp);
7517 gen_helper_mtc0_maar(cpu_env, arg);
7521 CP0_CHECK(ctx->mrp);
7522 gen_helper_mtc0_maari(cpu_env, arg);
7526 goto cp0_unimplemented;
7539 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7540 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7544 goto cp0_unimplemented;
7557 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7558 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7562 goto cp0_unimplemented;
7568 #if defined(TARGET_MIPS64)
7569 check_insn(ctx, ISA_MIPS3);
7570 gen_helper_mtc0_xcontext(cpu_env, arg);
7575 goto cp0_unimplemented;
7579 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7580 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7583 gen_helper_mtc0_framemask(cpu_env, arg);
7587 goto cp0_unimplemented;
7592 rn = "Diagnostic"; /* implementation dependent */
7597 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7598 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7599 gen_save_pc(ctx->base.pc_next + 4);
7600 ctx->base.is_jmp = DISAS_EXIT;
7604 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7605 rn = "TraceControl";
7606 /* Stop translation as we may have switched the execution mode */
7607 ctx->base.is_jmp = DISAS_STOP;
7608 goto cp0_unimplemented;
7610 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7611 rn = "TraceControl2";
7612 /* Stop translation as we may have switched the execution mode */
7613 ctx->base.is_jmp = DISAS_STOP;
7614 goto cp0_unimplemented;
7616 /* Stop translation as we may have switched the execution mode */
7617 ctx->base.is_jmp = DISAS_STOP;
7618 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7619 rn = "UserTraceData";
7620 /* Stop translation as we may have switched the execution mode */
7621 ctx->base.is_jmp = DISAS_STOP;
7622 goto cp0_unimplemented;
7624 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7625 /* Stop translation as we may have switched the execution mode */
7626 ctx->base.is_jmp = DISAS_STOP;
7628 goto cp0_unimplemented;
7630 goto cp0_unimplemented;
7637 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7641 goto cp0_unimplemented;
7647 gen_helper_mtc0_performance0(cpu_env, arg);
7648 rn = "Performance0";
7651 // gen_helper_mtc0_performance1(arg);
7652 rn = "Performance1";
7653 goto cp0_unimplemented;
7655 // gen_helper_mtc0_performance2(arg);
7656 rn = "Performance2";
7657 goto cp0_unimplemented;
7659 // gen_helper_mtc0_performance3(arg);
7660 rn = "Performance3";
7661 goto cp0_unimplemented;
7663 // gen_helper_mtc0_performance4(arg);
7664 rn = "Performance4";
7665 goto cp0_unimplemented;
7667 // gen_helper_mtc0_performance5(arg);
7668 rn = "Performance5";
7669 goto cp0_unimplemented;
7671 // gen_helper_mtc0_performance6(arg);
7672 rn = "Performance6";
7673 goto cp0_unimplemented;
7675 // gen_helper_mtc0_performance7(arg);
7676 rn = "Performance7";
7677 goto cp0_unimplemented;
7679 goto cp0_unimplemented;
7685 gen_helper_mtc0_errctl(cpu_env, arg);
7686 ctx->base.is_jmp = DISAS_STOP;
7690 goto cp0_unimplemented;
7703 goto cp0_unimplemented;
7712 gen_helper_mtc0_taglo(cpu_env, arg);
7719 gen_helper_mtc0_datalo(cpu_env, arg);
7723 goto cp0_unimplemented;
7732 gen_helper_mtc0_taghi(cpu_env, arg);
7739 gen_helper_mtc0_datahi(cpu_env, arg);
7744 goto cp0_unimplemented;
7750 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7754 goto cp0_unimplemented;
7761 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7770 CP0_CHECK(ctx->kscrexist & (1 << sel));
7771 tcg_gen_st_tl(arg, cpu_env,
7772 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7776 goto cp0_unimplemented;
7780 goto cp0_unimplemented;
7782 trace_mips_translate_c0("mtc0", rn, reg, sel);
7784 /* For simplicity assume that all writes can cause interrupts. */
7785 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7787 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
7788 * translated code to check for pending interrupts. */
7789 gen_save_pc(ctx->base.pc_next + 4);
7790 ctx->base.is_jmp = DISAS_EXIT;
7795 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7798 #if defined(TARGET_MIPS64)
7799 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7801 const char *rn = "invalid";
7804 check_insn(ctx, ISA_MIPS64);
7810 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7814 CP0_CHECK(ctx->insn_flags & ASE_MT);
7815 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7819 CP0_CHECK(ctx->insn_flags & ASE_MT);
7820 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7824 CP0_CHECK(ctx->insn_flags & ASE_MT);
7825 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7834 goto cp0_unimplemented;
7840 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7841 gen_helper_mfc0_random(arg, cpu_env);
7845 CP0_CHECK(ctx->insn_flags & ASE_MT);
7846 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7850 CP0_CHECK(ctx->insn_flags & ASE_MT);
7851 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7855 CP0_CHECK(ctx->insn_flags & ASE_MT);
7856 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7860 CP0_CHECK(ctx->insn_flags & ASE_MT);
7861 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
7865 CP0_CHECK(ctx->insn_flags & ASE_MT);
7866 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7870 CP0_CHECK(ctx->insn_flags & ASE_MT);
7871 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7872 rn = "VPEScheFBack";
7875 CP0_CHECK(ctx->insn_flags & ASE_MT);
7876 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7880 goto cp0_unimplemented;
7886 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7890 CP0_CHECK(ctx->insn_flags & ASE_MT);
7891 gen_helper_mfc0_tcstatus(arg, cpu_env);
7895 CP0_CHECK(ctx->insn_flags & ASE_MT);
7896 gen_helper_mfc0_tcbind(arg, cpu_env);
7900 CP0_CHECK(ctx->insn_flags & ASE_MT);
7901 gen_helper_dmfc0_tcrestart(arg, cpu_env);
7905 CP0_CHECK(ctx->insn_flags & ASE_MT);
7906 gen_helper_dmfc0_tchalt(arg, cpu_env);
7910 CP0_CHECK(ctx->insn_flags & ASE_MT);
7911 gen_helper_dmfc0_tccontext(arg, cpu_env);
7915 CP0_CHECK(ctx->insn_flags & ASE_MT);
7916 gen_helper_dmfc0_tcschedule(arg, cpu_env);
7920 CP0_CHECK(ctx->insn_flags & ASE_MT);
7921 gen_helper_dmfc0_tcschefback(arg, cpu_env);
7925 goto cp0_unimplemented;
7931 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7936 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7937 rn = "GlobalNumber";
7940 goto cp0_unimplemented;
7946 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7950 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
7951 rn = "ContextConfig";
7952 goto cp0_unimplemented;
7954 CP0_CHECK(ctx->ulri);
7955 tcg_gen_ld_tl(arg, cpu_env,
7956 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7960 goto cp0_unimplemented;
7966 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7970 check_insn(ctx, ISA_MIPS32R2);
7971 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7976 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7981 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7986 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7991 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7996 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8001 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8005 goto cp0_unimplemented;
8011 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8015 check_insn(ctx, ISA_MIPS32R2);
8016 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8020 check_insn(ctx, ISA_MIPS32R2);
8021 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8025 check_insn(ctx, ISA_MIPS32R2);
8026 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8030 check_insn(ctx, ISA_MIPS32R2);
8031 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8035 check_insn(ctx, ISA_MIPS32R2);
8036 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8041 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8045 goto cp0_unimplemented;
8051 check_insn(ctx, ISA_MIPS32R2);
8052 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8056 goto cp0_unimplemented;
8062 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8067 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8072 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8077 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8078 tcg_gen_andi_tl(arg, arg, ~0xffff);
8082 goto cp0_unimplemented;
8088 /* Mark as an IO operation because we read the time. */
8089 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8092 gen_helper_mfc0_count(arg, cpu_env);
8093 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8096 /* Break the TB to be able to take timer interrupts immediately
8097 after reading count. DISAS_STOP isn't sufficient, we need to
8098 ensure we break completely out of translated code. */
8099 gen_save_pc(ctx->base.pc_next + 4);
8100 ctx->base.is_jmp = DISAS_EXIT;
8103 /* 6,7 are implementation dependent */
8105 goto cp0_unimplemented;
8111 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8115 goto cp0_unimplemented;
8121 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8124 /* 6,7 are implementation dependent */
8126 goto cp0_unimplemented;
8132 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8136 check_insn(ctx, ISA_MIPS32R2);
8137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8141 check_insn(ctx, ISA_MIPS32R2);
8142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8146 check_insn(ctx, ISA_MIPS32R2);
8147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8151 goto cp0_unimplemented;
8157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8161 goto cp0_unimplemented;
8167 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8171 goto cp0_unimplemented;
8177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8181 check_insn(ctx, ISA_MIPS32R2);
8182 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8186 check_insn(ctx, ISA_MIPS32R2);
8187 CP0_CHECK(ctx->cmgcr);
8188 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8192 goto cp0_unimplemented;
8198 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8206 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8210 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8214 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8221 /* 6,7 are implementation dependent */
8223 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8227 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8231 goto cp0_unimplemented;
8237 gen_helper_dmfc0_lladdr(arg, cpu_env);
8241 CP0_CHECK(ctx->mrp);
8242 gen_helper_dmfc0_maar(arg, cpu_env);
8246 CP0_CHECK(ctx->mrp);
8247 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8251 goto cp0_unimplemented;
8264 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8265 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8269 goto cp0_unimplemented;
8282 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8283 gen_helper_1e0i(mfc0_watchhi, arg, sel);
8287 goto cp0_unimplemented;
8293 check_insn(ctx, ISA_MIPS3);
8294 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8298 goto cp0_unimplemented;
8302 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8303 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8310 goto cp0_unimplemented;
8314 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8315 rn = "'Diagnostic"; /* implementation dependent */
8320 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8324 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8325 rn = "TraceControl";
8326 goto cp0_unimplemented;
8328 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8329 rn = "TraceControl2";
8330 goto cp0_unimplemented;
8332 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8333 rn = "UserTraceData";
8334 goto cp0_unimplemented;
8336 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8338 goto cp0_unimplemented;
8340 goto cp0_unimplemented;
8347 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8351 goto cp0_unimplemented;
8357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8358 rn = "Performance0";
8361 // gen_helper_dmfc0_performance1(arg);
8362 rn = "Performance1";
8363 goto cp0_unimplemented;
8365 // gen_helper_dmfc0_performance2(arg);
8366 rn = "Performance2";
8367 goto cp0_unimplemented;
8369 // gen_helper_dmfc0_performance3(arg);
8370 rn = "Performance3";
8371 goto cp0_unimplemented;
8373 // gen_helper_dmfc0_performance4(arg);
8374 rn = "Performance4";
8375 goto cp0_unimplemented;
8377 // gen_helper_dmfc0_performance5(arg);
8378 rn = "Performance5";
8379 goto cp0_unimplemented;
8381 // gen_helper_dmfc0_performance6(arg);
8382 rn = "Performance6";
8383 goto cp0_unimplemented;
8385 // gen_helper_dmfc0_performance7(arg);
8386 rn = "Performance7";
8387 goto cp0_unimplemented;
8389 goto cp0_unimplemented;
8395 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8399 goto cp0_unimplemented;
8409 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8413 goto cp0_unimplemented;
8422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8433 goto cp0_unimplemented;
8442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8453 goto cp0_unimplemented;
8459 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8463 goto cp0_unimplemented;
8470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8479 CP0_CHECK(ctx->kscrexist & (1 << sel));
8480 tcg_gen_ld_tl(arg, cpu_env,
8481 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8485 goto cp0_unimplemented;
8489 goto cp0_unimplemented;
8491 trace_mips_translate_c0("dmfc0", rn, reg, sel);
8495 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
8496 gen_mfc0_unimplemented(ctx, arg);
8499 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8501 const char *rn = "invalid";
8504 check_insn(ctx, ISA_MIPS64);
8506 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8514 gen_helper_mtc0_index(cpu_env, arg);
8518 CP0_CHECK(ctx->insn_flags & ASE_MT);
8519 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8523 CP0_CHECK(ctx->insn_flags & ASE_MT);
8528 CP0_CHECK(ctx->insn_flags & ASE_MT);
8538 goto cp0_unimplemented;
8548 CP0_CHECK(ctx->insn_flags & ASE_MT);
8549 gen_helper_mtc0_vpecontrol(cpu_env, arg);
8553 CP0_CHECK(ctx->insn_flags & ASE_MT);
8554 gen_helper_mtc0_vpeconf0(cpu_env, arg);
8558 CP0_CHECK(ctx->insn_flags & ASE_MT);
8559 gen_helper_mtc0_vpeconf1(cpu_env, arg);
8563 CP0_CHECK(ctx->insn_flags & ASE_MT);
8564 gen_helper_mtc0_yqmask(cpu_env, arg);
8568 CP0_CHECK(ctx->insn_flags & ASE_MT);
8569 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8573 CP0_CHECK(ctx->insn_flags & ASE_MT);
8574 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8575 rn = "VPEScheFBack";
8578 CP0_CHECK(ctx->insn_flags & ASE_MT);
8579 gen_helper_mtc0_vpeopt(cpu_env, arg);
8583 goto cp0_unimplemented;
8589 gen_helper_dmtc0_entrylo0(cpu_env, arg);
8593 CP0_CHECK(ctx->insn_flags & ASE_MT);
8594 gen_helper_mtc0_tcstatus(cpu_env, arg);
8598 CP0_CHECK(ctx->insn_flags & ASE_MT);
8599 gen_helper_mtc0_tcbind(cpu_env, arg);
8603 CP0_CHECK(ctx->insn_flags & ASE_MT);
8604 gen_helper_mtc0_tcrestart(cpu_env, arg);
8608 CP0_CHECK(ctx->insn_flags & ASE_MT);
8609 gen_helper_mtc0_tchalt(cpu_env, arg);
8613 CP0_CHECK(ctx->insn_flags & ASE_MT);
8614 gen_helper_mtc0_tccontext(cpu_env, arg);
8618 CP0_CHECK(ctx->insn_flags & ASE_MT);
8619 gen_helper_mtc0_tcschedule(cpu_env, arg);
8623 CP0_CHECK(ctx->insn_flags & ASE_MT);
8624 gen_helper_mtc0_tcschefback(cpu_env, arg);
8628 goto cp0_unimplemented;
8634 gen_helper_dmtc0_entrylo1(cpu_env, arg);
8640 rn = "GlobalNumber";
8643 goto cp0_unimplemented;
8649 gen_helper_mtc0_context(cpu_env, arg);
8653 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8654 rn = "ContextConfig";
8655 goto cp0_unimplemented;
8657 CP0_CHECK(ctx->ulri);
8658 tcg_gen_st_tl(arg, cpu_env,
8659 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8663 goto cp0_unimplemented;
8669 gen_helper_mtc0_pagemask(cpu_env, arg);
8673 check_insn(ctx, ISA_MIPS32R2);
8674 gen_helper_mtc0_pagegrain(cpu_env, arg);
8679 gen_helper_mtc0_segctl0(cpu_env, arg);
8684 gen_helper_mtc0_segctl1(cpu_env, arg);
8689 gen_helper_mtc0_segctl2(cpu_env, arg);
8694 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8699 gen_helper_mtc0_pwfield(cpu_env, arg);
8704 gen_helper_mtc0_pwsize(cpu_env, arg);
8708 goto cp0_unimplemented;
8714 gen_helper_mtc0_wired(cpu_env, arg);
8718 check_insn(ctx, ISA_MIPS32R2);
8719 gen_helper_mtc0_srsconf0(cpu_env, arg);
8723 check_insn(ctx, ISA_MIPS32R2);
8724 gen_helper_mtc0_srsconf1(cpu_env, arg);
8728 check_insn(ctx, ISA_MIPS32R2);
8729 gen_helper_mtc0_srsconf2(cpu_env, arg);
8733 check_insn(ctx, ISA_MIPS32R2);
8734 gen_helper_mtc0_srsconf3(cpu_env, arg);
8738 check_insn(ctx, ISA_MIPS32R2);
8739 gen_helper_mtc0_srsconf4(cpu_env, arg);
8744 gen_helper_mtc0_pwctl(cpu_env, arg);
8748 goto cp0_unimplemented;
8754 check_insn(ctx, ISA_MIPS32R2);
8755 gen_helper_mtc0_hwrena(cpu_env, arg);
8756 ctx->base.is_jmp = DISAS_STOP;
8760 goto cp0_unimplemented;
8782 goto cp0_unimplemented;
8788 gen_helper_mtc0_count(cpu_env, arg);
8791 /* 6,7 are implementation dependent */
8793 goto cp0_unimplemented;
8795 /* Stop translation as we may have switched the execution mode */
8796 ctx->base.is_jmp = DISAS_STOP;
8801 gen_helper_mtc0_entryhi(cpu_env, arg);
8805 goto cp0_unimplemented;
8811 gen_helper_mtc0_compare(cpu_env, arg);
8814 /* 6,7 are implementation dependent */
8816 goto cp0_unimplemented;
8818 /* Stop translation as we may have switched the execution mode */
8819 ctx->base.is_jmp = DISAS_STOP;
8824 save_cpu_state(ctx, 1);
8825 gen_helper_mtc0_status(cpu_env, arg);
8826 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8827 gen_save_pc(ctx->base.pc_next + 4);
8828 ctx->base.is_jmp = DISAS_EXIT;
8832 check_insn(ctx, ISA_MIPS32R2);
8833 gen_helper_mtc0_intctl(cpu_env, arg);
8834 /* Stop translation as we may have switched the execution mode */
8835 ctx->base.is_jmp = DISAS_STOP;
8839 check_insn(ctx, ISA_MIPS32R2);
8840 gen_helper_mtc0_srsctl(cpu_env, arg);
8841 /* Stop translation as we may have switched the execution mode */
8842 ctx->base.is_jmp = DISAS_STOP;
8846 check_insn(ctx, ISA_MIPS32R2);
8847 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8848 /* Stop translation as we may have switched the execution mode */
8849 ctx->base.is_jmp = DISAS_STOP;
8853 goto cp0_unimplemented;
8859 save_cpu_state(ctx, 1);
8860 gen_helper_mtc0_cause(cpu_env, arg);
8861 /* Stop translation as we may have triggered an interrupt.
8862 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8863 * translated code to check for pending interrupts. */
8864 gen_save_pc(ctx->base.pc_next + 4);
8865 ctx->base.is_jmp = DISAS_EXIT;
8869 goto cp0_unimplemented;
8875 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8879 goto cp0_unimplemented;
8889 check_insn(ctx, ISA_MIPS32R2);
8890 gen_helper_mtc0_ebase(cpu_env, arg);
8894 goto cp0_unimplemented;
8900 gen_helper_mtc0_config0(cpu_env, arg);
8902 /* Stop translation as we may have switched the execution mode */
8903 ctx->base.is_jmp = DISAS_STOP;
8906 /* ignored, read only */
8910 gen_helper_mtc0_config2(cpu_env, arg);
8912 /* Stop translation as we may have switched the execution mode */
8913 ctx->base.is_jmp = DISAS_STOP;
8916 gen_helper_mtc0_config3(cpu_env, arg);
8918 /* Stop translation as we may have switched the execution mode */
8919 ctx->base.is_jmp = DISAS_STOP;
8922 /* currently ignored */
8926 gen_helper_mtc0_config5(cpu_env, arg);
8928 /* Stop translation as we may have switched the execution mode */
8929 ctx->base.is_jmp = DISAS_STOP;
8931 /* 6,7 are implementation dependent */
8933 rn = "Invalid config selector";
8934 goto cp0_unimplemented;
8940 gen_helper_mtc0_lladdr(cpu_env, arg);
8944 CP0_CHECK(ctx->mrp);
8945 gen_helper_mtc0_maar(cpu_env, arg);
8949 CP0_CHECK(ctx->mrp);
8950 gen_helper_mtc0_maari(cpu_env, arg);
8954 goto cp0_unimplemented;
8967 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8968 gen_helper_0e1i(mtc0_watchlo, arg, sel);
8972 goto cp0_unimplemented;
8985 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8986 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8990 goto cp0_unimplemented;
8996 check_insn(ctx, ISA_MIPS3);
8997 gen_helper_mtc0_xcontext(cpu_env, arg);
9001 goto cp0_unimplemented;
9005 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9006 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9009 gen_helper_mtc0_framemask(cpu_env, arg);
9013 goto cp0_unimplemented;
9018 rn = "Diagnostic"; /* implementation dependent */
9023 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9024 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9025 gen_save_pc(ctx->base.pc_next + 4);
9026 ctx->base.is_jmp = DISAS_EXIT;
9030 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9031 /* Stop translation as we may have switched the execution mode */
9032 ctx->base.is_jmp = DISAS_STOP;
9033 rn = "TraceControl";
9034 goto cp0_unimplemented;
9036 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9037 /* Stop translation as we may have switched the execution mode */
9038 ctx->base.is_jmp = DISAS_STOP;
9039 rn = "TraceControl2";
9040 goto cp0_unimplemented;
9042 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9043 /* Stop translation as we may have switched the execution mode */
9044 ctx->base.is_jmp = DISAS_STOP;
9045 rn = "UserTraceData";
9046 goto cp0_unimplemented;
9048 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9049 /* Stop translation as we may have switched the execution mode */
9050 ctx->base.is_jmp = DISAS_STOP;
9052 goto cp0_unimplemented;
9054 goto cp0_unimplemented;
9061 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9065 goto cp0_unimplemented;
9071 gen_helper_mtc0_performance0(cpu_env, arg);
9072 rn = "Performance0";
9075 // gen_helper_mtc0_performance1(cpu_env, arg);
9076 rn = "Performance1";
9077 goto cp0_unimplemented;
9079 // gen_helper_mtc0_performance2(cpu_env, arg);
9080 rn = "Performance2";
9081 goto cp0_unimplemented;
9083 // gen_helper_mtc0_performance3(cpu_env, arg);
9084 rn = "Performance3";
9085 goto cp0_unimplemented;
9087 // gen_helper_mtc0_performance4(cpu_env, arg);
9088 rn = "Performance4";
9089 goto cp0_unimplemented;
9091 // gen_helper_mtc0_performance5(cpu_env, arg);
9092 rn = "Performance5";
9093 goto cp0_unimplemented;
9095 // gen_helper_mtc0_performance6(cpu_env, arg);
9096 rn = "Performance6";
9097 goto cp0_unimplemented;
9099 // gen_helper_mtc0_performance7(cpu_env, arg);
9100 rn = "Performance7";
9101 goto cp0_unimplemented;
9103 goto cp0_unimplemented;
9109 gen_helper_mtc0_errctl(cpu_env, arg);
9110 ctx->base.is_jmp = DISAS_STOP;
9114 goto cp0_unimplemented;
9127 goto cp0_unimplemented;
9136 gen_helper_mtc0_taglo(cpu_env, arg);
9143 gen_helper_mtc0_datalo(cpu_env, arg);
9147 goto cp0_unimplemented;
9156 gen_helper_mtc0_taghi(cpu_env, arg);
9163 gen_helper_mtc0_datahi(cpu_env, arg);
9168 goto cp0_unimplemented;
9174 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9178 goto cp0_unimplemented;
9185 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9194 CP0_CHECK(ctx->kscrexist & (1 << sel));
9195 tcg_gen_st_tl(arg, cpu_env,
9196 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9200 goto cp0_unimplemented;
9204 goto cp0_unimplemented;
9206 trace_mips_translate_c0("dmtc0", rn, reg, sel);
9208 /* For simplicity assume that all writes can cause interrupts. */
9209 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9211 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9212 * translated code to check for pending interrupts. */
9213 gen_save_pc(ctx->base.pc_next + 4);
9214 ctx->base.is_jmp = DISAS_EXIT;
9219 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9221 #endif /* TARGET_MIPS64 */
9223 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9224 int u, int sel, int h)
9226 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9227 TCGv t0 = tcg_temp_local_new();
9229 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9230 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9231 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9232 tcg_gen_movi_tl(t0, -1);
9233 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9234 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9235 tcg_gen_movi_tl(t0, -1);
9241 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9244 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9254 gen_helper_mftc0_tcstatus(t0, cpu_env);
9257 gen_helper_mftc0_tcbind(t0, cpu_env);
9260 gen_helper_mftc0_tcrestart(t0, cpu_env);
9263 gen_helper_mftc0_tchalt(t0, cpu_env);
9266 gen_helper_mftc0_tccontext(t0, cpu_env);
9269 gen_helper_mftc0_tcschedule(t0, cpu_env);
9272 gen_helper_mftc0_tcschefback(t0, cpu_env);
9275 gen_mfc0(ctx, t0, rt, sel);
9282 gen_helper_mftc0_entryhi(t0, cpu_env);
9285 gen_mfc0(ctx, t0, rt, sel);
9291 gen_helper_mftc0_status(t0, cpu_env);
9294 gen_mfc0(ctx, t0, rt, sel);
9300 gen_helper_mftc0_cause(t0, cpu_env);
9310 gen_helper_mftc0_epc(t0, cpu_env);
9320 gen_helper_mftc0_ebase(t0, cpu_env);
9337 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9347 gen_helper_mftc0_debug(t0, cpu_env);
9350 gen_mfc0(ctx, t0, rt, sel);
9355 gen_mfc0(ctx, t0, rt, sel);
9357 } else switch (sel) {
9358 /* GPR registers. */
9360 gen_helper_1e0i(mftgpr, t0, rt);
9362 /* Auxiliary CPU registers */
9366 gen_helper_1e0i(mftlo, t0, 0);
9369 gen_helper_1e0i(mfthi, t0, 0);
9372 gen_helper_1e0i(mftacx, t0, 0);
9375 gen_helper_1e0i(mftlo, t0, 1);
9378 gen_helper_1e0i(mfthi, t0, 1);
9381 gen_helper_1e0i(mftacx, t0, 1);
9384 gen_helper_1e0i(mftlo, t0, 2);
9387 gen_helper_1e0i(mfthi, t0, 2);
9390 gen_helper_1e0i(mftacx, t0, 2);
9393 gen_helper_1e0i(mftlo, t0, 3);
9396 gen_helper_1e0i(mfthi, t0, 3);
9399 gen_helper_1e0i(mftacx, t0, 3);
9402 gen_helper_mftdsp(t0, cpu_env);
9408 /* Floating point (COP1). */
9410 /* XXX: For now we support only a single FPU context. */
9412 TCGv_i32 fp0 = tcg_temp_new_i32();
9414 gen_load_fpr32(ctx, fp0, rt);
9415 tcg_gen_ext_i32_tl(t0, fp0);
9416 tcg_temp_free_i32(fp0);
9418 TCGv_i32 fp0 = tcg_temp_new_i32();
9420 gen_load_fpr32h(ctx, fp0, rt);
9421 tcg_gen_ext_i32_tl(t0, fp0);
9422 tcg_temp_free_i32(fp0);
9426 /* XXX: For now we support only a single FPU context. */
9427 gen_helper_1e0i(cfc1, t0, rt);
9429 /* COP2: Not implemented. */
9436 trace_mips_translate_tr("mftr", rt, u, sel, h);
9437 gen_store_gpr(t0, rd);
9443 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9444 generate_exception_end(ctx, EXCP_RI);
9447 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9448 int u, int sel, int h)
9450 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9451 TCGv t0 = tcg_temp_local_new();
9453 gen_load_gpr(t0, rt);
9454 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9455 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9456 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9458 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9459 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9466 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9469 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9479 gen_helper_mttc0_tcstatus(cpu_env, t0);
9482 gen_helper_mttc0_tcbind(cpu_env, t0);
9485 gen_helper_mttc0_tcrestart(cpu_env, t0);
9488 gen_helper_mttc0_tchalt(cpu_env, t0);
9491 gen_helper_mttc0_tccontext(cpu_env, t0);
9494 gen_helper_mttc0_tcschedule(cpu_env, t0);
9497 gen_helper_mttc0_tcschefback(cpu_env, t0);
9500 gen_mtc0(ctx, t0, rd, sel);
9507 gen_helper_mttc0_entryhi(cpu_env, t0);
9510 gen_mtc0(ctx, t0, rd, sel);
9516 gen_helper_mttc0_status(cpu_env, t0);
9519 gen_mtc0(ctx, t0, rd, sel);
9525 gen_helper_mttc0_cause(cpu_env, t0);
9535 gen_helper_mttc0_ebase(cpu_env, t0);
9545 gen_helper_mttc0_debug(cpu_env, t0);
9548 gen_mtc0(ctx, t0, rd, sel);
9553 gen_mtc0(ctx, t0, rd, sel);
9555 } else switch (sel) {
9556 /* GPR registers. */
9558 gen_helper_0e1i(mttgpr, t0, rd);
9560 /* Auxiliary CPU registers */
9564 gen_helper_0e1i(mttlo, t0, 0);
9567 gen_helper_0e1i(mtthi, t0, 0);
9570 gen_helper_0e1i(mttacx, t0, 0);
9573 gen_helper_0e1i(mttlo, t0, 1);
9576 gen_helper_0e1i(mtthi, t0, 1);
9579 gen_helper_0e1i(mttacx, t0, 1);
9582 gen_helper_0e1i(mttlo, t0, 2);
9585 gen_helper_0e1i(mtthi, t0, 2);
9588 gen_helper_0e1i(mttacx, t0, 2);
9591 gen_helper_0e1i(mttlo, t0, 3);
9594 gen_helper_0e1i(mtthi, t0, 3);
9597 gen_helper_0e1i(mttacx, t0, 3);
9600 gen_helper_mttdsp(cpu_env, t0);
9606 /* Floating point (COP1). */
9608 /* XXX: For now we support only a single FPU context. */
9610 TCGv_i32 fp0 = tcg_temp_new_i32();
9612 tcg_gen_trunc_tl_i32(fp0, t0);
9613 gen_store_fpr32(ctx, fp0, rd);
9614 tcg_temp_free_i32(fp0);
9616 TCGv_i32 fp0 = tcg_temp_new_i32();
9618 tcg_gen_trunc_tl_i32(fp0, t0);
9619 gen_store_fpr32h(ctx, fp0, rd);
9620 tcg_temp_free_i32(fp0);
9624 /* XXX: For now we support only a single FPU context. */
9626 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9628 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9629 tcg_temp_free_i32(fs_tmp);
9631 /* Stop translation as we may have changed hflags */
9632 ctx->base.is_jmp = DISAS_STOP;
9634 /* COP2: Not implemented. */
9641 trace_mips_translate_tr("mttr", rd, u, sel, h);
9647 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9648 generate_exception_end(ctx, EXCP_RI);
9651 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9653 const char *opn = "ldst";
9655 check_cp0_enabled(ctx);
9662 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9667 TCGv t0 = tcg_temp_new();
9669 gen_load_gpr(t0, rt);
9670 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9675 #if defined(TARGET_MIPS64)
9677 check_insn(ctx, ISA_MIPS3);
9682 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9686 check_insn(ctx, ISA_MIPS3);
9688 TCGv t0 = tcg_temp_new();
9690 gen_load_gpr(t0, rt);
9691 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9703 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9709 TCGv t0 = tcg_temp_new();
9710 gen_load_gpr(t0, rt);
9711 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9717 check_cp0_enabled(ctx);
9722 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9723 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9727 check_cp0_enabled(ctx);
9728 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9729 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9734 if (!env->tlb->helper_tlbwi)
9736 gen_helper_tlbwi(cpu_env);
9741 if (!env->tlb->helper_tlbinv) {
9744 gen_helper_tlbinv(cpu_env);
9745 } /* treat as nop if TLBINV not supported */
9750 if (!env->tlb->helper_tlbinvf) {
9753 gen_helper_tlbinvf(cpu_env);
9754 } /* treat as nop if TLBINV not supported */
9758 if (!env->tlb->helper_tlbwr)
9760 gen_helper_tlbwr(cpu_env);
9764 if (!env->tlb->helper_tlbp)
9766 gen_helper_tlbp(cpu_env);
9770 if (!env->tlb->helper_tlbr)
9772 gen_helper_tlbr(cpu_env);
9774 case OPC_ERET: /* OPC_ERETNC */
9775 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9776 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9779 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9780 if (ctx->opcode & (1 << bit_shift)) {
9783 check_insn(ctx, ISA_MIPS32R5);
9784 gen_helper_eretnc(cpu_env);
9788 check_insn(ctx, ISA_MIPS2);
9789 gen_helper_eret(cpu_env);
9791 ctx->base.is_jmp = DISAS_EXIT;
9796 check_insn(ctx, ISA_MIPS32);
9797 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9798 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9801 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9803 generate_exception_end(ctx, EXCP_RI);
9805 gen_helper_deret(cpu_env);
9806 ctx->base.is_jmp = DISAS_EXIT;
9811 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
9812 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9813 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9816 /* If we get an exception, we want to restart at next instruction */
9817 ctx->base.pc_next += 4;
9818 save_cpu_state(ctx, 1);
9819 ctx->base.pc_next -= 4;
9820 gen_helper_wait(cpu_env);
9821 ctx->base.is_jmp = DISAS_NORETURN;
9826 generate_exception_end(ctx, EXCP_RI);
9829 (void)opn; /* avoid a compiler warning */
9831 #endif /* !CONFIG_USER_ONLY */
9833 /* CP1 Branches (before delay slot) */
9834 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9835 int32_t cc, int32_t offset)
9837 target_ulong btarget;
9838 TCGv_i32 t0 = tcg_temp_new_i32();
9840 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9841 generate_exception_end(ctx, EXCP_RI);
9846 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
9848 btarget = ctx->base.pc_next + 4 + offset;
9852 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9853 tcg_gen_not_i32(t0, t0);
9854 tcg_gen_andi_i32(t0, t0, 1);
9855 tcg_gen_extu_i32_tl(bcond, t0);
9858 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9859 tcg_gen_not_i32(t0, t0);
9860 tcg_gen_andi_i32(t0, t0, 1);
9861 tcg_gen_extu_i32_tl(bcond, t0);
9864 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9865 tcg_gen_andi_i32(t0, t0, 1);
9866 tcg_gen_extu_i32_tl(bcond, t0);
9869 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9870 tcg_gen_andi_i32(t0, t0, 1);
9871 tcg_gen_extu_i32_tl(bcond, t0);
9873 ctx->hflags |= MIPS_HFLAG_BL;
9877 TCGv_i32 t1 = tcg_temp_new_i32();
9878 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9879 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9880 tcg_gen_nand_i32(t0, t0, t1);
9881 tcg_temp_free_i32(t1);
9882 tcg_gen_andi_i32(t0, t0, 1);
9883 tcg_gen_extu_i32_tl(bcond, t0);
9888 TCGv_i32 t1 = tcg_temp_new_i32();
9889 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9890 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9891 tcg_gen_or_i32(t0, t0, t1);
9892 tcg_temp_free_i32(t1);
9893 tcg_gen_andi_i32(t0, t0, 1);
9894 tcg_gen_extu_i32_tl(bcond, t0);
9899 TCGv_i32 t1 = tcg_temp_new_i32();
9900 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9901 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9902 tcg_gen_and_i32(t0, t0, t1);
9903 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9904 tcg_gen_and_i32(t0, t0, t1);
9905 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9906 tcg_gen_nand_i32(t0, t0, t1);
9907 tcg_temp_free_i32(t1);
9908 tcg_gen_andi_i32(t0, t0, 1);
9909 tcg_gen_extu_i32_tl(bcond, t0);
9914 TCGv_i32 t1 = tcg_temp_new_i32();
9915 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9916 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9917 tcg_gen_or_i32(t0, t0, t1);
9918 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9919 tcg_gen_or_i32(t0, t0, t1);
9920 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9921 tcg_gen_or_i32(t0, t0, t1);
9922 tcg_temp_free_i32(t1);
9923 tcg_gen_andi_i32(t0, t0, 1);
9924 tcg_gen_extu_i32_tl(bcond, t0);
9927 ctx->hflags |= MIPS_HFLAG_BC;
9930 MIPS_INVAL("cp1 cond branch");
9931 generate_exception_end(ctx, EXCP_RI);
9934 ctx->btarget = btarget;
9935 ctx->hflags |= MIPS_HFLAG_BDS32;
9937 tcg_temp_free_i32(t0);
9940 /* R6 CP1 Branches */
9941 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9942 int32_t ft, int32_t offset,
9945 target_ulong btarget;
9946 TCGv_i64 t0 = tcg_temp_new_i64();
9948 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9949 #ifdef MIPS_DEBUG_DISAS
9950 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9951 "\n", ctx->base.pc_next);
9953 generate_exception_end(ctx, EXCP_RI);
9957 gen_load_fpr64(ctx, t0, ft);
9958 tcg_gen_andi_i64(t0, t0, 1);
9960 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9964 tcg_gen_xori_i64(t0, t0, 1);
9965 ctx->hflags |= MIPS_HFLAG_BC;
9968 /* t0 already set */
9969 ctx->hflags |= MIPS_HFLAG_BC;
9972 MIPS_INVAL("cp1 cond branch");
9973 generate_exception_end(ctx, EXCP_RI);
9977 tcg_gen_trunc_i64_tl(bcond, t0);
9979 ctx->btarget = btarget;
9981 switch (delayslot_size) {
9983 ctx->hflags |= MIPS_HFLAG_BDS16;
9986 ctx->hflags |= MIPS_HFLAG_BDS32;
9991 tcg_temp_free_i64(t0);
9994 /* Coprocessor 1 (FPU) */
9996 #define FOP(func, fmt) (((fmt) << 21) | (func))
9999 OPC_ADD_S = FOP(0, FMT_S),
10000 OPC_SUB_S = FOP(1, FMT_S),
10001 OPC_MUL_S = FOP(2, FMT_S),
10002 OPC_DIV_S = FOP(3, FMT_S),
10003 OPC_SQRT_S = FOP(4, FMT_S),
10004 OPC_ABS_S = FOP(5, FMT_S),
10005 OPC_MOV_S = FOP(6, FMT_S),
10006 OPC_NEG_S = FOP(7, FMT_S),
10007 OPC_ROUND_L_S = FOP(8, FMT_S),
10008 OPC_TRUNC_L_S = FOP(9, FMT_S),
10009 OPC_CEIL_L_S = FOP(10, FMT_S),
10010 OPC_FLOOR_L_S = FOP(11, FMT_S),
10011 OPC_ROUND_W_S = FOP(12, FMT_S),
10012 OPC_TRUNC_W_S = FOP(13, FMT_S),
10013 OPC_CEIL_W_S = FOP(14, FMT_S),
10014 OPC_FLOOR_W_S = FOP(15, FMT_S),
10015 OPC_SEL_S = FOP(16, FMT_S),
10016 OPC_MOVCF_S = FOP(17, FMT_S),
10017 OPC_MOVZ_S = FOP(18, FMT_S),
10018 OPC_MOVN_S = FOP(19, FMT_S),
10019 OPC_SELEQZ_S = FOP(20, FMT_S),
10020 OPC_RECIP_S = FOP(21, FMT_S),
10021 OPC_RSQRT_S = FOP(22, FMT_S),
10022 OPC_SELNEZ_S = FOP(23, FMT_S),
10023 OPC_MADDF_S = FOP(24, FMT_S),
10024 OPC_MSUBF_S = FOP(25, FMT_S),
10025 OPC_RINT_S = FOP(26, FMT_S),
10026 OPC_CLASS_S = FOP(27, FMT_S),
10027 OPC_MIN_S = FOP(28, FMT_S),
10028 OPC_RECIP2_S = FOP(28, FMT_S),
10029 OPC_MINA_S = FOP(29, FMT_S),
10030 OPC_RECIP1_S = FOP(29, FMT_S),
10031 OPC_MAX_S = FOP(30, FMT_S),
10032 OPC_RSQRT1_S = FOP(30, FMT_S),
10033 OPC_MAXA_S = FOP(31, FMT_S),
10034 OPC_RSQRT2_S = FOP(31, FMT_S),
10035 OPC_CVT_D_S = FOP(33, FMT_S),
10036 OPC_CVT_W_S = FOP(36, FMT_S),
10037 OPC_CVT_L_S = FOP(37, FMT_S),
10038 OPC_CVT_PS_S = FOP(38, FMT_S),
10039 OPC_CMP_F_S = FOP (48, FMT_S),
10040 OPC_CMP_UN_S = FOP (49, FMT_S),
10041 OPC_CMP_EQ_S = FOP (50, FMT_S),
10042 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10043 OPC_CMP_OLT_S = FOP (52, FMT_S),
10044 OPC_CMP_ULT_S = FOP (53, FMT_S),
10045 OPC_CMP_OLE_S = FOP (54, FMT_S),
10046 OPC_CMP_ULE_S = FOP (55, FMT_S),
10047 OPC_CMP_SF_S = FOP (56, FMT_S),
10048 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10049 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10050 OPC_CMP_NGL_S = FOP (59, FMT_S),
10051 OPC_CMP_LT_S = FOP (60, FMT_S),
10052 OPC_CMP_NGE_S = FOP (61, FMT_S),
10053 OPC_CMP_LE_S = FOP (62, FMT_S),
10054 OPC_CMP_NGT_S = FOP (63, FMT_S),
10056 OPC_ADD_D = FOP(0, FMT_D),
10057 OPC_SUB_D = FOP(1, FMT_D),
10058 OPC_MUL_D = FOP(2, FMT_D),
10059 OPC_DIV_D = FOP(3, FMT_D),
10060 OPC_SQRT_D = FOP(4, FMT_D),
10061 OPC_ABS_D = FOP(5, FMT_D),
10062 OPC_MOV_D = FOP(6, FMT_D),
10063 OPC_NEG_D = FOP(7, FMT_D),
10064 OPC_ROUND_L_D = FOP(8, FMT_D),
10065 OPC_TRUNC_L_D = FOP(9, FMT_D),
10066 OPC_CEIL_L_D = FOP(10, FMT_D),
10067 OPC_FLOOR_L_D = FOP(11, FMT_D),
10068 OPC_ROUND_W_D = FOP(12, FMT_D),
10069 OPC_TRUNC_W_D = FOP(13, FMT_D),
10070 OPC_CEIL_W_D = FOP(14, FMT_D),
10071 OPC_FLOOR_W_D = FOP(15, FMT_D),
10072 OPC_SEL_D = FOP(16, FMT_D),
10073 OPC_MOVCF_D = FOP(17, FMT_D),
10074 OPC_MOVZ_D = FOP(18, FMT_D),
10075 OPC_MOVN_D = FOP(19, FMT_D),
10076 OPC_SELEQZ_D = FOP(20, FMT_D),
10077 OPC_RECIP_D = FOP(21, FMT_D),
10078 OPC_RSQRT_D = FOP(22, FMT_D),
10079 OPC_SELNEZ_D = FOP(23, FMT_D),
10080 OPC_MADDF_D = FOP(24, FMT_D),
10081 OPC_MSUBF_D = FOP(25, FMT_D),
10082 OPC_RINT_D = FOP(26, FMT_D),
10083 OPC_CLASS_D = FOP(27, FMT_D),
10084 OPC_MIN_D = FOP(28, FMT_D),
10085 OPC_RECIP2_D = FOP(28, FMT_D),
10086 OPC_MINA_D = FOP(29, FMT_D),
10087 OPC_RECIP1_D = FOP(29, FMT_D),
10088 OPC_MAX_D = FOP(30, FMT_D),
10089 OPC_RSQRT1_D = FOP(30, FMT_D),
10090 OPC_MAXA_D = FOP(31, FMT_D),
10091 OPC_RSQRT2_D = FOP(31, FMT_D),
10092 OPC_CVT_S_D = FOP(32, FMT_D),
10093 OPC_CVT_W_D = FOP(36, FMT_D),
10094 OPC_CVT_L_D = FOP(37, FMT_D),
10095 OPC_CMP_F_D = FOP (48, FMT_D),
10096 OPC_CMP_UN_D = FOP (49, FMT_D),
10097 OPC_CMP_EQ_D = FOP (50, FMT_D),
10098 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10099 OPC_CMP_OLT_D = FOP (52, FMT_D),
10100 OPC_CMP_ULT_D = FOP (53, FMT_D),
10101 OPC_CMP_OLE_D = FOP (54, FMT_D),
10102 OPC_CMP_ULE_D = FOP (55, FMT_D),
10103 OPC_CMP_SF_D = FOP (56, FMT_D),
10104 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10105 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10106 OPC_CMP_NGL_D = FOP (59, FMT_D),
10107 OPC_CMP_LT_D = FOP (60, FMT_D),
10108 OPC_CMP_NGE_D = FOP (61, FMT_D),
10109 OPC_CMP_LE_D = FOP (62, FMT_D),
10110 OPC_CMP_NGT_D = FOP (63, FMT_D),
10112 OPC_CVT_S_W = FOP(32, FMT_W),
10113 OPC_CVT_D_W = FOP(33, FMT_W),
10114 OPC_CVT_S_L = FOP(32, FMT_L),
10115 OPC_CVT_D_L = FOP(33, FMT_L),
10116 OPC_CVT_PS_PW = FOP(38, FMT_W),
10118 OPC_ADD_PS = FOP(0, FMT_PS),
10119 OPC_SUB_PS = FOP(1, FMT_PS),
10120 OPC_MUL_PS = FOP(2, FMT_PS),
10121 OPC_DIV_PS = FOP(3, FMT_PS),
10122 OPC_ABS_PS = FOP(5, FMT_PS),
10123 OPC_MOV_PS = FOP(6, FMT_PS),
10124 OPC_NEG_PS = FOP(7, FMT_PS),
10125 OPC_MOVCF_PS = FOP(17, FMT_PS),
10126 OPC_MOVZ_PS = FOP(18, FMT_PS),
10127 OPC_MOVN_PS = FOP(19, FMT_PS),
10128 OPC_ADDR_PS = FOP(24, FMT_PS),
10129 OPC_MULR_PS = FOP(26, FMT_PS),
10130 OPC_RECIP2_PS = FOP(28, FMT_PS),
10131 OPC_RECIP1_PS = FOP(29, FMT_PS),
10132 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10133 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10135 OPC_CVT_S_PU = FOP(32, FMT_PS),
10136 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10137 OPC_CVT_S_PL = FOP(40, FMT_PS),
10138 OPC_PLL_PS = FOP(44, FMT_PS),
10139 OPC_PLU_PS = FOP(45, FMT_PS),
10140 OPC_PUL_PS = FOP(46, FMT_PS),
10141 OPC_PUU_PS = FOP(47, FMT_PS),
10142 OPC_CMP_F_PS = FOP (48, FMT_PS),
10143 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10144 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10145 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10146 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10147 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10148 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10149 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10150 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10151 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10152 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10153 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10154 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10155 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10156 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10157 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10161 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10162 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10163 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10164 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10165 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10166 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10167 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10168 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10169 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10170 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10171 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10172 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10173 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10174 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10175 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10176 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10177 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10178 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10179 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10180 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10181 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10182 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10184 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10185 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10186 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10187 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10188 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10189 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10190 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10191 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10192 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10193 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10194 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10195 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10196 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10197 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10198 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10199 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10200 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10201 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10202 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10203 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10204 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10205 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10207 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10209 TCGv t0 = tcg_temp_new();
10214 TCGv_i32 fp0 = tcg_temp_new_i32();
10216 gen_load_fpr32(ctx, fp0, fs);
10217 tcg_gen_ext_i32_tl(t0, fp0);
10218 tcg_temp_free_i32(fp0);
10220 gen_store_gpr(t0, rt);
10223 gen_load_gpr(t0, rt);
10225 TCGv_i32 fp0 = tcg_temp_new_i32();
10227 tcg_gen_trunc_tl_i32(fp0, t0);
10228 gen_store_fpr32(ctx, fp0, fs);
10229 tcg_temp_free_i32(fp0);
10233 gen_helper_1e0i(cfc1, t0, fs);
10234 gen_store_gpr(t0, rt);
10237 gen_load_gpr(t0, rt);
10238 save_cpu_state(ctx, 0);
10240 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10242 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10243 tcg_temp_free_i32(fs_tmp);
10245 /* Stop translation as we may have changed hflags */
10246 ctx->base.is_jmp = DISAS_STOP;
10248 #if defined(TARGET_MIPS64)
10250 gen_load_fpr64(ctx, t0, fs);
10251 gen_store_gpr(t0, rt);
10254 gen_load_gpr(t0, rt);
10255 gen_store_fpr64(ctx, t0, fs);
10260 TCGv_i32 fp0 = tcg_temp_new_i32();
10262 gen_load_fpr32h(ctx, fp0, fs);
10263 tcg_gen_ext_i32_tl(t0, fp0);
10264 tcg_temp_free_i32(fp0);
10266 gen_store_gpr(t0, rt);
10269 gen_load_gpr(t0, rt);
10271 TCGv_i32 fp0 = tcg_temp_new_i32();
10273 tcg_gen_trunc_tl_i32(fp0, t0);
10274 gen_store_fpr32h(ctx, fp0, fs);
10275 tcg_temp_free_i32(fp0);
10279 MIPS_INVAL("cp1 move");
10280 generate_exception_end(ctx, EXCP_RI);
10288 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10295 /* Treat as NOP. */
10300 cond = TCG_COND_EQ;
10302 cond = TCG_COND_NE;
10304 l1 = gen_new_label();
10305 t0 = tcg_temp_new_i32();
10306 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10307 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10308 tcg_temp_free_i32(t0);
10310 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10312 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10317 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10321 TCGv_i32 t0 = tcg_temp_new_i32();
10322 TCGLabel *l1 = gen_new_label();
10325 cond = TCG_COND_EQ;
10327 cond = TCG_COND_NE;
10329 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10330 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10331 gen_load_fpr32(ctx, t0, fs);
10332 gen_store_fpr32(ctx, t0, fd);
10334 tcg_temp_free_i32(t0);
10337 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10340 TCGv_i32 t0 = tcg_temp_new_i32();
10342 TCGLabel *l1 = gen_new_label();
10345 cond = TCG_COND_EQ;
10347 cond = TCG_COND_NE;
10349 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10350 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10351 tcg_temp_free_i32(t0);
10352 fp0 = tcg_temp_new_i64();
10353 gen_load_fpr64(ctx, fp0, fs);
10354 gen_store_fpr64(ctx, fp0, fd);
10355 tcg_temp_free_i64(fp0);
10359 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10363 TCGv_i32 t0 = tcg_temp_new_i32();
10364 TCGLabel *l1 = gen_new_label();
10365 TCGLabel *l2 = gen_new_label();
10368 cond = TCG_COND_EQ;
10370 cond = TCG_COND_NE;
10372 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10373 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10374 gen_load_fpr32(ctx, t0, fs);
10375 gen_store_fpr32(ctx, t0, fd);
10378 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10379 tcg_gen_brcondi_i32(cond, t0, 0, l2);
10380 gen_load_fpr32h(ctx, t0, fs);
10381 gen_store_fpr32h(ctx, t0, fd);
10382 tcg_temp_free_i32(t0);
10386 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10389 TCGv_i32 t1 = tcg_const_i32(0);
10390 TCGv_i32 fp0 = tcg_temp_new_i32();
10391 TCGv_i32 fp1 = tcg_temp_new_i32();
10392 TCGv_i32 fp2 = tcg_temp_new_i32();
10393 gen_load_fpr32(ctx, fp0, fd);
10394 gen_load_fpr32(ctx, fp1, ft);
10395 gen_load_fpr32(ctx, fp2, fs);
10399 tcg_gen_andi_i32(fp0, fp0, 1);
10400 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10403 tcg_gen_andi_i32(fp1, fp1, 1);
10404 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10407 tcg_gen_andi_i32(fp1, fp1, 1);
10408 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10411 MIPS_INVAL("gen_sel_s");
10412 generate_exception_end(ctx, EXCP_RI);
10416 gen_store_fpr32(ctx, fp0, fd);
10417 tcg_temp_free_i32(fp2);
10418 tcg_temp_free_i32(fp1);
10419 tcg_temp_free_i32(fp0);
10420 tcg_temp_free_i32(t1);
10423 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10426 TCGv_i64 t1 = tcg_const_i64(0);
10427 TCGv_i64 fp0 = tcg_temp_new_i64();
10428 TCGv_i64 fp1 = tcg_temp_new_i64();
10429 TCGv_i64 fp2 = tcg_temp_new_i64();
10430 gen_load_fpr64(ctx, fp0, fd);
10431 gen_load_fpr64(ctx, fp1, ft);
10432 gen_load_fpr64(ctx, fp2, fs);
10436 tcg_gen_andi_i64(fp0, fp0, 1);
10437 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10440 tcg_gen_andi_i64(fp1, fp1, 1);
10441 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10444 tcg_gen_andi_i64(fp1, fp1, 1);
10445 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10448 MIPS_INVAL("gen_sel_d");
10449 generate_exception_end(ctx, EXCP_RI);
10453 gen_store_fpr64(ctx, fp0, fd);
10454 tcg_temp_free_i64(fp2);
10455 tcg_temp_free_i64(fp1);
10456 tcg_temp_free_i64(fp0);
10457 tcg_temp_free_i64(t1);
10460 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10461 int ft, int fs, int fd, int cc)
10463 uint32_t func = ctx->opcode & 0x3f;
10467 TCGv_i32 fp0 = tcg_temp_new_i32();
10468 TCGv_i32 fp1 = tcg_temp_new_i32();
10470 gen_load_fpr32(ctx, fp0, fs);
10471 gen_load_fpr32(ctx, fp1, ft);
10472 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10473 tcg_temp_free_i32(fp1);
10474 gen_store_fpr32(ctx, fp0, fd);
10475 tcg_temp_free_i32(fp0);
10480 TCGv_i32 fp0 = tcg_temp_new_i32();
10481 TCGv_i32 fp1 = tcg_temp_new_i32();
10483 gen_load_fpr32(ctx, fp0, fs);
10484 gen_load_fpr32(ctx, fp1, ft);
10485 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10486 tcg_temp_free_i32(fp1);
10487 gen_store_fpr32(ctx, fp0, fd);
10488 tcg_temp_free_i32(fp0);
10493 TCGv_i32 fp0 = tcg_temp_new_i32();
10494 TCGv_i32 fp1 = tcg_temp_new_i32();
10496 gen_load_fpr32(ctx, fp0, fs);
10497 gen_load_fpr32(ctx, fp1, ft);
10498 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10499 tcg_temp_free_i32(fp1);
10500 gen_store_fpr32(ctx, fp0, fd);
10501 tcg_temp_free_i32(fp0);
10506 TCGv_i32 fp0 = tcg_temp_new_i32();
10507 TCGv_i32 fp1 = tcg_temp_new_i32();
10509 gen_load_fpr32(ctx, fp0, fs);
10510 gen_load_fpr32(ctx, fp1, ft);
10511 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10512 tcg_temp_free_i32(fp1);
10513 gen_store_fpr32(ctx, fp0, fd);
10514 tcg_temp_free_i32(fp0);
10519 TCGv_i32 fp0 = tcg_temp_new_i32();
10521 gen_load_fpr32(ctx, fp0, fs);
10522 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10523 gen_store_fpr32(ctx, fp0, fd);
10524 tcg_temp_free_i32(fp0);
10529 TCGv_i32 fp0 = tcg_temp_new_i32();
10531 gen_load_fpr32(ctx, fp0, fs);
10532 if (ctx->abs2008) {
10533 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10535 gen_helper_float_abs_s(fp0, fp0);
10537 gen_store_fpr32(ctx, fp0, fd);
10538 tcg_temp_free_i32(fp0);
10543 TCGv_i32 fp0 = tcg_temp_new_i32();
10545 gen_load_fpr32(ctx, fp0, fs);
10546 gen_store_fpr32(ctx, fp0, fd);
10547 tcg_temp_free_i32(fp0);
10552 TCGv_i32 fp0 = tcg_temp_new_i32();
10554 gen_load_fpr32(ctx, fp0, fs);
10555 if (ctx->abs2008) {
10556 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10558 gen_helper_float_chs_s(fp0, fp0);
10560 gen_store_fpr32(ctx, fp0, fd);
10561 tcg_temp_free_i32(fp0);
10564 case OPC_ROUND_L_S:
10565 check_cp1_64bitmode(ctx);
10567 TCGv_i32 fp32 = tcg_temp_new_i32();
10568 TCGv_i64 fp64 = tcg_temp_new_i64();
10570 gen_load_fpr32(ctx, fp32, fs);
10571 if (ctx->nan2008) {
10572 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10574 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10576 tcg_temp_free_i32(fp32);
10577 gen_store_fpr64(ctx, fp64, fd);
10578 tcg_temp_free_i64(fp64);
10581 case OPC_TRUNC_L_S:
10582 check_cp1_64bitmode(ctx);
10584 TCGv_i32 fp32 = tcg_temp_new_i32();
10585 TCGv_i64 fp64 = tcg_temp_new_i64();
10587 gen_load_fpr32(ctx, fp32, fs);
10588 if (ctx->nan2008) {
10589 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10591 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10593 tcg_temp_free_i32(fp32);
10594 gen_store_fpr64(ctx, fp64, fd);
10595 tcg_temp_free_i64(fp64);
10599 check_cp1_64bitmode(ctx);
10601 TCGv_i32 fp32 = tcg_temp_new_i32();
10602 TCGv_i64 fp64 = tcg_temp_new_i64();
10604 gen_load_fpr32(ctx, fp32, fs);
10605 if (ctx->nan2008) {
10606 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10608 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10610 tcg_temp_free_i32(fp32);
10611 gen_store_fpr64(ctx, fp64, fd);
10612 tcg_temp_free_i64(fp64);
10615 case OPC_FLOOR_L_S:
10616 check_cp1_64bitmode(ctx);
10618 TCGv_i32 fp32 = tcg_temp_new_i32();
10619 TCGv_i64 fp64 = tcg_temp_new_i64();
10621 gen_load_fpr32(ctx, fp32, fs);
10622 if (ctx->nan2008) {
10623 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10625 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10627 tcg_temp_free_i32(fp32);
10628 gen_store_fpr64(ctx, fp64, fd);
10629 tcg_temp_free_i64(fp64);
10632 case OPC_ROUND_W_S:
10634 TCGv_i32 fp0 = tcg_temp_new_i32();
10636 gen_load_fpr32(ctx, fp0, fs);
10637 if (ctx->nan2008) {
10638 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10640 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10642 gen_store_fpr32(ctx, fp0, fd);
10643 tcg_temp_free_i32(fp0);
10646 case OPC_TRUNC_W_S:
10648 TCGv_i32 fp0 = tcg_temp_new_i32();
10650 gen_load_fpr32(ctx, fp0, fs);
10651 if (ctx->nan2008) {
10652 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10654 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10656 gen_store_fpr32(ctx, fp0, fd);
10657 tcg_temp_free_i32(fp0);
10662 TCGv_i32 fp0 = tcg_temp_new_i32();
10664 gen_load_fpr32(ctx, fp0, fs);
10665 if (ctx->nan2008) {
10666 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10668 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10670 gen_store_fpr32(ctx, fp0, fd);
10671 tcg_temp_free_i32(fp0);
10674 case OPC_FLOOR_W_S:
10676 TCGv_i32 fp0 = tcg_temp_new_i32();
10678 gen_load_fpr32(ctx, fp0, fs);
10679 if (ctx->nan2008) {
10680 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10682 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10684 gen_store_fpr32(ctx, fp0, fd);
10685 tcg_temp_free_i32(fp0);
10689 check_insn(ctx, ISA_MIPS32R6);
10690 gen_sel_s(ctx, op1, fd, ft, fs);
10693 check_insn(ctx, ISA_MIPS32R6);
10694 gen_sel_s(ctx, op1, fd, ft, fs);
10697 check_insn(ctx, ISA_MIPS32R6);
10698 gen_sel_s(ctx, op1, fd, ft, fs);
10701 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10702 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10705 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10707 TCGLabel *l1 = gen_new_label();
10711 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10713 fp0 = tcg_temp_new_i32();
10714 gen_load_fpr32(ctx, fp0, fs);
10715 gen_store_fpr32(ctx, fp0, fd);
10716 tcg_temp_free_i32(fp0);
10721 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10723 TCGLabel *l1 = gen_new_label();
10727 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10728 fp0 = tcg_temp_new_i32();
10729 gen_load_fpr32(ctx, fp0, fs);
10730 gen_store_fpr32(ctx, fp0, fd);
10731 tcg_temp_free_i32(fp0);
10738 TCGv_i32 fp0 = tcg_temp_new_i32();
10740 gen_load_fpr32(ctx, fp0, fs);
10741 gen_helper_float_recip_s(fp0, cpu_env, fp0);
10742 gen_store_fpr32(ctx, fp0, fd);
10743 tcg_temp_free_i32(fp0);
10748 TCGv_i32 fp0 = tcg_temp_new_i32();
10750 gen_load_fpr32(ctx, fp0, fs);
10751 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10752 gen_store_fpr32(ctx, fp0, fd);
10753 tcg_temp_free_i32(fp0);
10757 check_insn(ctx, ISA_MIPS32R6);
10759 TCGv_i32 fp0 = tcg_temp_new_i32();
10760 TCGv_i32 fp1 = tcg_temp_new_i32();
10761 TCGv_i32 fp2 = tcg_temp_new_i32();
10762 gen_load_fpr32(ctx, fp0, fs);
10763 gen_load_fpr32(ctx, fp1, ft);
10764 gen_load_fpr32(ctx, fp2, fd);
10765 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10766 gen_store_fpr32(ctx, fp2, fd);
10767 tcg_temp_free_i32(fp2);
10768 tcg_temp_free_i32(fp1);
10769 tcg_temp_free_i32(fp0);
10773 check_insn(ctx, ISA_MIPS32R6);
10775 TCGv_i32 fp0 = tcg_temp_new_i32();
10776 TCGv_i32 fp1 = tcg_temp_new_i32();
10777 TCGv_i32 fp2 = tcg_temp_new_i32();
10778 gen_load_fpr32(ctx, fp0, fs);
10779 gen_load_fpr32(ctx, fp1, ft);
10780 gen_load_fpr32(ctx, fp2, fd);
10781 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10782 gen_store_fpr32(ctx, fp2, fd);
10783 tcg_temp_free_i32(fp2);
10784 tcg_temp_free_i32(fp1);
10785 tcg_temp_free_i32(fp0);
10789 check_insn(ctx, ISA_MIPS32R6);
10791 TCGv_i32 fp0 = tcg_temp_new_i32();
10792 gen_load_fpr32(ctx, fp0, fs);
10793 gen_helper_float_rint_s(fp0, cpu_env, fp0);
10794 gen_store_fpr32(ctx, fp0, fd);
10795 tcg_temp_free_i32(fp0);
10799 check_insn(ctx, ISA_MIPS32R6);
10801 TCGv_i32 fp0 = tcg_temp_new_i32();
10802 gen_load_fpr32(ctx, fp0, fs);
10803 gen_helper_float_class_s(fp0, cpu_env, fp0);
10804 gen_store_fpr32(ctx, fp0, fd);
10805 tcg_temp_free_i32(fp0);
10808 case OPC_MIN_S: /* OPC_RECIP2_S */
10809 if (ctx->insn_flags & ISA_MIPS32R6) {
10811 TCGv_i32 fp0 = tcg_temp_new_i32();
10812 TCGv_i32 fp1 = tcg_temp_new_i32();
10813 TCGv_i32 fp2 = tcg_temp_new_i32();
10814 gen_load_fpr32(ctx, fp0, fs);
10815 gen_load_fpr32(ctx, fp1, ft);
10816 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10817 gen_store_fpr32(ctx, fp2, fd);
10818 tcg_temp_free_i32(fp2);
10819 tcg_temp_free_i32(fp1);
10820 tcg_temp_free_i32(fp0);
10823 check_cp1_64bitmode(ctx);
10825 TCGv_i32 fp0 = tcg_temp_new_i32();
10826 TCGv_i32 fp1 = tcg_temp_new_i32();
10828 gen_load_fpr32(ctx, fp0, fs);
10829 gen_load_fpr32(ctx, fp1, ft);
10830 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10831 tcg_temp_free_i32(fp1);
10832 gen_store_fpr32(ctx, fp0, fd);
10833 tcg_temp_free_i32(fp0);
10837 case OPC_MINA_S: /* OPC_RECIP1_S */
10838 if (ctx->insn_flags & ISA_MIPS32R6) {
10840 TCGv_i32 fp0 = tcg_temp_new_i32();
10841 TCGv_i32 fp1 = tcg_temp_new_i32();
10842 TCGv_i32 fp2 = tcg_temp_new_i32();
10843 gen_load_fpr32(ctx, fp0, fs);
10844 gen_load_fpr32(ctx, fp1, ft);
10845 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10846 gen_store_fpr32(ctx, fp2, fd);
10847 tcg_temp_free_i32(fp2);
10848 tcg_temp_free_i32(fp1);
10849 tcg_temp_free_i32(fp0);
10852 check_cp1_64bitmode(ctx);
10854 TCGv_i32 fp0 = tcg_temp_new_i32();
10856 gen_load_fpr32(ctx, fp0, fs);
10857 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10858 gen_store_fpr32(ctx, fp0, fd);
10859 tcg_temp_free_i32(fp0);
10863 case OPC_MAX_S: /* OPC_RSQRT1_S */
10864 if (ctx->insn_flags & ISA_MIPS32R6) {
10866 TCGv_i32 fp0 = tcg_temp_new_i32();
10867 TCGv_i32 fp1 = tcg_temp_new_i32();
10868 gen_load_fpr32(ctx, fp0, fs);
10869 gen_load_fpr32(ctx, fp1, ft);
10870 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10871 gen_store_fpr32(ctx, fp1, fd);
10872 tcg_temp_free_i32(fp1);
10873 tcg_temp_free_i32(fp0);
10876 check_cp1_64bitmode(ctx);
10878 TCGv_i32 fp0 = tcg_temp_new_i32();
10880 gen_load_fpr32(ctx, fp0, fs);
10881 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10882 gen_store_fpr32(ctx, fp0, fd);
10883 tcg_temp_free_i32(fp0);
10887 case OPC_MAXA_S: /* OPC_RSQRT2_S */
10888 if (ctx->insn_flags & ISA_MIPS32R6) {
10890 TCGv_i32 fp0 = tcg_temp_new_i32();
10891 TCGv_i32 fp1 = tcg_temp_new_i32();
10892 gen_load_fpr32(ctx, fp0, fs);
10893 gen_load_fpr32(ctx, fp1, ft);
10894 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10895 gen_store_fpr32(ctx, fp1, fd);
10896 tcg_temp_free_i32(fp1);
10897 tcg_temp_free_i32(fp0);
10900 check_cp1_64bitmode(ctx);
10902 TCGv_i32 fp0 = tcg_temp_new_i32();
10903 TCGv_i32 fp1 = tcg_temp_new_i32();
10905 gen_load_fpr32(ctx, fp0, fs);
10906 gen_load_fpr32(ctx, fp1, ft);
10907 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10908 tcg_temp_free_i32(fp1);
10909 gen_store_fpr32(ctx, fp0, fd);
10910 tcg_temp_free_i32(fp0);
10915 check_cp1_registers(ctx, fd);
10917 TCGv_i32 fp32 = tcg_temp_new_i32();
10918 TCGv_i64 fp64 = tcg_temp_new_i64();
10920 gen_load_fpr32(ctx, fp32, fs);
10921 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10922 tcg_temp_free_i32(fp32);
10923 gen_store_fpr64(ctx, fp64, fd);
10924 tcg_temp_free_i64(fp64);
10929 TCGv_i32 fp0 = tcg_temp_new_i32();
10931 gen_load_fpr32(ctx, fp0, fs);
10932 if (ctx->nan2008) {
10933 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10935 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10937 gen_store_fpr32(ctx, fp0, fd);
10938 tcg_temp_free_i32(fp0);
10942 check_cp1_64bitmode(ctx);
10944 TCGv_i32 fp32 = tcg_temp_new_i32();
10945 TCGv_i64 fp64 = tcg_temp_new_i64();
10947 gen_load_fpr32(ctx, fp32, fs);
10948 if (ctx->nan2008) {
10949 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10951 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10953 tcg_temp_free_i32(fp32);
10954 gen_store_fpr64(ctx, fp64, fd);
10955 tcg_temp_free_i64(fp64);
10961 TCGv_i64 fp64 = tcg_temp_new_i64();
10962 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10963 TCGv_i32 fp32_1 = tcg_temp_new_i32();
10965 gen_load_fpr32(ctx, fp32_0, fs);
10966 gen_load_fpr32(ctx, fp32_1, ft);
10967 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10968 tcg_temp_free_i32(fp32_1);
10969 tcg_temp_free_i32(fp32_0);
10970 gen_store_fpr64(ctx, fp64, fd);
10971 tcg_temp_free_i64(fp64);
10977 case OPC_CMP_UEQ_S:
10978 case OPC_CMP_OLT_S:
10979 case OPC_CMP_ULT_S:
10980 case OPC_CMP_OLE_S:
10981 case OPC_CMP_ULE_S:
10983 case OPC_CMP_NGLE_S:
10984 case OPC_CMP_SEQ_S:
10985 case OPC_CMP_NGL_S:
10987 case OPC_CMP_NGE_S:
10989 case OPC_CMP_NGT_S:
10990 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10991 if (ctx->opcode & (1 << 6)) {
10992 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
10994 gen_cmp_s(ctx, func-48, ft, fs, cc);
10998 check_cp1_registers(ctx, fs | ft | fd);
11000 TCGv_i64 fp0 = tcg_temp_new_i64();
11001 TCGv_i64 fp1 = tcg_temp_new_i64();
11003 gen_load_fpr64(ctx, fp0, fs);
11004 gen_load_fpr64(ctx, fp1, ft);
11005 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11006 tcg_temp_free_i64(fp1);
11007 gen_store_fpr64(ctx, fp0, fd);
11008 tcg_temp_free_i64(fp0);
11012 check_cp1_registers(ctx, fs | ft | fd);
11014 TCGv_i64 fp0 = tcg_temp_new_i64();
11015 TCGv_i64 fp1 = tcg_temp_new_i64();
11017 gen_load_fpr64(ctx, fp0, fs);
11018 gen_load_fpr64(ctx, fp1, ft);
11019 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11020 tcg_temp_free_i64(fp1);
11021 gen_store_fpr64(ctx, fp0, fd);
11022 tcg_temp_free_i64(fp0);
11026 check_cp1_registers(ctx, fs | ft | fd);
11028 TCGv_i64 fp0 = tcg_temp_new_i64();
11029 TCGv_i64 fp1 = tcg_temp_new_i64();
11031 gen_load_fpr64(ctx, fp0, fs);
11032 gen_load_fpr64(ctx, fp1, ft);
11033 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11034 tcg_temp_free_i64(fp1);
11035 gen_store_fpr64(ctx, fp0, fd);
11036 tcg_temp_free_i64(fp0);
11040 check_cp1_registers(ctx, fs | ft | fd);
11042 TCGv_i64 fp0 = tcg_temp_new_i64();
11043 TCGv_i64 fp1 = tcg_temp_new_i64();
11045 gen_load_fpr64(ctx, fp0, fs);
11046 gen_load_fpr64(ctx, fp1, ft);
11047 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11048 tcg_temp_free_i64(fp1);
11049 gen_store_fpr64(ctx, fp0, fd);
11050 tcg_temp_free_i64(fp0);
11054 check_cp1_registers(ctx, fs | fd);
11056 TCGv_i64 fp0 = tcg_temp_new_i64();
11058 gen_load_fpr64(ctx, fp0, fs);
11059 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11060 gen_store_fpr64(ctx, fp0, fd);
11061 tcg_temp_free_i64(fp0);
11065 check_cp1_registers(ctx, fs | fd);
11067 TCGv_i64 fp0 = tcg_temp_new_i64();
11069 gen_load_fpr64(ctx, fp0, fs);
11070 if (ctx->abs2008) {
11071 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11073 gen_helper_float_abs_d(fp0, fp0);
11075 gen_store_fpr64(ctx, fp0, fd);
11076 tcg_temp_free_i64(fp0);
11080 check_cp1_registers(ctx, fs | fd);
11082 TCGv_i64 fp0 = tcg_temp_new_i64();
11084 gen_load_fpr64(ctx, fp0, fs);
11085 gen_store_fpr64(ctx, fp0, fd);
11086 tcg_temp_free_i64(fp0);
11090 check_cp1_registers(ctx, fs | fd);
11092 TCGv_i64 fp0 = tcg_temp_new_i64();
11094 gen_load_fpr64(ctx, fp0, fs);
11095 if (ctx->abs2008) {
11096 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11098 gen_helper_float_chs_d(fp0, fp0);
11100 gen_store_fpr64(ctx, fp0, fd);
11101 tcg_temp_free_i64(fp0);
11104 case OPC_ROUND_L_D:
11105 check_cp1_64bitmode(ctx);
11107 TCGv_i64 fp0 = tcg_temp_new_i64();
11109 gen_load_fpr64(ctx, fp0, fs);
11110 if (ctx->nan2008) {
11111 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11113 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11115 gen_store_fpr64(ctx, fp0, fd);
11116 tcg_temp_free_i64(fp0);
11119 case OPC_TRUNC_L_D:
11120 check_cp1_64bitmode(ctx);
11122 TCGv_i64 fp0 = tcg_temp_new_i64();
11124 gen_load_fpr64(ctx, fp0, fs);
11125 if (ctx->nan2008) {
11126 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11128 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11130 gen_store_fpr64(ctx, fp0, fd);
11131 tcg_temp_free_i64(fp0);
11135 check_cp1_64bitmode(ctx);
11137 TCGv_i64 fp0 = tcg_temp_new_i64();
11139 gen_load_fpr64(ctx, fp0, fs);
11140 if (ctx->nan2008) {
11141 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11143 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11145 gen_store_fpr64(ctx, fp0, fd);
11146 tcg_temp_free_i64(fp0);
11149 case OPC_FLOOR_L_D:
11150 check_cp1_64bitmode(ctx);
11152 TCGv_i64 fp0 = tcg_temp_new_i64();
11154 gen_load_fpr64(ctx, fp0, fs);
11155 if (ctx->nan2008) {
11156 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11158 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11160 gen_store_fpr64(ctx, fp0, fd);
11161 tcg_temp_free_i64(fp0);
11164 case OPC_ROUND_W_D:
11165 check_cp1_registers(ctx, fs);
11167 TCGv_i32 fp32 = tcg_temp_new_i32();
11168 TCGv_i64 fp64 = tcg_temp_new_i64();
11170 gen_load_fpr64(ctx, fp64, fs);
11171 if (ctx->nan2008) {
11172 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11174 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11176 tcg_temp_free_i64(fp64);
11177 gen_store_fpr32(ctx, fp32, fd);
11178 tcg_temp_free_i32(fp32);
11181 case OPC_TRUNC_W_D:
11182 check_cp1_registers(ctx, fs);
11184 TCGv_i32 fp32 = tcg_temp_new_i32();
11185 TCGv_i64 fp64 = tcg_temp_new_i64();
11187 gen_load_fpr64(ctx, fp64, fs);
11188 if (ctx->nan2008) {
11189 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11191 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11193 tcg_temp_free_i64(fp64);
11194 gen_store_fpr32(ctx, fp32, fd);
11195 tcg_temp_free_i32(fp32);
11199 check_cp1_registers(ctx, fs);
11201 TCGv_i32 fp32 = tcg_temp_new_i32();
11202 TCGv_i64 fp64 = tcg_temp_new_i64();
11204 gen_load_fpr64(ctx, fp64, fs);
11205 if (ctx->nan2008) {
11206 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11208 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11210 tcg_temp_free_i64(fp64);
11211 gen_store_fpr32(ctx, fp32, fd);
11212 tcg_temp_free_i32(fp32);
11215 case OPC_FLOOR_W_D:
11216 check_cp1_registers(ctx, fs);
11218 TCGv_i32 fp32 = tcg_temp_new_i32();
11219 TCGv_i64 fp64 = tcg_temp_new_i64();
11221 gen_load_fpr64(ctx, fp64, fs);
11222 if (ctx->nan2008) {
11223 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11225 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11227 tcg_temp_free_i64(fp64);
11228 gen_store_fpr32(ctx, fp32, fd);
11229 tcg_temp_free_i32(fp32);
11233 check_insn(ctx, ISA_MIPS32R6);
11234 gen_sel_d(ctx, op1, fd, ft, fs);
11237 check_insn(ctx, ISA_MIPS32R6);
11238 gen_sel_d(ctx, op1, fd, ft, fs);
11241 check_insn(ctx, ISA_MIPS32R6);
11242 gen_sel_d(ctx, op1, fd, ft, fs);
11245 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11246 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11249 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11251 TCGLabel *l1 = gen_new_label();
11255 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11257 fp0 = tcg_temp_new_i64();
11258 gen_load_fpr64(ctx, fp0, fs);
11259 gen_store_fpr64(ctx, fp0, fd);
11260 tcg_temp_free_i64(fp0);
11265 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11267 TCGLabel *l1 = gen_new_label();
11271 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11272 fp0 = tcg_temp_new_i64();
11273 gen_load_fpr64(ctx, fp0, fs);
11274 gen_store_fpr64(ctx, fp0, fd);
11275 tcg_temp_free_i64(fp0);
11281 check_cp1_registers(ctx, fs | fd);
11283 TCGv_i64 fp0 = tcg_temp_new_i64();
11285 gen_load_fpr64(ctx, fp0, fs);
11286 gen_helper_float_recip_d(fp0, cpu_env, fp0);
11287 gen_store_fpr64(ctx, fp0, fd);
11288 tcg_temp_free_i64(fp0);
11292 check_cp1_registers(ctx, fs | fd);
11294 TCGv_i64 fp0 = tcg_temp_new_i64();
11296 gen_load_fpr64(ctx, fp0, fs);
11297 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11298 gen_store_fpr64(ctx, fp0, fd);
11299 tcg_temp_free_i64(fp0);
11303 check_insn(ctx, ISA_MIPS32R6);
11305 TCGv_i64 fp0 = tcg_temp_new_i64();
11306 TCGv_i64 fp1 = tcg_temp_new_i64();
11307 TCGv_i64 fp2 = tcg_temp_new_i64();
11308 gen_load_fpr64(ctx, fp0, fs);
11309 gen_load_fpr64(ctx, fp1, ft);
11310 gen_load_fpr64(ctx, fp2, fd);
11311 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11312 gen_store_fpr64(ctx, fp2, fd);
11313 tcg_temp_free_i64(fp2);
11314 tcg_temp_free_i64(fp1);
11315 tcg_temp_free_i64(fp0);
11319 check_insn(ctx, ISA_MIPS32R6);
11321 TCGv_i64 fp0 = tcg_temp_new_i64();
11322 TCGv_i64 fp1 = tcg_temp_new_i64();
11323 TCGv_i64 fp2 = tcg_temp_new_i64();
11324 gen_load_fpr64(ctx, fp0, fs);
11325 gen_load_fpr64(ctx, fp1, ft);
11326 gen_load_fpr64(ctx, fp2, fd);
11327 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11328 gen_store_fpr64(ctx, fp2, fd);
11329 tcg_temp_free_i64(fp2);
11330 tcg_temp_free_i64(fp1);
11331 tcg_temp_free_i64(fp0);
11335 check_insn(ctx, ISA_MIPS32R6);
11337 TCGv_i64 fp0 = tcg_temp_new_i64();
11338 gen_load_fpr64(ctx, fp0, fs);
11339 gen_helper_float_rint_d(fp0, cpu_env, fp0);
11340 gen_store_fpr64(ctx, fp0, fd);
11341 tcg_temp_free_i64(fp0);
11345 check_insn(ctx, ISA_MIPS32R6);
11347 TCGv_i64 fp0 = tcg_temp_new_i64();
11348 gen_load_fpr64(ctx, fp0, fs);
11349 gen_helper_float_class_d(fp0, cpu_env, fp0);
11350 gen_store_fpr64(ctx, fp0, fd);
11351 tcg_temp_free_i64(fp0);
11354 case OPC_MIN_D: /* OPC_RECIP2_D */
11355 if (ctx->insn_flags & ISA_MIPS32R6) {
11357 TCGv_i64 fp0 = tcg_temp_new_i64();
11358 TCGv_i64 fp1 = tcg_temp_new_i64();
11359 gen_load_fpr64(ctx, fp0, fs);
11360 gen_load_fpr64(ctx, fp1, ft);
11361 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11362 gen_store_fpr64(ctx, fp1, fd);
11363 tcg_temp_free_i64(fp1);
11364 tcg_temp_free_i64(fp0);
11367 check_cp1_64bitmode(ctx);
11369 TCGv_i64 fp0 = tcg_temp_new_i64();
11370 TCGv_i64 fp1 = tcg_temp_new_i64();
11372 gen_load_fpr64(ctx, fp0, fs);
11373 gen_load_fpr64(ctx, fp1, ft);
11374 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11375 tcg_temp_free_i64(fp1);
11376 gen_store_fpr64(ctx, fp0, fd);
11377 tcg_temp_free_i64(fp0);
11381 case OPC_MINA_D: /* OPC_RECIP1_D */
11382 if (ctx->insn_flags & ISA_MIPS32R6) {
11384 TCGv_i64 fp0 = tcg_temp_new_i64();
11385 TCGv_i64 fp1 = tcg_temp_new_i64();
11386 gen_load_fpr64(ctx, fp0, fs);
11387 gen_load_fpr64(ctx, fp1, ft);
11388 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11389 gen_store_fpr64(ctx, fp1, fd);
11390 tcg_temp_free_i64(fp1);
11391 tcg_temp_free_i64(fp0);
11394 check_cp1_64bitmode(ctx);
11396 TCGv_i64 fp0 = tcg_temp_new_i64();
11398 gen_load_fpr64(ctx, fp0, fs);
11399 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11400 gen_store_fpr64(ctx, fp0, fd);
11401 tcg_temp_free_i64(fp0);
11405 case OPC_MAX_D: /* OPC_RSQRT1_D */
11406 if (ctx->insn_flags & ISA_MIPS32R6) {
11408 TCGv_i64 fp0 = tcg_temp_new_i64();
11409 TCGv_i64 fp1 = tcg_temp_new_i64();
11410 gen_load_fpr64(ctx, fp0, fs);
11411 gen_load_fpr64(ctx, fp1, ft);
11412 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11413 gen_store_fpr64(ctx, fp1, fd);
11414 tcg_temp_free_i64(fp1);
11415 tcg_temp_free_i64(fp0);
11418 check_cp1_64bitmode(ctx);
11420 TCGv_i64 fp0 = tcg_temp_new_i64();
11422 gen_load_fpr64(ctx, fp0, fs);
11423 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11424 gen_store_fpr64(ctx, fp0, fd);
11425 tcg_temp_free_i64(fp0);
11429 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11430 if (ctx->insn_flags & ISA_MIPS32R6) {
11432 TCGv_i64 fp0 = tcg_temp_new_i64();
11433 TCGv_i64 fp1 = tcg_temp_new_i64();
11434 gen_load_fpr64(ctx, fp0, fs);
11435 gen_load_fpr64(ctx, fp1, ft);
11436 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11437 gen_store_fpr64(ctx, fp1, fd);
11438 tcg_temp_free_i64(fp1);
11439 tcg_temp_free_i64(fp0);
11442 check_cp1_64bitmode(ctx);
11444 TCGv_i64 fp0 = tcg_temp_new_i64();
11445 TCGv_i64 fp1 = tcg_temp_new_i64();
11447 gen_load_fpr64(ctx, fp0, fs);
11448 gen_load_fpr64(ctx, fp1, ft);
11449 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11450 tcg_temp_free_i64(fp1);
11451 gen_store_fpr64(ctx, fp0, fd);
11452 tcg_temp_free_i64(fp0);
11459 case OPC_CMP_UEQ_D:
11460 case OPC_CMP_OLT_D:
11461 case OPC_CMP_ULT_D:
11462 case OPC_CMP_OLE_D:
11463 case OPC_CMP_ULE_D:
11465 case OPC_CMP_NGLE_D:
11466 case OPC_CMP_SEQ_D:
11467 case OPC_CMP_NGL_D:
11469 case OPC_CMP_NGE_D:
11471 case OPC_CMP_NGT_D:
11472 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11473 if (ctx->opcode & (1 << 6)) {
11474 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11476 gen_cmp_d(ctx, func-48, ft, fs, cc);
11480 check_cp1_registers(ctx, fs);
11482 TCGv_i32 fp32 = tcg_temp_new_i32();
11483 TCGv_i64 fp64 = tcg_temp_new_i64();
11485 gen_load_fpr64(ctx, fp64, fs);
11486 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11487 tcg_temp_free_i64(fp64);
11488 gen_store_fpr32(ctx, fp32, fd);
11489 tcg_temp_free_i32(fp32);
11493 check_cp1_registers(ctx, fs);
11495 TCGv_i32 fp32 = tcg_temp_new_i32();
11496 TCGv_i64 fp64 = tcg_temp_new_i64();
11498 gen_load_fpr64(ctx, fp64, fs);
11499 if (ctx->nan2008) {
11500 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11502 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11504 tcg_temp_free_i64(fp64);
11505 gen_store_fpr32(ctx, fp32, fd);
11506 tcg_temp_free_i32(fp32);
11510 check_cp1_64bitmode(ctx);
11512 TCGv_i64 fp0 = tcg_temp_new_i64();
11514 gen_load_fpr64(ctx, fp0, fs);
11515 if (ctx->nan2008) {
11516 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11518 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11520 gen_store_fpr64(ctx, fp0, fd);
11521 tcg_temp_free_i64(fp0);
11526 TCGv_i32 fp0 = tcg_temp_new_i32();
11528 gen_load_fpr32(ctx, fp0, fs);
11529 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11530 gen_store_fpr32(ctx, fp0, fd);
11531 tcg_temp_free_i32(fp0);
11535 check_cp1_registers(ctx, fd);
11537 TCGv_i32 fp32 = tcg_temp_new_i32();
11538 TCGv_i64 fp64 = tcg_temp_new_i64();
11540 gen_load_fpr32(ctx, fp32, fs);
11541 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11542 tcg_temp_free_i32(fp32);
11543 gen_store_fpr64(ctx, fp64, fd);
11544 tcg_temp_free_i64(fp64);
11548 check_cp1_64bitmode(ctx);
11550 TCGv_i32 fp32 = tcg_temp_new_i32();
11551 TCGv_i64 fp64 = tcg_temp_new_i64();
11553 gen_load_fpr64(ctx, fp64, fs);
11554 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11555 tcg_temp_free_i64(fp64);
11556 gen_store_fpr32(ctx, fp32, fd);
11557 tcg_temp_free_i32(fp32);
11561 check_cp1_64bitmode(ctx);
11563 TCGv_i64 fp0 = tcg_temp_new_i64();
11565 gen_load_fpr64(ctx, fp0, fs);
11566 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11567 gen_store_fpr64(ctx, fp0, fd);
11568 tcg_temp_free_i64(fp0);
11571 case OPC_CVT_PS_PW:
11574 TCGv_i64 fp0 = tcg_temp_new_i64();
11576 gen_load_fpr64(ctx, fp0, fs);
11577 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11578 gen_store_fpr64(ctx, fp0, fd);
11579 tcg_temp_free_i64(fp0);
11585 TCGv_i64 fp0 = tcg_temp_new_i64();
11586 TCGv_i64 fp1 = tcg_temp_new_i64();
11588 gen_load_fpr64(ctx, fp0, fs);
11589 gen_load_fpr64(ctx, fp1, ft);
11590 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11591 tcg_temp_free_i64(fp1);
11592 gen_store_fpr64(ctx, fp0, fd);
11593 tcg_temp_free_i64(fp0);
11599 TCGv_i64 fp0 = tcg_temp_new_i64();
11600 TCGv_i64 fp1 = tcg_temp_new_i64();
11602 gen_load_fpr64(ctx, fp0, fs);
11603 gen_load_fpr64(ctx, fp1, ft);
11604 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11605 tcg_temp_free_i64(fp1);
11606 gen_store_fpr64(ctx, fp0, fd);
11607 tcg_temp_free_i64(fp0);
11613 TCGv_i64 fp0 = tcg_temp_new_i64();
11614 TCGv_i64 fp1 = tcg_temp_new_i64();
11616 gen_load_fpr64(ctx, fp0, fs);
11617 gen_load_fpr64(ctx, fp1, ft);
11618 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11619 tcg_temp_free_i64(fp1);
11620 gen_store_fpr64(ctx, fp0, fd);
11621 tcg_temp_free_i64(fp0);
11627 TCGv_i64 fp0 = tcg_temp_new_i64();
11629 gen_load_fpr64(ctx, fp0, fs);
11630 gen_helper_float_abs_ps(fp0, fp0);
11631 gen_store_fpr64(ctx, fp0, fd);
11632 tcg_temp_free_i64(fp0);
11638 TCGv_i64 fp0 = tcg_temp_new_i64();
11640 gen_load_fpr64(ctx, fp0, fs);
11641 gen_store_fpr64(ctx, fp0, fd);
11642 tcg_temp_free_i64(fp0);
11648 TCGv_i64 fp0 = tcg_temp_new_i64();
11650 gen_load_fpr64(ctx, fp0, fs);
11651 gen_helper_float_chs_ps(fp0, fp0);
11652 gen_store_fpr64(ctx, fp0, fd);
11653 tcg_temp_free_i64(fp0);
11658 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11663 TCGLabel *l1 = gen_new_label();
11667 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11668 fp0 = tcg_temp_new_i64();
11669 gen_load_fpr64(ctx, fp0, fs);
11670 gen_store_fpr64(ctx, fp0, fd);
11671 tcg_temp_free_i64(fp0);
11678 TCGLabel *l1 = gen_new_label();
11682 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11683 fp0 = tcg_temp_new_i64();
11684 gen_load_fpr64(ctx, fp0, fs);
11685 gen_store_fpr64(ctx, fp0, fd);
11686 tcg_temp_free_i64(fp0);
11694 TCGv_i64 fp0 = tcg_temp_new_i64();
11695 TCGv_i64 fp1 = tcg_temp_new_i64();
11697 gen_load_fpr64(ctx, fp0, ft);
11698 gen_load_fpr64(ctx, fp1, fs);
11699 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11700 tcg_temp_free_i64(fp1);
11701 gen_store_fpr64(ctx, fp0, fd);
11702 tcg_temp_free_i64(fp0);
11708 TCGv_i64 fp0 = tcg_temp_new_i64();
11709 TCGv_i64 fp1 = tcg_temp_new_i64();
11711 gen_load_fpr64(ctx, fp0, ft);
11712 gen_load_fpr64(ctx, fp1, fs);
11713 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11714 tcg_temp_free_i64(fp1);
11715 gen_store_fpr64(ctx, fp0, fd);
11716 tcg_temp_free_i64(fp0);
11719 case OPC_RECIP2_PS:
11722 TCGv_i64 fp0 = tcg_temp_new_i64();
11723 TCGv_i64 fp1 = tcg_temp_new_i64();
11725 gen_load_fpr64(ctx, fp0, fs);
11726 gen_load_fpr64(ctx, fp1, ft);
11727 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11728 tcg_temp_free_i64(fp1);
11729 gen_store_fpr64(ctx, fp0, fd);
11730 tcg_temp_free_i64(fp0);
11733 case OPC_RECIP1_PS:
11736 TCGv_i64 fp0 = tcg_temp_new_i64();
11738 gen_load_fpr64(ctx, fp0, fs);
11739 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11740 gen_store_fpr64(ctx, fp0, fd);
11741 tcg_temp_free_i64(fp0);
11744 case OPC_RSQRT1_PS:
11747 TCGv_i64 fp0 = tcg_temp_new_i64();
11749 gen_load_fpr64(ctx, fp0, fs);
11750 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11751 gen_store_fpr64(ctx, fp0, fd);
11752 tcg_temp_free_i64(fp0);
11755 case OPC_RSQRT2_PS:
11758 TCGv_i64 fp0 = tcg_temp_new_i64();
11759 TCGv_i64 fp1 = tcg_temp_new_i64();
11761 gen_load_fpr64(ctx, fp0, fs);
11762 gen_load_fpr64(ctx, fp1, ft);
11763 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11764 tcg_temp_free_i64(fp1);
11765 gen_store_fpr64(ctx, fp0, fd);
11766 tcg_temp_free_i64(fp0);
11770 check_cp1_64bitmode(ctx);
11772 TCGv_i32 fp0 = tcg_temp_new_i32();
11774 gen_load_fpr32h(ctx, fp0, fs);
11775 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11776 gen_store_fpr32(ctx, fp0, fd);
11777 tcg_temp_free_i32(fp0);
11780 case OPC_CVT_PW_PS:
11783 TCGv_i64 fp0 = tcg_temp_new_i64();
11785 gen_load_fpr64(ctx, fp0, fs);
11786 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11787 gen_store_fpr64(ctx, fp0, fd);
11788 tcg_temp_free_i64(fp0);
11792 check_cp1_64bitmode(ctx);
11794 TCGv_i32 fp0 = tcg_temp_new_i32();
11796 gen_load_fpr32(ctx, fp0, fs);
11797 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11798 gen_store_fpr32(ctx, fp0, fd);
11799 tcg_temp_free_i32(fp0);
11805 TCGv_i32 fp0 = tcg_temp_new_i32();
11806 TCGv_i32 fp1 = tcg_temp_new_i32();
11808 gen_load_fpr32(ctx, fp0, fs);
11809 gen_load_fpr32(ctx, fp1, ft);
11810 gen_store_fpr32h(ctx, fp0, fd);
11811 gen_store_fpr32(ctx, fp1, fd);
11812 tcg_temp_free_i32(fp0);
11813 tcg_temp_free_i32(fp1);
11819 TCGv_i32 fp0 = tcg_temp_new_i32();
11820 TCGv_i32 fp1 = tcg_temp_new_i32();
11822 gen_load_fpr32(ctx, fp0, fs);
11823 gen_load_fpr32h(ctx, fp1, ft);
11824 gen_store_fpr32(ctx, fp1, fd);
11825 gen_store_fpr32h(ctx, fp0, fd);
11826 tcg_temp_free_i32(fp0);
11827 tcg_temp_free_i32(fp1);
11833 TCGv_i32 fp0 = tcg_temp_new_i32();
11834 TCGv_i32 fp1 = tcg_temp_new_i32();
11836 gen_load_fpr32h(ctx, fp0, fs);
11837 gen_load_fpr32(ctx, fp1, ft);
11838 gen_store_fpr32(ctx, fp1, fd);
11839 gen_store_fpr32h(ctx, fp0, fd);
11840 tcg_temp_free_i32(fp0);
11841 tcg_temp_free_i32(fp1);
11847 TCGv_i32 fp0 = tcg_temp_new_i32();
11848 TCGv_i32 fp1 = tcg_temp_new_i32();
11850 gen_load_fpr32h(ctx, fp0, fs);
11851 gen_load_fpr32h(ctx, fp1, ft);
11852 gen_store_fpr32(ctx, fp1, fd);
11853 gen_store_fpr32h(ctx, fp0, fd);
11854 tcg_temp_free_i32(fp0);
11855 tcg_temp_free_i32(fp1);
11859 case OPC_CMP_UN_PS:
11860 case OPC_CMP_EQ_PS:
11861 case OPC_CMP_UEQ_PS:
11862 case OPC_CMP_OLT_PS:
11863 case OPC_CMP_ULT_PS:
11864 case OPC_CMP_OLE_PS:
11865 case OPC_CMP_ULE_PS:
11866 case OPC_CMP_SF_PS:
11867 case OPC_CMP_NGLE_PS:
11868 case OPC_CMP_SEQ_PS:
11869 case OPC_CMP_NGL_PS:
11870 case OPC_CMP_LT_PS:
11871 case OPC_CMP_NGE_PS:
11872 case OPC_CMP_LE_PS:
11873 case OPC_CMP_NGT_PS:
11874 if (ctx->opcode & (1 << 6)) {
11875 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
11877 gen_cmp_ps(ctx, func-48, ft, fs, cc);
11881 MIPS_INVAL("farith");
11882 generate_exception_end(ctx, EXCP_RI);
11887 /* Coprocessor 3 (FPU) */
11888 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
11889 int fd, int fs, int base, int index)
11891 TCGv t0 = tcg_temp_new();
11894 gen_load_gpr(t0, index);
11895 } else if (index == 0) {
11896 gen_load_gpr(t0, base);
11898 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11900 /* Don't do NOP if destination is zero: we must perform the actual
11906 TCGv_i32 fp0 = tcg_temp_new_i32();
11908 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11909 tcg_gen_trunc_tl_i32(fp0, t0);
11910 gen_store_fpr32(ctx, fp0, fd);
11911 tcg_temp_free_i32(fp0);
11916 check_cp1_registers(ctx, fd);
11918 TCGv_i64 fp0 = tcg_temp_new_i64();
11919 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11920 gen_store_fpr64(ctx, fp0, fd);
11921 tcg_temp_free_i64(fp0);
11925 check_cp1_64bitmode(ctx);
11926 tcg_gen_andi_tl(t0, t0, ~0x7);
11928 TCGv_i64 fp0 = tcg_temp_new_i64();
11930 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11931 gen_store_fpr64(ctx, fp0, fd);
11932 tcg_temp_free_i64(fp0);
11938 TCGv_i32 fp0 = tcg_temp_new_i32();
11939 gen_load_fpr32(ctx, fp0, fs);
11940 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11941 tcg_temp_free_i32(fp0);
11946 check_cp1_registers(ctx, fs);
11948 TCGv_i64 fp0 = tcg_temp_new_i64();
11949 gen_load_fpr64(ctx, fp0, fs);
11950 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11951 tcg_temp_free_i64(fp0);
11955 check_cp1_64bitmode(ctx);
11956 tcg_gen_andi_tl(t0, t0, ~0x7);
11958 TCGv_i64 fp0 = tcg_temp_new_i64();
11959 gen_load_fpr64(ctx, fp0, fs);
11960 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11961 tcg_temp_free_i64(fp0);
11968 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
11969 int fd, int fr, int fs, int ft)
11975 TCGv t0 = tcg_temp_local_new();
11976 TCGv_i32 fp = tcg_temp_new_i32();
11977 TCGv_i32 fph = tcg_temp_new_i32();
11978 TCGLabel *l1 = gen_new_label();
11979 TCGLabel *l2 = gen_new_label();
11981 gen_load_gpr(t0, fr);
11982 tcg_gen_andi_tl(t0, t0, 0x7);
11984 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11985 gen_load_fpr32(ctx, fp, fs);
11986 gen_load_fpr32h(ctx, fph, fs);
11987 gen_store_fpr32(ctx, fp, fd);
11988 gen_store_fpr32h(ctx, fph, fd);
11991 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11993 #ifdef TARGET_WORDS_BIGENDIAN
11994 gen_load_fpr32(ctx, fp, fs);
11995 gen_load_fpr32h(ctx, fph, ft);
11996 gen_store_fpr32h(ctx, fp, fd);
11997 gen_store_fpr32(ctx, fph, fd);
11999 gen_load_fpr32h(ctx, fph, fs);
12000 gen_load_fpr32(ctx, fp, ft);
12001 gen_store_fpr32(ctx, fph, fd);
12002 gen_store_fpr32h(ctx, fp, fd);
12005 tcg_temp_free_i32(fp);
12006 tcg_temp_free_i32(fph);
12012 TCGv_i32 fp0 = tcg_temp_new_i32();
12013 TCGv_i32 fp1 = tcg_temp_new_i32();
12014 TCGv_i32 fp2 = tcg_temp_new_i32();
12016 gen_load_fpr32(ctx, fp0, fs);
12017 gen_load_fpr32(ctx, fp1, ft);
12018 gen_load_fpr32(ctx, fp2, fr);
12019 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12020 tcg_temp_free_i32(fp0);
12021 tcg_temp_free_i32(fp1);
12022 gen_store_fpr32(ctx, fp2, fd);
12023 tcg_temp_free_i32(fp2);
12028 check_cp1_registers(ctx, fd | fs | ft | fr);
12030 TCGv_i64 fp0 = tcg_temp_new_i64();
12031 TCGv_i64 fp1 = tcg_temp_new_i64();
12032 TCGv_i64 fp2 = tcg_temp_new_i64();
12034 gen_load_fpr64(ctx, fp0, fs);
12035 gen_load_fpr64(ctx, fp1, ft);
12036 gen_load_fpr64(ctx, fp2, fr);
12037 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12038 tcg_temp_free_i64(fp0);
12039 tcg_temp_free_i64(fp1);
12040 gen_store_fpr64(ctx, fp2, fd);
12041 tcg_temp_free_i64(fp2);
12047 TCGv_i64 fp0 = tcg_temp_new_i64();
12048 TCGv_i64 fp1 = tcg_temp_new_i64();
12049 TCGv_i64 fp2 = tcg_temp_new_i64();
12051 gen_load_fpr64(ctx, fp0, fs);
12052 gen_load_fpr64(ctx, fp1, ft);
12053 gen_load_fpr64(ctx, fp2, fr);
12054 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12055 tcg_temp_free_i64(fp0);
12056 tcg_temp_free_i64(fp1);
12057 gen_store_fpr64(ctx, fp2, fd);
12058 tcg_temp_free_i64(fp2);
12064 TCGv_i32 fp0 = tcg_temp_new_i32();
12065 TCGv_i32 fp1 = tcg_temp_new_i32();
12066 TCGv_i32 fp2 = tcg_temp_new_i32();
12068 gen_load_fpr32(ctx, fp0, fs);
12069 gen_load_fpr32(ctx, fp1, ft);
12070 gen_load_fpr32(ctx, fp2, fr);
12071 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12072 tcg_temp_free_i32(fp0);
12073 tcg_temp_free_i32(fp1);
12074 gen_store_fpr32(ctx, fp2, fd);
12075 tcg_temp_free_i32(fp2);
12080 check_cp1_registers(ctx, fd | fs | ft | fr);
12082 TCGv_i64 fp0 = tcg_temp_new_i64();
12083 TCGv_i64 fp1 = tcg_temp_new_i64();
12084 TCGv_i64 fp2 = tcg_temp_new_i64();
12086 gen_load_fpr64(ctx, fp0, fs);
12087 gen_load_fpr64(ctx, fp1, ft);
12088 gen_load_fpr64(ctx, fp2, fr);
12089 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12090 tcg_temp_free_i64(fp0);
12091 tcg_temp_free_i64(fp1);
12092 gen_store_fpr64(ctx, fp2, fd);
12093 tcg_temp_free_i64(fp2);
12099 TCGv_i64 fp0 = tcg_temp_new_i64();
12100 TCGv_i64 fp1 = tcg_temp_new_i64();
12101 TCGv_i64 fp2 = tcg_temp_new_i64();
12103 gen_load_fpr64(ctx, fp0, fs);
12104 gen_load_fpr64(ctx, fp1, ft);
12105 gen_load_fpr64(ctx, fp2, fr);
12106 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12107 tcg_temp_free_i64(fp0);
12108 tcg_temp_free_i64(fp1);
12109 gen_store_fpr64(ctx, fp2, fd);
12110 tcg_temp_free_i64(fp2);
12116 TCGv_i32 fp0 = tcg_temp_new_i32();
12117 TCGv_i32 fp1 = tcg_temp_new_i32();
12118 TCGv_i32 fp2 = tcg_temp_new_i32();
12120 gen_load_fpr32(ctx, fp0, fs);
12121 gen_load_fpr32(ctx, fp1, ft);
12122 gen_load_fpr32(ctx, fp2, fr);
12123 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12124 tcg_temp_free_i32(fp0);
12125 tcg_temp_free_i32(fp1);
12126 gen_store_fpr32(ctx, fp2, fd);
12127 tcg_temp_free_i32(fp2);
12132 check_cp1_registers(ctx, fd | fs | ft | fr);
12134 TCGv_i64 fp0 = tcg_temp_new_i64();
12135 TCGv_i64 fp1 = tcg_temp_new_i64();
12136 TCGv_i64 fp2 = tcg_temp_new_i64();
12138 gen_load_fpr64(ctx, fp0, fs);
12139 gen_load_fpr64(ctx, fp1, ft);
12140 gen_load_fpr64(ctx, fp2, fr);
12141 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12142 tcg_temp_free_i64(fp0);
12143 tcg_temp_free_i64(fp1);
12144 gen_store_fpr64(ctx, fp2, fd);
12145 tcg_temp_free_i64(fp2);
12151 TCGv_i64 fp0 = tcg_temp_new_i64();
12152 TCGv_i64 fp1 = tcg_temp_new_i64();
12153 TCGv_i64 fp2 = tcg_temp_new_i64();
12155 gen_load_fpr64(ctx, fp0, fs);
12156 gen_load_fpr64(ctx, fp1, ft);
12157 gen_load_fpr64(ctx, fp2, fr);
12158 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12159 tcg_temp_free_i64(fp0);
12160 tcg_temp_free_i64(fp1);
12161 gen_store_fpr64(ctx, fp2, fd);
12162 tcg_temp_free_i64(fp2);
12168 TCGv_i32 fp0 = tcg_temp_new_i32();
12169 TCGv_i32 fp1 = tcg_temp_new_i32();
12170 TCGv_i32 fp2 = tcg_temp_new_i32();
12172 gen_load_fpr32(ctx, fp0, fs);
12173 gen_load_fpr32(ctx, fp1, ft);
12174 gen_load_fpr32(ctx, fp2, fr);
12175 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12176 tcg_temp_free_i32(fp0);
12177 tcg_temp_free_i32(fp1);
12178 gen_store_fpr32(ctx, fp2, fd);
12179 tcg_temp_free_i32(fp2);
12184 check_cp1_registers(ctx, fd | fs | ft | fr);
12186 TCGv_i64 fp0 = tcg_temp_new_i64();
12187 TCGv_i64 fp1 = tcg_temp_new_i64();
12188 TCGv_i64 fp2 = tcg_temp_new_i64();
12190 gen_load_fpr64(ctx, fp0, fs);
12191 gen_load_fpr64(ctx, fp1, ft);
12192 gen_load_fpr64(ctx, fp2, fr);
12193 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12194 tcg_temp_free_i64(fp0);
12195 tcg_temp_free_i64(fp1);
12196 gen_store_fpr64(ctx, fp2, fd);
12197 tcg_temp_free_i64(fp2);
12203 TCGv_i64 fp0 = tcg_temp_new_i64();
12204 TCGv_i64 fp1 = tcg_temp_new_i64();
12205 TCGv_i64 fp2 = tcg_temp_new_i64();
12207 gen_load_fpr64(ctx, fp0, fs);
12208 gen_load_fpr64(ctx, fp1, ft);
12209 gen_load_fpr64(ctx, fp2, fr);
12210 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12211 tcg_temp_free_i64(fp0);
12212 tcg_temp_free_i64(fp1);
12213 gen_store_fpr64(ctx, fp2, fd);
12214 tcg_temp_free_i64(fp2);
12218 MIPS_INVAL("flt3_arith");
12219 generate_exception_end(ctx, EXCP_RI);
12224 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12228 #if !defined(CONFIG_USER_ONLY)
12229 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12230 Therefore only check the ISA in system mode. */
12231 check_insn(ctx, ISA_MIPS32R2);
12233 t0 = tcg_temp_new();
12237 gen_helper_rdhwr_cpunum(t0, cpu_env);
12238 gen_store_gpr(t0, rt);
12241 gen_helper_rdhwr_synci_step(t0, cpu_env);
12242 gen_store_gpr(t0, rt);
12245 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12248 gen_helper_rdhwr_cc(t0, cpu_env);
12249 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12252 gen_store_gpr(t0, rt);
12253 /* Break the TB to be able to take timer interrupts immediately
12254 after reading count. DISAS_STOP isn't sufficient, we need to ensure
12255 we break completely out of translated code. */
12256 gen_save_pc(ctx->base.pc_next + 4);
12257 ctx->base.is_jmp = DISAS_EXIT;
12260 gen_helper_rdhwr_ccres(t0, cpu_env);
12261 gen_store_gpr(t0, rt);
12264 check_insn(ctx, ISA_MIPS32R6);
12266 /* Performance counter registers are not implemented other than
12267 * control register 0.
12269 generate_exception(ctx, EXCP_RI);
12271 gen_helper_rdhwr_performance(t0, cpu_env);
12272 gen_store_gpr(t0, rt);
12275 check_insn(ctx, ISA_MIPS32R6);
12276 gen_helper_rdhwr_xnp(t0, cpu_env);
12277 gen_store_gpr(t0, rt);
12280 #if defined(CONFIG_USER_ONLY)
12281 tcg_gen_ld_tl(t0, cpu_env,
12282 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12283 gen_store_gpr(t0, rt);
12286 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12287 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12288 tcg_gen_ld_tl(t0, cpu_env,
12289 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12290 gen_store_gpr(t0, rt);
12292 generate_exception_end(ctx, EXCP_RI);
12296 default: /* Invalid */
12297 MIPS_INVAL("rdhwr");
12298 generate_exception_end(ctx, EXCP_RI);
12304 static inline void clear_branch_hflags(DisasContext *ctx)
12306 ctx->hflags &= ~MIPS_HFLAG_BMASK;
12307 if (ctx->base.is_jmp == DISAS_NEXT) {
12308 save_cpu_state(ctx, 0);
12310 /* it is not safe to save ctx->hflags as hflags may be changed
12311 in execution time by the instruction in delay / forbidden slot. */
12312 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12316 static void gen_branch(DisasContext *ctx, int insn_bytes)
12318 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12319 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12320 /* Branches completion */
12321 clear_branch_hflags(ctx);
12322 ctx->base.is_jmp = DISAS_NORETURN;
12323 /* FIXME: Need to clear can_do_io. */
12324 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12325 case MIPS_HFLAG_FBNSLOT:
12326 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12329 /* unconditional branch */
12330 if (proc_hflags & MIPS_HFLAG_BX) {
12331 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12333 gen_goto_tb(ctx, 0, ctx->btarget);
12335 case MIPS_HFLAG_BL:
12336 /* blikely taken case */
12337 gen_goto_tb(ctx, 0, ctx->btarget);
12339 case MIPS_HFLAG_BC:
12340 /* Conditional branch */
12342 TCGLabel *l1 = gen_new_label();
12344 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12345 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12347 gen_goto_tb(ctx, 0, ctx->btarget);
12350 case MIPS_HFLAG_BR:
12351 /* unconditional branch to register */
12352 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12353 TCGv t0 = tcg_temp_new();
12354 TCGv_i32 t1 = tcg_temp_new_i32();
12356 tcg_gen_andi_tl(t0, btarget, 0x1);
12357 tcg_gen_trunc_tl_i32(t1, t0);
12359 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12360 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12361 tcg_gen_or_i32(hflags, hflags, t1);
12362 tcg_temp_free_i32(t1);
12364 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12366 tcg_gen_mov_tl(cpu_PC, btarget);
12368 if (ctx->base.singlestep_enabled) {
12369 save_cpu_state(ctx, 0);
12370 gen_helper_raise_exception_debug(cpu_env);
12372 tcg_gen_lookup_and_goto_ptr();
12375 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12381 /* Compact Branches */
12382 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12383 int rs, int rt, int32_t offset)
12385 int bcond_compute = 0;
12386 TCGv t0 = tcg_temp_new();
12387 TCGv t1 = tcg_temp_new();
12388 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12390 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12391 #ifdef MIPS_DEBUG_DISAS
12392 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12393 "\n", ctx->base.pc_next);
12395 generate_exception_end(ctx, EXCP_RI);
12399 /* Load needed operands and calculate btarget */
12401 /* compact branch */
12402 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12403 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12404 gen_load_gpr(t0, rs);
12405 gen_load_gpr(t1, rt);
12407 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12408 if (rs <= rt && rs == 0) {
12409 /* OPC_BEQZALC, OPC_BNEZALC */
12410 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12413 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12414 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12415 gen_load_gpr(t0, rs);
12416 gen_load_gpr(t1, rt);
12418 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12420 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12421 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12422 if (rs == 0 || rs == rt) {
12423 /* OPC_BLEZALC, OPC_BGEZALC */
12424 /* OPC_BGTZALC, OPC_BLTZALC */
12425 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12427 gen_load_gpr(t0, rs);
12428 gen_load_gpr(t1, rt);
12430 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12434 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12439 /* OPC_BEQZC, OPC_BNEZC */
12440 gen_load_gpr(t0, rs);
12442 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12444 /* OPC_JIC, OPC_JIALC */
12445 TCGv tbase = tcg_temp_new();
12446 TCGv toffset = tcg_temp_new();
12448 gen_load_gpr(tbase, rt);
12449 tcg_gen_movi_tl(toffset, offset);
12450 gen_op_addr_add(ctx, btarget, tbase, toffset);
12451 tcg_temp_free(tbase);
12452 tcg_temp_free(toffset);
12456 MIPS_INVAL("Compact branch/jump");
12457 generate_exception_end(ctx, EXCP_RI);
12461 if (bcond_compute == 0) {
12462 /* Uncoditional compact branch */
12465 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12468 ctx->hflags |= MIPS_HFLAG_BR;
12471 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12474 ctx->hflags |= MIPS_HFLAG_B;
12477 MIPS_INVAL("Compact branch/jump");
12478 generate_exception_end(ctx, EXCP_RI);
12482 /* Generating branch here as compact branches don't have delay slot */
12483 gen_branch(ctx, 4);
12485 /* Conditional compact branch */
12486 TCGLabel *fs = gen_new_label();
12487 save_cpu_state(ctx, 0);
12490 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12491 if (rs == 0 && rt != 0) {
12493 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12494 } else if (rs != 0 && rt != 0 && rs == rt) {
12496 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12499 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12502 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12503 if (rs == 0 && rt != 0) {
12505 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12506 } else if (rs != 0 && rt != 0 && rs == rt) {
12508 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12511 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12514 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12515 if (rs == 0 && rt != 0) {
12517 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12518 } else if (rs != 0 && rt != 0 && rs == rt) {
12520 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12523 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12526 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12527 if (rs == 0 && rt != 0) {
12529 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12530 } else if (rs != 0 && rt != 0 && rs == rt) {
12532 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12535 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12538 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12539 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12541 /* OPC_BOVC, OPC_BNVC */
12542 TCGv t2 = tcg_temp_new();
12543 TCGv t3 = tcg_temp_new();
12544 TCGv t4 = tcg_temp_new();
12545 TCGv input_overflow = tcg_temp_new();
12547 gen_load_gpr(t0, rs);
12548 gen_load_gpr(t1, rt);
12549 tcg_gen_ext32s_tl(t2, t0);
12550 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12551 tcg_gen_ext32s_tl(t3, t1);
12552 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12553 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12555 tcg_gen_add_tl(t4, t2, t3);
12556 tcg_gen_ext32s_tl(t4, t4);
12557 tcg_gen_xor_tl(t2, t2, t3);
12558 tcg_gen_xor_tl(t3, t4, t3);
12559 tcg_gen_andc_tl(t2, t3, t2);
12560 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12561 tcg_gen_or_tl(t4, t4, input_overflow);
12562 if (opc == OPC_BOVC) {
12564 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12567 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12569 tcg_temp_free(input_overflow);
12573 } else if (rs < rt && rs == 0) {
12574 /* OPC_BEQZALC, OPC_BNEZALC */
12575 if (opc == OPC_BEQZALC) {
12577 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12580 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12583 /* OPC_BEQC, OPC_BNEC */
12584 if (opc == OPC_BEQC) {
12586 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12589 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12594 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12597 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12600 MIPS_INVAL("Compact conditional branch/jump");
12601 generate_exception_end(ctx, EXCP_RI);
12605 /* Generating branch here as compact branches don't have delay slot */
12606 gen_goto_tb(ctx, 1, ctx->btarget);
12609 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12617 /* ISA extensions (ASEs) */
12618 /* MIPS16 extension to MIPS32 */
12620 /* MIPS16 major opcodes */
12622 M16_OPC_ADDIUSP = 0x00,
12623 M16_OPC_ADDIUPC = 0x01,
12625 M16_OPC_JAL = 0x03,
12626 M16_OPC_BEQZ = 0x04,
12627 M16_OPC_BNEQZ = 0x05,
12628 M16_OPC_SHIFT = 0x06,
12630 M16_OPC_RRIA = 0x08,
12631 M16_OPC_ADDIU8 = 0x09,
12632 M16_OPC_SLTI = 0x0a,
12633 M16_OPC_SLTIU = 0x0b,
12636 M16_OPC_CMPI = 0x0e,
12640 M16_OPC_LWSP = 0x12,
12642 M16_OPC_LBU = 0x14,
12643 M16_OPC_LHU = 0x15,
12644 M16_OPC_LWPC = 0x16,
12645 M16_OPC_LWU = 0x17,
12648 M16_OPC_SWSP = 0x1a,
12650 M16_OPC_RRR = 0x1c,
12652 M16_OPC_EXTEND = 0x1e,
12656 /* I8 funct field */
12675 /* RR funct field */
12709 /* I64 funct field */
12717 I64_DADDIUPC = 0x6,
12721 /* RR ry field for CNVT */
12723 RR_RY_CNVT_ZEB = 0x0,
12724 RR_RY_CNVT_ZEH = 0x1,
12725 RR_RY_CNVT_ZEW = 0x2,
12726 RR_RY_CNVT_SEB = 0x4,
12727 RR_RY_CNVT_SEH = 0x5,
12728 RR_RY_CNVT_SEW = 0x6,
12731 static int xlat (int r)
12733 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12738 static void gen_mips16_save (DisasContext *ctx,
12739 int xsregs, int aregs,
12740 int do_ra, int do_s0, int do_s1,
12743 TCGv t0 = tcg_temp_new();
12744 TCGv t1 = tcg_temp_new();
12745 TCGv t2 = tcg_temp_new();
12775 generate_exception_end(ctx, EXCP_RI);
12781 gen_base_offset_addr(ctx, t0, 29, 12);
12782 gen_load_gpr(t1, 7);
12783 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12786 gen_base_offset_addr(ctx, t0, 29, 8);
12787 gen_load_gpr(t1, 6);
12788 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12791 gen_base_offset_addr(ctx, t0, 29, 4);
12792 gen_load_gpr(t1, 5);
12793 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12796 gen_base_offset_addr(ctx, t0, 29, 0);
12797 gen_load_gpr(t1, 4);
12798 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12801 gen_load_gpr(t0, 29);
12803 #define DECR_AND_STORE(reg) do { \
12804 tcg_gen_movi_tl(t2, -4); \
12805 gen_op_addr_add(ctx, t0, t0, t2); \
12806 gen_load_gpr(t1, reg); \
12807 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12811 DECR_AND_STORE(31);
12816 DECR_AND_STORE(30);
12819 DECR_AND_STORE(23);
12822 DECR_AND_STORE(22);
12825 DECR_AND_STORE(21);
12828 DECR_AND_STORE(20);
12831 DECR_AND_STORE(19);
12834 DECR_AND_STORE(18);
12838 DECR_AND_STORE(17);
12841 DECR_AND_STORE(16);
12871 generate_exception_end(ctx, EXCP_RI);
12887 #undef DECR_AND_STORE
12889 tcg_gen_movi_tl(t2, -framesize);
12890 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12896 static void gen_mips16_restore (DisasContext *ctx,
12897 int xsregs, int aregs,
12898 int do_ra, int do_s0, int do_s1,
12902 TCGv t0 = tcg_temp_new();
12903 TCGv t1 = tcg_temp_new();
12904 TCGv t2 = tcg_temp_new();
12906 tcg_gen_movi_tl(t2, framesize);
12907 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
12909 #define DECR_AND_LOAD(reg) do { \
12910 tcg_gen_movi_tl(t2, -4); \
12911 gen_op_addr_add(ctx, t0, t0, t2); \
12912 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12913 gen_store_gpr(t1, reg); \
12977 generate_exception_end(ctx, EXCP_RI);
12993 #undef DECR_AND_LOAD
12995 tcg_gen_movi_tl(t2, framesize);
12996 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13002 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13003 int is_64_bit, int extended)
13007 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13008 generate_exception_end(ctx, EXCP_RI);
13012 t0 = tcg_temp_new();
13014 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13015 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13017 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13023 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13026 TCGv_i32 t0 = tcg_const_i32(op);
13027 TCGv t1 = tcg_temp_new();
13028 gen_base_offset_addr(ctx, t1, base, offset);
13029 gen_helper_cache(cpu_env, t1, t0);
13032 #if defined(TARGET_MIPS64)
13033 static void decode_i64_mips16 (DisasContext *ctx,
13034 int ry, int funct, int16_t offset,
13039 check_insn(ctx, ISA_MIPS3);
13040 check_mips_64(ctx);
13041 offset = extended ? offset : offset << 3;
13042 gen_ld(ctx, OPC_LD, ry, 29, offset);
13045 check_insn(ctx, ISA_MIPS3);
13046 check_mips_64(ctx);
13047 offset = extended ? offset : offset << 3;
13048 gen_st(ctx, OPC_SD, ry, 29, offset);
13051 check_insn(ctx, ISA_MIPS3);
13052 check_mips_64(ctx);
13053 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13054 gen_st(ctx, OPC_SD, 31, 29, offset);
13057 check_insn(ctx, ISA_MIPS3);
13058 check_mips_64(ctx);
13059 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13060 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13063 check_insn(ctx, ISA_MIPS3);
13064 check_mips_64(ctx);
13065 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13066 generate_exception_end(ctx, EXCP_RI);
13068 offset = extended ? offset : offset << 3;
13069 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13073 check_insn(ctx, ISA_MIPS3);
13074 check_mips_64(ctx);
13075 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13076 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13079 check_insn(ctx, ISA_MIPS3);
13080 check_mips_64(ctx);
13081 offset = extended ? offset : offset << 2;
13082 gen_addiupc(ctx, ry, offset, 1, extended);
13085 check_insn(ctx, ISA_MIPS3);
13086 check_mips_64(ctx);
13087 offset = extended ? offset : offset << 2;
13088 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13094 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13096 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13097 int op, rx, ry, funct, sa;
13098 int16_t imm, offset;
13100 ctx->opcode = (ctx->opcode << 16) | extend;
13101 op = (ctx->opcode >> 11) & 0x1f;
13102 sa = (ctx->opcode >> 22) & 0x1f;
13103 funct = (ctx->opcode >> 8) & 0x7;
13104 rx = xlat((ctx->opcode >> 8) & 0x7);
13105 ry = xlat((ctx->opcode >> 5) & 0x7);
13106 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13107 | ((ctx->opcode >> 21) & 0x3f) << 5
13108 | (ctx->opcode & 0x1f));
13110 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13113 case M16_OPC_ADDIUSP:
13114 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13116 case M16_OPC_ADDIUPC:
13117 gen_addiupc(ctx, rx, imm, 0, 1);
13120 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13121 /* No delay slot, so just process as a normal instruction */
13124 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13125 /* No delay slot, so just process as a normal instruction */
13127 case M16_OPC_BNEQZ:
13128 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13129 /* No delay slot, so just process as a normal instruction */
13131 case M16_OPC_SHIFT:
13132 switch (ctx->opcode & 0x3) {
13134 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13137 #if defined(TARGET_MIPS64)
13138 check_mips_64(ctx);
13139 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13141 generate_exception_end(ctx, EXCP_RI);
13145 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13148 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13152 #if defined(TARGET_MIPS64)
13154 check_insn(ctx, ISA_MIPS3);
13155 check_mips_64(ctx);
13156 gen_ld(ctx, OPC_LD, ry, rx, offset);
13160 imm = ctx->opcode & 0xf;
13161 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13162 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13163 imm = (int16_t) (imm << 1) >> 1;
13164 if ((ctx->opcode >> 4) & 0x1) {
13165 #if defined(TARGET_MIPS64)
13166 check_mips_64(ctx);
13167 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13169 generate_exception_end(ctx, EXCP_RI);
13172 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13175 case M16_OPC_ADDIU8:
13176 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13179 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13181 case M16_OPC_SLTIU:
13182 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13187 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13190 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13193 gen_st(ctx, OPC_SW, 31, 29, imm);
13196 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13199 check_insn(ctx, ISA_MIPS32);
13201 int xsregs = (ctx->opcode >> 24) & 0x7;
13202 int aregs = (ctx->opcode >> 16) & 0xf;
13203 int do_ra = (ctx->opcode >> 6) & 0x1;
13204 int do_s0 = (ctx->opcode >> 5) & 0x1;
13205 int do_s1 = (ctx->opcode >> 4) & 0x1;
13206 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13207 | (ctx->opcode & 0xf)) << 3;
13209 if (ctx->opcode & (1 << 7)) {
13210 gen_mips16_save(ctx, xsregs, aregs,
13211 do_ra, do_s0, do_s1,
13214 gen_mips16_restore(ctx, xsregs, aregs,
13215 do_ra, do_s0, do_s1,
13221 generate_exception_end(ctx, EXCP_RI);
13226 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13229 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13231 #if defined(TARGET_MIPS64)
13233 check_insn(ctx, ISA_MIPS3);
13234 check_mips_64(ctx);
13235 gen_st(ctx, OPC_SD, ry, rx, offset);
13239 gen_ld(ctx, OPC_LB, ry, rx, offset);
13242 gen_ld(ctx, OPC_LH, ry, rx, offset);
13245 gen_ld(ctx, OPC_LW, rx, 29, offset);
13248 gen_ld(ctx, OPC_LW, ry, rx, offset);
13251 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13254 gen_ld(ctx, OPC_LHU, ry, rx, offset);
13257 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13259 #if defined(TARGET_MIPS64)
13261 check_insn(ctx, ISA_MIPS3);
13262 check_mips_64(ctx);
13263 gen_ld(ctx, OPC_LWU, ry, rx, offset);
13267 gen_st(ctx, OPC_SB, ry, rx, offset);
13270 gen_st(ctx, OPC_SH, ry, rx, offset);
13273 gen_st(ctx, OPC_SW, rx, 29, offset);
13276 gen_st(ctx, OPC_SW, ry, rx, offset);
13278 #if defined(TARGET_MIPS64)
13280 decode_i64_mips16(ctx, ry, funct, offset, 1);
13284 generate_exception_end(ctx, EXCP_RI);
13291 static inline bool is_uhi(int sdbbp_code)
13293 #ifdef CONFIG_USER_ONLY
13296 return semihosting_enabled() && sdbbp_code == 1;
13300 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13304 int op, cnvt_op, op1, offset;
13308 op = (ctx->opcode >> 11) & 0x1f;
13309 sa = (ctx->opcode >> 2) & 0x7;
13310 sa = sa == 0 ? 8 : sa;
13311 rx = xlat((ctx->opcode >> 8) & 0x7);
13312 cnvt_op = (ctx->opcode >> 5) & 0x7;
13313 ry = xlat((ctx->opcode >> 5) & 0x7);
13314 op1 = offset = ctx->opcode & 0x1f;
13319 case M16_OPC_ADDIUSP:
13321 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13323 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13326 case M16_OPC_ADDIUPC:
13327 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13330 offset = (ctx->opcode & 0x7ff) << 1;
13331 offset = (int16_t)(offset << 4) >> 4;
13332 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13333 /* No delay slot, so just process as a normal instruction */
13336 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13337 offset = (((ctx->opcode & 0x1f) << 21)
13338 | ((ctx->opcode >> 5) & 0x1f) << 16
13340 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13341 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13345 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13346 ((int8_t)ctx->opcode) << 1, 0);
13347 /* No delay slot, so just process as a normal instruction */
13349 case M16_OPC_BNEQZ:
13350 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13351 ((int8_t)ctx->opcode) << 1, 0);
13352 /* No delay slot, so just process as a normal instruction */
13354 case M16_OPC_SHIFT:
13355 switch (ctx->opcode & 0x3) {
13357 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13360 #if defined(TARGET_MIPS64)
13361 check_insn(ctx, ISA_MIPS3);
13362 check_mips_64(ctx);
13363 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13365 generate_exception_end(ctx, EXCP_RI);
13369 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13372 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13376 #if defined(TARGET_MIPS64)
13378 check_insn(ctx, ISA_MIPS3);
13379 check_mips_64(ctx);
13380 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13385 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13387 if ((ctx->opcode >> 4) & 1) {
13388 #if defined(TARGET_MIPS64)
13389 check_insn(ctx, ISA_MIPS3);
13390 check_mips_64(ctx);
13391 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13393 generate_exception_end(ctx, EXCP_RI);
13396 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13400 case M16_OPC_ADDIU8:
13402 int16_t imm = (int8_t) ctx->opcode;
13404 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13409 int16_t imm = (uint8_t) ctx->opcode;
13410 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13413 case M16_OPC_SLTIU:
13415 int16_t imm = (uint8_t) ctx->opcode;
13416 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13423 funct = (ctx->opcode >> 8) & 0x7;
13426 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13427 ((int8_t)ctx->opcode) << 1, 0);
13430 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13431 ((int8_t)ctx->opcode) << 1, 0);
13434 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13437 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13438 ((int8_t)ctx->opcode) << 3);
13441 check_insn(ctx, ISA_MIPS32);
13443 int do_ra = ctx->opcode & (1 << 6);
13444 int do_s0 = ctx->opcode & (1 << 5);
13445 int do_s1 = ctx->opcode & (1 << 4);
13446 int framesize = ctx->opcode & 0xf;
13448 if (framesize == 0) {
13451 framesize = framesize << 3;
13454 if (ctx->opcode & (1 << 7)) {
13455 gen_mips16_save(ctx, 0, 0,
13456 do_ra, do_s0, do_s1, framesize);
13458 gen_mips16_restore(ctx, 0, 0,
13459 do_ra, do_s0, do_s1, framesize);
13465 int rz = xlat(ctx->opcode & 0x7);
13467 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13468 ((ctx->opcode >> 5) & 0x7);
13469 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13473 reg32 = ctx->opcode & 0x1f;
13474 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13477 generate_exception_end(ctx, EXCP_RI);
13484 int16_t imm = (uint8_t) ctx->opcode;
13486 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13491 int16_t imm = (uint8_t) ctx->opcode;
13492 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13495 #if defined(TARGET_MIPS64)
13497 check_insn(ctx, ISA_MIPS3);
13498 check_mips_64(ctx);
13499 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13503 gen_ld(ctx, OPC_LB, ry, rx, offset);
13506 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13509 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13512 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13515 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13518 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13521 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13523 #if defined (TARGET_MIPS64)
13525 check_insn(ctx, ISA_MIPS3);
13526 check_mips_64(ctx);
13527 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13531 gen_st(ctx, OPC_SB, ry, rx, offset);
13534 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13537 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13540 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13544 int rz = xlat((ctx->opcode >> 2) & 0x7);
13547 switch (ctx->opcode & 0x3) {
13549 mips32_op = OPC_ADDU;
13552 mips32_op = OPC_SUBU;
13554 #if defined(TARGET_MIPS64)
13556 mips32_op = OPC_DADDU;
13557 check_insn(ctx, ISA_MIPS3);
13558 check_mips_64(ctx);
13561 mips32_op = OPC_DSUBU;
13562 check_insn(ctx, ISA_MIPS3);
13563 check_mips_64(ctx);
13567 generate_exception_end(ctx, EXCP_RI);
13571 gen_arith(ctx, mips32_op, rz, rx, ry);
13580 int nd = (ctx->opcode >> 7) & 0x1;
13581 int link = (ctx->opcode >> 6) & 0x1;
13582 int ra = (ctx->opcode >> 5) & 0x1;
13585 check_insn(ctx, ISA_MIPS32);
13594 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13599 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13600 gen_helper_do_semihosting(cpu_env);
13602 /* XXX: not clear which exception should be raised
13603 * when in debug mode...
13605 check_insn(ctx, ISA_MIPS32);
13606 generate_exception_end(ctx, EXCP_DBp);
13610 gen_slt(ctx, OPC_SLT, 24, rx, ry);
13613 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13616 generate_exception_end(ctx, EXCP_BREAK);
13619 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13622 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13625 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13627 #if defined (TARGET_MIPS64)
13629 check_insn(ctx, ISA_MIPS3);
13630 check_mips_64(ctx);
13631 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13635 gen_logic(ctx, OPC_XOR, 24, rx, ry);
13638 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13641 gen_logic(ctx, OPC_AND, rx, rx, ry);
13644 gen_logic(ctx, OPC_OR, rx, rx, ry);
13647 gen_logic(ctx, OPC_XOR, rx, rx, ry);
13650 gen_logic(ctx, OPC_NOR, rx, ry, 0);
13653 gen_HILO(ctx, OPC_MFHI, 0, rx);
13656 check_insn(ctx, ISA_MIPS32);
13658 case RR_RY_CNVT_ZEB:
13659 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13661 case RR_RY_CNVT_ZEH:
13662 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13664 case RR_RY_CNVT_SEB:
13665 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13667 case RR_RY_CNVT_SEH:
13668 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13670 #if defined (TARGET_MIPS64)
13671 case RR_RY_CNVT_ZEW:
13672 check_insn(ctx, ISA_MIPS64);
13673 check_mips_64(ctx);
13674 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13676 case RR_RY_CNVT_SEW:
13677 check_insn(ctx, ISA_MIPS64);
13678 check_mips_64(ctx);
13679 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13683 generate_exception_end(ctx, EXCP_RI);
13688 gen_HILO(ctx, OPC_MFLO, 0, rx);
13690 #if defined (TARGET_MIPS64)
13692 check_insn(ctx, ISA_MIPS3);
13693 check_mips_64(ctx);
13694 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13697 check_insn(ctx, ISA_MIPS3);
13698 check_mips_64(ctx);
13699 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
13702 check_insn(ctx, ISA_MIPS3);
13703 check_mips_64(ctx);
13704 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
13707 check_insn(ctx, ISA_MIPS3);
13708 check_mips_64(ctx);
13709 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
13713 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
13716 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
13719 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
13722 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
13724 #if defined (TARGET_MIPS64)
13726 check_insn(ctx, ISA_MIPS3);
13727 check_mips_64(ctx);
13728 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
13731 check_insn(ctx, ISA_MIPS3);
13732 check_mips_64(ctx);
13733 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
13736 check_insn(ctx, ISA_MIPS3);
13737 check_mips_64(ctx);
13738 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
13741 check_insn(ctx, ISA_MIPS3);
13742 check_mips_64(ctx);
13743 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
13747 generate_exception_end(ctx, EXCP_RI);
13751 case M16_OPC_EXTEND:
13752 decode_extended_mips16_opc(env, ctx);
13755 #if defined(TARGET_MIPS64)
13757 funct = (ctx->opcode >> 8) & 0x7;
13758 decode_i64_mips16(ctx, ry, funct, offset, 0);
13762 generate_exception_end(ctx, EXCP_RI);
13769 /* microMIPS extension to MIPS32/MIPS64 */
13772 * microMIPS32/microMIPS64 major opcodes
13774 * 1. MIPS Architecture for Programmers Volume II-B:
13775 * The microMIPS32 Instruction Set (Revision 3.05)
13777 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13779 * 2. MIPS Architecture For Programmers Volume II-A:
13780 * The MIPS64 Instruction Set (Revision 3.51)
13810 POOL32S = 0x16, /* MIPS64 */
13811 DADDIU32 = 0x17, /* MIPS64 */
13840 /* 0x29 is reserved */
13853 /* 0x31 is reserved */
13866 SD32 = 0x36, /* MIPS64 */
13867 LD32 = 0x37, /* MIPS64 */
13869 /* 0x39 is reserved */
13885 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13907 /* POOL32A encoding of minor opcode field */
13910 /* These opcodes are distinguished only by bits 9..6; those bits are
13911 * what are recorded below. */
13948 /* The following can be distinguished by their lower 6 bits. */
13958 /* POOL32AXF encoding of minor opcode field extension */
13961 * 1. MIPS Architecture for Programmers Volume II-B:
13962 * The microMIPS32 Instruction Set (Revision 3.05)
13964 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13966 * 2. MIPS Architecture for Programmers VolumeIV-e:
13967 * The MIPS DSP Application-Specific Extension
13968 * to the microMIPS32 Architecture (Revision 2.34)
13970 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13985 /* begin of microMIPS32 DSP */
13987 /* bits 13..12 for 0x01 */
13993 /* bits 13..12 for 0x2a */
13999 /* bits 13..12 for 0x32 */
14003 /* end of microMIPS32 DSP */
14005 /* bits 15..12 for 0x2c */
14022 /* bits 15..12 for 0x34 */
14030 /* bits 15..12 for 0x3c */
14032 JR = 0x0, /* alias */
14040 /* bits 15..12 for 0x05 */
14044 /* bits 15..12 for 0x0d */
14056 /* bits 15..12 for 0x15 */
14062 /* bits 15..12 for 0x1d */
14066 /* bits 15..12 for 0x2d */
14071 /* bits 15..12 for 0x35 */
14078 /* POOL32B encoding of minor opcode field (bits 15..12) */
14094 /* POOL32C encoding of minor opcode field (bits 15..12) */
14115 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14128 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14141 /* POOL32F encoding of minor opcode field (bits 5..0) */
14144 /* These are the bit 7..6 values */
14153 /* These are the bit 8..6 values */
14178 MOVZ_FMT_05 = 0x05,
14212 CABS_COND_FMT = 0x1c, /* MIPS3D */
14219 /* POOL32Fxf encoding of minor opcode extension field */
14257 /* POOL32I encoding of minor opcode field (bits 25..21) */
14287 /* These overlap and are distinguished by bit16 of the instruction */
14296 /* POOL16A encoding of minor opcode field */
14303 /* POOL16B encoding of minor opcode field */
14310 /* POOL16C encoding of minor opcode field */
14330 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14354 /* POOL16D encoding of minor opcode field */
14361 /* POOL16E encoding of minor opcode field */
14368 static int mmreg (int r)
14370 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14375 /* Used for 16-bit store instructions. */
14376 static int mmreg2 (int r)
14378 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14383 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14384 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14385 #define uMIPS_RS2(op) uMIPS_RS(op)
14386 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14387 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14388 #define uMIPS_RS5(op) (op & 0x1f)
14390 /* Signed immediate */
14391 #define SIMM(op, start, width) \
14392 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14395 /* Zero-extended immediate */
14396 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14398 static void gen_addiur1sp(DisasContext *ctx)
14400 int rd = mmreg(uMIPS_RD(ctx->opcode));
14402 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14405 static void gen_addiur2(DisasContext *ctx)
14407 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14408 int rd = mmreg(uMIPS_RD(ctx->opcode));
14409 int rs = mmreg(uMIPS_RS(ctx->opcode));
14411 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14414 static void gen_addiusp(DisasContext *ctx)
14416 int encoded = ZIMM(ctx->opcode, 1, 9);
14419 if (encoded <= 1) {
14420 decoded = 256 + encoded;
14421 } else if (encoded <= 255) {
14423 } else if (encoded <= 509) {
14424 decoded = encoded - 512;
14426 decoded = encoded - 768;
14429 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14432 static void gen_addius5(DisasContext *ctx)
14434 int imm = SIMM(ctx->opcode, 1, 4);
14435 int rd = (ctx->opcode >> 5) & 0x1f;
14437 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14440 static void gen_andi16(DisasContext *ctx)
14442 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14443 31, 32, 63, 64, 255, 32768, 65535 };
14444 int rd = mmreg(uMIPS_RD(ctx->opcode));
14445 int rs = mmreg(uMIPS_RS(ctx->opcode));
14446 int encoded = ZIMM(ctx->opcode, 0, 4);
14448 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14451 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14452 int base, int16_t offset)
14457 if (ctx->hflags & MIPS_HFLAG_BMASK) {
14458 generate_exception_end(ctx, EXCP_RI);
14462 t0 = tcg_temp_new();
14464 gen_base_offset_addr(ctx, t0, base, offset);
14466 t1 = tcg_const_tl(reglist);
14467 t2 = tcg_const_i32(ctx->mem_idx);
14469 save_cpu_state(ctx, 1);
14472 gen_helper_lwm(cpu_env, t0, t1, t2);
14475 gen_helper_swm(cpu_env, t0, t1, t2);
14477 #ifdef TARGET_MIPS64
14479 gen_helper_ldm(cpu_env, t0, t1, t2);
14482 gen_helper_sdm(cpu_env, t0, t1, t2);
14488 tcg_temp_free_i32(t2);
14492 static void gen_pool16c_insn(DisasContext *ctx)
14494 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14495 int rs = mmreg(ctx->opcode & 0x7);
14497 switch (((ctx->opcode) >> 4) & 0x3f) {
14502 gen_logic(ctx, OPC_NOR, rd, rs, 0);
14508 gen_logic(ctx, OPC_XOR, rd, rd, rs);
14514 gen_logic(ctx, OPC_AND, rd, rd, rs);
14520 gen_logic(ctx, OPC_OR, rd, rd, rs);
14527 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14528 int offset = ZIMM(ctx->opcode, 0, 4);
14530 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14539 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14540 int offset = ZIMM(ctx->opcode, 0, 4);
14542 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14549 int reg = ctx->opcode & 0x1f;
14551 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14557 int reg = ctx->opcode & 0x1f;
14558 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14559 /* Let normal delay slot handling in our caller take us
14560 to the branch target. */
14565 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14566 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14570 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14571 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14575 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14579 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14582 generate_exception_end(ctx, EXCP_BREAK);
14585 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14586 gen_helper_do_semihosting(cpu_env);
14588 /* XXX: not clear which exception should be raised
14589 * when in debug mode...
14591 check_insn(ctx, ISA_MIPS32);
14592 generate_exception_end(ctx, EXCP_DBp);
14595 case JRADDIUSP + 0:
14596 case JRADDIUSP + 1:
14598 int imm = ZIMM(ctx->opcode, 0, 5);
14599 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14600 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14601 /* Let normal delay slot handling in our caller take us
14602 to the branch target. */
14606 generate_exception_end(ctx, EXCP_RI);
14611 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14614 int rd, rs, re, rt;
14615 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14616 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14617 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14618 rd = rd_enc[enc_dest];
14619 re = re_enc[enc_dest];
14620 rs = rs_rt_enc[enc_rs];
14621 rt = rs_rt_enc[enc_rt];
14623 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14625 tcg_gen_movi_tl(cpu_gpr[rd], 0);
14628 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14630 tcg_gen_movi_tl(cpu_gpr[re], 0);
14634 static void gen_pool16c_r6_insn(DisasContext *ctx)
14636 int rt = mmreg((ctx->opcode >> 7) & 0x7);
14637 int rs = mmreg((ctx->opcode >> 4) & 0x7);
14639 switch (ctx->opcode & 0xf) {
14641 gen_logic(ctx, OPC_NOR, rt, rs, 0);
14644 gen_logic(ctx, OPC_AND, rt, rt, rs);
14648 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14649 int offset = extract32(ctx->opcode, 4, 4);
14650 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14653 case R6_JRC16: /* JRCADDIUSP */
14654 if ((ctx->opcode >> 4) & 1) {
14656 int imm = extract32(ctx->opcode, 5, 5);
14657 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14658 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14661 rs = extract32(ctx->opcode, 5, 5);
14662 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14674 int enc_dest = uMIPS_RD(ctx->opcode);
14675 int enc_rt = uMIPS_RS2(ctx->opcode);
14676 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14677 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14681 gen_logic(ctx, OPC_XOR, rt, rt, rs);
14684 gen_logic(ctx, OPC_OR, rt, rt, rs);
14688 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14689 int offset = extract32(ctx->opcode, 4, 4);
14690 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14693 case JALRC16: /* BREAK16, SDBBP16 */
14694 switch (ctx->opcode & 0x3f) {
14696 case JALRC16 + 0x20:
14698 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14703 generate_exception(ctx, EXCP_BREAK);
14707 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14708 gen_helper_do_semihosting(cpu_env);
14710 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14711 generate_exception(ctx, EXCP_RI);
14713 generate_exception(ctx, EXCP_DBp);
14720 generate_exception(ctx, EXCP_RI);
14725 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14727 TCGv t0 = tcg_temp_new();
14728 TCGv t1 = tcg_temp_new();
14730 gen_load_gpr(t0, base);
14733 gen_load_gpr(t1, index);
14734 tcg_gen_shli_tl(t1, t1, 2);
14735 gen_op_addr_add(ctx, t0, t1, t0);
14738 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14739 gen_store_gpr(t1, rd);
14745 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14746 int base, int16_t offset)
14750 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
14751 generate_exception_end(ctx, EXCP_RI);
14755 t0 = tcg_temp_new();
14756 t1 = tcg_temp_new();
14758 gen_base_offset_addr(ctx, t0, base, offset);
14763 generate_exception_end(ctx, EXCP_RI);
14766 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14767 gen_store_gpr(t1, rd);
14768 tcg_gen_movi_tl(t1, 4);
14769 gen_op_addr_add(ctx, t0, t0, t1);
14770 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14771 gen_store_gpr(t1, rd+1);
14774 gen_load_gpr(t1, rd);
14775 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14776 tcg_gen_movi_tl(t1, 4);
14777 gen_op_addr_add(ctx, t0, t0, t1);
14778 gen_load_gpr(t1, rd+1);
14779 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14781 #ifdef TARGET_MIPS64
14784 generate_exception_end(ctx, EXCP_RI);
14787 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14788 gen_store_gpr(t1, rd);
14789 tcg_gen_movi_tl(t1, 8);
14790 gen_op_addr_add(ctx, t0, t0, t1);
14791 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14792 gen_store_gpr(t1, rd+1);
14795 gen_load_gpr(t1, rd);
14796 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14797 tcg_gen_movi_tl(t1, 8);
14798 gen_op_addr_add(ctx, t0, t0, t1);
14799 gen_load_gpr(t1, rd+1);
14800 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14808 static void gen_sync(int stype)
14810 TCGBar tcg_mo = TCG_BAR_SC;
14813 case 0x4: /* SYNC_WMB */
14814 tcg_mo |= TCG_MO_ST_ST;
14816 case 0x10: /* SYNC_MB */
14817 tcg_mo |= TCG_MO_ALL;
14819 case 0x11: /* SYNC_ACQUIRE */
14820 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14822 case 0x12: /* SYNC_RELEASE */
14823 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14825 case 0x13: /* SYNC_RMB */
14826 tcg_mo |= TCG_MO_LD_LD;
14829 tcg_mo |= TCG_MO_ALL;
14833 tcg_gen_mb(tcg_mo);
14836 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
14838 int extension = (ctx->opcode >> 6) & 0x3f;
14839 int minor = (ctx->opcode >> 12) & 0xf;
14840 uint32_t mips32_op;
14842 switch (extension) {
14844 mips32_op = OPC_TEQ;
14847 mips32_op = OPC_TGE;
14850 mips32_op = OPC_TGEU;
14853 mips32_op = OPC_TLT;
14856 mips32_op = OPC_TLTU;
14859 mips32_op = OPC_TNE;
14861 gen_trap(ctx, mips32_op, rs, rt, -1);
14863 #ifndef CONFIG_USER_ONLY
14866 check_cp0_enabled(ctx);
14868 /* Treat as NOP. */
14871 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
14875 check_cp0_enabled(ctx);
14877 TCGv t0 = tcg_temp_new();
14879 gen_load_gpr(t0, rt);
14880 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
14886 switch (minor & 3) {
14888 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
14891 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
14894 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
14897 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
14900 goto pool32axf_invalid;
14904 switch (minor & 3) {
14906 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
14909 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
14912 goto pool32axf_invalid;
14918 check_insn(ctx, ISA_MIPS32R6);
14919 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
14922 gen_bshfl(ctx, OPC_SEB, rs, rt);
14925 gen_bshfl(ctx, OPC_SEH, rs, rt);
14928 mips32_op = OPC_CLO;
14931 mips32_op = OPC_CLZ;
14933 check_insn(ctx, ISA_MIPS32);
14934 gen_cl(ctx, mips32_op, rt, rs);
14937 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14938 gen_rdhwr(ctx, rt, rs, 0);
14941 gen_bshfl(ctx, OPC_WSBH, rs, rt);
14944 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14945 mips32_op = OPC_MULT;
14948 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14949 mips32_op = OPC_MULTU;
14952 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14953 mips32_op = OPC_DIV;
14956 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14957 mips32_op = OPC_DIVU;
14960 check_insn(ctx, ISA_MIPS32);
14961 gen_muldiv(ctx, mips32_op, 0, rs, rt);
14964 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14965 mips32_op = OPC_MADD;
14968 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14969 mips32_op = OPC_MADDU;
14972 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14973 mips32_op = OPC_MSUB;
14976 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14977 mips32_op = OPC_MSUBU;
14979 check_insn(ctx, ISA_MIPS32);
14980 gen_muldiv(ctx, mips32_op, 0, rs, rt);
14983 goto pool32axf_invalid;
14994 generate_exception_err(ctx, EXCP_CpU, 2);
14997 goto pool32axf_invalid;
15002 case JALR: /* JALRC */
15003 case JALR_HB: /* JALRC_HB */
15004 if (ctx->insn_flags & ISA_MIPS32R6) {
15005 /* JALRC, JALRC_HB */
15006 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15008 /* JALR, JALR_HB */
15009 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15010 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15015 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15016 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15017 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15020 goto pool32axf_invalid;
15026 check_cp0_enabled(ctx);
15027 check_insn(ctx, ISA_MIPS32R2);
15028 gen_load_srsgpr(rs, rt);
15031 check_cp0_enabled(ctx);
15032 check_insn(ctx, ISA_MIPS32R2);
15033 gen_store_srsgpr(rs, rt);
15036 goto pool32axf_invalid;
15039 #ifndef CONFIG_USER_ONLY
15043 mips32_op = OPC_TLBP;
15046 mips32_op = OPC_TLBR;
15049 mips32_op = OPC_TLBWI;
15052 mips32_op = OPC_TLBWR;
15055 mips32_op = OPC_TLBINV;
15058 mips32_op = OPC_TLBINVF;
15061 mips32_op = OPC_WAIT;
15064 mips32_op = OPC_DERET;
15067 mips32_op = OPC_ERET;
15069 gen_cp0(env, ctx, mips32_op, rt, rs);
15072 goto pool32axf_invalid;
15078 check_cp0_enabled(ctx);
15080 TCGv t0 = tcg_temp_new();
15082 save_cpu_state(ctx, 1);
15083 gen_helper_di(t0, cpu_env);
15084 gen_store_gpr(t0, rs);
15085 /* Stop translation as we may have switched the execution mode */
15086 ctx->base.is_jmp = DISAS_STOP;
15091 check_cp0_enabled(ctx);
15093 TCGv t0 = tcg_temp_new();
15095 save_cpu_state(ctx, 1);
15096 gen_helper_ei(t0, cpu_env);
15097 gen_store_gpr(t0, rs);
15098 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15099 of translated code to check for pending interrupts. */
15100 gen_save_pc(ctx->base.pc_next + 4);
15101 ctx->base.is_jmp = DISAS_EXIT;
15106 goto pool32axf_invalid;
15113 gen_sync(extract32(ctx->opcode, 16, 5));
15116 generate_exception_end(ctx, EXCP_SYSCALL);
15119 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15120 gen_helper_do_semihosting(cpu_env);
15122 check_insn(ctx, ISA_MIPS32);
15123 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15124 generate_exception_end(ctx, EXCP_RI);
15126 generate_exception_end(ctx, EXCP_DBp);
15131 goto pool32axf_invalid;
15135 switch (minor & 3) {
15137 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15140 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15143 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15146 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15149 goto pool32axf_invalid;
15153 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15156 gen_HILO(ctx, OPC_MFHI, 0, rs);
15159 gen_HILO(ctx, OPC_MFLO, 0, rs);
15162 gen_HILO(ctx, OPC_MTHI, 0, rs);
15165 gen_HILO(ctx, OPC_MTLO, 0, rs);
15168 goto pool32axf_invalid;
15173 MIPS_INVAL("pool32axf");
15174 generate_exception_end(ctx, EXCP_RI);
15179 /* Values for microMIPS fmt field. Variable-width, depending on which
15180 formats the instruction supports. */
15199 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15201 int extension = (ctx->opcode >> 6) & 0x3ff;
15202 uint32_t mips32_op;
15204 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15205 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15206 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15208 switch (extension) {
15209 case FLOAT_1BIT_FMT(CFC1, 0):
15210 mips32_op = OPC_CFC1;
15212 case FLOAT_1BIT_FMT(CTC1, 0):
15213 mips32_op = OPC_CTC1;
15215 case FLOAT_1BIT_FMT(MFC1, 0):
15216 mips32_op = OPC_MFC1;
15218 case FLOAT_1BIT_FMT(MTC1, 0):
15219 mips32_op = OPC_MTC1;
15221 case FLOAT_1BIT_FMT(MFHC1, 0):
15222 mips32_op = OPC_MFHC1;
15224 case FLOAT_1BIT_FMT(MTHC1, 0):
15225 mips32_op = OPC_MTHC1;
15227 gen_cp1(ctx, mips32_op, rt, rs);
15230 /* Reciprocal square root */
15231 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15232 mips32_op = OPC_RSQRT_S;
15234 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15235 mips32_op = OPC_RSQRT_D;
15239 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15240 mips32_op = OPC_SQRT_S;
15242 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15243 mips32_op = OPC_SQRT_D;
15247 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15248 mips32_op = OPC_RECIP_S;
15250 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15251 mips32_op = OPC_RECIP_D;
15255 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15256 mips32_op = OPC_FLOOR_L_S;
15258 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15259 mips32_op = OPC_FLOOR_L_D;
15261 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15262 mips32_op = OPC_FLOOR_W_S;
15264 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15265 mips32_op = OPC_FLOOR_W_D;
15269 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15270 mips32_op = OPC_CEIL_L_S;
15272 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15273 mips32_op = OPC_CEIL_L_D;
15275 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15276 mips32_op = OPC_CEIL_W_S;
15278 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15279 mips32_op = OPC_CEIL_W_D;
15283 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15284 mips32_op = OPC_TRUNC_L_S;
15286 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15287 mips32_op = OPC_TRUNC_L_D;
15289 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15290 mips32_op = OPC_TRUNC_W_S;
15292 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15293 mips32_op = OPC_TRUNC_W_D;
15297 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15298 mips32_op = OPC_ROUND_L_S;
15300 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15301 mips32_op = OPC_ROUND_L_D;
15303 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15304 mips32_op = OPC_ROUND_W_S;
15306 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15307 mips32_op = OPC_ROUND_W_D;
15310 /* Integer to floating-point conversion */
15311 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15312 mips32_op = OPC_CVT_L_S;
15314 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15315 mips32_op = OPC_CVT_L_D;
15317 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15318 mips32_op = OPC_CVT_W_S;
15320 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15321 mips32_op = OPC_CVT_W_D;
15324 /* Paired-foo conversions */
15325 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15326 mips32_op = OPC_CVT_S_PL;
15328 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15329 mips32_op = OPC_CVT_S_PU;
15331 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15332 mips32_op = OPC_CVT_PW_PS;
15334 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15335 mips32_op = OPC_CVT_PS_PW;
15338 /* Floating-point moves */
15339 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15340 mips32_op = OPC_MOV_S;
15342 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15343 mips32_op = OPC_MOV_D;
15345 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15346 mips32_op = OPC_MOV_PS;
15349 /* Absolute value */
15350 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15351 mips32_op = OPC_ABS_S;
15353 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15354 mips32_op = OPC_ABS_D;
15356 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15357 mips32_op = OPC_ABS_PS;
15361 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15362 mips32_op = OPC_NEG_S;
15364 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15365 mips32_op = OPC_NEG_D;
15367 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15368 mips32_op = OPC_NEG_PS;
15371 /* Reciprocal square root step */
15372 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15373 mips32_op = OPC_RSQRT1_S;
15375 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15376 mips32_op = OPC_RSQRT1_D;
15378 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15379 mips32_op = OPC_RSQRT1_PS;
15382 /* Reciprocal step */
15383 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15384 mips32_op = OPC_RECIP1_S;
15386 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15387 mips32_op = OPC_RECIP1_S;
15389 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15390 mips32_op = OPC_RECIP1_PS;
15393 /* Conversions from double */
15394 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15395 mips32_op = OPC_CVT_D_S;
15397 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15398 mips32_op = OPC_CVT_D_W;
15400 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15401 mips32_op = OPC_CVT_D_L;
15404 /* Conversions from single */
15405 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15406 mips32_op = OPC_CVT_S_D;
15408 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15409 mips32_op = OPC_CVT_S_W;
15411 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15412 mips32_op = OPC_CVT_S_L;
15414 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15417 /* Conditional moves on floating-point codes */
15418 case COND_FLOAT_MOV(MOVT, 0):
15419 case COND_FLOAT_MOV(MOVT, 1):
15420 case COND_FLOAT_MOV(MOVT, 2):
15421 case COND_FLOAT_MOV(MOVT, 3):
15422 case COND_FLOAT_MOV(MOVT, 4):
15423 case COND_FLOAT_MOV(MOVT, 5):
15424 case COND_FLOAT_MOV(MOVT, 6):
15425 case COND_FLOAT_MOV(MOVT, 7):
15426 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15427 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15429 case COND_FLOAT_MOV(MOVF, 0):
15430 case COND_FLOAT_MOV(MOVF, 1):
15431 case COND_FLOAT_MOV(MOVF, 2):
15432 case COND_FLOAT_MOV(MOVF, 3):
15433 case COND_FLOAT_MOV(MOVF, 4):
15434 case COND_FLOAT_MOV(MOVF, 5):
15435 case COND_FLOAT_MOV(MOVF, 6):
15436 case COND_FLOAT_MOV(MOVF, 7):
15437 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15438 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15441 MIPS_INVAL("pool32fxf");
15442 generate_exception_end(ctx, EXCP_RI);
15447 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15451 int rt, rs, rd, rr;
15453 uint32_t op, minor, minor2, mips32_op;
15454 uint32_t cond, fmt, cc;
15456 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15457 ctx->opcode = (ctx->opcode << 16) | insn;
15459 rt = (ctx->opcode >> 21) & 0x1f;
15460 rs = (ctx->opcode >> 16) & 0x1f;
15461 rd = (ctx->opcode >> 11) & 0x1f;
15462 rr = (ctx->opcode >> 6) & 0x1f;
15463 imm = (int16_t) ctx->opcode;
15465 op = (ctx->opcode >> 26) & 0x3f;
15468 minor = ctx->opcode & 0x3f;
15471 minor = (ctx->opcode >> 6) & 0xf;
15474 mips32_op = OPC_SLL;
15477 mips32_op = OPC_SRA;
15480 mips32_op = OPC_SRL;
15483 mips32_op = OPC_ROTR;
15485 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15488 check_insn(ctx, ISA_MIPS32R6);
15489 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15492 check_insn(ctx, ISA_MIPS32R6);
15493 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15496 check_insn(ctx, ISA_MIPS32R6);
15497 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15500 goto pool32a_invalid;
15504 minor = (ctx->opcode >> 6) & 0xf;
15508 mips32_op = OPC_ADD;
15511 mips32_op = OPC_ADDU;
15514 mips32_op = OPC_SUB;
15517 mips32_op = OPC_SUBU;
15520 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15521 mips32_op = OPC_MUL;
15523 gen_arith(ctx, mips32_op, rd, rs, rt);
15527 mips32_op = OPC_SLLV;
15530 mips32_op = OPC_SRLV;
15533 mips32_op = OPC_SRAV;
15536 mips32_op = OPC_ROTRV;
15538 gen_shift(ctx, mips32_op, rd, rs, rt);
15540 /* Logical operations */
15542 mips32_op = OPC_AND;
15545 mips32_op = OPC_OR;
15548 mips32_op = OPC_NOR;
15551 mips32_op = OPC_XOR;
15553 gen_logic(ctx, mips32_op, rd, rs, rt);
15555 /* Set less than */
15557 mips32_op = OPC_SLT;
15560 mips32_op = OPC_SLTU;
15562 gen_slt(ctx, mips32_op, rd, rs, rt);
15565 goto pool32a_invalid;
15569 minor = (ctx->opcode >> 6) & 0xf;
15571 /* Conditional moves */
15572 case MOVN: /* MUL */
15573 if (ctx->insn_flags & ISA_MIPS32R6) {
15575 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15578 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15581 case MOVZ: /* MUH */
15582 if (ctx->insn_flags & ISA_MIPS32R6) {
15584 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15587 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15591 check_insn(ctx, ISA_MIPS32R6);
15592 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15595 check_insn(ctx, ISA_MIPS32R6);
15596 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15598 case LWXS: /* DIV */
15599 if (ctx->insn_flags & ISA_MIPS32R6) {
15601 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15604 gen_ldxs(ctx, rs, rt, rd);
15608 check_insn(ctx, ISA_MIPS32R6);
15609 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15612 check_insn(ctx, ISA_MIPS32R6);
15613 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15616 check_insn(ctx, ISA_MIPS32R6);
15617 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15620 goto pool32a_invalid;
15624 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15627 check_insn(ctx, ISA_MIPS32R6);
15628 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15629 extract32(ctx->opcode, 9, 2));
15632 check_insn(ctx, ISA_MIPS32R6);
15633 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15636 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15639 gen_pool32axf(env, ctx, rt, rs);
15642 generate_exception_end(ctx, EXCP_BREAK);
15645 check_insn(ctx, ISA_MIPS32R6);
15646 generate_exception_end(ctx, EXCP_RI);
15650 MIPS_INVAL("pool32a");
15651 generate_exception_end(ctx, EXCP_RI);
15656 minor = (ctx->opcode >> 12) & 0xf;
15659 check_cp0_enabled(ctx);
15660 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15661 gen_cache_operation(ctx, rt, rs, imm);
15666 /* COP2: Not implemented. */
15667 generate_exception_err(ctx, EXCP_CpU, 2);
15669 #ifdef TARGET_MIPS64
15672 check_insn(ctx, ISA_MIPS3);
15673 check_mips_64(ctx);
15678 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15680 #ifdef TARGET_MIPS64
15683 check_insn(ctx, ISA_MIPS3);
15684 check_mips_64(ctx);
15689 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15692 MIPS_INVAL("pool32b");
15693 generate_exception_end(ctx, EXCP_RI);
15698 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15699 minor = ctx->opcode & 0x3f;
15700 check_cp1_enabled(ctx);
15703 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15704 mips32_op = OPC_ALNV_PS;
15707 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15708 mips32_op = OPC_MADD_S;
15711 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15712 mips32_op = OPC_MADD_D;
15715 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15716 mips32_op = OPC_MADD_PS;
15719 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15720 mips32_op = OPC_MSUB_S;
15723 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15724 mips32_op = OPC_MSUB_D;
15727 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15728 mips32_op = OPC_MSUB_PS;
15731 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15732 mips32_op = OPC_NMADD_S;
15735 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15736 mips32_op = OPC_NMADD_D;
15739 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15740 mips32_op = OPC_NMADD_PS;
15743 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15744 mips32_op = OPC_NMSUB_S;
15747 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15748 mips32_op = OPC_NMSUB_D;
15751 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15752 mips32_op = OPC_NMSUB_PS;
15754 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15756 case CABS_COND_FMT:
15757 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15758 cond = (ctx->opcode >> 6) & 0xf;
15759 cc = (ctx->opcode >> 13) & 0x7;
15760 fmt = (ctx->opcode >> 10) & 0x3;
15763 gen_cmpabs_s(ctx, cond, rt, rs, cc);
15766 gen_cmpabs_d(ctx, cond, rt, rs, cc);
15769 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15772 goto pool32f_invalid;
15776 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15777 cond = (ctx->opcode >> 6) & 0xf;
15778 cc = (ctx->opcode >> 13) & 0x7;
15779 fmt = (ctx->opcode >> 10) & 0x3;
15782 gen_cmp_s(ctx, cond, rt, rs, cc);
15785 gen_cmp_d(ctx, cond, rt, rs, cc);
15788 gen_cmp_ps(ctx, cond, rt, rs, cc);
15791 goto pool32f_invalid;
15795 check_insn(ctx, ISA_MIPS32R6);
15796 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15799 check_insn(ctx, ISA_MIPS32R6);
15800 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15803 gen_pool32fxf(ctx, rt, rs);
15807 switch ((ctx->opcode >> 6) & 0x7) {
15809 mips32_op = OPC_PLL_PS;
15812 mips32_op = OPC_PLU_PS;
15815 mips32_op = OPC_PUL_PS;
15818 mips32_op = OPC_PUU_PS;
15821 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15822 mips32_op = OPC_CVT_PS_S;
15824 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15827 goto pool32f_invalid;
15831 check_insn(ctx, ISA_MIPS32R6);
15832 switch ((ctx->opcode >> 9) & 0x3) {
15834 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15837 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15840 goto pool32f_invalid;
15845 switch ((ctx->opcode >> 6) & 0x7) {
15847 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15848 mips32_op = OPC_LWXC1;
15851 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15852 mips32_op = OPC_SWXC1;
15855 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15856 mips32_op = OPC_LDXC1;
15859 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15860 mips32_op = OPC_SDXC1;
15863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15864 mips32_op = OPC_LUXC1;
15867 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15868 mips32_op = OPC_SUXC1;
15870 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
15873 goto pool32f_invalid;
15877 check_insn(ctx, ISA_MIPS32R6);
15878 switch ((ctx->opcode >> 9) & 0x3) {
15880 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
15883 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
15886 goto pool32f_invalid;
15891 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15892 fmt = (ctx->opcode >> 9) & 0x3;
15893 switch ((ctx->opcode >> 6) & 0x7) {
15897 mips32_op = OPC_RSQRT2_S;
15900 mips32_op = OPC_RSQRT2_D;
15903 mips32_op = OPC_RSQRT2_PS;
15906 goto pool32f_invalid;
15912 mips32_op = OPC_RECIP2_S;
15915 mips32_op = OPC_RECIP2_D;
15918 mips32_op = OPC_RECIP2_PS;
15921 goto pool32f_invalid;
15925 mips32_op = OPC_ADDR_PS;
15928 mips32_op = OPC_MULR_PS;
15930 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15933 goto pool32f_invalid;
15937 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15938 cc = (ctx->opcode >> 13) & 0x7;
15939 fmt = (ctx->opcode >> 9) & 0x3;
15940 switch ((ctx->opcode >> 6) & 0x7) {
15941 case MOVF_FMT: /* RINT_FMT */
15942 if (ctx->insn_flags & ISA_MIPS32R6) {
15946 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
15949 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
15952 goto pool32f_invalid;
15958 gen_movcf_s(ctx, rs, rt, cc, 0);
15961 gen_movcf_d(ctx, rs, rt, cc, 0);
15965 gen_movcf_ps(ctx, rs, rt, cc, 0);
15968 goto pool32f_invalid;
15972 case MOVT_FMT: /* CLASS_FMT */
15973 if (ctx->insn_flags & ISA_MIPS32R6) {
15977 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
15980 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
15983 goto pool32f_invalid;
15989 gen_movcf_s(ctx, rs, rt, cc, 1);
15992 gen_movcf_d(ctx, rs, rt, cc, 1);
15996 gen_movcf_ps(ctx, rs, rt, cc, 1);
15999 goto pool32f_invalid;
16004 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16007 goto pool32f_invalid;
16010 #define FINSN_3ARG_SDPS(prfx) \
16011 switch ((ctx->opcode >> 8) & 0x3) { \
16013 mips32_op = OPC_##prfx##_S; \
16016 mips32_op = OPC_##prfx##_D; \
16018 case FMT_SDPS_PS: \
16020 mips32_op = OPC_##prfx##_PS; \
16023 goto pool32f_invalid; \
16026 check_insn(ctx, ISA_MIPS32R6);
16027 switch ((ctx->opcode >> 9) & 0x3) {
16029 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16032 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16035 goto pool32f_invalid;
16039 check_insn(ctx, ISA_MIPS32R6);
16040 switch ((ctx->opcode >> 9) & 0x3) {
16042 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16045 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16048 goto pool32f_invalid;
16052 /* regular FP ops */
16053 switch ((ctx->opcode >> 6) & 0x3) {
16055 FINSN_3ARG_SDPS(ADD);
16058 FINSN_3ARG_SDPS(SUB);
16061 FINSN_3ARG_SDPS(MUL);
16064 fmt = (ctx->opcode >> 8) & 0x3;
16066 mips32_op = OPC_DIV_D;
16067 } else if (fmt == 0) {
16068 mips32_op = OPC_DIV_S;
16070 goto pool32f_invalid;
16074 goto pool32f_invalid;
16079 switch ((ctx->opcode >> 6) & 0x7) {
16080 case MOVN_FMT: /* SELEQZ_FMT */
16081 if (ctx->insn_flags & ISA_MIPS32R6) {
16083 switch ((ctx->opcode >> 9) & 0x3) {
16085 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16088 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16091 goto pool32f_invalid;
16095 FINSN_3ARG_SDPS(MOVN);
16099 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16100 FINSN_3ARG_SDPS(MOVN);
16102 case MOVZ_FMT: /* SELNEZ_FMT */
16103 if (ctx->insn_flags & ISA_MIPS32R6) {
16105 switch ((ctx->opcode >> 9) & 0x3) {
16107 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16110 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16113 goto pool32f_invalid;
16117 FINSN_3ARG_SDPS(MOVZ);
16121 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16122 FINSN_3ARG_SDPS(MOVZ);
16125 check_insn(ctx, ISA_MIPS32R6);
16126 switch ((ctx->opcode >> 9) & 0x3) {
16128 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16131 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16134 goto pool32f_invalid;
16138 check_insn(ctx, ISA_MIPS32R6);
16139 switch ((ctx->opcode >> 9) & 0x3) {
16141 mips32_op = OPC_MADDF_S;
16144 mips32_op = OPC_MADDF_D;
16147 goto pool32f_invalid;
16151 check_insn(ctx, ISA_MIPS32R6);
16152 switch ((ctx->opcode >> 9) & 0x3) {
16154 mips32_op = OPC_MSUBF_S;
16157 mips32_op = OPC_MSUBF_D;
16160 goto pool32f_invalid;
16164 goto pool32f_invalid;
16168 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16172 MIPS_INVAL("pool32f");
16173 generate_exception_end(ctx, EXCP_RI);
16177 generate_exception_err(ctx, EXCP_CpU, 1);
16181 minor = (ctx->opcode >> 21) & 0x1f;
16184 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16185 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16188 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16189 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16190 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16193 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16194 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16195 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16198 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16199 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16202 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16203 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16204 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16207 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16208 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16209 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16212 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16213 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16216 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16217 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16221 case TLTI: /* BC1EQZC */
16222 if (ctx->insn_flags & ISA_MIPS32R6) {
16224 check_cp1_enabled(ctx);
16225 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16228 mips32_op = OPC_TLTI;
16232 case TGEI: /* BC1NEZC */
16233 if (ctx->insn_flags & ISA_MIPS32R6) {
16235 check_cp1_enabled(ctx);
16236 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16239 mips32_op = OPC_TGEI;
16244 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16245 mips32_op = OPC_TLTIU;
16248 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16249 mips32_op = OPC_TGEIU;
16251 case TNEI: /* SYNCI */
16252 if (ctx->insn_flags & ISA_MIPS32R6) {
16254 /* Break the TB to be able to sync copied instructions
16256 ctx->base.is_jmp = DISAS_STOP;
16259 mips32_op = OPC_TNEI;
16264 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16265 mips32_op = OPC_TEQI;
16267 gen_trap(ctx, mips32_op, rs, -1, imm);
16272 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16273 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16274 4, rs, 0, imm << 1, 0);
16275 /* Compact branches don't have a delay slot, so just let
16276 the normal delay slot handling take us to the branch
16280 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16281 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16284 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16285 /* Break the TB to be able to sync copied instructions
16287 ctx->base.is_jmp = DISAS_STOP;
16291 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16292 /* COP2: Not implemented. */
16293 generate_exception_err(ctx, EXCP_CpU, 2);
16296 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16297 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16300 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16301 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16304 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16305 mips32_op = OPC_BC1FANY4;
16308 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16309 mips32_op = OPC_BC1TANY4;
16312 check_insn(ctx, ASE_MIPS3D);
16315 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16316 check_cp1_enabled(ctx);
16317 gen_compute_branch1(ctx, mips32_op,
16318 (ctx->opcode >> 18) & 0x7, imm << 1);
16320 generate_exception_err(ctx, EXCP_CpU, 1);
16325 /* MIPS DSP: not implemented */
16328 MIPS_INVAL("pool32i");
16329 generate_exception_end(ctx, EXCP_RI);
16334 minor = (ctx->opcode >> 12) & 0xf;
16335 offset = sextract32(ctx->opcode, 0,
16336 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16339 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16340 mips32_op = OPC_LWL;
16343 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16344 mips32_op = OPC_SWL;
16347 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16348 mips32_op = OPC_LWR;
16351 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16352 mips32_op = OPC_SWR;
16354 #if defined(TARGET_MIPS64)
16356 check_insn(ctx, ISA_MIPS3);
16357 check_mips_64(ctx);
16358 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16359 mips32_op = OPC_LDL;
16362 check_insn(ctx, ISA_MIPS3);
16363 check_mips_64(ctx);
16364 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16365 mips32_op = OPC_SDL;
16368 check_insn(ctx, ISA_MIPS3);
16369 check_mips_64(ctx);
16370 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16371 mips32_op = OPC_LDR;
16374 check_insn(ctx, ISA_MIPS3);
16375 check_mips_64(ctx);
16376 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16377 mips32_op = OPC_SDR;
16380 check_insn(ctx, ISA_MIPS3);
16381 check_mips_64(ctx);
16382 mips32_op = OPC_LWU;
16385 check_insn(ctx, ISA_MIPS3);
16386 check_mips_64(ctx);
16387 mips32_op = OPC_LLD;
16391 mips32_op = OPC_LL;
16394 gen_ld(ctx, mips32_op, rt, rs, offset);
16397 gen_st(ctx, mips32_op, rt, rs, offset);
16400 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
16402 #if defined(TARGET_MIPS64)
16404 check_insn(ctx, ISA_MIPS3);
16405 check_mips_64(ctx);
16406 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
16411 MIPS_INVAL("pool32c ld-eva");
16412 generate_exception_end(ctx, EXCP_RI);
16415 check_cp0_enabled(ctx);
16417 minor2 = (ctx->opcode >> 9) & 0x7;
16418 offset = sextract32(ctx->opcode, 0, 9);
16421 mips32_op = OPC_LBUE;
16424 mips32_op = OPC_LHUE;
16427 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16428 mips32_op = OPC_LWLE;
16431 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16432 mips32_op = OPC_LWRE;
16435 mips32_op = OPC_LBE;
16438 mips32_op = OPC_LHE;
16441 mips32_op = OPC_LLE;
16444 mips32_op = OPC_LWE;
16450 MIPS_INVAL("pool32c st-eva");
16451 generate_exception_end(ctx, EXCP_RI);
16454 check_cp0_enabled(ctx);
16456 minor2 = (ctx->opcode >> 9) & 0x7;
16457 offset = sextract32(ctx->opcode, 0, 9);
16460 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16461 mips32_op = OPC_SWLE;
16464 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16465 mips32_op = OPC_SWRE;
16468 /* Treat as no-op */
16469 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16470 /* hint codes 24-31 are reserved and signal RI */
16471 generate_exception(ctx, EXCP_RI);
16475 /* Treat as no-op */
16476 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16477 gen_cache_operation(ctx, rt, rs, offset);
16481 mips32_op = OPC_SBE;
16484 mips32_op = OPC_SHE;
16487 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16490 mips32_op = OPC_SWE;
16495 /* Treat as no-op */
16496 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16497 /* hint codes 24-31 are reserved and signal RI */
16498 generate_exception(ctx, EXCP_RI);
16502 MIPS_INVAL("pool32c");
16503 generate_exception_end(ctx, EXCP_RI);
16507 case ADDI32: /* AUI, LUI */
16508 if (ctx->insn_flags & ISA_MIPS32R6) {
16510 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16513 mips32_op = OPC_ADDI;
16518 mips32_op = OPC_ADDIU;
16520 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16523 /* Logical operations */
16525 mips32_op = OPC_ORI;
16528 mips32_op = OPC_XORI;
16531 mips32_op = OPC_ANDI;
16533 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16536 /* Set less than immediate */
16538 mips32_op = OPC_SLTI;
16541 mips32_op = OPC_SLTIU;
16543 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16546 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16547 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16548 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16549 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16551 case JALS32: /* BOVC, BEQC, BEQZALC */
16552 if (ctx->insn_flags & ISA_MIPS32R6) {
16555 mips32_op = OPC_BOVC;
16556 } else if (rs < rt && rs == 0) {
16558 mips32_op = OPC_BEQZALC;
16561 mips32_op = OPC_BEQC;
16563 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16566 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16567 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16568 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16571 case BEQ32: /* BC */
16572 if (ctx->insn_flags & ISA_MIPS32R6) {
16574 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16575 sextract32(ctx->opcode << 1, 0, 27));
16578 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16581 case BNE32: /* BALC */
16582 if (ctx->insn_flags & ISA_MIPS32R6) {
16584 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16585 sextract32(ctx->opcode << 1, 0, 27));
16588 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16591 case J32: /* BGTZC, BLTZC, BLTC */
16592 if (ctx->insn_flags & ISA_MIPS32R6) {
16593 if (rs == 0 && rt != 0) {
16595 mips32_op = OPC_BGTZC;
16596 } else if (rs != 0 && rt != 0 && rs == rt) {
16598 mips32_op = OPC_BLTZC;
16601 mips32_op = OPC_BLTC;
16603 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16606 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16607 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16610 case JAL32: /* BLEZC, BGEZC, BGEC */
16611 if (ctx->insn_flags & ISA_MIPS32R6) {
16612 if (rs == 0 && rt != 0) {
16614 mips32_op = OPC_BLEZC;
16615 } else if (rs != 0 && rt != 0 && rs == rt) {
16617 mips32_op = OPC_BGEZC;
16620 mips32_op = OPC_BGEC;
16622 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16625 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16626 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16627 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16630 /* Floating point (COP1) */
16632 mips32_op = OPC_LWC1;
16635 mips32_op = OPC_LDC1;
16638 mips32_op = OPC_SWC1;
16641 mips32_op = OPC_SDC1;
16643 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16645 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16646 if (ctx->insn_flags & ISA_MIPS32R6) {
16647 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16648 switch ((ctx->opcode >> 16) & 0x1f) {
16657 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16660 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16663 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16673 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16676 generate_exception(ctx, EXCP_RI);
16681 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16682 offset = SIMM(ctx->opcode, 0, 23) << 2;
16684 gen_addiupc(ctx, reg, offset, 0, 0);
16687 case BNVC: /* BNEC, BNEZALC */
16688 check_insn(ctx, ISA_MIPS32R6);
16691 mips32_op = OPC_BNVC;
16692 } else if (rs < rt && rs == 0) {
16694 mips32_op = OPC_BNEZALC;
16697 mips32_op = OPC_BNEC;
16699 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16701 case R6_BNEZC: /* JIALC */
16702 check_insn(ctx, ISA_MIPS32R6);
16705 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16706 sextract32(ctx->opcode << 1, 0, 22));
16709 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16712 case R6_BEQZC: /* JIC */
16713 check_insn(ctx, ISA_MIPS32R6);
16716 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16717 sextract32(ctx->opcode << 1, 0, 22));
16720 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16723 case BLEZALC: /* BGEZALC, BGEUC */
16724 check_insn(ctx, ISA_MIPS32R6);
16725 if (rs == 0 && rt != 0) {
16727 mips32_op = OPC_BLEZALC;
16728 } else if (rs != 0 && rt != 0 && rs == rt) {
16730 mips32_op = OPC_BGEZALC;
16733 mips32_op = OPC_BGEUC;
16735 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16737 case BGTZALC: /* BLTZALC, BLTUC */
16738 check_insn(ctx, ISA_MIPS32R6);
16739 if (rs == 0 && rt != 0) {
16741 mips32_op = OPC_BGTZALC;
16742 } else if (rs != 0 && rt != 0 && rs == rt) {
16744 mips32_op = OPC_BLTZALC;
16747 mips32_op = OPC_BLTUC;
16749 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16751 /* Loads and stores */
16753 mips32_op = OPC_LB;
16756 mips32_op = OPC_LBU;
16759 mips32_op = OPC_LH;
16762 mips32_op = OPC_LHU;
16765 mips32_op = OPC_LW;
16767 #ifdef TARGET_MIPS64
16769 check_insn(ctx, ISA_MIPS3);
16770 check_mips_64(ctx);
16771 mips32_op = OPC_LD;
16774 check_insn(ctx, ISA_MIPS3);
16775 check_mips_64(ctx);
16776 mips32_op = OPC_SD;
16780 mips32_op = OPC_SB;
16783 mips32_op = OPC_SH;
16786 mips32_op = OPC_SW;
16789 gen_ld(ctx, mips32_op, rt, rs, imm);
16792 gen_st(ctx, mips32_op, rt, rs, imm);
16795 generate_exception_end(ctx, EXCP_RI);
16800 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
16804 /* make sure instructions are on a halfword boundary */
16805 if (ctx->base.pc_next & 0x1) {
16806 env->CP0_BadVAddr = ctx->base.pc_next;
16807 generate_exception_end(ctx, EXCP_AdEL);
16811 op = (ctx->opcode >> 10) & 0x3f;
16812 /* Enforce properly-sized instructions in a delay slot */
16813 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16814 switch (op & 0x7) { /* MSB-3..MSB-5 */
16816 /* POOL32A, POOL32B, POOL32I, POOL32C */
16818 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16820 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16822 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16824 /* LB32, LH32, LWC132, LDC132, LW32 */
16825 if (ctx->hflags & MIPS_HFLAG_BDS16) {
16826 generate_exception_end(ctx, EXCP_RI);
16831 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16833 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16835 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16836 if (ctx->hflags & MIPS_HFLAG_BDS32) {
16837 generate_exception_end(ctx, EXCP_RI);
16847 int rd = mmreg(uMIPS_RD(ctx->opcode));
16848 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16849 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16852 switch (ctx->opcode & 0x1) {
16860 if (ctx->insn_flags & ISA_MIPS32R6) {
16861 /* In the Release 6 the register number location in
16862 * the instruction encoding has changed.
16864 gen_arith(ctx, opc, rs1, rd, rs2);
16866 gen_arith(ctx, opc, rd, rs1, rs2);
16872 int rd = mmreg(uMIPS_RD(ctx->opcode));
16873 int rs = mmreg(uMIPS_RS(ctx->opcode));
16874 int amount = (ctx->opcode >> 1) & 0x7;
16876 amount = amount == 0 ? 8 : amount;
16878 switch (ctx->opcode & 0x1) {
16887 gen_shift_imm(ctx, opc, rd, rs, amount);
16891 if (ctx->insn_flags & ISA_MIPS32R6) {
16892 gen_pool16c_r6_insn(ctx);
16894 gen_pool16c_insn(ctx);
16899 int rd = mmreg(uMIPS_RD(ctx->opcode));
16900 int rb = 28; /* GP */
16901 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
16903 gen_ld(ctx, OPC_LW, rd, rb, offset);
16907 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16908 if (ctx->opcode & 1) {
16909 generate_exception_end(ctx, EXCP_RI);
16912 int enc_dest = uMIPS_RD(ctx->opcode);
16913 int enc_rt = uMIPS_RS2(ctx->opcode);
16914 int enc_rs = uMIPS_RS1(ctx->opcode);
16915 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
16920 int rd = mmreg(uMIPS_RD(ctx->opcode));
16921 int rb = mmreg(uMIPS_RS(ctx->opcode));
16922 int16_t offset = ZIMM(ctx->opcode, 0, 4);
16923 offset = (offset == 0xf ? -1 : offset);
16925 gen_ld(ctx, OPC_LBU, rd, rb, offset);
16930 int rd = mmreg(uMIPS_RD(ctx->opcode));
16931 int rb = mmreg(uMIPS_RS(ctx->opcode));
16932 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16934 gen_ld(ctx, OPC_LHU, rd, rb, offset);
16939 int rd = (ctx->opcode >> 5) & 0x1f;
16940 int rb = 29; /* SP */
16941 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16943 gen_ld(ctx, OPC_LW, rd, rb, offset);
16948 int rd = mmreg(uMIPS_RD(ctx->opcode));
16949 int rb = mmreg(uMIPS_RS(ctx->opcode));
16950 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16952 gen_ld(ctx, OPC_LW, rd, rb, offset);
16957 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16958 int rb = mmreg(uMIPS_RS(ctx->opcode));
16959 int16_t offset = ZIMM(ctx->opcode, 0, 4);
16961 gen_st(ctx, OPC_SB, rd, rb, offset);
16966 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16967 int rb = mmreg(uMIPS_RS(ctx->opcode));
16968 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16970 gen_st(ctx, OPC_SH, rd, rb, offset);
16975 int rd = (ctx->opcode >> 5) & 0x1f;
16976 int rb = 29; /* SP */
16977 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16979 gen_st(ctx, OPC_SW, rd, rb, offset);
16984 int rd = mmreg2(uMIPS_RD(ctx->opcode));
16985 int rb = mmreg(uMIPS_RS(ctx->opcode));
16986 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16988 gen_st(ctx, OPC_SW, rd, rb, offset);
16993 int rd = uMIPS_RD5(ctx->opcode);
16994 int rs = uMIPS_RS5(ctx->opcode);
16996 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17003 switch (ctx->opcode & 0x1) {
17013 switch (ctx->opcode & 0x1) {
17018 gen_addiur1sp(ctx);
17022 case B16: /* BC16 */
17023 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17024 sextract32(ctx->opcode, 0, 10) << 1,
17025 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17027 case BNEZ16: /* BNEZC16 */
17028 case BEQZ16: /* BEQZC16 */
17029 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17030 mmreg(uMIPS_RD(ctx->opcode)),
17031 0, sextract32(ctx->opcode, 0, 7) << 1,
17032 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17037 int reg = mmreg(uMIPS_RD(ctx->opcode));
17038 int imm = ZIMM(ctx->opcode, 0, 7);
17040 imm = (imm == 0x7f ? -1 : imm);
17041 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17047 generate_exception_end(ctx, EXCP_RI);
17050 decode_micromips32_opc(env, ctx);
17063 /* MAJOR, P16, and P32 pools opcodes */
17067 NM_MOVE_BALC = 0x02,
17075 NM_P16_SHIFT = 0x0c,
17093 NM_P_LS_U12 = 0x21,
17103 NM_P16_ADDU = 0x2c,
17117 NM_MOVEPREV = 0x3f,
17120 /* POOL32A instruction pool */
17122 NM_POOL32A0 = 0x00,
17123 NM_SPECIAL2 = 0x01,
17126 NM_POOL32A5 = 0x05,
17127 NM_POOL32A7 = 0x07,
17130 /* P.GP.W instruction pool */
17132 NM_ADDIUGP_W = 0x00,
17137 /* P48I instruction pool */
17141 NM_ADDIUGP48 = 0x02,
17142 NM_ADDIUPC48 = 0x03,
17147 /* P.U12 instruction pool */
17156 NM_ADDIUNEG = 0x08,
17163 /* POOL32F instruction pool */
17165 NM_POOL32F_0 = 0x00,
17166 NM_POOL32F_3 = 0x03,
17167 NM_POOL32F_5 = 0x05,
17170 /* POOL32S instruction pool */
17172 NM_POOL32S_0 = 0x00,
17173 NM_POOL32S_4 = 0x04,
17176 /* P.LUI instruction pool */
17182 /* P.GP.BH instruction pool */
17187 NM_ADDIUGP_B = 0x03,
17190 NM_P_GP_CP1 = 0x06,
17193 /* P.LS.U12 instruction pool */
17198 NM_P_PREFU12 = 0x03,
17211 /* P.LS.S9 instruction pool */
17217 NM_P_LS_UAWM = 0x05,
17220 /* P.BAL instruction pool */
17226 /* P.J instruction pool */
17229 NM_JALRC_HB = 0x01,
17230 NM_P_BALRSC = 0x08,
17233 /* P.BR1 instruction pool */
17241 /* P.BR2 instruction pool */
17248 /* P.BRI instruction pool */
17260 /* P16.SHIFT instruction pool */
17266 /* POOL16C instruction pool */
17268 NM_POOL16C_0 = 0x00,
17272 /* P16.A1 instruction pool */
17274 NM_ADDIUR1SP = 0x01,
17277 /* P16.A2 instruction pool */
17280 NM_P_ADDIURS5 = 0x01,
17283 /* P16.ADDU instruction pool */
17289 /* P16.SR instruction pool */
17292 NM_RESTORE_JRC16 = 0x01,
17295 /* P16.4X4 instruction pool */
17301 /* P16.LB instruction pool */
17308 /* P16.LH instruction pool */
17315 /* P.RI instruction pool */
17318 NM_P_SYSCALL = 0x01,
17323 /* POOL32A0 instruction pool */
17358 NM_D_E_MT_VPE = 0x56,
17366 /* POOL32A5 instruction pool */
17368 NM_CMP_EQ_PH = 0x00,
17369 NM_CMP_LT_PH = 0x08,
17370 NM_CMP_LE_PH = 0x10,
17371 NM_CMPGU_EQ_QB = 0x18,
17372 NM_CMPGU_LT_QB = 0x20,
17373 NM_CMPGU_LE_QB = 0x28,
17374 NM_CMPGDU_EQ_QB = 0x30,
17375 NM_CMPGDU_LT_QB = 0x38,
17376 NM_CMPGDU_LE_QB = 0x40,
17377 NM_CMPU_EQ_QB = 0x48,
17378 NM_CMPU_LT_QB = 0x50,
17379 NM_CMPU_LE_QB = 0x58,
17380 NM_ADDQ_S_W = 0x60,
17381 NM_SUBQ_S_W = 0x68,
17385 NM_ADDQ_S_PH = 0x01,
17386 NM_ADDQH_R_PH = 0x09,
17387 NM_ADDQH_R_W = 0x11,
17388 NM_ADDU_S_QB = 0x19,
17389 NM_ADDU_S_PH = 0x21,
17390 NM_ADDUH_R_QB = 0x29,
17391 NM_SHRAV_R_PH = 0x31,
17392 NM_SHRAV_R_QB = 0x39,
17393 NM_SUBQ_S_PH = 0x41,
17394 NM_SUBQH_R_PH = 0x49,
17395 NM_SUBQH_R_W = 0x51,
17396 NM_SUBU_S_QB = 0x59,
17397 NM_SUBU_S_PH = 0x61,
17398 NM_SUBUH_R_QB = 0x69,
17399 NM_SHLLV_S_PH = 0x71,
17400 NM_PRECR_SRA_R_PH_W = 0x79,
17402 NM_MULEU_S_PH_QBL = 0x12,
17403 NM_MULEU_S_PH_QBR = 0x1a,
17404 NM_MULQ_RS_PH = 0x22,
17405 NM_MULQ_S_PH = 0x2a,
17406 NM_MULQ_RS_W = 0x32,
17407 NM_MULQ_S_W = 0x3a,
17410 NM_SHRAV_R_W = 0x5a,
17411 NM_SHRLV_PH = 0x62,
17412 NM_SHRLV_QB = 0x6a,
17413 NM_SHLLV_QB = 0x72,
17414 NM_SHLLV_S_W = 0x7a,
17418 NM_MULEQ_S_W_PHL = 0x04,
17419 NM_MULEQ_S_W_PHR = 0x0c,
17421 NM_MUL_S_PH = 0x05,
17422 NM_PRECR_QB_PH = 0x0d,
17423 NM_PRECRQ_QB_PH = 0x15,
17424 NM_PRECRQ_PH_W = 0x1d,
17425 NM_PRECRQ_RS_PH_W = 0x25,
17426 NM_PRECRQU_S_QB_PH = 0x2d,
17427 NM_PACKRL_PH = 0x35,
17431 NM_SHRA_R_W = 0x5e,
17432 NM_SHRA_R_PH = 0x66,
17433 NM_SHLL_S_PH = 0x76,
17434 NM_SHLL_S_W = 0x7e,
17439 /* POOL32A7 instruction pool */
17444 NM_POOL32AXF = 0x07,
17447 /* P.SR instruction pool */
17453 /* P.SHIFT instruction pool */
17461 /* P.ROTX instruction pool */
17466 /* P.INS instruction pool */
17471 /* P.EXT instruction pool */
17476 /* POOL32F_0 (fmt) instruction pool */
17481 NM_SELEQZ_S = 0x07,
17482 NM_SELEQZ_D = 0x47,
17486 NM_SELNEZ_S = 0x0f,
17487 NM_SELNEZ_D = 0x4f,
17502 /* POOL32F_3 instruction pool */
17506 NM_MINA_FMT = 0x04,
17507 NM_MAXA_FMT = 0x05,
17508 NM_POOL32FXF = 0x07,
17511 /* POOL32F_5 instruction pool */
17513 NM_CMP_CONDN_S = 0x00,
17514 NM_CMP_CONDN_D = 0x02,
17517 /* P.GP.LH instruction pool */
17523 /* P.GP.SH instruction pool */
17528 /* P.GP.CP1 instruction pool */
17536 /* P.LS.S0 instruction pool */
17553 NM_P_PREFS9 = 0x03,
17559 /* P.LS.S1 instruction pool */
17561 NM_ASET_ACLR = 0x02,
17569 /* P.LS.E0 instruction pool */
17585 /* P.PREFE instruction pool */
17591 /* P.LLE instruction pool */
17597 /* P.SCE instruction pool */
17603 /* P.LS.WM instruction pool */
17609 /* P.LS.UAWM instruction pool */
17615 /* P.BR3A instruction pool */
17621 NM_BPOSGE32C = 0x04,
17624 /* P16.RI instruction pool */
17626 NM_P16_SYSCALL = 0x01,
17631 /* POOL16C_0 instruction pool */
17633 NM_POOL16C_00 = 0x00,
17636 /* P16.JRC instruction pool */
17642 /* P.SYSCALL instruction pool */
17648 /* P.TRAP instruction pool */
17654 /* P.CMOVE instruction pool */
17660 /* POOL32Axf instruction pool */
17662 NM_POOL32AXF_1 = 0x01,
17663 NM_POOL32AXF_2 = 0x02,
17664 NM_POOL32AXF_4 = 0x04,
17665 NM_POOL32AXF_5 = 0x05,
17666 NM_POOL32AXF_7 = 0x07,
17669 /* POOL32Axf_1 instruction pool */
17671 NM_POOL32AXF_1_0 = 0x00,
17672 NM_POOL32AXF_1_1 = 0x01,
17673 NM_POOL32AXF_1_3 = 0x03,
17674 NM_POOL32AXF_1_4 = 0x04,
17675 NM_POOL32AXF_1_5 = 0x05,
17676 NM_POOL32AXF_1_7 = 0x07,
17679 /* POOL32Axf_2 instruction pool */
17681 NM_POOL32AXF_2_0_7 = 0x00,
17682 NM_POOL32AXF_2_8_15 = 0x01,
17683 NM_POOL32AXF_2_16_23 = 0x02,
17684 NM_POOL32AXF_2_24_31 = 0x03,
17687 /* POOL32Axf_7 instruction pool */
17689 NM_SHRA_R_QB = 0x0,
17694 /* POOL32Axf_1_0 instruction pool */
17702 /* POOL32Axf_1_1 instruction pool */
17708 /* POOL32Axf_1_3 instruction pool */
17716 /* POOL32Axf_1_4 instruction pool */
17722 /* POOL32Axf_1_5 instruction pool */
17724 NM_MAQ_S_W_PHR = 0x0,
17725 NM_MAQ_S_W_PHL = 0x1,
17726 NM_MAQ_SA_W_PHR = 0x2,
17727 NM_MAQ_SA_W_PHL = 0x3,
17730 /* POOL32Axf_1_7 instruction pool */
17734 NM_EXTR_RS_W = 0x2,
17738 /* POOL32Axf_2_0_7 instruction pool */
17741 NM_DPAQ_S_W_PH = 0x1,
17743 NM_DPSQ_S_W_PH = 0x3,
17750 /* POOL32Axf_2_8_15 instruction pool */
17752 NM_DPAX_W_PH = 0x0,
17753 NM_DPAQ_SA_L_W = 0x1,
17754 NM_DPSX_W_PH = 0x2,
17755 NM_DPSQ_SA_L_W = 0x3,
17758 NM_EXTRV_R_W = 0x7,
17761 /* POOL32Axf_2_16_23 instruction pool */
17763 NM_DPAU_H_QBL = 0x0,
17764 NM_DPAQX_S_W_PH = 0x1,
17765 NM_DPSU_H_QBL = 0x2,
17766 NM_DPSQX_S_W_PH = 0x3,
17769 NM_MULSA_W_PH = 0x6,
17770 NM_EXTRV_RS_W = 0x7,
17773 /* POOL32Axf_2_24_31 instruction pool */
17775 NM_DPAU_H_QBR = 0x0,
17776 NM_DPAQX_SA_W_PH = 0x1,
17777 NM_DPSU_H_QBR = 0x2,
17778 NM_DPSQX_SA_W_PH = 0x3,
17781 NM_MULSAQ_S_W_PH = 0x6,
17782 NM_EXTRV_S_H = 0x7,
17785 /* POOL32Axf_{4, 5} instruction pool */
17804 /* nanoMIPS DSP instructions */
17805 NM_ABSQ_S_QB = 0x00,
17806 NM_ABSQ_S_PH = 0x08,
17807 NM_ABSQ_S_W = 0x10,
17808 NM_PRECEQ_W_PHL = 0x28,
17809 NM_PRECEQ_W_PHR = 0x30,
17810 NM_PRECEQU_PH_QBL = 0x38,
17811 NM_PRECEQU_PH_QBR = 0x48,
17812 NM_PRECEU_PH_QBL = 0x58,
17813 NM_PRECEU_PH_QBR = 0x68,
17814 NM_PRECEQU_PH_QBLA = 0x39,
17815 NM_PRECEQU_PH_QBRA = 0x49,
17816 NM_PRECEU_PH_QBLA = 0x59,
17817 NM_PRECEU_PH_QBRA = 0x69,
17818 NM_REPLV_PH = 0x01,
17819 NM_REPLV_QB = 0x09,
17822 NM_RADDU_W_QB = 0x78,
17828 /* PP.SR instruction pool */
17832 NM_RESTORE_JRC = 0x03,
17835 /* P.SR.F instruction pool */
17838 NM_RESTOREF = 0x01,
17841 /* P16.SYSCALL instruction pool */
17843 NM_SYSCALL16 = 0x00,
17844 NM_HYPCALL16 = 0x01,
17847 /* POOL16C_00 instruction pool */
17855 /* PP.LSX and PP.LSXS instruction pool */
17893 /* ERETx instruction pool */
17899 /* POOL32FxF_{0, 1} insturction pool */
17908 NM_CVT_S_PL = 0x84,
17909 NM_CVT_S_PU = 0xa4,
17911 NM_CVT_L_S = 0x004,
17912 NM_CVT_L_D = 0x104,
17913 NM_CVT_W_S = 0x024,
17914 NM_CVT_W_D = 0x124,
17916 NM_RSQRT_S = 0x008,
17917 NM_RSQRT_D = 0x108,
17922 NM_RECIP_S = 0x048,
17923 NM_RECIP_D = 0x148,
17925 NM_FLOOR_L_S = 0x00c,
17926 NM_FLOOR_L_D = 0x10c,
17928 NM_FLOOR_W_S = 0x02c,
17929 NM_FLOOR_W_D = 0x12c,
17931 NM_CEIL_L_S = 0x04c,
17932 NM_CEIL_L_D = 0x14c,
17933 NM_CEIL_W_S = 0x06c,
17934 NM_CEIL_W_D = 0x16c,
17935 NM_TRUNC_L_S = 0x08c,
17936 NM_TRUNC_L_D = 0x18c,
17937 NM_TRUNC_W_S = 0x0ac,
17938 NM_TRUNC_W_D = 0x1ac,
17939 NM_ROUND_L_S = 0x0cc,
17940 NM_ROUND_L_D = 0x1cc,
17941 NM_ROUND_W_S = 0x0ec,
17942 NM_ROUND_W_D = 0x1ec,
17950 NM_CVT_D_S = 0x04d,
17951 NM_CVT_D_W = 0x0cd,
17952 NM_CVT_D_L = 0x14d,
17953 NM_CVT_S_D = 0x06d,
17954 NM_CVT_S_W = 0x0ed,
17955 NM_CVT_S_L = 0x16d,
17958 /* P.LL instruction pool */
17964 /* P.SC instruction pool */
17970 /* P.DVP instruction pool */
17979 * nanoMIPS decoding engine
17984 /* extraction utilities */
17986 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17987 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17988 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17989 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17990 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17991 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17993 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17994 static inline int decode_gpr_gpr3(int r)
17996 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
17998 return map[r & 0x7];
18001 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18002 static inline int decode_gpr_gpr3_src_store(int r)
18004 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18006 return map[r & 0x7];
18009 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18010 static inline int decode_gpr_gpr4(int r)
18012 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18013 16, 17, 18, 19, 20, 21, 22, 23 };
18015 return map[r & 0xf];
18018 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18019 static inline int decode_gpr_gpr4_zero(int r)
18021 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18022 16, 17, 18, 19, 20, 21, 22, 23 };
18024 return map[r & 0xf];
18028 /* extraction utilities */
18030 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18031 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18032 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18033 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18034 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18035 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18038 static void gen_adjust_sp(DisasContext *ctx, int u)
18040 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18043 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18044 uint8_t gp, uint16_t u)
18047 TCGv va = tcg_temp_new();
18048 TCGv t0 = tcg_temp_new();
18050 while (counter != count) {
18051 bool use_gp = gp && (counter == count - 1);
18052 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18053 int this_offset = -((counter + 1) << 2);
18054 gen_base_offset_addr(ctx, va, 29, this_offset);
18055 gen_load_gpr(t0, this_rt);
18056 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18057 (MO_TEUL | ctx->default_tcg_memop_mask));
18061 /* adjust stack pointer */
18062 gen_adjust_sp(ctx, -u);
18068 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18069 uint8_t gp, uint16_t u)
18072 TCGv va = tcg_temp_new();
18073 TCGv t0 = tcg_temp_new();
18075 while (counter != count) {
18076 bool use_gp = gp && (counter == count - 1);
18077 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18078 int this_offset = u - ((counter + 1) << 2);
18079 gen_base_offset_addr(ctx, va, 29, this_offset);
18080 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18081 ctx->default_tcg_memop_mask);
18082 tcg_gen_ext32s_tl(t0, t0);
18083 gen_store_gpr(t0, this_rt);
18087 /* adjust stack pointer */
18088 gen_adjust_sp(ctx, u);
18094 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18096 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18097 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18099 switch (extract32(ctx->opcode, 2, 2)) {
18101 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18104 gen_logic(ctx, OPC_AND, rt, rt, rs);
18107 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18110 gen_logic(ctx, OPC_OR, rt, rt, rs);
18115 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18117 int rt = extract32(ctx->opcode, 21, 5);
18118 int rs = extract32(ctx->opcode, 16, 5);
18119 int rd = extract32(ctx->opcode, 11, 5);
18121 switch (extract32(ctx->opcode, 3, 7)) {
18123 switch (extract32(ctx->opcode, 10, 1)) {
18126 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18130 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18136 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18140 gen_bshfl(ctx, OPC_SEB, rs, rt);
18143 gen_bshfl(ctx, OPC_SEH, rs, rt);
18146 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18149 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18152 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18155 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18158 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18161 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18165 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18168 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18171 switch (extract32(ctx->opcode, 10, 1)) {
18173 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18176 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18181 gen_logic(ctx, OPC_AND, rd, rs, rt);
18184 gen_logic(ctx, OPC_OR, rd, rs, rt);
18187 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18190 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18193 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18198 #ifndef CONFIG_USER_ONLY
18199 TCGv t0 = tcg_temp_new();
18200 switch (extract32(ctx->opcode, 10, 1)) {
18203 check_cp0_enabled(ctx);
18204 gen_helper_dvp(t0, cpu_env);
18205 gen_store_gpr(t0, rt);
18210 check_cp0_enabled(ctx);
18211 gen_helper_evp(t0, cpu_env);
18212 gen_store_gpr(t0, rt);
18219 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18224 TCGv t0 = tcg_temp_new();
18225 TCGv t1 = tcg_temp_new();
18226 TCGv t2 = tcg_temp_new();
18228 gen_load_gpr(t1, rs);
18229 gen_load_gpr(t2, rt);
18230 tcg_gen_add_tl(t0, t1, t2);
18231 tcg_gen_ext32s_tl(t0, t0);
18232 tcg_gen_xor_tl(t1, t1, t2);
18233 tcg_gen_xor_tl(t2, t0, t2);
18234 tcg_gen_andc_tl(t1, t2, t1);
18236 /* operands of same sign, result different sign */
18237 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18238 gen_store_gpr(t0, rd);
18246 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18249 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18252 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18255 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18258 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18261 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18264 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18267 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18269 #ifndef CONFIG_USER_ONLY
18271 check_cp0_enabled(ctx);
18273 /* Treat as NOP. */
18276 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18279 check_cp0_enabled(ctx);
18281 TCGv t0 = tcg_temp_new();
18283 gen_load_gpr(t0, rt);
18284 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18288 case NM_D_E_MT_VPE:
18290 uint8_t sc = extract32(ctx->opcode, 10, 1);
18291 TCGv t0 = tcg_temp_new();
18298 gen_helper_dmt(t0);
18299 gen_store_gpr(t0, rt);
18300 } else if (rs == 0) {
18303 gen_helper_dvpe(t0, cpu_env);
18304 gen_store_gpr(t0, rt);
18306 generate_exception_end(ctx, EXCP_RI);
18313 gen_helper_emt(t0);
18314 gen_store_gpr(t0, rt);
18315 } else if (rs == 0) {
18318 gen_helper_evpe(t0, cpu_env);
18319 gen_store_gpr(t0, rt);
18321 generate_exception_end(ctx, EXCP_RI);
18332 TCGv t0 = tcg_temp_new();
18333 TCGv t1 = tcg_temp_new();
18335 gen_load_gpr(t0, rt);
18336 gen_load_gpr(t1, rs);
18337 gen_helper_fork(t0, t1);
18344 check_cp0_enabled(ctx);
18346 /* Treat as NOP. */
18349 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18350 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18354 check_cp0_enabled(ctx);
18355 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18356 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18361 TCGv t0 = tcg_temp_new();
18363 gen_load_gpr(t0, rs);
18364 gen_helper_yield(t0, cpu_env, t0);
18365 gen_store_gpr(t0, rt);
18371 generate_exception_end(ctx, EXCP_RI);
18377 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18378 int ret, int v1, int v2)
18384 t0 = tcg_temp_new_i32();
18386 v0_t = tcg_temp_new();
18387 v1_t = tcg_temp_new();
18389 tcg_gen_movi_i32(t0, v2 >> 3);
18391 gen_load_gpr(v0_t, ret);
18392 gen_load_gpr(v1_t, v1);
18395 case NM_MAQ_S_W_PHR:
18397 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18399 case NM_MAQ_S_W_PHL:
18401 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18403 case NM_MAQ_SA_W_PHR:
18405 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18407 case NM_MAQ_SA_W_PHL:
18409 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18412 generate_exception_end(ctx, EXCP_RI);
18416 tcg_temp_free_i32(t0);
18418 tcg_temp_free(v0_t);
18419 tcg_temp_free(v1_t);
18423 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18424 int ret, int v1, int v2)
18427 TCGv t0 = tcg_temp_new();
18428 TCGv t1 = tcg_temp_new();
18429 TCGv v0_t = tcg_temp_new();
18431 gen_load_gpr(v0_t, v1);
18434 case NM_POOL32AXF_1_0:
18436 switch (extract32(ctx->opcode, 12, 2)) {
18438 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18441 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18444 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18447 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18451 case NM_POOL32AXF_1_1:
18453 switch (extract32(ctx->opcode, 12, 2)) {
18455 tcg_gen_movi_tl(t0, v2);
18456 gen_helper_mthlip(t0, v0_t, cpu_env);
18459 tcg_gen_movi_tl(t0, v2 >> 3);
18460 gen_helper_shilo(t0, v0_t, cpu_env);
18463 generate_exception_end(ctx, EXCP_RI);
18467 case NM_POOL32AXF_1_3:
18469 imm = extract32(ctx->opcode, 14, 7);
18470 switch (extract32(ctx->opcode, 12, 2)) {
18472 tcg_gen_movi_tl(t0, imm);
18473 gen_helper_rddsp(t0, t0, cpu_env);
18474 gen_store_gpr(t0, ret);
18477 gen_load_gpr(t0, ret);
18478 tcg_gen_movi_tl(t1, imm);
18479 gen_helper_wrdsp(t0, t1, cpu_env);
18482 tcg_gen_movi_tl(t0, v2 >> 3);
18483 tcg_gen_movi_tl(t1, v1);
18484 gen_helper_extp(t0, t0, t1, cpu_env);
18485 gen_store_gpr(t0, ret);
18488 tcg_gen_movi_tl(t0, v2 >> 3);
18489 tcg_gen_movi_tl(t1, v1);
18490 gen_helper_extpdp(t0, t0, t1, cpu_env);
18491 gen_store_gpr(t0, ret);
18495 case NM_POOL32AXF_1_4:
18497 tcg_gen_movi_tl(t0, v2 >> 2);
18498 switch (extract32(ctx->opcode, 12, 1)) {
18500 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18501 gen_store_gpr(t0, ret);
18504 gen_helper_shrl_qb(t0, t0, v0_t);
18505 gen_store_gpr(t0, ret);
18509 case NM_POOL32AXF_1_5:
18510 opc = extract32(ctx->opcode, 12, 2);
18511 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18513 case NM_POOL32AXF_1_7:
18515 tcg_gen_movi_tl(t0, v2 >> 3);
18516 tcg_gen_movi_tl(t1, v1);
18517 switch (extract32(ctx->opcode, 12, 2)) {
18519 gen_helper_extr_w(t0, t0, t1, cpu_env);
18520 gen_store_gpr(t0, ret);
18523 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18524 gen_store_gpr(t0, ret);
18527 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18528 gen_store_gpr(t0, ret);
18531 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18532 gen_store_gpr(t0, ret);
18537 generate_exception_end(ctx, EXCP_RI);
18543 tcg_temp_free(v0_t);
18546 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18547 TCGv v0, TCGv v1, int rd)
18551 t0 = tcg_temp_new_i32();
18553 tcg_gen_movi_i32(t0, rd >> 3);
18556 case NM_POOL32AXF_2_0_7:
18557 switch (extract32(ctx->opcode, 9, 3)) {
18560 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18562 case NM_DPAQ_S_W_PH:
18564 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18568 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18570 case NM_DPSQ_S_W_PH:
18572 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18575 generate_exception_end(ctx, EXCP_RI);
18579 case NM_POOL32AXF_2_8_15:
18580 switch (extract32(ctx->opcode, 9, 3)) {
18583 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18585 case NM_DPAQ_SA_L_W:
18587 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18591 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18593 case NM_DPSQ_SA_L_W:
18595 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18598 generate_exception_end(ctx, EXCP_RI);
18602 case NM_POOL32AXF_2_16_23:
18603 switch (extract32(ctx->opcode, 9, 3)) {
18604 case NM_DPAU_H_QBL:
18606 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18608 case NM_DPAQX_S_W_PH:
18610 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18612 case NM_DPSU_H_QBL:
18614 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18616 case NM_DPSQX_S_W_PH:
18618 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18620 case NM_MULSA_W_PH:
18622 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18625 generate_exception_end(ctx, EXCP_RI);
18629 case NM_POOL32AXF_2_24_31:
18630 switch (extract32(ctx->opcode, 9, 3)) {
18631 case NM_DPAU_H_QBR:
18633 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18635 case NM_DPAQX_SA_W_PH:
18637 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18639 case NM_DPSU_H_QBR:
18641 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18643 case NM_DPSQX_SA_W_PH:
18645 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18647 case NM_MULSAQ_S_W_PH:
18649 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18652 generate_exception_end(ctx, EXCP_RI);
18657 generate_exception_end(ctx, EXCP_RI);
18661 tcg_temp_free_i32(t0);
18664 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18665 int rt, int rs, int rd)
18668 TCGv t0 = tcg_temp_new();
18669 TCGv t1 = tcg_temp_new();
18670 TCGv v0_t = tcg_temp_new();
18671 TCGv v1_t = tcg_temp_new();
18673 gen_load_gpr(v0_t, rt);
18674 gen_load_gpr(v1_t, rs);
18677 case NM_POOL32AXF_2_0_7:
18678 switch (extract32(ctx->opcode, 9, 3)) {
18680 case NM_DPAQ_S_W_PH:
18682 case NM_DPSQ_S_W_PH:
18683 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18688 gen_load_gpr(t0, rs);
18690 if (rd != 0 && rd != 2) {
18691 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18692 tcg_gen_ext32u_tl(t0, t0);
18693 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18694 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18696 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18702 int acc = extract32(ctx->opcode, 14, 2);
18703 TCGv_i64 t2 = tcg_temp_new_i64();
18704 TCGv_i64 t3 = tcg_temp_new_i64();
18706 gen_load_gpr(t0, rt);
18707 gen_load_gpr(t1, rs);
18708 tcg_gen_ext_tl_i64(t2, t0);
18709 tcg_gen_ext_tl_i64(t3, t1);
18710 tcg_gen_mul_i64(t2, t2, t3);
18711 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18712 tcg_gen_add_i64(t2, t2, t3);
18713 tcg_temp_free_i64(t3);
18714 gen_move_low32(cpu_LO[acc], t2);
18715 gen_move_high32(cpu_HI[acc], t2);
18716 tcg_temp_free_i64(t2);
18722 int acc = extract32(ctx->opcode, 14, 2);
18723 TCGv_i32 t2 = tcg_temp_new_i32();
18724 TCGv_i32 t3 = tcg_temp_new_i32();
18726 gen_load_gpr(t0, rs);
18727 gen_load_gpr(t1, rt);
18728 tcg_gen_trunc_tl_i32(t2, t0);
18729 tcg_gen_trunc_tl_i32(t3, t1);
18730 tcg_gen_muls2_i32(t2, t3, t2, t3);
18731 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18732 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18733 tcg_temp_free_i32(t2);
18734 tcg_temp_free_i32(t3);
18739 gen_load_gpr(v1_t, rs);
18740 tcg_gen_movi_tl(t0, rd >> 3);
18741 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18742 gen_store_gpr(t0, ret);
18746 case NM_POOL32AXF_2_8_15:
18747 switch (extract32(ctx->opcode, 9, 3)) {
18749 case NM_DPAQ_SA_L_W:
18751 case NM_DPSQ_SA_L_W:
18752 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18757 int acc = extract32(ctx->opcode, 14, 2);
18758 TCGv_i64 t2 = tcg_temp_new_i64();
18759 TCGv_i64 t3 = tcg_temp_new_i64();
18761 gen_load_gpr(t0, rs);
18762 gen_load_gpr(t1, rt);
18763 tcg_gen_ext32u_tl(t0, t0);
18764 tcg_gen_ext32u_tl(t1, t1);
18765 tcg_gen_extu_tl_i64(t2, t0);
18766 tcg_gen_extu_tl_i64(t3, t1);
18767 tcg_gen_mul_i64(t2, t2, t3);
18768 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18769 tcg_gen_add_i64(t2, t2, t3);
18770 tcg_temp_free_i64(t3);
18771 gen_move_low32(cpu_LO[acc], t2);
18772 gen_move_high32(cpu_HI[acc], t2);
18773 tcg_temp_free_i64(t2);
18779 int acc = extract32(ctx->opcode, 14, 2);
18780 TCGv_i32 t2 = tcg_temp_new_i32();
18781 TCGv_i32 t3 = tcg_temp_new_i32();
18783 gen_load_gpr(t0, rs);
18784 gen_load_gpr(t1, rt);
18785 tcg_gen_trunc_tl_i32(t2, t0);
18786 tcg_gen_trunc_tl_i32(t3, t1);
18787 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18788 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18789 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18790 tcg_temp_free_i32(t2);
18791 tcg_temp_free_i32(t3);
18796 tcg_gen_movi_tl(t0, rd >> 3);
18797 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18798 gen_store_gpr(t0, ret);
18801 generate_exception_end(ctx, EXCP_RI);
18805 case NM_POOL32AXF_2_16_23:
18806 switch (extract32(ctx->opcode, 9, 3)) {
18807 case NM_DPAU_H_QBL:
18808 case NM_DPAQX_S_W_PH:
18809 case NM_DPSU_H_QBL:
18810 case NM_DPSQX_S_W_PH:
18811 case NM_MULSA_W_PH:
18812 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18816 tcg_gen_movi_tl(t0, rd >> 3);
18817 gen_helper_extp(t0, t0, v1_t, cpu_env);
18818 gen_store_gpr(t0, ret);
18823 int acc = extract32(ctx->opcode, 14, 2);
18824 TCGv_i64 t2 = tcg_temp_new_i64();
18825 TCGv_i64 t3 = tcg_temp_new_i64();
18827 gen_load_gpr(t0, rs);
18828 gen_load_gpr(t1, rt);
18829 tcg_gen_ext_tl_i64(t2, t0);
18830 tcg_gen_ext_tl_i64(t3, t1);
18831 tcg_gen_mul_i64(t2, t2, t3);
18832 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18833 tcg_gen_sub_i64(t2, t3, t2);
18834 tcg_temp_free_i64(t3);
18835 gen_move_low32(cpu_LO[acc], t2);
18836 gen_move_high32(cpu_HI[acc], t2);
18837 tcg_temp_free_i64(t2);
18840 case NM_EXTRV_RS_W:
18842 tcg_gen_movi_tl(t0, rd >> 3);
18843 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18844 gen_store_gpr(t0, ret);
18848 case NM_POOL32AXF_2_24_31:
18849 switch (extract32(ctx->opcode, 9, 3)) {
18850 case NM_DPAU_H_QBR:
18851 case NM_DPAQX_SA_W_PH:
18852 case NM_DPSU_H_QBR:
18853 case NM_DPSQX_SA_W_PH:
18854 case NM_MULSAQ_S_W_PH:
18855 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18859 tcg_gen_movi_tl(t0, rd >> 3);
18860 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
18861 gen_store_gpr(t0, ret);
18866 int acc = extract32(ctx->opcode, 14, 2);
18867 TCGv_i64 t2 = tcg_temp_new_i64();
18868 TCGv_i64 t3 = tcg_temp_new_i64();
18870 gen_load_gpr(t0, rs);
18871 gen_load_gpr(t1, rt);
18872 tcg_gen_ext32u_tl(t0, t0);
18873 tcg_gen_ext32u_tl(t1, t1);
18874 tcg_gen_extu_tl_i64(t2, t0);
18875 tcg_gen_extu_tl_i64(t3, t1);
18876 tcg_gen_mul_i64(t2, t2, t3);
18877 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18878 tcg_gen_sub_i64(t2, t3, t2);
18879 tcg_temp_free_i64(t3);
18880 gen_move_low32(cpu_LO[acc], t2);
18881 gen_move_high32(cpu_HI[acc], t2);
18882 tcg_temp_free_i64(t2);
18887 tcg_gen_movi_tl(t0, rd >> 3);
18888 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
18889 gen_store_gpr(t0, ret);
18894 generate_exception_end(ctx, EXCP_RI);
18901 tcg_temp_free(v0_t);
18902 tcg_temp_free(v1_t);
18905 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
18909 TCGv t0 = tcg_temp_new();
18910 TCGv v0_t = tcg_temp_new();
18912 gen_load_gpr(v0_t, rs);
18917 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
18918 gen_store_gpr(v0_t, ret);
18922 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
18923 gen_store_gpr(v0_t, ret);
18927 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
18928 gen_store_gpr(v0_t, ret);
18930 case NM_PRECEQ_W_PHL:
18932 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
18933 tcg_gen_ext32s_tl(v0_t, v0_t);
18934 gen_store_gpr(v0_t, ret);
18936 case NM_PRECEQ_W_PHR:
18938 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
18939 tcg_gen_shli_tl(v0_t, v0_t, 16);
18940 tcg_gen_ext32s_tl(v0_t, v0_t);
18941 gen_store_gpr(v0_t, ret);
18943 case NM_PRECEQU_PH_QBL:
18945 gen_helper_precequ_ph_qbl(v0_t, v0_t);
18946 gen_store_gpr(v0_t, ret);
18948 case NM_PRECEQU_PH_QBR:
18950 gen_helper_precequ_ph_qbr(v0_t, v0_t);
18951 gen_store_gpr(v0_t, ret);
18953 case NM_PRECEQU_PH_QBLA:
18955 gen_helper_precequ_ph_qbla(v0_t, v0_t);
18956 gen_store_gpr(v0_t, ret);
18958 case NM_PRECEQU_PH_QBRA:
18960 gen_helper_precequ_ph_qbra(v0_t, v0_t);
18961 gen_store_gpr(v0_t, ret);
18963 case NM_PRECEU_PH_QBL:
18965 gen_helper_preceu_ph_qbl(v0_t, v0_t);
18966 gen_store_gpr(v0_t, ret);
18968 case NM_PRECEU_PH_QBR:
18970 gen_helper_preceu_ph_qbr(v0_t, v0_t);
18971 gen_store_gpr(v0_t, ret);
18973 case NM_PRECEU_PH_QBLA:
18975 gen_helper_preceu_ph_qbla(v0_t, v0_t);
18976 gen_store_gpr(v0_t, ret);
18978 case NM_PRECEU_PH_QBRA:
18980 gen_helper_preceu_ph_qbra(v0_t, v0_t);
18981 gen_store_gpr(v0_t, ret);
18985 tcg_gen_ext16u_tl(v0_t, v0_t);
18986 tcg_gen_shli_tl(t0, v0_t, 16);
18987 tcg_gen_or_tl(v0_t, v0_t, t0);
18988 tcg_gen_ext32s_tl(v0_t, v0_t);
18989 gen_store_gpr(v0_t, ret);
18993 tcg_gen_ext8u_tl(v0_t, v0_t);
18994 tcg_gen_shli_tl(t0, v0_t, 8);
18995 tcg_gen_or_tl(v0_t, v0_t, t0);
18996 tcg_gen_shli_tl(t0, v0_t, 16);
18997 tcg_gen_or_tl(v0_t, v0_t, t0);
18998 tcg_gen_ext32s_tl(v0_t, v0_t);
18999 gen_store_gpr(v0_t, ret);
19003 gen_helper_bitrev(v0_t, v0_t);
19004 gen_store_gpr(v0_t, ret);
19009 TCGv tv0 = tcg_temp_new();
19011 gen_load_gpr(tv0, rt);
19012 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19013 gen_store_gpr(v0_t, ret);
19014 tcg_temp_free(tv0);
19017 case NM_RADDU_W_QB:
19019 gen_helper_raddu_w_qb(v0_t, v0_t);
19020 gen_store_gpr(v0_t, ret);
19023 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19027 gen_cl(ctx, OPC_CLO, ret, rs);
19031 gen_cl(ctx, OPC_CLZ, ret, rs);
19034 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19037 generate_exception_end(ctx, EXCP_RI);
19041 tcg_temp_free(v0_t);
19045 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19046 int rt, int rs, int rd)
19048 TCGv t0 = tcg_temp_new();
19049 TCGv rs_t = tcg_temp_new();
19051 gen_load_gpr(rs_t, rs);
19056 tcg_gen_movi_tl(t0, rd >> 2);
19057 switch (extract32(ctx->opcode, 12, 1)) {
19060 gen_helper_shra_qb(t0, t0, rs_t);
19061 gen_store_gpr(t0, rt);
19065 gen_helper_shra_r_qb(t0, t0, rs_t);
19066 gen_store_gpr(t0, rt);
19072 tcg_gen_movi_tl(t0, rd >> 1);
19073 gen_helper_shrl_ph(t0, t0, rs_t);
19074 gen_store_gpr(t0, rt);
19080 target_long result;
19081 imm = extract32(ctx->opcode, 13, 8);
19082 result = (uint32_t)imm << 24 |
19083 (uint32_t)imm << 16 |
19084 (uint32_t)imm << 8 |
19086 result = (int32_t)result;
19087 tcg_gen_movi_tl(t0, result);
19088 gen_store_gpr(t0, rt);
19092 generate_exception_end(ctx, EXCP_RI);
19096 tcg_temp_free(rs_t);
19100 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19102 int rt = extract32(ctx->opcode, 21, 5);
19103 int rs = extract32(ctx->opcode, 16, 5);
19104 int rd = extract32(ctx->opcode, 11, 5);
19106 switch (extract32(ctx->opcode, 6, 3)) {
19107 case NM_POOL32AXF_1:
19109 int32_t op1 = extract32(ctx->opcode, 9, 3);
19110 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19113 case NM_POOL32AXF_2:
19115 int32_t op1 = extract32(ctx->opcode, 12, 2);
19116 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19119 case NM_POOL32AXF_4:
19121 int32_t op1 = extract32(ctx->opcode, 9, 7);
19122 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19125 case NM_POOL32AXF_5:
19126 switch (extract32(ctx->opcode, 9, 7)) {
19127 #ifndef CONFIG_USER_ONLY
19129 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19132 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19135 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19138 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19141 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19144 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19147 check_cp0_enabled(ctx);
19149 TCGv t0 = tcg_temp_new();
19151 save_cpu_state(ctx, 1);
19152 gen_helper_di(t0, cpu_env);
19153 gen_store_gpr(t0, rt);
19154 /* Stop translation as we may have switched the execution mode */
19155 ctx->base.is_jmp = DISAS_STOP;
19160 check_cp0_enabled(ctx);
19162 TCGv t0 = tcg_temp_new();
19164 save_cpu_state(ctx, 1);
19165 gen_helper_ei(t0, cpu_env);
19166 gen_store_gpr(t0, rt);
19167 /* Stop translation as we may have switched the execution mode */
19168 ctx->base.is_jmp = DISAS_STOP;
19173 gen_load_srsgpr(rs, rt);
19176 gen_store_srsgpr(rs, rt);
19179 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19182 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19185 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19189 generate_exception_end(ctx, EXCP_RI);
19193 case NM_POOL32AXF_7:
19195 int32_t op1 = extract32(ctx->opcode, 9, 3);
19196 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19200 generate_exception_end(ctx, EXCP_RI);
19205 /* Immediate Value Compact Branches */
19206 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19207 int rt, int32_t imm, int32_t offset)
19210 int bcond_compute = 0;
19211 TCGv t0 = tcg_temp_new();
19212 TCGv t1 = tcg_temp_new();
19214 gen_load_gpr(t0, rt);
19215 tcg_gen_movi_tl(t1, imm);
19216 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19218 /* Load needed operands and calculate btarget */
19221 if (rt == 0 && imm == 0) {
19222 /* Unconditional branch */
19223 } else if (rt == 0 && imm != 0) {
19228 cond = TCG_COND_EQ;
19234 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19235 generate_exception_end(ctx, EXCP_RI);
19237 } else if (rt == 0 && opc == NM_BBEQZC) {
19238 /* Unconditional branch */
19239 } else if (rt == 0 && opc == NM_BBNEZC) {
19243 tcg_gen_shri_tl(t0, t0, imm);
19244 tcg_gen_andi_tl(t0, t0, 1);
19245 tcg_gen_movi_tl(t1, 0);
19247 if (opc == NM_BBEQZC) {
19248 cond = TCG_COND_EQ;
19250 cond = TCG_COND_NE;
19255 if (rt == 0 && imm == 0) {
19258 } else if (rt == 0 && imm != 0) {
19259 /* Unconditional branch */
19262 cond = TCG_COND_NE;
19266 if (rt == 0 && imm == 0) {
19267 /* Unconditional branch */
19270 cond = TCG_COND_GE;
19275 cond = TCG_COND_LT;
19278 if (rt == 0 && imm == 0) {
19279 /* Unconditional branch */
19282 cond = TCG_COND_GEU;
19287 cond = TCG_COND_LTU;
19290 MIPS_INVAL("Immediate Value Compact branch");
19291 generate_exception_end(ctx, EXCP_RI);
19295 if (bcond_compute == 0) {
19296 /* Uncoditional compact branch */
19297 gen_goto_tb(ctx, 0, ctx->btarget);
19299 /* Conditional compact branch */
19300 TCGLabel *fs = gen_new_label();
19302 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19304 gen_goto_tb(ctx, 1, ctx->btarget);
19307 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19315 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19316 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19319 TCGv t0 = tcg_temp_new();
19320 TCGv t1 = tcg_temp_new();
19323 gen_load_gpr(t0, rs);
19327 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19330 /* calculate btarget */
19331 tcg_gen_shli_tl(t0, t0, 1);
19332 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19333 gen_op_addr_add(ctx, btarget, t1, t0);
19335 /* unconditional branch to register */
19336 tcg_gen_mov_tl(cpu_PC, btarget);
19337 tcg_gen_lookup_and_goto_ptr();
19343 /* nanoMIPS Branches */
19344 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19345 int rs, int rt, int32_t offset)
19347 int bcond_compute = 0;
19348 TCGv t0 = tcg_temp_new();
19349 TCGv t1 = tcg_temp_new();
19351 /* Load needed operands and calculate btarget */
19353 /* compact branch */
19356 gen_load_gpr(t0, rs);
19357 gen_load_gpr(t1, rt);
19359 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19363 if (rs == 0 || rs == rt) {
19364 /* OPC_BLEZALC, OPC_BGEZALC */
19365 /* OPC_BGTZALC, OPC_BLTZALC */
19366 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19368 gen_load_gpr(t0, rs);
19369 gen_load_gpr(t1, rt);
19371 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19374 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19378 /* OPC_BEQZC, OPC_BNEZC */
19379 gen_load_gpr(t0, rs);
19381 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19383 /* OPC_JIC, OPC_JIALC */
19384 TCGv tbase = tcg_temp_new();
19385 TCGv toffset = tcg_temp_new();
19387 gen_load_gpr(tbase, rt);
19388 tcg_gen_movi_tl(toffset, offset);
19389 gen_op_addr_add(ctx, btarget, tbase, toffset);
19390 tcg_temp_free(tbase);
19391 tcg_temp_free(toffset);
19395 MIPS_INVAL("Compact branch/jump");
19396 generate_exception_end(ctx, EXCP_RI);
19400 if (bcond_compute == 0) {
19401 /* Uncoditional compact branch */
19404 gen_goto_tb(ctx, 0, ctx->btarget);
19407 MIPS_INVAL("Compact branch/jump");
19408 generate_exception_end(ctx, EXCP_RI);
19412 /* Conditional compact branch */
19413 TCGLabel *fs = gen_new_label();
19417 if (rs == 0 && rt != 0) {
19419 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19420 } else if (rs != 0 && rt != 0 && rs == rt) {
19422 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19425 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19429 if (rs == 0 && rt != 0) {
19431 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19432 } else if (rs != 0 && rt != 0 && rs == rt) {
19434 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19437 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19441 if (rs == 0 && rt != 0) {
19443 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19444 } else if (rs != 0 && rt != 0 && rs == rt) {
19446 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19449 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19453 if (rs == 0 && rt != 0) {
19455 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19456 } else if (rs != 0 && rt != 0 && rs == rt) {
19458 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19461 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19465 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19468 MIPS_INVAL("Compact conditional branch/jump");
19469 generate_exception_end(ctx, EXCP_RI);
19473 /* Generating branch here as compact branches don't have delay slot */
19474 gen_goto_tb(ctx, 1, ctx->btarget);
19477 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19486 /* nanoMIPS CP1 Branches */
19487 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19488 int32_t ft, int32_t offset)
19490 target_ulong btarget;
19491 TCGv_i64 t0 = tcg_temp_new_i64();
19493 gen_load_fpr64(ctx, t0, ft);
19494 tcg_gen_andi_i64(t0, t0, 1);
19496 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19500 tcg_gen_xori_i64(t0, t0, 1);
19501 ctx->hflags |= MIPS_HFLAG_BC;
19504 /* t0 already set */
19505 ctx->hflags |= MIPS_HFLAG_BC;
19508 MIPS_INVAL("cp1 cond branch");
19509 generate_exception_end(ctx, EXCP_RI);
19513 tcg_gen_trunc_i64_tl(bcond, t0);
19515 ctx->btarget = btarget;
19518 tcg_temp_free_i64(t0);
19522 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19525 t0 = tcg_temp_new();
19526 t1 = tcg_temp_new();
19528 gen_load_gpr(t0, rs);
19529 gen_load_gpr(t1, rt);
19531 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19532 /* PP.LSXS instructions require shifting */
19533 switch (extract32(ctx->opcode, 7, 4)) {
19538 tcg_gen_shli_tl(t0, t0, 1);
19545 tcg_gen_shli_tl(t0, t0, 2);
19549 tcg_gen_shli_tl(t0, t0, 3);
19553 gen_op_addr_add(ctx, t0, t0, t1);
19555 switch (extract32(ctx->opcode, 7, 4)) {
19557 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19559 gen_store_gpr(t0, rd);
19563 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19565 gen_store_gpr(t0, rd);
19569 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19571 gen_store_gpr(t0, rd);
19574 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19576 gen_store_gpr(t0, rd);
19580 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19582 gen_store_gpr(t0, rd);
19586 gen_load_gpr(t1, rd);
19587 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19593 gen_load_gpr(t1, rd);
19594 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19600 gen_load_gpr(t1, rd);
19601 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19605 /*case NM_LWC1XS:*/
19607 /*case NM_LDC1XS:*/
19609 /*case NM_SWC1XS:*/
19611 /*case NM_SDC1XS:*/
19612 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19613 check_cp1_enabled(ctx);
19614 switch (extract32(ctx->opcode, 7, 4)) {
19616 /*case NM_LWC1XS:*/
19617 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19620 /*case NM_LDC1XS:*/
19621 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19624 /*case NM_SWC1XS:*/
19625 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19628 /*case NM_SDC1XS:*/
19629 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19633 generate_exception_err(ctx, EXCP_CpU, 1);
19637 generate_exception_end(ctx, EXCP_RI);
19645 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19649 rt = extract32(ctx->opcode, 21, 5);
19650 rs = extract32(ctx->opcode, 16, 5);
19651 rd = extract32(ctx->opcode, 11, 5);
19653 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19654 generate_exception_end(ctx, EXCP_RI);
19657 check_cp1_enabled(ctx);
19658 switch (extract32(ctx->opcode, 0, 3)) {
19660 switch (extract32(ctx->opcode, 3, 7)) {
19662 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19665 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19668 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19671 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19674 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19677 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19680 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19683 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19686 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19689 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19692 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19695 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19698 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19701 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19704 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19707 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19710 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19713 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19716 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19719 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19722 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19725 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19728 generate_exception_end(ctx, EXCP_RI);
19733 switch (extract32(ctx->opcode, 3, 3)) {
19735 switch (extract32(ctx->opcode, 9, 1)) {
19737 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19740 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19745 switch (extract32(ctx->opcode, 9, 1)) {
19747 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19750 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19755 switch (extract32(ctx->opcode, 9, 1)) {
19757 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19760 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19765 switch (extract32(ctx->opcode, 9, 1)) {
19767 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19770 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19775 switch (extract32(ctx->opcode, 6, 8)) {
19777 gen_cp1(ctx, OPC_CFC1, rt, rs);
19780 gen_cp1(ctx, OPC_CTC1, rt, rs);
19783 gen_cp1(ctx, OPC_MFC1, rt, rs);
19786 gen_cp1(ctx, OPC_MTC1, rt, rs);
19789 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19792 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19795 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19798 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19801 switch (extract32(ctx->opcode, 6, 9)) {
19803 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19806 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19809 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19812 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19815 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19818 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19821 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19824 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19827 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19830 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19833 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19836 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19839 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19842 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19845 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19848 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
19851 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
19854 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
19857 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
19860 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
19863 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
19866 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
19869 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
19872 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
19875 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
19878 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
19881 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
19884 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
19887 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
19890 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
19893 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
19896 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
19899 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
19902 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
19905 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
19908 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
19911 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
19914 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
19917 generate_exception_end(ctx, EXCP_RI);
19926 switch (extract32(ctx->opcode, 3, 3)) {
19927 case NM_CMP_CONDN_S:
19928 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19930 case NM_CMP_CONDN_D:
19931 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19934 generate_exception_end(ctx, EXCP_RI);
19939 generate_exception_end(ctx, EXCP_RI);
19944 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
19945 int rd, int rs, int rt)
19948 TCGv t0 = tcg_temp_new();
19949 TCGv v1_t = tcg_temp_new();
19950 TCGv v2_t = tcg_temp_new();
19952 gen_load_gpr(v1_t, rs);
19953 gen_load_gpr(v2_t, rt);
19958 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
19962 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
19966 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
19968 case NM_CMPU_EQ_QB:
19970 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
19972 case NM_CMPU_LT_QB:
19974 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
19976 case NM_CMPU_LE_QB:
19978 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
19980 case NM_CMPGU_EQ_QB:
19982 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19983 gen_store_gpr(v1_t, ret);
19985 case NM_CMPGU_LT_QB:
19987 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19988 gen_store_gpr(v1_t, ret);
19990 case NM_CMPGU_LE_QB:
19992 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19993 gen_store_gpr(v1_t, ret);
19995 case NM_CMPGDU_EQ_QB:
19997 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19998 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19999 gen_store_gpr(v1_t, ret);
20001 case NM_CMPGDU_LT_QB:
20003 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20004 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20005 gen_store_gpr(v1_t, ret);
20007 case NM_CMPGDU_LE_QB:
20009 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20010 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20011 gen_store_gpr(v1_t, ret);
20015 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20016 gen_store_gpr(v1_t, ret);
20020 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20021 gen_store_gpr(v1_t, ret);
20025 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20026 gen_store_gpr(v1_t, ret);
20030 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20031 gen_store_gpr(v1_t, ret);
20035 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20036 gen_store_gpr(v1_t, ret);
20040 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20041 gen_store_gpr(v1_t, ret);
20045 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20046 gen_store_gpr(v1_t, ret);
20050 switch (extract32(ctx->opcode, 10, 1)) {
20053 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20054 gen_store_gpr(v1_t, ret);
20058 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20059 gen_store_gpr(v1_t, ret);
20063 case NM_ADDQH_R_PH:
20065 switch (extract32(ctx->opcode, 10, 1)) {
20068 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20069 gen_store_gpr(v1_t, ret);
20073 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20074 gen_store_gpr(v1_t, ret);
20080 switch (extract32(ctx->opcode, 10, 1)) {
20083 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20084 gen_store_gpr(v1_t, ret);
20088 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20089 gen_store_gpr(v1_t, ret);
20095 switch (extract32(ctx->opcode, 10, 1)) {
20098 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20099 gen_store_gpr(v1_t, ret);
20103 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20104 gen_store_gpr(v1_t, ret);
20110 switch (extract32(ctx->opcode, 10, 1)) {
20113 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20114 gen_store_gpr(v1_t, ret);
20118 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20119 gen_store_gpr(v1_t, ret);
20123 case NM_ADDUH_R_QB:
20125 switch (extract32(ctx->opcode, 10, 1)) {
20128 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20129 gen_store_gpr(v1_t, ret);
20133 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20134 gen_store_gpr(v1_t, ret);
20138 case NM_SHRAV_R_PH:
20140 switch (extract32(ctx->opcode, 10, 1)) {
20143 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20144 gen_store_gpr(v1_t, ret);
20148 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20149 gen_store_gpr(v1_t, ret);
20153 case NM_SHRAV_R_QB:
20155 switch (extract32(ctx->opcode, 10, 1)) {
20158 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20159 gen_store_gpr(v1_t, ret);
20163 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20164 gen_store_gpr(v1_t, ret);
20170 switch (extract32(ctx->opcode, 10, 1)) {
20173 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20174 gen_store_gpr(v1_t, ret);
20178 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20179 gen_store_gpr(v1_t, ret);
20183 case NM_SUBQH_R_PH:
20185 switch (extract32(ctx->opcode, 10, 1)) {
20188 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20189 gen_store_gpr(v1_t, ret);
20193 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20194 gen_store_gpr(v1_t, ret);
20200 switch (extract32(ctx->opcode, 10, 1)) {
20203 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20204 gen_store_gpr(v1_t, ret);
20208 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20209 gen_store_gpr(v1_t, ret);
20215 switch (extract32(ctx->opcode, 10, 1)) {
20218 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20219 gen_store_gpr(v1_t, ret);
20223 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20224 gen_store_gpr(v1_t, ret);
20230 switch (extract32(ctx->opcode, 10, 1)) {
20233 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20234 gen_store_gpr(v1_t, ret);
20238 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20239 gen_store_gpr(v1_t, ret);
20243 case NM_SUBUH_R_QB:
20245 switch (extract32(ctx->opcode, 10, 1)) {
20248 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20249 gen_store_gpr(v1_t, ret);
20253 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20254 gen_store_gpr(v1_t, ret);
20258 case NM_SHLLV_S_PH:
20260 switch (extract32(ctx->opcode, 10, 1)) {
20263 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20264 gen_store_gpr(v1_t, ret);
20268 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20269 gen_store_gpr(v1_t, ret);
20273 case NM_PRECR_SRA_R_PH_W:
20275 switch (extract32(ctx->opcode, 10, 1)) {
20277 /* PRECR_SRA_PH_W */
20279 TCGv_i32 sa_t = tcg_const_i32(rd);
20280 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20282 gen_store_gpr(v1_t, rt);
20283 tcg_temp_free_i32(sa_t);
20287 /* PRECR_SRA_R_PH_W */
20289 TCGv_i32 sa_t = tcg_const_i32(rd);
20290 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20292 gen_store_gpr(v1_t, rt);
20293 tcg_temp_free_i32(sa_t);
20298 case NM_MULEU_S_PH_QBL:
20300 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20301 gen_store_gpr(v1_t, ret);
20303 case NM_MULEU_S_PH_QBR:
20305 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20306 gen_store_gpr(v1_t, ret);
20308 case NM_MULQ_RS_PH:
20310 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20311 gen_store_gpr(v1_t, ret);
20315 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20316 gen_store_gpr(v1_t, ret);
20320 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20321 gen_store_gpr(v1_t, ret);
20325 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20326 gen_store_gpr(v1_t, ret);
20330 gen_load_gpr(t0, rs);
20332 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20334 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20338 gen_helper_modsub(v1_t, v1_t, v2_t);
20339 gen_store_gpr(v1_t, ret);
20343 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20344 gen_store_gpr(v1_t, ret);
20348 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20349 gen_store_gpr(v1_t, ret);
20353 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20354 gen_store_gpr(v1_t, ret);
20358 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20359 gen_store_gpr(v1_t, ret);
20363 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20364 gen_store_gpr(v1_t, ret);
20369 TCGv tv0 = tcg_temp_new();
20370 TCGv tv1 = tcg_temp_new();
20371 int16_t imm = extract32(ctx->opcode, 16, 7);
20373 tcg_gen_movi_tl(tv0, rd >> 3);
20374 tcg_gen_movi_tl(tv1, imm);
20375 gen_helper_shilo(tv0, tv1, cpu_env);
20378 case NM_MULEQ_S_W_PHL:
20380 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20381 gen_store_gpr(v1_t, ret);
20383 case NM_MULEQ_S_W_PHR:
20385 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20386 gen_store_gpr(v1_t, ret);
20390 switch (extract32(ctx->opcode, 10, 1)) {
20393 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20394 gen_store_gpr(v1_t, ret);
20398 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20399 gen_store_gpr(v1_t, ret);
20403 case NM_PRECR_QB_PH:
20405 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20406 gen_store_gpr(v1_t, ret);
20408 case NM_PRECRQ_QB_PH:
20410 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20411 gen_store_gpr(v1_t, ret);
20413 case NM_PRECRQ_PH_W:
20415 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20416 gen_store_gpr(v1_t, ret);
20418 case NM_PRECRQ_RS_PH_W:
20420 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20421 gen_store_gpr(v1_t, ret);
20423 case NM_PRECRQU_S_QB_PH:
20425 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20426 gen_store_gpr(v1_t, ret);
20430 tcg_gen_movi_tl(t0, rd);
20431 gen_helper_shra_r_w(v1_t, t0, v1_t);
20432 gen_store_gpr(v1_t, rt);
20436 tcg_gen_movi_tl(t0, rd >> 1);
20437 switch (extract32(ctx->opcode, 10, 1)) {
20440 gen_helper_shra_ph(v1_t, t0, v1_t);
20441 gen_store_gpr(v1_t, rt);
20445 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20446 gen_store_gpr(v1_t, rt);
20452 tcg_gen_movi_tl(t0, rd >> 1);
20453 switch (extract32(ctx->opcode, 10, 2)) {
20456 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20457 gen_store_gpr(v1_t, rt);
20461 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20462 gen_store_gpr(v1_t, rt);
20465 generate_exception_end(ctx, EXCP_RI);
20471 tcg_gen_movi_tl(t0, rd);
20472 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20473 gen_store_gpr(v1_t, rt);
20479 imm = sextract32(ctx->opcode, 11, 11);
20480 imm = (int16_t)(imm << 6) >> 6;
20482 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20487 generate_exception_end(ctx, EXCP_RI);
20492 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20500 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20501 ctx->opcode = (ctx->opcode << 16) | insn;
20503 rt = extract32(ctx->opcode, 21, 5);
20504 rs = extract32(ctx->opcode, 16, 5);
20505 rd = extract32(ctx->opcode, 11, 5);
20507 op = extract32(ctx->opcode, 26, 6);
20512 switch (extract32(ctx->opcode, 19, 2)) {
20515 generate_exception_end(ctx, EXCP_RI);
20518 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20519 generate_exception_end(ctx, EXCP_SYSCALL);
20521 generate_exception_end(ctx, EXCP_RI);
20525 generate_exception_end(ctx, EXCP_BREAK);
20528 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20529 gen_helper_do_semihosting(cpu_env);
20531 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20532 generate_exception_end(ctx, EXCP_RI);
20534 generate_exception_end(ctx, EXCP_DBp);
20541 imm = extract32(ctx->opcode, 0, 16);
20543 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20545 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20547 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20552 offset = sextract32(ctx->opcode, 0, 1) << 21 |
20553 extract32(ctx->opcode, 1, 20) << 1;
20554 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20555 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20559 switch (ctx->opcode & 0x07) {
20561 gen_pool32a0_nanomips_insn(env, ctx);
20565 int32_t op1 = extract32(ctx->opcode, 3, 7);
20566 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20570 switch (extract32(ctx->opcode, 3, 3)) {
20572 gen_p_lsx(ctx, rd, rs, rt);
20575 /* In nanoMIPS, the shift field directly encodes the shift
20576 * amount, meaning that the supported shift values are in
20577 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20578 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20579 extract32(ctx->opcode, 9, 2) - 1);
20582 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20585 gen_pool32axf_nanomips_insn(env, ctx);
20588 generate_exception_end(ctx, EXCP_RI);
20593 generate_exception_end(ctx, EXCP_RI);
20598 switch (ctx->opcode & 0x03) {
20601 offset = extract32(ctx->opcode, 0, 21);
20602 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20606 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20609 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20612 generate_exception_end(ctx, EXCP_RI);
20618 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20619 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20620 switch (extract32(ctx->opcode, 16, 5)) {
20624 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20630 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20631 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20637 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20643 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20646 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20653 t0 = tcg_temp_new();
20655 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20658 tcg_gen_movi_tl(t0, addr);
20659 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20667 t0 = tcg_temp_new();
20668 t1 = tcg_temp_new();
20670 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20673 tcg_gen_movi_tl(t0, addr);
20674 gen_load_gpr(t1, rt);
20676 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20683 generate_exception_end(ctx, EXCP_RI);
20689 switch (extract32(ctx->opcode, 12, 4)) {
20691 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20694 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20697 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20700 switch (extract32(ctx->opcode, 20, 1)) {
20702 switch (ctx->opcode & 3) {
20704 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20705 extract32(ctx->opcode, 2, 1),
20706 extract32(ctx->opcode, 3, 9) << 3);
20709 case NM_RESTORE_JRC:
20710 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20711 extract32(ctx->opcode, 2, 1),
20712 extract32(ctx->opcode, 3, 9) << 3);
20713 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20714 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20718 generate_exception_end(ctx, EXCP_RI);
20723 generate_exception_end(ctx, EXCP_RI);
20728 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20731 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20735 TCGv t0 = tcg_temp_new();
20737 imm = extract32(ctx->opcode, 0, 12);
20738 gen_load_gpr(t0, rs);
20739 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20740 gen_store_gpr(t0, rt);
20746 imm = (int16_t) extract32(ctx->opcode, 0, 12);
20747 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20751 int shift = extract32(ctx->opcode, 0, 5);
20752 switch (extract32(ctx->opcode, 5, 4)) {
20754 if (rt == 0 && shift == 0) {
20756 } else if (rt == 0 && shift == 3) {
20757 /* EHB - treat as NOP */
20758 } else if (rt == 0 && shift == 5) {
20759 /* PAUSE - treat as NOP */
20760 } else if (rt == 0 && shift == 6) {
20762 gen_sync(extract32(ctx->opcode, 16, 5));
20765 gen_shift_imm(ctx, OPC_SLL, rt, rs,
20766 extract32(ctx->opcode, 0, 5));
20770 gen_shift_imm(ctx, OPC_SRL, rt, rs,
20771 extract32(ctx->opcode, 0, 5));
20774 gen_shift_imm(ctx, OPC_SRA, rt, rs,
20775 extract32(ctx->opcode, 0, 5));
20778 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20779 extract32(ctx->opcode, 0, 5));
20787 TCGv t0 = tcg_temp_new();
20788 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20789 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20791 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20793 gen_load_gpr(t0, rs);
20794 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20797 tcg_temp_free_i32(shift);
20798 tcg_temp_free_i32(shiftx);
20799 tcg_temp_free_i32(stripe);
20803 switch (((ctx->opcode >> 10) & 2) |
20804 (extract32(ctx->opcode, 5, 1))) {
20807 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20808 extract32(ctx->opcode, 6, 5));
20811 generate_exception_end(ctx, EXCP_RI);
20816 switch (((ctx->opcode >> 10) & 2) |
20817 (extract32(ctx->opcode, 5, 1))) {
20820 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20821 extract32(ctx->opcode, 6, 5));
20824 generate_exception_end(ctx, EXCP_RI);
20829 generate_exception_end(ctx, EXCP_RI);
20834 gen_pool32f_nanomips_insn(ctx);
20839 switch (extract32(ctx->opcode, 1, 1)) {
20842 tcg_gen_movi_tl(cpu_gpr[rt],
20843 sextract32(ctx->opcode, 0, 1) << 31 |
20844 extract32(ctx->opcode, 2, 10) << 21 |
20845 extract32(ctx->opcode, 12, 9) << 12);
20850 offset = sextract32(ctx->opcode, 0, 1) << 31 |
20851 extract32(ctx->opcode, 2, 10) << 21 |
20852 extract32(ctx->opcode, 12, 9) << 12;
20854 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
20855 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20862 uint32_t u = extract32(ctx->opcode, 0, 18);
20864 switch (extract32(ctx->opcode, 18, 3)) {
20866 gen_ld(ctx, OPC_LB, rt, 28, u);
20869 gen_st(ctx, OPC_SB, rt, 28, u);
20872 gen_ld(ctx, OPC_LBU, rt, 28, u);
20876 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
20881 switch (ctx->opcode & 1) {
20883 gen_ld(ctx, OPC_LH, rt, 28, u);
20886 gen_ld(ctx, OPC_LHU, rt, 28, u);
20892 switch (ctx->opcode & 1) {
20894 gen_st(ctx, OPC_SH, rt, 28, u);
20897 generate_exception_end(ctx, EXCP_RI);
20903 switch (ctx->opcode & 0x3) {
20905 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
20908 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
20911 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
20914 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
20919 generate_exception_end(ctx, EXCP_RI);
20926 uint32_t u = extract32(ctx->opcode, 0, 12);
20928 switch (extract32(ctx->opcode, 12, 4)) {
20932 /* Break the TB to be able to sync copied instructions
20934 ctx->base.is_jmp = DISAS_STOP;
20937 /* Treat as NOP. */
20941 gen_ld(ctx, OPC_LB, rt, rs, u);
20944 gen_ld(ctx, OPC_LH, rt, rs, u);
20947 gen_ld(ctx, OPC_LW, rt, rs, u);
20950 gen_ld(ctx, OPC_LBU, rt, rs, u);
20953 gen_ld(ctx, OPC_LHU, rt, rs, u);
20956 gen_st(ctx, OPC_SB, rt, rs, u);
20959 gen_st(ctx, OPC_SH, rt, rs, u);
20962 gen_st(ctx, OPC_SW, rt, rs, u);
20965 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
20968 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
20971 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
20974 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
20977 generate_exception_end(ctx, EXCP_RI);
20984 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
20985 extract32(ctx->opcode, 0, 8);
20987 switch (extract32(ctx->opcode, 8, 3)) {
20989 switch (extract32(ctx->opcode, 11, 4)) {
20991 gen_ld(ctx, OPC_LB, rt, rs, s);
20994 gen_ld(ctx, OPC_LH, rt, rs, s);
20997 gen_ld(ctx, OPC_LW, rt, rs, s);
21000 gen_ld(ctx, OPC_LBU, rt, rs, s);
21003 gen_ld(ctx, OPC_LHU, rt, rs, s);
21006 gen_st(ctx, OPC_SB, rt, rs, s);
21009 gen_st(ctx, OPC_SH, rt, rs, s);
21012 gen_st(ctx, OPC_SW, rt, rs, s);
21015 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21018 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21021 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21024 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21029 /* Break the TB to be able to sync copied instructions
21031 ctx->base.is_jmp = DISAS_STOP;
21034 /* Treat as NOP. */
21038 generate_exception_end(ctx, EXCP_RI);
21043 switch (extract32(ctx->opcode, 11, 4)) {
21048 TCGv t0 = tcg_temp_new();
21049 TCGv t1 = tcg_temp_new();
21051 gen_base_offset_addr(ctx, t0, rs, s);
21053 switch (extract32(ctx->opcode, 11, 4)) {
21055 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21057 gen_store_gpr(t0, rt);
21060 gen_load_gpr(t1, rt);
21061 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21070 switch (ctx->opcode & 0x03) {
21072 gen_ld(ctx, OPC_LL, rt, rs, s);
21076 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21081 switch (ctx->opcode & 0x03) {
21083 gen_st_cond(ctx, OPC_SC, rt, rs, s);
21087 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21092 check_cp0_enabled(ctx);
21093 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21094 gen_cache_operation(ctx, rt, rs, s);
21103 int count = extract32(ctx->opcode, 12, 3);
21106 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21107 extract32(ctx->opcode, 0, 8);
21108 TCGv va = tcg_temp_new();
21109 TCGv t1 = tcg_temp_new();
21110 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21111 NM_P_LS_UAWM ? MO_UNALN : 0;
21113 count = (count == 0) ? 8 : count;
21114 while (counter != count) {
21115 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21116 int this_offset = offset + (counter << 2);
21118 gen_base_offset_addr(ctx, va, rs, this_offset);
21120 switch (extract32(ctx->opcode, 11, 1)) {
21122 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21124 gen_store_gpr(t1, this_rt);
21125 if ((this_rt == rs) &&
21126 (counter != (count - 1))) {
21127 /* UNPREDICTABLE */
21131 this_rt = (rt == 0) ? 0 : this_rt;
21132 gen_load_gpr(t1, this_rt);
21133 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21144 generate_exception_end(ctx, EXCP_RI);
21152 TCGv t0 = tcg_temp_new();
21153 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21154 extract32(ctx->opcode, 1, 20) << 1;
21155 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21156 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21157 extract32(ctx->opcode, 21, 3));
21158 gen_load_gpr(t0, rt);
21159 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21160 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21166 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21167 extract32(ctx->opcode, 1, 24) << 1;
21169 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21171 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21174 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21179 switch (extract32(ctx->opcode, 12, 4)) {
21182 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21185 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21188 generate_exception_end(ctx, EXCP_RI);
21194 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21195 extract32(ctx->opcode, 1, 13) << 1;
21196 switch (extract32(ctx->opcode, 14, 2)) {
21199 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21202 s = sextract32(ctx->opcode, 0, 1) << 14 |
21203 extract32(ctx->opcode, 1, 13) << 1;
21204 check_cp1_enabled(ctx);
21205 switch (extract32(ctx->opcode, 16, 5)) {
21207 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21210 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21215 int32_t imm = extract32(ctx->opcode, 1, 13) |
21216 extract32(ctx->opcode, 0, 1) << 13;
21218 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21223 generate_exception_end(ctx, EXCP_RI);
21229 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21231 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21235 if (rs == rt || rt == 0) {
21236 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21237 } else if (rs == 0) {
21238 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21240 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21248 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21249 extract32(ctx->opcode, 1, 13) << 1;
21250 switch (extract32(ctx->opcode, 14, 2)) {
21253 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21256 if (rs != 0 && rt != 0 && rs == rt) {
21258 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21260 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21264 if (rs == 0 || rs == rt) {
21266 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21268 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21272 generate_exception_end(ctx, EXCP_RI);
21279 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21280 extract32(ctx->opcode, 1, 10) << 1;
21281 uint32_t u = extract32(ctx->opcode, 11, 7);
21283 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21288 generate_exception_end(ctx, EXCP_RI);
21294 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21297 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21298 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21299 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
21303 /* make sure instructions are on a halfword boundary */
21304 if (ctx->base.pc_next & 0x1) {
21305 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21306 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21307 tcg_temp_free(tmp);
21308 generate_exception_end(ctx, EXCP_AdEL);
21312 op = extract32(ctx->opcode, 10, 6);
21315 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21318 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21319 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21322 switch (extract32(ctx->opcode, 3, 2)) {
21323 case NM_P16_SYSCALL:
21324 if (extract32(ctx->opcode, 2, 1) == 0) {
21325 generate_exception_end(ctx, EXCP_SYSCALL);
21327 generate_exception_end(ctx, EXCP_RI);
21331 generate_exception_end(ctx, EXCP_BREAK);
21334 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21335 gen_helper_do_semihosting(cpu_env);
21337 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21338 generate_exception_end(ctx, EXCP_RI);
21340 generate_exception_end(ctx, EXCP_DBp);
21345 generate_exception_end(ctx, EXCP_RI);
21352 int shift = extract32(ctx->opcode, 0, 3);
21354 shift = (shift == 0) ? 8 : shift;
21356 switch (extract32(ctx->opcode, 3, 1)) {
21364 gen_shift_imm(ctx, opc, rt, rs, shift);
21368 switch (ctx->opcode & 1) {
21370 gen_pool16c_nanomips_insn(ctx);
21373 gen_ldxs(ctx, rt, rs, rd);
21378 switch (extract32(ctx->opcode, 6, 1)) {
21380 imm = extract32(ctx->opcode, 0, 6) << 2;
21381 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21384 generate_exception_end(ctx, EXCP_RI);
21389 switch (extract32(ctx->opcode, 3, 1)) {
21391 imm = extract32(ctx->opcode, 0, 3) << 2;
21392 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21394 case NM_P_ADDIURS5:
21395 rt = extract32(ctx->opcode, 5, 5);
21397 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21398 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21399 (extract32(ctx->opcode, 0, 3));
21400 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21406 switch (ctx->opcode & 0x1) {
21408 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21411 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21416 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21417 extract32(ctx->opcode, 5, 3);
21418 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21419 extract32(ctx->opcode, 0, 3);
21420 rt = decode_gpr_gpr4(rt);
21421 rs = decode_gpr_gpr4(rs);
21422 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21423 (extract32(ctx->opcode, 3, 1))) {
21426 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21430 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21433 generate_exception_end(ctx, EXCP_RI);
21439 int imm = extract32(ctx->opcode, 0, 7);
21440 imm = (imm == 0x7f ? -1 : imm);
21442 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21448 uint32_t u = extract32(ctx->opcode, 0, 4);
21449 u = (u == 12) ? 0xff :
21450 (u == 13) ? 0xffff : u;
21451 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21455 offset = extract32(ctx->opcode, 0, 2);
21456 switch (extract32(ctx->opcode, 2, 2)) {
21458 gen_ld(ctx, OPC_LB, rt, rs, offset);
21461 rt = decode_gpr_gpr3_src_store(
21462 NANOMIPS_EXTRACT_RD(ctx->opcode));
21463 gen_st(ctx, OPC_SB, rt, rs, offset);
21466 gen_ld(ctx, OPC_LBU, rt, rs, offset);
21469 generate_exception_end(ctx, EXCP_RI);
21474 offset = extract32(ctx->opcode, 1, 2) << 1;
21475 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21477 gen_ld(ctx, OPC_LH, rt, rs, offset);
21480 rt = decode_gpr_gpr3_src_store(
21481 NANOMIPS_EXTRACT_RD(ctx->opcode));
21482 gen_st(ctx, OPC_SH, rt, rs, offset);
21485 gen_ld(ctx, OPC_LHU, rt, rs, offset);
21488 generate_exception_end(ctx, EXCP_RI);
21493 offset = extract32(ctx->opcode, 0, 4) << 2;
21494 gen_ld(ctx, OPC_LW, rt, rs, offset);
21497 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21498 offset = extract32(ctx->opcode, 0, 5) << 2;
21499 gen_ld(ctx, OPC_LW, rt, 29, offset);
21503 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21504 extract32(ctx->opcode, 5, 3);
21505 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21506 extract32(ctx->opcode, 0, 3);
21507 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21508 (extract32(ctx->opcode, 8, 1) << 2);
21509 rt = decode_gpr_gpr4(rt);
21510 rs = decode_gpr_gpr4(rs);
21511 gen_ld(ctx, OPC_LW, rt, rs, offset);
21515 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21516 extract32(ctx->opcode, 5, 3);
21517 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21518 extract32(ctx->opcode, 0, 3);
21519 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21520 (extract32(ctx->opcode, 8, 1) << 2);
21521 rt = decode_gpr_gpr4_zero(rt);
21522 rs = decode_gpr_gpr4(rs);
21523 gen_st(ctx, OPC_SW, rt, rs, offset);
21526 offset = extract32(ctx->opcode, 0, 7) << 2;
21527 gen_ld(ctx, OPC_LW, rt, 28, offset);
21530 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21531 offset = extract32(ctx->opcode, 0, 5) << 2;
21532 gen_st(ctx, OPC_SW, rt, 29, offset);
21535 rt = decode_gpr_gpr3_src_store(
21536 NANOMIPS_EXTRACT_RD(ctx->opcode));
21537 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21538 offset = extract32(ctx->opcode, 0, 4) << 2;
21539 gen_st(ctx, OPC_SW, rt, rs, offset);
21542 rt = decode_gpr_gpr3_src_store(
21543 NANOMIPS_EXTRACT_RD(ctx->opcode));
21544 offset = extract32(ctx->opcode, 0, 7) << 2;
21545 gen_st(ctx, OPC_SW, rt, 28, offset);
21548 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21549 (sextract32(ctx->opcode, 0, 1) << 10) |
21550 (extract32(ctx->opcode, 1, 9) << 1));
21553 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21554 (sextract32(ctx->opcode, 0, 1) << 10) |
21555 (extract32(ctx->opcode, 1, 9) << 1));
21558 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21559 (sextract32(ctx->opcode, 0, 1) << 7) |
21560 (extract32(ctx->opcode, 1, 6) << 1));
21563 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21564 (sextract32(ctx->opcode, 0, 1) << 7) |
21565 (extract32(ctx->opcode, 1, 6) << 1));
21568 switch (ctx->opcode & 0xf) {
21571 switch (extract32(ctx->opcode, 4, 1)) {
21573 gen_compute_branch_nm(ctx, OPC_JR, 2,
21574 extract32(ctx->opcode, 5, 5), 0, 0);
21577 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21578 extract32(ctx->opcode, 5, 5), 31, 0);
21585 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21586 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21587 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21588 extract32(ctx->opcode, 0, 4) << 1);
21595 int count = extract32(ctx->opcode, 0, 4);
21596 int u = extract32(ctx->opcode, 4, 4) << 4;
21598 rt = 30 + extract32(ctx->opcode, 9, 1);
21599 switch (extract32(ctx->opcode, 8, 1)) {
21601 gen_save(ctx, rt, count, 0, u);
21603 case NM_RESTORE_JRC16:
21604 gen_restore(ctx, rt, count, 0, u);
21605 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21614 static const int gpr2reg1[] = {4, 5, 6, 7};
21615 static const int gpr2reg2[] = {5, 6, 7, 8};
21617 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21618 extract32(ctx->opcode, 8, 1);
21619 int r1 = gpr2reg1[rd2];
21620 int r2 = gpr2reg2[rd2];
21621 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21622 extract32(ctx->opcode, 0, 3);
21623 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21624 extract32(ctx->opcode, 5, 3);
21625 TCGv t0 = tcg_temp_new();
21626 TCGv t1 = tcg_temp_new();
21627 if (op == NM_MOVEP) {
21630 rs = decode_gpr_gpr4_zero(r3);
21631 rt = decode_gpr_gpr4_zero(r4);
21633 rd = decode_gpr_gpr4(r3);
21634 re = decode_gpr_gpr4(r4);
21638 gen_load_gpr(t0, rs);
21639 gen_load_gpr(t1, rt);
21640 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21641 tcg_gen_mov_tl(cpu_gpr[re], t1);
21647 return decode_nanomips_32_48_opc(env, ctx);
21654 /* SmartMIPS extension to MIPS32 */
21656 #if defined(TARGET_MIPS64)
21658 /* MDMX extension to MIPS64 */
21662 /* MIPSDSP functions. */
21663 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
21664 int rd, int base, int offset)
21669 t0 = tcg_temp_new();
21672 gen_load_gpr(t0, offset);
21673 } else if (offset == 0) {
21674 gen_load_gpr(t0, base);
21676 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21681 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
21682 gen_store_gpr(t0, rd);
21685 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
21686 gen_store_gpr(t0, rd);
21689 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
21690 gen_store_gpr(t0, rd);
21692 #if defined(TARGET_MIPS64)
21694 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
21695 gen_store_gpr(t0, rd);
21702 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21703 int ret, int v1, int v2)
21709 /* Treat as NOP. */
21713 v1_t = tcg_temp_new();
21714 v2_t = tcg_temp_new();
21716 gen_load_gpr(v1_t, v1);
21717 gen_load_gpr(v2_t, v2);
21720 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21721 case OPC_MULT_G_2E:
21725 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21727 case OPC_ADDUH_R_QB:
21728 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21731 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21733 case OPC_ADDQH_R_PH:
21734 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21737 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21739 case OPC_ADDQH_R_W:
21740 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21743 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21745 case OPC_SUBUH_R_QB:
21746 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21749 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
21751 case OPC_SUBQH_R_PH:
21752 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21755 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
21757 case OPC_SUBQH_R_W:
21758 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21762 case OPC_ABSQ_S_PH_DSP:
21764 case OPC_ABSQ_S_QB:
21766 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
21768 case OPC_ABSQ_S_PH:
21770 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
21774 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
21776 case OPC_PRECEQ_W_PHL:
21778 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
21779 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21781 case OPC_PRECEQ_W_PHR:
21783 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
21784 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
21785 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21787 case OPC_PRECEQU_PH_QBL:
21789 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
21791 case OPC_PRECEQU_PH_QBR:
21793 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
21795 case OPC_PRECEQU_PH_QBLA:
21797 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
21799 case OPC_PRECEQU_PH_QBRA:
21801 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
21803 case OPC_PRECEU_PH_QBL:
21805 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
21807 case OPC_PRECEU_PH_QBR:
21809 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
21811 case OPC_PRECEU_PH_QBLA:
21813 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
21815 case OPC_PRECEU_PH_QBRA:
21817 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
21821 case OPC_ADDU_QB_DSP:
21825 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21827 case OPC_ADDQ_S_PH:
21829 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21833 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21837 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21839 case OPC_ADDU_S_QB:
21841 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21845 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21847 case OPC_ADDU_S_PH:
21849 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21853 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21855 case OPC_SUBQ_S_PH:
21857 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21861 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21865 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21867 case OPC_SUBU_S_QB:
21869 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21873 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21875 case OPC_SUBU_S_PH:
21877 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21881 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21885 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21889 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
21891 case OPC_RADDU_W_QB:
21893 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
21897 case OPC_CMPU_EQ_QB_DSP:
21899 case OPC_PRECR_QB_PH:
21901 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21903 case OPC_PRECRQ_QB_PH:
21905 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21907 case OPC_PRECR_SRA_PH_W:
21910 TCGv_i32 sa_t = tcg_const_i32(v2);
21911 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
21913 tcg_temp_free_i32(sa_t);
21916 case OPC_PRECR_SRA_R_PH_W:
21919 TCGv_i32 sa_t = tcg_const_i32(v2);
21920 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
21922 tcg_temp_free_i32(sa_t);
21925 case OPC_PRECRQ_PH_W:
21927 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
21929 case OPC_PRECRQ_RS_PH_W:
21931 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21933 case OPC_PRECRQU_S_QB_PH:
21935 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21939 #ifdef TARGET_MIPS64
21940 case OPC_ABSQ_S_QH_DSP:
21942 case OPC_PRECEQ_L_PWL:
21944 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
21946 case OPC_PRECEQ_L_PWR:
21948 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
21950 case OPC_PRECEQ_PW_QHL:
21952 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
21954 case OPC_PRECEQ_PW_QHR:
21956 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
21958 case OPC_PRECEQ_PW_QHLA:
21960 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
21962 case OPC_PRECEQ_PW_QHRA:
21964 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
21966 case OPC_PRECEQU_QH_OBL:
21968 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
21970 case OPC_PRECEQU_QH_OBR:
21972 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
21974 case OPC_PRECEQU_QH_OBLA:
21976 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
21978 case OPC_PRECEQU_QH_OBRA:
21980 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
21982 case OPC_PRECEU_QH_OBL:
21984 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
21986 case OPC_PRECEU_QH_OBR:
21988 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
21990 case OPC_PRECEU_QH_OBLA:
21992 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
21994 case OPC_PRECEU_QH_OBRA:
21996 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
21998 case OPC_ABSQ_S_OB:
22000 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22002 case OPC_ABSQ_S_PW:
22004 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22006 case OPC_ABSQ_S_QH:
22008 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22012 case OPC_ADDU_OB_DSP:
22014 case OPC_RADDU_L_OB:
22016 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22020 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22022 case OPC_SUBQ_S_PW:
22024 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22028 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22030 case OPC_SUBQ_S_QH:
22032 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22036 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22038 case OPC_SUBU_S_OB:
22040 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22044 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22046 case OPC_SUBU_S_QH:
22048 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22052 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22054 case OPC_SUBUH_R_OB:
22056 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22060 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22062 case OPC_ADDQ_S_PW:
22064 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22068 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22070 case OPC_ADDQ_S_QH:
22072 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22076 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22078 case OPC_ADDU_S_OB:
22080 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22084 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22086 case OPC_ADDU_S_QH:
22088 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22092 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22094 case OPC_ADDUH_R_OB:
22096 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22100 case OPC_CMPU_EQ_OB_DSP:
22102 case OPC_PRECR_OB_QH:
22104 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22106 case OPC_PRECR_SRA_QH_PW:
22109 TCGv_i32 ret_t = tcg_const_i32(ret);
22110 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22111 tcg_temp_free_i32(ret_t);
22114 case OPC_PRECR_SRA_R_QH_PW:
22117 TCGv_i32 sa_v = tcg_const_i32(ret);
22118 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22119 tcg_temp_free_i32(sa_v);
22122 case OPC_PRECRQ_OB_QH:
22124 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22126 case OPC_PRECRQ_PW_L:
22128 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22130 case OPC_PRECRQ_QH_PW:
22132 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22134 case OPC_PRECRQ_RS_QH_PW:
22136 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22138 case OPC_PRECRQU_S_OB_QH:
22140 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22147 tcg_temp_free(v1_t);
22148 tcg_temp_free(v2_t);
22151 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22152 int ret, int v1, int v2)
22160 /* Treat as NOP. */
22164 t0 = tcg_temp_new();
22165 v1_t = tcg_temp_new();
22166 v2_t = tcg_temp_new();
22168 tcg_gen_movi_tl(t0, v1);
22169 gen_load_gpr(v1_t, v1);
22170 gen_load_gpr(v2_t, v2);
22173 case OPC_SHLL_QB_DSP:
22175 op2 = MASK_SHLL_QB(ctx->opcode);
22179 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22183 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22187 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22191 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22193 case OPC_SHLL_S_PH:
22195 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22197 case OPC_SHLLV_S_PH:
22199 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22203 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22205 case OPC_SHLLV_S_W:
22207 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22211 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22215 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22219 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22223 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22227 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22229 case OPC_SHRA_R_QB:
22231 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22235 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22237 case OPC_SHRAV_R_QB:
22239 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22243 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22245 case OPC_SHRA_R_PH:
22247 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22251 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22253 case OPC_SHRAV_R_PH:
22255 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22259 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22261 case OPC_SHRAV_R_W:
22263 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22265 default: /* Invalid */
22266 MIPS_INVAL("MASK SHLL.QB");
22267 generate_exception_end(ctx, EXCP_RI);
22272 #ifdef TARGET_MIPS64
22273 case OPC_SHLL_OB_DSP:
22274 op2 = MASK_SHLL_OB(ctx->opcode);
22278 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22282 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22284 case OPC_SHLL_S_PW:
22286 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22288 case OPC_SHLLV_S_PW:
22290 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22294 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22298 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22302 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22306 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22308 case OPC_SHLL_S_QH:
22310 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22312 case OPC_SHLLV_S_QH:
22314 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22318 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22322 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22324 case OPC_SHRA_R_OB:
22326 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22328 case OPC_SHRAV_R_OB:
22330 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22334 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22338 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22340 case OPC_SHRA_R_PW:
22342 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22344 case OPC_SHRAV_R_PW:
22346 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22350 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22354 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22356 case OPC_SHRA_R_QH:
22358 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22360 case OPC_SHRAV_R_QH:
22362 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22366 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22370 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22374 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22378 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22380 default: /* Invalid */
22381 MIPS_INVAL("MASK SHLL.OB");
22382 generate_exception_end(ctx, EXCP_RI);
22390 tcg_temp_free(v1_t);
22391 tcg_temp_free(v2_t);
22394 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22395 int ret, int v1, int v2, int check_ret)
22401 if ((ret == 0) && (check_ret == 1)) {
22402 /* Treat as NOP. */
22406 t0 = tcg_temp_new_i32();
22407 v1_t = tcg_temp_new();
22408 v2_t = tcg_temp_new();
22410 tcg_gen_movi_i32(t0, ret);
22411 gen_load_gpr(v1_t, v1);
22412 gen_load_gpr(v2_t, v2);
22415 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22416 * the same mask and op1. */
22417 case OPC_MULT_G_2E:
22421 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22424 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22427 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22429 case OPC_MULQ_RS_W:
22430 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22434 case OPC_DPA_W_PH_DSP:
22436 case OPC_DPAU_H_QBL:
22438 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22440 case OPC_DPAU_H_QBR:
22442 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22444 case OPC_DPSU_H_QBL:
22446 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22448 case OPC_DPSU_H_QBR:
22450 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22454 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22456 case OPC_DPAX_W_PH:
22458 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22460 case OPC_DPAQ_S_W_PH:
22462 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22464 case OPC_DPAQX_S_W_PH:
22466 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22468 case OPC_DPAQX_SA_W_PH:
22470 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22474 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22476 case OPC_DPSX_W_PH:
22478 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22480 case OPC_DPSQ_S_W_PH:
22482 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22484 case OPC_DPSQX_S_W_PH:
22486 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22488 case OPC_DPSQX_SA_W_PH:
22490 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22492 case OPC_MULSAQ_S_W_PH:
22494 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22496 case OPC_DPAQ_SA_L_W:
22498 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22500 case OPC_DPSQ_SA_L_W:
22502 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22504 case OPC_MAQ_S_W_PHL:
22506 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22508 case OPC_MAQ_S_W_PHR:
22510 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22512 case OPC_MAQ_SA_W_PHL:
22514 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22516 case OPC_MAQ_SA_W_PHR:
22518 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22520 case OPC_MULSA_W_PH:
22522 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22526 #ifdef TARGET_MIPS64
22527 case OPC_DPAQ_W_QH_DSP:
22529 int ac = ret & 0x03;
22530 tcg_gen_movi_i32(t0, ac);
22535 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22539 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22543 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22547 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22551 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22553 case OPC_DPAQ_S_W_QH:
22555 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22557 case OPC_DPAQ_SA_L_PW:
22559 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22561 case OPC_DPAU_H_OBL:
22563 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22565 case OPC_DPAU_H_OBR:
22567 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22571 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22573 case OPC_DPSQ_S_W_QH:
22575 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22577 case OPC_DPSQ_SA_L_PW:
22579 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22581 case OPC_DPSU_H_OBL:
22583 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22585 case OPC_DPSU_H_OBR:
22587 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22589 case OPC_MAQ_S_L_PWL:
22591 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22593 case OPC_MAQ_S_L_PWR:
22595 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22597 case OPC_MAQ_S_W_QHLL:
22599 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22601 case OPC_MAQ_SA_W_QHLL:
22603 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22605 case OPC_MAQ_S_W_QHLR:
22607 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22609 case OPC_MAQ_SA_W_QHLR:
22611 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22613 case OPC_MAQ_S_W_QHRL:
22615 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22617 case OPC_MAQ_SA_W_QHRL:
22619 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22621 case OPC_MAQ_S_W_QHRR:
22623 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22625 case OPC_MAQ_SA_W_QHRR:
22627 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22629 case OPC_MULSAQ_S_L_PW:
22631 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22633 case OPC_MULSAQ_S_W_QH:
22635 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22641 case OPC_ADDU_QB_DSP:
22643 case OPC_MULEU_S_PH_QBL:
22645 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22647 case OPC_MULEU_S_PH_QBR:
22649 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22651 case OPC_MULQ_RS_PH:
22653 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22655 case OPC_MULEQ_S_W_PHL:
22657 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22659 case OPC_MULEQ_S_W_PHR:
22661 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22663 case OPC_MULQ_S_PH:
22665 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22669 #ifdef TARGET_MIPS64
22670 case OPC_ADDU_OB_DSP:
22672 case OPC_MULEQ_S_PW_QHL:
22674 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22676 case OPC_MULEQ_S_PW_QHR:
22678 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22680 case OPC_MULEU_S_QH_OBL:
22682 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22684 case OPC_MULEU_S_QH_OBR:
22686 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22688 case OPC_MULQ_RS_QH:
22690 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22697 tcg_temp_free_i32(t0);
22698 tcg_temp_free(v1_t);
22699 tcg_temp_free(v2_t);
22702 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22710 /* Treat as NOP. */
22714 t0 = tcg_temp_new();
22715 val_t = tcg_temp_new();
22716 gen_load_gpr(val_t, val);
22719 case OPC_ABSQ_S_PH_DSP:
22723 gen_helper_bitrev(cpu_gpr[ret], val_t);
22728 target_long result;
22729 imm = (ctx->opcode >> 16) & 0xFF;
22730 result = (uint32_t)imm << 24 |
22731 (uint32_t)imm << 16 |
22732 (uint32_t)imm << 8 |
22734 result = (int32_t)result;
22735 tcg_gen_movi_tl(cpu_gpr[ret], result);
22740 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22741 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22742 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22743 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22744 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22745 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22750 imm = (ctx->opcode >> 16) & 0x03FF;
22751 imm = (int16_t)(imm << 6) >> 6;
22752 tcg_gen_movi_tl(cpu_gpr[ret], \
22753 (target_long)((int32_t)imm << 16 | \
22759 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22760 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22761 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22762 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22766 #ifdef TARGET_MIPS64
22767 case OPC_ABSQ_S_QH_DSP:
22774 imm = (ctx->opcode >> 16) & 0xFF;
22775 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
22776 temp = (temp << 16) | temp;
22777 temp = (temp << 32) | temp;
22778 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22786 imm = (ctx->opcode >> 16) & 0x03FF;
22787 imm = (int16_t)(imm << 6) >> 6;
22788 temp = ((target_long)imm << 32) \
22789 | ((target_long)imm & 0xFFFFFFFF);
22790 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22798 imm = (ctx->opcode >> 16) & 0x03FF;
22799 imm = (int16_t)(imm << 6) >> 6;
22801 temp = ((uint64_t)(uint16_t)imm << 48) |
22802 ((uint64_t)(uint16_t)imm << 32) |
22803 ((uint64_t)(uint16_t)imm << 16) |
22804 (uint64_t)(uint16_t)imm;
22805 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22810 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22811 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22812 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22813 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22814 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22815 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22816 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22820 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
22821 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22822 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22826 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22827 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22828 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22829 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22830 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22837 tcg_temp_free(val_t);
22840 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
22841 uint32_t op1, uint32_t op2,
22842 int ret, int v1, int v2, int check_ret)
22848 if ((ret == 0) && (check_ret == 1)) {
22849 /* Treat as NOP. */
22853 t1 = tcg_temp_new();
22854 v1_t = tcg_temp_new();
22855 v2_t = tcg_temp_new();
22857 gen_load_gpr(v1_t, v1);
22858 gen_load_gpr(v2_t, v2);
22861 case OPC_CMPU_EQ_QB_DSP:
22863 case OPC_CMPU_EQ_QB:
22865 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
22867 case OPC_CMPU_LT_QB:
22869 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
22871 case OPC_CMPU_LE_QB:
22873 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
22875 case OPC_CMPGU_EQ_QB:
22877 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
22879 case OPC_CMPGU_LT_QB:
22881 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
22883 case OPC_CMPGU_LE_QB:
22885 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
22887 case OPC_CMPGDU_EQ_QB:
22889 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
22890 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22891 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22892 tcg_gen_shli_tl(t1, t1, 24);
22893 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22895 case OPC_CMPGDU_LT_QB:
22897 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
22898 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22899 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22900 tcg_gen_shli_tl(t1, t1, 24);
22901 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22903 case OPC_CMPGDU_LE_QB:
22905 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
22906 tcg_gen_mov_tl(cpu_gpr[ret], t1);
22907 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22908 tcg_gen_shli_tl(t1, t1, 24);
22909 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22911 case OPC_CMP_EQ_PH:
22913 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
22915 case OPC_CMP_LT_PH:
22917 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
22919 case OPC_CMP_LE_PH:
22921 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
22925 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22929 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22931 case OPC_PACKRL_PH:
22933 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
22937 #ifdef TARGET_MIPS64
22938 case OPC_CMPU_EQ_OB_DSP:
22940 case OPC_CMP_EQ_PW:
22942 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
22944 case OPC_CMP_LT_PW:
22946 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
22948 case OPC_CMP_LE_PW:
22950 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
22952 case OPC_CMP_EQ_QH:
22954 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
22956 case OPC_CMP_LT_QH:
22958 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
22960 case OPC_CMP_LE_QH:
22962 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
22964 case OPC_CMPGDU_EQ_OB:
22966 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22968 case OPC_CMPGDU_LT_OB:
22970 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22972 case OPC_CMPGDU_LE_OB:
22974 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22976 case OPC_CMPGU_EQ_OB:
22978 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
22980 case OPC_CMPGU_LT_OB:
22982 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
22984 case OPC_CMPGU_LE_OB:
22986 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
22988 case OPC_CMPU_EQ_OB:
22990 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
22992 case OPC_CMPU_LT_OB:
22994 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
22996 case OPC_CMPU_LE_OB:
22998 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23000 case OPC_PACKRL_PW:
23002 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23006 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23010 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23014 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23022 tcg_temp_free(v1_t);
23023 tcg_temp_free(v2_t);
23026 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23027 uint32_t op1, int rt, int rs, int sa)
23034 /* Treat as NOP. */
23038 t0 = tcg_temp_new();
23039 gen_load_gpr(t0, rs);
23042 case OPC_APPEND_DSP:
23043 switch (MASK_APPEND(ctx->opcode)) {
23046 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23048 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23052 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23053 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23054 tcg_gen_shli_tl(t0, t0, 32 - sa);
23055 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23057 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23061 if (sa != 0 && sa != 2) {
23062 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23063 tcg_gen_ext32u_tl(t0, t0);
23064 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23065 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23067 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23069 default: /* Invalid */
23070 MIPS_INVAL("MASK APPEND");
23071 generate_exception_end(ctx, EXCP_RI);
23075 #ifdef TARGET_MIPS64
23076 case OPC_DAPPEND_DSP:
23077 switch (MASK_DAPPEND(ctx->opcode)) {
23080 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23084 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23085 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23086 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23090 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23091 tcg_gen_shli_tl(t0, t0, 64 - sa);
23092 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23097 if (sa != 0 && sa != 2 && sa != 4) {
23098 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23099 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23100 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23103 default: /* Invalid */
23104 MIPS_INVAL("MASK DAPPEND");
23105 generate_exception_end(ctx, EXCP_RI);
23114 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23115 int ret, int v1, int v2, int check_ret)
23124 if ((ret == 0) && (check_ret == 1)) {
23125 /* Treat as NOP. */
23129 t0 = tcg_temp_new();
23130 t1 = tcg_temp_new();
23131 v1_t = tcg_temp_new();
23132 v2_t = tcg_temp_new();
23134 gen_load_gpr(v1_t, v1);
23135 gen_load_gpr(v2_t, v2);
23138 case OPC_EXTR_W_DSP:
23142 tcg_gen_movi_tl(t0, v2);
23143 tcg_gen_movi_tl(t1, v1);
23144 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23147 tcg_gen_movi_tl(t0, v2);
23148 tcg_gen_movi_tl(t1, v1);
23149 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23151 case OPC_EXTR_RS_W:
23152 tcg_gen_movi_tl(t0, v2);
23153 tcg_gen_movi_tl(t1, v1);
23154 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23157 tcg_gen_movi_tl(t0, v2);
23158 tcg_gen_movi_tl(t1, v1);
23159 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23161 case OPC_EXTRV_S_H:
23162 tcg_gen_movi_tl(t0, v2);
23163 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23166 tcg_gen_movi_tl(t0, v2);
23167 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23169 case OPC_EXTRV_R_W:
23170 tcg_gen_movi_tl(t0, v2);
23171 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23173 case OPC_EXTRV_RS_W:
23174 tcg_gen_movi_tl(t0, v2);
23175 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23178 tcg_gen_movi_tl(t0, v2);
23179 tcg_gen_movi_tl(t1, v1);
23180 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23183 tcg_gen_movi_tl(t0, v2);
23184 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23187 tcg_gen_movi_tl(t0, v2);
23188 tcg_gen_movi_tl(t1, v1);
23189 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23192 tcg_gen_movi_tl(t0, v2);
23193 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23196 imm = (ctx->opcode >> 20) & 0x3F;
23197 tcg_gen_movi_tl(t0, ret);
23198 tcg_gen_movi_tl(t1, imm);
23199 gen_helper_shilo(t0, t1, cpu_env);
23202 tcg_gen_movi_tl(t0, ret);
23203 gen_helper_shilo(t0, v1_t, cpu_env);
23206 tcg_gen_movi_tl(t0, ret);
23207 gen_helper_mthlip(t0, v1_t, cpu_env);
23210 imm = (ctx->opcode >> 11) & 0x3FF;
23211 tcg_gen_movi_tl(t0, imm);
23212 gen_helper_wrdsp(v1_t, t0, cpu_env);
23215 imm = (ctx->opcode >> 16) & 0x03FF;
23216 tcg_gen_movi_tl(t0, imm);
23217 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23221 #ifdef TARGET_MIPS64
23222 case OPC_DEXTR_W_DSP:
23226 tcg_gen_movi_tl(t0, ret);
23227 gen_helper_dmthlip(v1_t, t0, cpu_env);
23231 int shift = (ctx->opcode >> 19) & 0x7F;
23232 int ac = (ctx->opcode >> 11) & 0x03;
23233 tcg_gen_movi_tl(t0, shift);
23234 tcg_gen_movi_tl(t1, ac);
23235 gen_helper_dshilo(t0, t1, cpu_env);
23240 int ac = (ctx->opcode >> 11) & 0x03;
23241 tcg_gen_movi_tl(t0, ac);
23242 gen_helper_dshilo(v1_t, t0, cpu_env);
23246 tcg_gen_movi_tl(t0, v2);
23247 tcg_gen_movi_tl(t1, v1);
23249 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23252 tcg_gen_movi_tl(t0, v2);
23253 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23256 tcg_gen_movi_tl(t0, v2);
23257 tcg_gen_movi_tl(t1, v1);
23258 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23261 tcg_gen_movi_tl(t0, v2);
23262 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23265 tcg_gen_movi_tl(t0, v2);
23266 tcg_gen_movi_tl(t1, v1);
23267 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23269 case OPC_DEXTR_R_L:
23270 tcg_gen_movi_tl(t0, v2);
23271 tcg_gen_movi_tl(t1, v1);
23272 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23274 case OPC_DEXTR_RS_L:
23275 tcg_gen_movi_tl(t0, v2);
23276 tcg_gen_movi_tl(t1, v1);
23277 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23280 tcg_gen_movi_tl(t0, v2);
23281 tcg_gen_movi_tl(t1, v1);
23282 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23284 case OPC_DEXTR_R_W:
23285 tcg_gen_movi_tl(t0, v2);
23286 tcg_gen_movi_tl(t1, v1);
23287 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23289 case OPC_DEXTR_RS_W:
23290 tcg_gen_movi_tl(t0, v2);
23291 tcg_gen_movi_tl(t1, v1);
23292 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23294 case OPC_DEXTR_S_H:
23295 tcg_gen_movi_tl(t0, v2);
23296 tcg_gen_movi_tl(t1, v1);
23297 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23299 case OPC_DEXTRV_S_H:
23300 tcg_gen_movi_tl(t0, v2);
23301 tcg_gen_movi_tl(t1, v1);
23302 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23305 tcg_gen_movi_tl(t0, v2);
23306 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23308 case OPC_DEXTRV_R_L:
23309 tcg_gen_movi_tl(t0, v2);
23310 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23312 case OPC_DEXTRV_RS_L:
23313 tcg_gen_movi_tl(t0, v2);
23314 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23317 tcg_gen_movi_tl(t0, v2);
23318 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23320 case OPC_DEXTRV_R_W:
23321 tcg_gen_movi_tl(t0, v2);
23322 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23324 case OPC_DEXTRV_RS_W:
23325 tcg_gen_movi_tl(t0, v2);
23326 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23335 tcg_temp_free(v1_t);
23336 tcg_temp_free(v2_t);
23339 /* End MIPSDSP functions. */
23341 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23343 int rs, rt, rd, sa;
23346 rs = (ctx->opcode >> 21) & 0x1f;
23347 rt = (ctx->opcode >> 16) & 0x1f;
23348 rd = (ctx->opcode >> 11) & 0x1f;
23349 sa = (ctx->opcode >> 6) & 0x1f;
23351 op1 = MASK_SPECIAL(ctx->opcode);
23354 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23360 op2 = MASK_R6_MULDIV(ctx->opcode);
23370 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23373 MIPS_INVAL("special_r6 muldiv");
23374 generate_exception_end(ctx, EXCP_RI);
23380 gen_cond_move(ctx, op1, rd, rs, rt);
23384 if (rt == 0 && sa == 1) {
23385 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23386 We need additionally to check other fields */
23387 gen_cl(ctx, op1, rd, rs);
23389 generate_exception_end(ctx, EXCP_RI);
23393 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23394 gen_helper_do_semihosting(cpu_env);
23396 if (ctx->hflags & MIPS_HFLAG_SBRI) {
23397 generate_exception_end(ctx, EXCP_RI);
23399 generate_exception_end(ctx, EXCP_DBp);
23403 #if defined(TARGET_MIPS64)
23405 check_mips_64(ctx);
23406 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23410 if (rt == 0 && sa == 1) {
23411 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23412 We need additionally to check other fields */
23413 check_mips_64(ctx);
23414 gen_cl(ctx, op1, rd, rs);
23416 generate_exception_end(ctx, EXCP_RI);
23424 op2 = MASK_R6_MULDIV(ctx->opcode);
23434 check_mips_64(ctx);
23435 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23438 MIPS_INVAL("special_r6 muldiv");
23439 generate_exception_end(ctx, EXCP_RI);
23444 default: /* Invalid */
23445 MIPS_INVAL("special_r6");
23446 generate_exception_end(ctx, EXCP_RI);
23451 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23453 int rs, rt, rd, sa;
23456 rs = (ctx->opcode >> 21) & 0x1f;
23457 rt = (ctx->opcode >> 16) & 0x1f;
23458 rd = (ctx->opcode >> 11) & 0x1f;
23459 sa = (ctx->opcode >> 6) & 0x1f;
23461 op1 = MASK_SPECIAL(ctx->opcode);
23463 case OPC_MOVN: /* Conditional move */
23465 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
23466 INSN_LOONGSON2E | INSN_LOONGSON2F);
23467 gen_cond_move(ctx, op1, rd, rs, rt);
23469 case OPC_MFHI: /* Move from HI/LO */
23471 gen_HILO(ctx, op1, rs & 3, rd);
23474 case OPC_MTLO: /* Move to HI/LO */
23475 gen_HILO(ctx, op1, rd & 3, rs);
23478 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23479 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23480 check_cp1_enabled(ctx);
23481 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23482 (ctx->opcode >> 16) & 1);
23484 generate_exception_err(ctx, EXCP_CpU, 1);
23490 check_insn(ctx, INSN_VR54XX);
23491 op1 = MASK_MUL_VR54XX(ctx->opcode);
23492 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23494 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23499 gen_muldiv(ctx, op1, 0, rs, rt);
23501 #if defined(TARGET_MIPS64)
23506 check_insn(ctx, ISA_MIPS3);
23507 check_mips_64(ctx);
23508 gen_muldiv(ctx, op1, 0, rs, rt);
23512 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23515 #ifdef MIPS_STRICT_STANDARD
23516 MIPS_INVAL("SPIM");
23517 generate_exception_end(ctx, EXCP_RI);
23519 /* Implemented as RI exception for now. */
23520 MIPS_INVAL("spim (unofficial)");
23521 generate_exception_end(ctx, EXCP_RI);
23524 default: /* Invalid */
23525 MIPS_INVAL("special_legacy");
23526 generate_exception_end(ctx, EXCP_RI);
23531 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
23533 int rs, rt, rd, sa;
23536 rs = (ctx->opcode >> 21) & 0x1f;
23537 rt = (ctx->opcode >> 16) & 0x1f;
23538 rd = (ctx->opcode >> 11) & 0x1f;
23539 sa = (ctx->opcode >> 6) & 0x1f;
23541 op1 = MASK_SPECIAL(ctx->opcode);
23543 case OPC_SLL: /* Shift with immediate */
23544 if (sa == 5 && rd == 0 &&
23545 rs == 0 && rt == 0) { /* PAUSE */
23546 if ((ctx->insn_flags & ISA_MIPS32R6) &&
23547 (ctx->hflags & MIPS_HFLAG_BMASK)) {
23548 generate_exception_end(ctx, EXCP_RI);
23554 gen_shift_imm(ctx, op1, rd, rt, sa);
23557 switch ((ctx->opcode >> 21) & 0x1f) {
23559 /* rotr is decoded as srl on non-R2 CPUs */
23560 if (ctx->insn_flags & ISA_MIPS32R2) {
23565 gen_shift_imm(ctx, op1, rd, rt, sa);
23568 generate_exception_end(ctx, EXCP_RI);
23576 gen_arith(ctx, op1, rd, rs, rt);
23578 case OPC_SLLV: /* Shifts */
23580 gen_shift(ctx, op1, rd, rs, rt);
23583 switch ((ctx->opcode >> 6) & 0x1f) {
23585 /* rotrv is decoded as srlv on non-R2 CPUs */
23586 if (ctx->insn_flags & ISA_MIPS32R2) {
23591 gen_shift(ctx, op1, rd, rs, rt);
23594 generate_exception_end(ctx, EXCP_RI);
23598 case OPC_SLT: /* Set on less than */
23600 gen_slt(ctx, op1, rd, rs, rt);
23602 case OPC_AND: /* Logic*/
23606 gen_logic(ctx, op1, rd, rs, rt);
23609 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23611 case OPC_TGE: /* Traps */
23617 check_insn(ctx, ISA_MIPS2);
23618 gen_trap(ctx, op1, rs, rt, -1);
23620 case OPC_LSA: /* OPC_PMON */
23621 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23622 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23623 decode_opc_special_r6(env, ctx);
23625 /* Pmon entry point, also R4010 selsl */
23626 #ifdef MIPS_STRICT_STANDARD
23627 MIPS_INVAL("PMON / selsl");
23628 generate_exception_end(ctx, EXCP_RI);
23630 gen_helper_0e0i(pmon, sa);
23635 generate_exception_end(ctx, EXCP_SYSCALL);
23638 generate_exception_end(ctx, EXCP_BREAK);
23641 check_insn(ctx, ISA_MIPS2);
23642 gen_sync(extract32(ctx->opcode, 6, 5));
23645 #if defined(TARGET_MIPS64)
23646 /* MIPS64 specific opcodes */
23651 check_insn(ctx, ISA_MIPS3);
23652 check_mips_64(ctx);
23653 gen_shift_imm(ctx, op1, rd, rt, sa);
23656 switch ((ctx->opcode >> 21) & 0x1f) {
23658 /* drotr is decoded as dsrl on non-R2 CPUs */
23659 if (ctx->insn_flags & ISA_MIPS32R2) {
23664 check_insn(ctx, ISA_MIPS3);
23665 check_mips_64(ctx);
23666 gen_shift_imm(ctx, op1, rd, rt, sa);
23669 generate_exception_end(ctx, EXCP_RI);
23674 switch ((ctx->opcode >> 21) & 0x1f) {
23676 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23677 if (ctx->insn_flags & ISA_MIPS32R2) {
23682 check_insn(ctx, ISA_MIPS3);
23683 check_mips_64(ctx);
23684 gen_shift_imm(ctx, op1, rd, rt, sa);
23687 generate_exception_end(ctx, EXCP_RI);
23695 check_insn(ctx, ISA_MIPS3);
23696 check_mips_64(ctx);
23697 gen_arith(ctx, op1, rd, rs, rt);
23701 check_insn(ctx, ISA_MIPS3);
23702 check_mips_64(ctx);
23703 gen_shift(ctx, op1, rd, rs, rt);
23706 switch ((ctx->opcode >> 6) & 0x1f) {
23708 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23709 if (ctx->insn_flags & ISA_MIPS32R2) {
23714 check_insn(ctx, ISA_MIPS3);
23715 check_mips_64(ctx);
23716 gen_shift(ctx, op1, rd, rs, rt);
23719 generate_exception_end(ctx, EXCP_RI);
23724 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23725 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23726 decode_opc_special_r6(env, ctx);
23731 if (ctx->insn_flags & ISA_MIPS32R6) {
23732 decode_opc_special_r6(env, ctx);
23734 decode_opc_special_legacy(env, ctx);
23739 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
23744 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23746 rs = (ctx->opcode >> 21) & 0x1f;
23747 rt = (ctx->opcode >> 16) & 0x1f;
23748 rd = (ctx->opcode >> 11) & 0x1f;
23750 op1 = MASK_SPECIAL2(ctx->opcode);
23752 case OPC_MADD: /* Multiply and add/sub */
23756 check_insn(ctx, ISA_MIPS32);
23757 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23760 gen_arith(ctx, op1, rd, rs, rt);
23763 case OPC_DIVU_G_2F:
23764 case OPC_MULT_G_2F:
23765 case OPC_MULTU_G_2F:
23767 case OPC_MODU_G_2F:
23768 check_insn(ctx, INSN_LOONGSON2F);
23769 gen_loongson_integer(ctx, op1, rd, rs, rt);
23773 check_insn(ctx, ISA_MIPS32);
23774 gen_cl(ctx, op1, rd, rs);
23777 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23778 gen_helper_do_semihosting(cpu_env);
23780 /* XXX: not clear which exception should be raised
23781 * when in debug mode...
23783 check_insn(ctx, ISA_MIPS32);
23784 generate_exception_end(ctx, EXCP_DBp);
23787 #if defined(TARGET_MIPS64)
23790 check_insn(ctx, ISA_MIPS64);
23791 check_mips_64(ctx);
23792 gen_cl(ctx, op1, rd, rs);
23794 case OPC_DMULT_G_2F:
23795 case OPC_DMULTU_G_2F:
23796 case OPC_DDIV_G_2F:
23797 case OPC_DDIVU_G_2F:
23798 case OPC_DMOD_G_2F:
23799 case OPC_DMODU_G_2F:
23800 check_insn(ctx, INSN_LOONGSON2F);
23801 gen_loongson_integer(ctx, op1, rd, rs, rt);
23804 default: /* Invalid */
23805 MIPS_INVAL("special2_legacy");
23806 generate_exception_end(ctx, EXCP_RI);
23811 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
23813 int rs, rt, rd, sa;
23817 rs = (ctx->opcode >> 21) & 0x1f;
23818 rt = (ctx->opcode >> 16) & 0x1f;
23819 rd = (ctx->opcode >> 11) & 0x1f;
23820 sa = (ctx->opcode >> 6) & 0x1f;
23821 imm = (int16_t)ctx->opcode >> 7;
23823 op1 = MASK_SPECIAL3(ctx->opcode);
23827 /* hint codes 24-31 are reserved and signal RI */
23828 generate_exception_end(ctx, EXCP_RI);
23830 /* Treat as NOP. */
23833 check_cp0_enabled(ctx);
23834 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23835 gen_cache_operation(ctx, rt, rs, imm);
23839 gen_st_cond(ctx, op1, rt, rs, imm);
23842 gen_ld(ctx, op1, rt, rs, imm);
23847 /* Treat as NOP. */
23850 op2 = MASK_BSHFL(ctx->opcode);
23853 case OPC_ALIGN_END:
23854 gen_align(ctx, 32, rd, rs, rt, sa & 3);
23857 gen_bitswap(ctx, op2, rd, rt);
23862 #if defined(TARGET_MIPS64)
23864 gen_st_cond(ctx, op1, rt, rs, imm);
23867 gen_ld(ctx, op1, rt, rs, imm);
23870 check_mips_64(ctx);
23873 /* Treat as NOP. */
23876 op2 = MASK_DBSHFL(ctx->opcode);
23879 case OPC_DALIGN_END:
23880 gen_align(ctx, 64, rd, rs, rt, sa & 7);
23883 gen_bitswap(ctx, op2, rd, rt);
23890 default: /* Invalid */
23891 MIPS_INVAL("special3_r6");
23892 generate_exception_end(ctx, EXCP_RI);
23897 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
23902 rs = (ctx->opcode >> 21) & 0x1f;
23903 rt = (ctx->opcode >> 16) & 0x1f;
23904 rd = (ctx->opcode >> 11) & 0x1f;
23906 op1 = MASK_SPECIAL3(ctx->opcode);
23909 case OPC_DIVU_G_2E:
23911 case OPC_MODU_G_2E:
23912 case OPC_MULT_G_2E:
23913 case OPC_MULTU_G_2E:
23914 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23915 * the same mask and op1. */
23916 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
23917 op2 = MASK_ADDUH_QB(ctx->opcode);
23920 case OPC_ADDUH_R_QB:
23922 case OPC_ADDQH_R_PH:
23924 case OPC_ADDQH_R_W:
23926 case OPC_SUBUH_R_QB:
23928 case OPC_SUBQH_R_PH:
23930 case OPC_SUBQH_R_W:
23931 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23936 case OPC_MULQ_RS_W:
23937 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23940 MIPS_INVAL("MASK ADDUH.QB");
23941 generate_exception_end(ctx, EXCP_RI);
23944 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
23945 gen_loongson_integer(ctx, op1, rd, rs, rt);
23947 generate_exception_end(ctx, EXCP_RI);
23951 op2 = MASK_LX(ctx->opcode);
23953 #if defined(TARGET_MIPS64)
23959 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
23961 default: /* Invalid */
23962 MIPS_INVAL("MASK LX");
23963 generate_exception_end(ctx, EXCP_RI);
23967 case OPC_ABSQ_S_PH_DSP:
23968 op2 = MASK_ABSQ_S_PH(ctx->opcode);
23970 case OPC_ABSQ_S_QB:
23971 case OPC_ABSQ_S_PH:
23973 case OPC_PRECEQ_W_PHL:
23974 case OPC_PRECEQ_W_PHR:
23975 case OPC_PRECEQU_PH_QBL:
23976 case OPC_PRECEQU_PH_QBR:
23977 case OPC_PRECEQU_PH_QBLA:
23978 case OPC_PRECEQU_PH_QBRA:
23979 case OPC_PRECEU_PH_QBL:
23980 case OPC_PRECEU_PH_QBR:
23981 case OPC_PRECEU_PH_QBLA:
23982 case OPC_PRECEU_PH_QBRA:
23983 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23990 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23993 MIPS_INVAL("MASK ABSQ_S.PH");
23994 generate_exception_end(ctx, EXCP_RI);
23998 case OPC_ADDU_QB_DSP:
23999 op2 = MASK_ADDU_QB(ctx->opcode);
24002 case OPC_ADDQ_S_PH:
24005 case OPC_ADDU_S_QB:
24007 case OPC_ADDU_S_PH:
24009 case OPC_SUBQ_S_PH:
24012 case OPC_SUBU_S_QB:
24014 case OPC_SUBU_S_PH:
24018 case OPC_RADDU_W_QB:
24019 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24021 case OPC_MULEU_S_PH_QBL:
24022 case OPC_MULEU_S_PH_QBR:
24023 case OPC_MULQ_RS_PH:
24024 case OPC_MULEQ_S_W_PHL:
24025 case OPC_MULEQ_S_W_PHR:
24026 case OPC_MULQ_S_PH:
24027 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
24029 default: /* Invalid */
24030 MIPS_INVAL("MASK ADDU.QB");
24031 generate_exception_end(ctx, EXCP_RI);
24036 case OPC_CMPU_EQ_QB_DSP:
24037 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
24039 case OPC_PRECR_SRA_PH_W:
24040 case OPC_PRECR_SRA_R_PH_W:
24041 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
24043 case OPC_PRECR_QB_PH:
24044 case OPC_PRECRQ_QB_PH:
24045 case OPC_PRECRQ_PH_W:
24046 case OPC_PRECRQ_RS_PH_W:
24047 case OPC_PRECRQU_S_QB_PH:
24048 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24050 case OPC_CMPU_EQ_QB:
24051 case OPC_CMPU_LT_QB:
24052 case OPC_CMPU_LE_QB:
24053 case OPC_CMP_EQ_PH:
24054 case OPC_CMP_LT_PH:
24055 case OPC_CMP_LE_PH:
24056 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
24058 case OPC_CMPGU_EQ_QB:
24059 case OPC_CMPGU_LT_QB:
24060 case OPC_CMPGU_LE_QB:
24061 case OPC_CMPGDU_EQ_QB:
24062 case OPC_CMPGDU_LT_QB:
24063 case OPC_CMPGDU_LE_QB:
24066 case OPC_PACKRL_PH:
24067 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
24069 default: /* Invalid */
24070 MIPS_INVAL("MASK CMPU.EQ.QB");
24071 generate_exception_end(ctx, EXCP_RI);
24075 case OPC_SHLL_QB_DSP:
24076 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
24078 case OPC_DPA_W_PH_DSP:
24079 op2 = MASK_DPA_W_PH(ctx->opcode);
24081 case OPC_DPAU_H_QBL:
24082 case OPC_DPAU_H_QBR:
24083 case OPC_DPSU_H_QBL:
24084 case OPC_DPSU_H_QBR:
24086 case OPC_DPAX_W_PH:
24087 case OPC_DPAQ_S_W_PH:
24088 case OPC_DPAQX_S_W_PH:
24089 case OPC_DPAQX_SA_W_PH:
24091 case OPC_DPSX_W_PH:
24092 case OPC_DPSQ_S_W_PH:
24093 case OPC_DPSQX_S_W_PH:
24094 case OPC_DPSQX_SA_W_PH:
24095 case OPC_MULSAQ_S_W_PH:
24096 case OPC_DPAQ_SA_L_W:
24097 case OPC_DPSQ_SA_L_W:
24098 case OPC_MAQ_S_W_PHL:
24099 case OPC_MAQ_S_W_PHR:
24100 case OPC_MAQ_SA_W_PHL:
24101 case OPC_MAQ_SA_W_PHR:
24102 case OPC_MULSA_W_PH:
24103 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24105 default: /* Invalid */
24106 MIPS_INVAL("MASK DPAW.PH");
24107 generate_exception_end(ctx, EXCP_RI);
24112 op2 = MASK_INSV(ctx->opcode);
24123 t0 = tcg_temp_new();
24124 t1 = tcg_temp_new();
24126 gen_load_gpr(t0, rt);
24127 gen_load_gpr(t1, rs);
24129 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
24135 default: /* Invalid */
24136 MIPS_INVAL("MASK INSV");
24137 generate_exception_end(ctx, EXCP_RI);
24141 case OPC_APPEND_DSP:
24142 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
24144 case OPC_EXTR_W_DSP:
24145 op2 = MASK_EXTR_W(ctx->opcode);
24149 case OPC_EXTR_RS_W:
24151 case OPC_EXTRV_S_H:
24153 case OPC_EXTRV_R_W:
24154 case OPC_EXTRV_RS_W:
24159 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
24162 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
24168 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
24170 default: /* Invalid */
24171 MIPS_INVAL("MASK EXTR.W");
24172 generate_exception_end(ctx, EXCP_RI);
24176 #if defined(TARGET_MIPS64)
24177 case OPC_DDIV_G_2E:
24178 case OPC_DDIVU_G_2E:
24179 case OPC_DMULT_G_2E:
24180 case OPC_DMULTU_G_2E:
24181 case OPC_DMOD_G_2E:
24182 case OPC_DMODU_G_2E:
24183 check_insn(ctx, INSN_LOONGSON2E);
24184 gen_loongson_integer(ctx, op1, rd, rs, rt);
24186 case OPC_ABSQ_S_QH_DSP:
24187 op2 = MASK_ABSQ_S_QH(ctx->opcode);
24189 case OPC_PRECEQ_L_PWL:
24190 case OPC_PRECEQ_L_PWR:
24191 case OPC_PRECEQ_PW_QHL:
24192 case OPC_PRECEQ_PW_QHR:
24193 case OPC_PRECEQ_PW_QHLA:
24194 case OPC_PRECEQ_PW_QHRA:
24195 case OPC_PRECEQU_QH_OBL:
24196 case OPC_PRECEQU_QH_OBR:
24197 case OPC_PRECEQU_QH_OBLA:
24198 case OPC_PRECEQU_QH_OBRA:
24199 case OPC_PRECEU_QH_OBL:
24200 case OPC_PRECEU_QH_OBR:
24201 case OPC_PRECEU_QH_OBLA:
24202 case OPC_PRECEU_QH_OBRA:
24203 case OPC_ABSQ_S_OB:
24204 case OPC_ABSQ_S_PW:
24205 case OPC_ABSQ_S_QH:
24206 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24214 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
24216 default: /* Invalid */
24217 MIPS_INVAL("MASK ABSQ_S.QH");
24218 generate_exception_end(ctx, EXCP_RI);
24222 case OPC_ADDU_OB_DSP:
24223 op2 = MASK_ADDU_OB(ctx->opcode);
24225 case OPC_RADDU_L_OB:
24227 case OPC_SUBQ_S_PW:
24229 case OPC_SUBQ_S_QH:
24231 case OPC_SUBU_S_OB:
24233 case OPC_SUBU_S_QH:
24235 case OPC_SUBUH_R_OB:
24237 case OPC_ADDQ_S_PW:
24239 case OPC_ADDQ_S_QH:
24241 case OPC_ADDU_S_OB:
24243 case OPC_ADDU_S_QH:
24245 case OPC_ADDUH_R_OB:
24246 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24248 case OPC_MULEQ_S_PW_QHL:
24249 case OPC_MULEQ_S_PW_QHR:
24250 case OPC_MULEU_S_QH_OBL:
24251 case OPC_MULEU_S_QH_OBR:
24252 case OPC_MULQ_RS_QH:
24253 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
24255 default: /* Invalid */
24256 MIPS_INVAL("MASK ADDU.OB");
24257 generate_exception_end(ctx, EXCP_RI);
24261 case OPC_CMPU_EQ_OB_DSP:
24262 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
24264 case OPC_PRECR_SRA_QH_PW:
24265 case OPC_PRECR_SRA_R_QH_PW:
24266 /* Return value is rt. */
24267 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
24269 case OPC_PRECR_OB_QH:
24270 case OPC_PRECRQ_OB_QH:
24271 case OPC_PRECRQ_PW_L:
24272 case OPC_PRECRQ_QH_PW:
24273 case OPC_PRECRQ_RS_QH_PW:
24274 case OPC_PRECRQU_S_OB_QH:
24275 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24277 case OPC_CMPU_EQ_OB:
24278 case OPC_CMPU_LT_OB:
24279 case OPC_CMPU_LE_OB:
24280 case OPC_CMP_EQ_QH:
24281 case OPC_CMP_LT_QH:
24282 case OPC_CMP_LE_QH:
24283 case OPC_CMP_EQ_PW:
24284 case OPC_CMP_LT_PW:
24285 case OPC_CMP_LE_PW:
24286 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
24288 case OPC_CMPGDU_EQ_OB:
24289 case OPC_CMPGDU_LT_OB:
24290 case OPC_CMPGDU_LE_OB:
24291 case OPC_CMPGU_EQ_OB:
24292 case OPC_CMPGU_LT_OB:
24293 case OPC_CMPGU_LE_OB:
24294 case OPC_PACKRL_PW:
24298 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
24300 default: /* Invalid */
24301 MIPS_INVAL("MASK CMPU_EQ.OB");
24302 generate_exception_end(ctx, EXCP_RI);
24306 case OPC_DAPPEND_DSP:
24307 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
24309 case OPC_DEXTR_W_DSP:
24310 op2 = MASK_DEXTR_W(ctx->opcode);
24317 case OPC_DEXTR_R_L:
24318 case OPC_DEXTR_RS_L:
24320 case OPC_DEXTR_R_W:
24321 case OPC_DEXTR_RS_W:
24322 case OPC_DEXTR_S_H:
24324 case OPC_DEXTRV_R_L:
24325 case OPC_DEXTRV_RS_L:
24326 case OPC_DEXTRV_S_H:
24328 case OPC_DEXTRV_R_W:
24329 case OPC_DEXTRV_RS_W:
24330 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
24335 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
24337 default: /* Invalid */
24338 MIPS_INVAL("MASK EXTR.W");
24339 generate_exception_end(ctx, EXCP_RI);
24343 case OPC_DPAQ_W_QH_DSP:
24344 op2 = MASK_DPAQ_W_QH(ctx->opcode);
24346 case OPC_DPAU_H_OBL:
24347 case OPC_DPAU_H_OBR:
24348 case OPC_DPSU_H_OBL:
24349 case OPC_DPSU_H_OBR:
24351 case OPC_DPAQ_S_W_QH:
24353 case OPC_DPSQ_S_W_QH:
24354 case OPC_MULSAQ_S_W_QH:
24355 case OPC_DPAQ_SA_L_PW:
24356 case OPC_DPSQ_SA_L_PW:
24357 case OPC_MULSAQ_S_L_PW:
24358 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24360 case OPC_MAQ_S_W_QHLL:
24361 case OPC_MAQ_S_W_QHLR:
24362 case OPC_MAQ_S_W_QHRL:
24363 case OPC_MAQ_S_W_QHRR:
24364 case OPC_MAQ_SA_W_QHLL:
24365 case OPC_MAQ_SA_W_QHLR:
24366 case OPC_MAQ_SA_W_QHRL:
24367 case OPC_MAQ_SA_W_QHRR:
24368 case OPC_MAQ_S_L_PWL:
24369 case OPC_MAQ_S_L_PWR:
24374 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24376 default: /* Invalid */
24377 MIPS_INVAL("MASK DPAQ.W.QH");
24378 generate_exception_end(ctx, EXCP_RI);
24382 case OPC_DINSV_DSP:
24383 op2 = MASK_INSV(ctx->opcode);
24394 t0 = tcg_temp_new();
24395 t1 = tcg_temp_new();
24397 gen_load_gpr(t0, rt);
24398 gen_load_gpr(t1, rs);
24400 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
24406 default: /* Invalid */
24407 MIPS_INVAL("MASK DINSV");
24408 generate_exception_end(ctx, EXCP_RI);
24412 case OPC_SHLL_OB_DSP:
24413 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
24416 default: /* Invalid */
24417 MIPS_INVAL("special3_legacy");
24418 generate_exception_end(ctx, EXCP_RI);
24423 static void decode_tx79_mmi0(CPUMIPSState *env, DisasContext *ctx)
24425 uint32_t opc = MASK_TX79_MMI0(ctx->opcode);
24428 case TX79_MMI0_PADDW: /* TODO: TX79_MMI0_PADDW */
24429 case TX79_MMI0_PSUBW: /* TODO: TX79_MMI0_PSUBW */
24430 case TX79_MMI0_PCGTW: /* TODO: TX79_MMI0_PCGTW */
24431 case TX79_MMI0_PMAXW: /* TODO: TX79_MMI0_PMAXW */
24432 case TX79_MMI0_PADDH: /* TODO: TX79_MMI0_PADDH */
24433 case TX79_MMI0_PSUBH: /* TODO: TX79_MMI0_PSUBH */
24434 case TX79_MMI0_PCGTH: /* TODO: TX79_MMI0_PCGTH */
24435 case TX79_MMI0_PMAXH: /* TODO: TX79_MMI0_PMAXH */
24436 case TX79_MMI0_PADDB: /* TODO: TX79_MMI0_PADDB */
24437 case TX79_MMI0_PSUBB: /* TODO: TX79_MMI0_PSUBB */
24438 case TX79_MMI0_PCGTB: /* TODO: TX79_MMI0_PCGTB */
24439 case TX79_MMI0_PADDSW: /* TODO: TX79_MMI0_PADDSW */
24440 case TX79_MMI0_PSUBSW: /* TODO: TX79_MMI0_PSUBSW */
24441 case TX79_MMI0_PEXTLW: /* TODO: TX79_MMI0_PEXTLW */
24442 case TX79_MMI0_PPACW: /* TODO: TX79_MMI0_PPACW */
24443 case TX79_MMI0_PADDSH: /* TODO: TX79_MMI0_PADDSH */
24444 case TX79_MMI0_PSUBSH: /* TODO: TX79_MMI0_PSUBSH */
24445 case TX79_MMI0_PEXTLH: /* TODO: TX79_MMI0_PEXTLH */
24446 case TX79_MMI0_PPACH: /* TODO: TX79_MMI0_PPACH */
24447 case TX79_MMI0_PADDSB: /* TODO: TX79_MMI0_PADDSB */
24448 case TX79_MMI0_PSUBSB: /* TODO: TX79_MMI0_PSUBSB */
24449 case TX79_MMI0_PEXTLB: /* TODO: TX79_MMI0_PEXTLB */
24450 case TX79_MMI0_PPACB: /* TODO: TX79_MMI0_PPACB */
24451 case TX79_MMI0_PEXT5: /* TODO: TX79_MMI0_PEXT5 */
24452 case TX79_MMI0_PPAC5: /* TODO: TX79_MMI0_PPAC5 */
24453 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI0 */
24456 MIPS_INVAL("TX79 MMI class MMI0");
24457 generate_exception_end(ctx, EXCP_RI);
24462 static void decode_tx79_mmi1(CPUMIPSState *env, DisasContext *ctx)
24464 uint32_t opc = MASK_TX79_MMI1(ctx->opcode);
24467 case TX79_MMI1_PABSW: /* TODO: TX79_MMI1_PABSW */
24468 case TX79_MMI1_PCEQW: /* TODO: TX79_MMI1_PCEQW */
24469 case TX79_MMI1_PMINW: /* TODO: TX79_MMI1_PMINW */
24470 case TX79_MMI1_PADSBH: /* TODO: TX79_MMI1_PADSBH */
24471 case TX79_MMI1_PABSH: /* TODO: TX79_MMI1_PABSH */
24472 case TX79_MMI1_PCEQH: /* TODO: TX79_MMI1_PCEQH */
24473 case TX79_MMI1_PMINH: /* TODO: TX79_MMI1_PMINH */
24474 case TX79_MMI1_PCEQB: /* TODO: TX79_MMI1_PCEQB */
24475 case TX79_MMI1_PADDUW: /* TODO: TX79_MMI1_PADDUW */
24476 case TX79_MMI1_PSUBUW: /* TODO: TX79_MMI1_PSUBUW */
24477 case TX79_MMI1_PEXTUW: /* TODO: TX79_MMI1_PEXTUW */
24478 case TX79_MMI1_PADDUH: /* TODO: TX79_MMI1_PADDUH */
24479 case TX79_MMI1_PSUBUH: /* TODO: TX79_MMI1_PSUBUH */
24480 case TX79_MMI1_PEXTUH: /* TODO: TX79_MMI1_PEXTUH */
24481 case TX79_MMI1_PADDUB: /* TODO: TX79_MMI1_PADDUB */
24482 case TX79_MMI1_PSUBUB: /* TODO: TX79_MMI1_PSUBUB */
24483 case TX79_MMI1_PEXTUB: /* TODO: TX79_MMI1_PEXTUB */
24484 case TX79_MMI1_QFSRV: /* TODO: TX79_MMI1_QFSRV */
24485 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI1 */
24488 MIPS_INVAL("TX79 MMI class MMI1");
24489 generate_exception_end(ctx, EXCP_RI);
24494 static void decode_tx79_mmi2(CPUMIPSState *env, DisasContext *ctx)
24496 uint32_t opc = MASK_TX79_MMI2(ctx->opcode);
24499 case TX79_MMI2_PMADDW: /* TODO: TX79_MMI2_PMADDW */
24500 case TX79_MMI2_PSLLVW: /* TODO: TX79_MMI2_PSLLVW */
24501 case TX79_MMI2_PSRLVW: /* TODO: TX79_MMI2_PSRLVW */
24502 case TX79_MMI2_PMSUBW: /* TODO: TX79_MMI2_PMSUBW */
24503 case TX79_MMI2_PMFHI: /* TODO: TX79_MMI2_PMFHI */
24504 case TX79_MMI2_PMFLO: /* TODO: TX79_MMI2_PMFLO */
24505 case TX79_MMI2_PINTH: /* TODO: TX79_MMI2_PINTH */
24506 case TX79_MMI2_PMULTW: /* TODO: TX79_MMI2_PMULTW */
24507 case TX79_MMI2_PDIVW: /* TODO: TX79_MMI2_PDIVW */
24508 case TX79_MMI2_PCPYLD: /* TODO: TX79_MMI2_PCPYLD */
24509 case TX79_MMI2_PMADDH: /* TODO: TX79_MMI2_PMADDH */
24510 case TX79_MMI2_PHMADH: /* TODO: TX79_MMI2_PHMADH */
24511 case TX79_MMI2_PAND: /* TODO: TX79_MMI2_PAND */
24512 case TX79_MMI2_PXOR: /* TODO: TX79_MMI2_PXOR */
24513 case TX79_MMI2_PMSUBH: /* TODO: TX79_MMI2_PMSUBH */
24514 case TX79_MMI2_PHMSBH: /* TODO: TX79_MMI2_PHMSBH */
24515 case TX79_MMI2_PEXEH: /* TODO: TX79_MMI2_PEXEH */
24516 case TX79_MMI2_PREVH: /* TODO: TX79_MMI2_PREVH */
24517 case TX79_MMI2_PMULTH: /* TODO: TX79_MMI2_PMULTH */
24518 case TX79_MMI2_PDIVBW: /* TODO: TX79_MMI2_PDIVBW */
24519 case TX79_MMI2_PEXEW: /* TODO: TX79_MMI2_PEXEW */
24520 case TX79_MMI2_PROT3W: /* TODO: TX79_MMI2_PROT3W */
24521 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI2 */
24524 MIPS_INVAL("TX79 MMI class MMI2");
24525 generate_exception_end(ctx, EXCP_RI);
24530 static void decode_tx79_mmi3(CPUMIPSState *env, DisasContext *ctx)
24532 uint32_t opc = MASK_TX79_MMI3(ctx->opcode);
24535 case TX79_MMI3_PMADDUW: /* TODO: TX79_MMI3_PMADDUW */
24536 case TX79_MMI3_PSRAVW: /* TODO: TX79_MMI3_PSRAVW */
24537 case TX79_MMI3_PMTHI: /* TODO: TX79_MMI3_PMTHI */
24538 case TX79_MMI3_PMTLO: /* TODO: TX79_MMI3_PMTLO */
24539 case TX79_MMI3_PINTEH: /* TODO: TX79_MMI3_PINTEH */
24540 case TX79_MMI3_PMULTUW: /* TODO: TX79_MMI3_PMULTUW */
24541 case TX79_MMI3_PDIVUW: /* TODO: TX79_MMI3_PDIVUW */
24542 case TX79_MMI3_PCPYUD: /* TODO: TX79_MMI3_PCPYUD */
24543 case TX79_MMI3_POR: /* TODO: TX79_MMI3_POR */
24544 case TX79_MMI3_PNOR: /* TODO: TX79_MMI3_PNOR */
24545 case TX79_MMI3_PEXCH: /* TODO: TX79_MMI3_PEXCH */
24546 case TX79_MMI3_PCPYH: /* TODO: TX79_MMI3_PCPYH */
24547 case TX79_MMI3_PEXCW: /* TODO: TX79_MMI3_PEXCW */
24548 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI3 */
24551 MIPS_INVAL("TX79 MMI class MMI3");
24552 generate_exception_end(ctx, EXCP_RI);
24557 static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
24559 uint32_t opc = MASK_TX79_MMI(ctx->opcode);
24562 case TX79_MMI_CLASS_MMI0:
24563 decode_tx79_mmi0(env, ctx);
24565 case TX79_MMI_CLASS_MMI1:
24566 decode_tx79_mmi1(env, ctx);
24568 case TX79_MMI_CLASS_MMI2:
24569 decode_tx79_mmi2(env, ctx);
24571 case TX79_MMI_CLASS_MMI3:
24572 decode_tx79_mmi3(env, ctx);
24574 case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */
24575 case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */
24576 case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */
24577 case TX79_MMI_MFHI1: /* TODO: TX79_MMI_MFHI1 */
24578 case TX79_MMI_MTHI1: /* TODO: TX79_MMI_MTHI1 */
24579 case TX79_MMI_MFLO1: /* TODO: TX79_MMI_MFLO1 */
24580 case TX79_MMI_MTLO1: /* TODO: TX79_MMI_MTLO1 */
24581 case TX79_MMI_MULT1: /* TODO: TX79_MMI_MULT1 */
24582 case TX79_MMI_MULTU1: /* TODO: TX79_MMI_MULTU1 */
24583 case TX79_MMI_DIV1: /* TODO: TX79_MMI_DIV1 */
24584 case TX79_MMI_DIVU1: /* TODO: TX79_MMI_DIVU1 */
24585 case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */
24586 case TX79_MMI_MADDU1: /* TODO: TX79_MMI_MADDU1 */
24587 case TX79_MMI_PMFHL: /* TODO: TX79_MMI_PMFHL */
24588 case TX79_MMI_PMTHL: /* TODO: TX79_MMI_PMTHL */
24589 case TX79_MMI_PSLLH: /* TODO: TX79_MMI_PSLLH */
24590 case TX79_MMI_PSRLH: /* TODO: TX79_MMI_PSRLH */
24591 case TX79_MMI_PSRAH: /* TODO: TX79_MMI_PSRAH */
24592 case TX79_MMI_PSLLW: /* TODO: TX79_MMI_PSLLW */
24593 case TX79_MMI_PSRLW: /* TODO: TX79_MMI_PSRLW */
24594 case TX79_MMI_PSRAW: /* TODO: TX79_MMI_PSRAW */
24595 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_CLASS_MMI */
24598 MIPS_INVAL("TX79 MMI class");
24599 generate_exception_end(ctx, EXCP_RI);
24604 static void decode_tx79_lq(CPUMIPSState *env, DisasContext *ctx)
24606 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_LQ */
24609 static void gen_tx79_sq(DisasContext *ctx, int base, int rt, int offset)
24611 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_SQ */
24615 * The TX79-specific instruction Store Quadword
24617 * +--------+-------+-------+------------------------+
24618 * | 011111 | base | rt | offset | SQ
24619 * +--------+-------+-------+------------------------+
24622 * has the same opcode as the Read Hardware Register instruction
24624 * +--------+-------+-------+-------+-------+--------+
24625 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
24626 * +--------+-------+-------+-------+-------+--------+
24629 * that is required, trapped and emulated by the Linux kernel. However, all
24630 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
24631 * offset is odd. Therefore all valid SQ instructions can execute normally.
24632 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
24633 * between SQ and RDHWR, as the Linux kernel does.
24635 static void decode_tx79_sq(CPUMIPSState *env, DisasContext *ctx)
24637 int base = extract32(ctx->opcode, 21, 5);
24638 int rt = extract32(ctx->opcode, 16, 5);
24639 int offset = extract32(ctx->opcode, 0, 16);
24641 #ifdef CONFIG_USER_ONLY
24642 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
24643 uint32_t op2 = extract32(ctx->opcode, 6, 5);
24645 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
24646 int rd = extract32(ctx->opcode, 11, 5);
24648 gen_rdhwr(ctx, rt, rd, 0);
24653 gen_tx79_sq(ctx, base, rt, offset);
24656 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
24658 int rs, rt, rd, sa;
24662 rs = (ctx->opcode >> 21) & 0x1f;
24663 rt = (ctx->opcode >> 16) & 0x1f;
24664 rd = (ctx->opcode >> 11) & 0x1f;
24665 sa = (ctx->opcode >> 6) & 0x1f;
24666 imm = sextract32(ctx->opcode, 7, 9);
24668 op1 = MASK_SPECIAL3(ctx->opcode);
24671 * EVA loads and stores overlap Loongson 2E instructions decoded by
24672 * decode_opc_special3_legacy(), so be careful to allow their decoding when
24679 check_insn_opc_removed(ctx, ISA_MIPS32R6);
24687 check_cp0_enabled(ctx);
24688 gen_ld(ctx, op1, rt, rs, imm);
24692 check_insn_opc_removed(ctx, ISA_MIPS32R6);
24697 check_cp0_enabled(ctx);
24698 gen_st(ctx, op1, rt, rs, imm);
24701 check_cp0_enabled(ctx);
24702 gen_st_cond(ctx, op1, rt, rs, imm);
24705 check_cp0_enabled(ctx);
24706 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
24707 gen_cache_operation(ctx, rt, rs, imm);
24709 /* Treat as NOP. */
24712 check_cp0_enabled(ctx);
24713 /* Treat as NOP. */
24721 check_insn(ctx, ISA_MIPS32R2);
24722 gen_bitops(ctx, op1, rt, rs, sa, rd);
24725 op2 = MASK_BSHFL(ctx->opcode);
24728 case OPC_ALIGN_END:
24730 check_insn(ctx, ISA_MIPS32R6);
24731 decode_opc_special3_r6(env, ctx);
24734 check_insn(ctx, ISA_MIPS32R2);
24735 gen_bshfl(ctx, op2, rt, rd);
24739 #if defined(TARGET_MIPS64)
24746 check_insn(ctx, ISA_MIPS64R2);
24747 check_mips_64(ctx);
24748 gen_bitops(ctx, op1, rt, rs, sa, rd);
24751 op2 = MASK_DBSHFL(ctx->opcode);
24754 case OPC_DALIGN_END:
24756 check_insn(ctx, ISA_MIPS32R6);
24757 decode_opc_special3_r6(env, ctx);
24760 check_insn(ctx, ISA_MIPS64R2);
24761 check_mips_64(ctx);
24762 op2 = MASK_DBSHFL(ctx->opcode);
24763 gen_bshfl(ctx, op2, rt, rd);
24769 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
24774 TCGv t0 = tcg_temp_new();
24775 TCGv t1 = tcg_temp_new();
24777 gen_load_gpr(t0, rt);
24778 gen_load_gpr(t1, rs);
24779 gen_helper_fork(t0, t1);
24787 TCGv t0 = tcg_temp_new();
24789 gen_load_gpr(t0, rs);
24790 gen_helper_yield(t0, cpu_env, t0);
24791 gen_store_gpr(t0, rd);
24796 if (ctx->insn_flags & ISA_MIPS32R6) {
24797 decode_opc_special3_r6(env, ctx);
24799 decode_opc_special3_legacy(env, ctx);
24804 /* MIPS SIMD Architecture (MSA) */
24805 static inline int check_msa_access(DisasContext *ctx)
24807 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
24808 !(ctx->hflags & MIPS_HFLAG_F64))) {
24809 generate_exception_end(ctx, EXCP_RI);
24813 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
24814 if (ctx->insn_flags & ASE_MSA) {
24815 generate_exception_end(ctx, EXCP_MSADIS);
24818 generate_exception_end(ctx, EXCP_RI);
24825 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
24827 /* generates tcg ops to check if any element is 0 */
24828 /* Note this function only works with MSA_WRLEN = 128 */
24829 uint64_t eval_zero_or_big = 0;
24830 uint64_t eval_big = 0;
24831 TCGv_i64 t0 = tcg_temp_new_i64();
24832 TCGv_i64 t1 = tcg_temp_new_i64();
24835 eval_zero_or_big = 0x0101010101010101ULL;
24836 eval_big = 0x8080808080808080ULL;
24839 eval_zero_or_big = 0x0001000100010001ULL;
24840 eval_big = 0x8000800080008000ULL;
24843 eval_zero_or_big = 0x0000000100000001ULL;
24844 eval_big = 0x8000000080000000ULL;
24847 eval_zero_or_big = 0x0000000000000001ULL;
24848 eval_big = 0x8000000000000000ULL;
24851 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
24852 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
24853 tcg_gen_andi_i64(t0, t0, eval_big);
24854 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
24855 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
24856 tcg_gen_andi_i64(t1, t1, eval_big);
24857 tcg_gen_or_i64(t0, t0, t1);
24858 /* if all bits are zero then all elements are not zero */
24859 /* if some bit is non-zero then some element is zero */
24860 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
24861 tcg_gen_trunc_i64_tl(tresult, t0);
24862 tcg_temp_free_i64(t0);
24863 tcg_temp_free_i64(t1);
24866 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
24868 uint8_t df = (ctx->opcode >> 21) & 0x3;
24869 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24870 int64_t s16 = (int16_t)ctx->opcode;
24872 check_msa_access(ctx);
24874 if (ctx->hflags & MIPS_HFLAG_BMASK) {
24875 generate_exception_end(ctx, EXCP_RI);
24882 TCGv_i64 t0 = tcg_temp_new_i64();
24883 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
24884 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
24885 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
24886 tcg_gen_trunc_i64_tl(bcond, t0);
24887 tcg_temp_free_i64(t0);
24894 gen_check_zero_element(bcond, df, wt);
24900 gen_check_zero_element(bcond, df, wt);
24901 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
24905 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
24907 ctx->hflags |= MIPS_HFLAG_BC;
24908 ctx->hflags |= MIPS_HFLAG_BDS32;
24911 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
24913 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
24914 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
24915 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24916 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24918 TCGv_i32 twd = tcg_const_i32(wd);
24919 TCGv_i32 tws = tcg_const_i32(ws);
24920 TCGv_i32 ti8 = tcg_const_i32(i8);
24922 switch (MASK_MSA_I8(ctx->opcode)) {
24924 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
24927 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
24930 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
24933 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
24936 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
24939 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
24942 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
24948 uint8_t df = (ctx->opcode >> 24) & 0x3;
24949 if (df == DF_DOUBLE) {
24950 generate_exception_end(ctx, EXCP_RI);
24952 TCGv_i32 tdf = tcg_const_i32(df);
24953 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
24954 tcg_temp_free_i32(tdf);
24959 MIPS_INVAL("MSA instruction");
24960 generate_exception_end(ctx, EXCP_RI);
24964 tcg_temp_free_i32(twd);
24965 tcg_temp_free_i32(tws);
24966 tcg_temp_free_i32(ti8);
24969 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
24971 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24972 uint8_t df = (ctx->opcode >> 21) & 0x3;
24973 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
24974 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
24975 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24976 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24978 TCGv_i32 tdf = tcg_const_i32(df);
24979 TCGv_i32 twd = tcg_const_i32(wd);
24980 TCGv_i32 tws = tcg_const_i32(ws);
24981 TCGv_i32 timm = tcg_temp_new_i32();
24982 tcg_gen_movi_i32(timm, u5);
24984 switch (MASK_MSA_I5(ctx->opcode)) {
24986 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
24989 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
24991 case OPC_MAXI_S_df:
24992 tcg_gen_movi_i32(timm, s5);
24993 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
24995 case OPC_MAXI_U_df:
24996 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
24998 case OPC_MINI_S_df:
24999 tcg_gen_movi_i32(timm, s5);
25000 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
25002 case OPC_MINI_U_df:
25003 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
25006 tcg_gen_movi_i32(timm, s5);
25007 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
25009 case OPC_CLTI_S_df:
25010 tcg_gen_movi_i32(timm, s5);
25011 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
25013 case OPC_CLTI_U_df:
25014 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
25016 case OPC_CLEI_S_df:
25017 tcg_gen_movi_i32(timm, s5);
25018 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
25020 case OPC_CLEI_U_df:
25021 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
25025 int32_t s10 = sextract32(ctx->opcode, 11, 10);
25026 tcg_gen_movi_i32(timm, s10);
25027 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
25031 MIPS_INVAL("MSA instruction");
25032 generate_exception_end(ctx, EXCP_RI);
25036 tcg_temp_free_i32(tdf);
25037 tcg_temp_free_i32(twd);
25038 tcg_temp_free_i32(tws);
25039 tcg_temp_free_i32(timm);
25042 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
25044 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
25045 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
25046 uint32_t df = 0, m = 0;
25047 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25048 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25055 if ((dfm & 0x40) == 0x00) {
25058 } else if ((dfm & 0x60) == 0x40) {
25061 } else if ((dfm & 0x70) == 0x60) {
25064 } else if ((dfm & 0x78) == 0x70) {
25068 generate_exception_end(ctx, EXCP_RI);
25072 tdf = tcg_const_i32(df);
25073 tm = tcg_const_i32(m);
25074 twd = tcg_const_i32(wd);
25075 tws = tcg_const_i32(ws);
25077 switch (MASK_MSA_BIT(ctx->opcode)) {
25079 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
25082 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
25085 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
25088 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
25091 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
25094 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
25096 case OPC_BINSLI_df:
25097 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
25099 case OPC_BINSRI_df:
25100 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
25103 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
25106 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
25109 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
25112 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
25115 MIPS_INVAL("MSA instruction");
25116 generate_exception_end(ctx, EXCP_RI);
25120 tcg_temp_free_i32(tdf);
25121 tcg_temp_free_i32(tm);
25122 tcg_temp_free_i32(twd);
25123 tcg_temp_free_i32(tws);
25126 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
25128 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
25129 uint8_t df = (ctx->opcode >> 21) & 0x3;
25130 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25131 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25132 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25134 TCGv_i32 tdf = tcg_const_i32(df);
25135 TCGv_i32 twd = tcg_const_i32(wd);
25136 TCGv_i32 tws = tcg_const_i32(ws);
25137 TCGv_i32 twt = tcg_const_i32(wt);
25139 switch (MASK_MSA_3R(ctx->opcode)) {
25141 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
25144 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
25147 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
25150 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
25152 case OPC_SUBS_S_df:
25153 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
25156 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
25159 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
25162 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
25165 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
25168 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
25170 case OPC_ADDS_A_df:
25171 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
25173 case OPC_SUBS_U_df:
25174 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
25177 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
25180 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
25183 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
25186 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
25189 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
25192 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
25194 case OPC_ADDS_S_df:
25195 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
25197 case OPC_SUBSUS_U_df:
25198 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
25201 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
25204 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
25207 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
25210 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
25213 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
25216 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
25218 case OPC_ADDS_U_df:
25219 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
25221 case OPC_SUBSUU_S_df:
25222 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
25225 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
25228 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
25231 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
25234 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
25237 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
25239 case OPC_ASUB_S_df:
25240 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
25243 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
25246 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
25249 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
25252 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
25255 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
25258 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
25260 case OPC_ASUB_U_df:
25261 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
25264 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
25267 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
25270 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
25273 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
25275 case OPC_AVER_S_df:
25276 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
25279 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
25282 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
25285 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
25288 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
25290 case OPC_AVER_U_df:
25291 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
25294 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
25297 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
25300 case OPC_DOTP_S_df:
25301 case OPC_DOTP_U_df:
25302 case OPC_DPADD_S_df:
25303 case OPC_DPADD_U_df:
25304 case OPC_DPSUB_S_df:
25305 case OPC_HADD_S_df:
25306 case OPC_DPSUB_U_df:
25307 case OPC_HADD_U_df:
25308 case OPC_HSUB_S_df:
25309 case OPC_HSUB_U_df:
25310 if (df == DF_BYTE) {
25311 generate_exception_end(ctx, EXCP_RI);
25314 switch (MASK_MSA_3R(ctx->opcode)) {
25315 case OPC_DOTP_S_df:
25316 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
25318 case OPC_DOTP_U_df:
25319 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
25321 case OPC_DPADD_S_df:
25322 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
25324 case OPC_DPADD_U_df:
25325 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
25327 case OPC_DPSUB_S_df:
25328 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
25330 case OPC_HADD_S_df:
25331 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
25333 case OPC_DPSUB_U_df:
25334 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
25336 case OPC_HADD_U_df:
25337 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
25339 case OPC_HSUB_S_df:
25340 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
25342 case OPC_HSUB_U_df:
25343 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
25348 MIPS_INVAL("MSA instruction");
25349 generate_exception_end(ctx, EXCP_RI);
25352 tcg_temp_free_i32(twd);
25353 tcg_temp_free_i32(tws);
25354 tcg_temp_free_i32(twt);
25355 tcg_temp_free_i32(tdf);
25358 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
25360 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
25361 uint8_t source = (ctx->opcode >> 11) & 0x1f;
25362 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
25363 TCGv telm = tcg_temp_new();
25364 TCGv_i32 tsr = tcg_const_i32(source);
25365 TCGv_i32 tdt = tcg_const_i32(dest);
25367 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
25369 gen_load_gpr(telm, source);
25370 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
25373 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
25374 gen_store_gpr(telm, dest);
25377 gen_helper_msa_move_v(cpu_env, tdt, tsr);
25380 MIPS_INVAL("MSA instruction");
25381 generate_exception_end(ctx, EXCP_RI);
25385 tcg_temp_free(telm);
25386 tcg_temp_free_i32(tdt);
25387 tcg_temp_free_i32(tsr);
25390 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
25393 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
25394 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25395 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25397 TCGv_i32 tws = tcg_const_i32(ws);
25398 TCGv_i32 twd = tcg_const_i32(wd);
25399 TCGv_i32 tn = tcg_const_i32(n);
25400 TCGv_i32 tdf = tcg_const_i32(df);
25402 switch (MASK_MSA_ELM(ctx->opcode)) {
25404 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
25406 case OPC_SPLATI_df:
25407 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
25410 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
25412 case OPC_COPY_S_df:
25413 case OPC_COPY_U_df:
25414 case OPC_INSERT_df:
25415 #if !defined(TARGET_MIPS64)
25416 /* Double format valid only for MIPS64 */
25417 if (df == DF_DOUBLE) {
25418 generate_exception_end(ctx, EXCP_RI);
25422 switch (MASK_MSA_ELM(ctx->opcode)) {
25423 case OPC_COPY_S_df:
25424 if (likely(wd != 0)) {
25425 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
25428 case OPC_COPY_U_df:
25429 if (likely(wd != 0)) {
25430 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
25433 case OPC_INSERT_df:
25434 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
25439 MIPS_INVAL("MSA instruction");
25440 generate_exception_end(ctx, EXCP_RI);
25442 tcg_temp_free_i32(twd);
25443 tcg_temp_free_i32(tws);
25444 tcg_temp_free_i32(tn);
25445 tcg_temp_free_i32(tdf);
25448 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
25450 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
25451 uint32_t df = 0, n = 0;
25453 if ((dfn & 0x30) == 0x00) {
25456 } else if ((dfn & 0x38) == 0x20) {
25459 } else if ((dfn & 0x3c) == 0x30) {
25462 } else if ((dfn & 0x3e) == 0x38) {
25465 } else if (dfn == 0x3E) {
25466 /* CTCMSA, CFCMSA, MOVE.V */
25467 gen_msa_elm_3e(env, ctx);
25470 generate_exception_end(ctx, EXCP_RI);
25474 gen_msa_elm_df(env, ctx, df, n);
25477 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
25479 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
25480 uint8_t df = (ctx->opcode >> 21) & 0x1;
25481 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25482 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25483 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25485 TCGv_i32 twd = tcg_const_i32(wd);
25486 TCGv_i32 tws = tcg_const_i32(ws);
25487 TCGv_i32 twt = tcg_const_i32(wt);
25488 TCGv_i32 tdf = tcg_temp_new_i32();
25490 /* adjust df value for floating-point instruction */
25491 tcg_gen_movi_i32(tdf, df + 2);
25493 switch (MASK_MSA_3RF(ctx->opcode)) {
25495 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
25498 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
25501 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
25504 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
25507 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
25510 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
25513 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
25516 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
25519 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
25522 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
25525 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
25528 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
25531 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
25534 tcg_gen_movi_i32(tdf, df + 1);
25535 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
25538 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
25541 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
25543 case OPC_MADD_Q_df:
25544 tcg_gen_movi_i32(tdf, df + 1);
25545 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
25548 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
25550 case OPC_MSUB_Q_df:
25551 tcg_gen_movi_i32(tdf, df + 1);
25552 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
25555 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
25558 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
25561 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
25564 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
25567 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
25570 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
25573 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
25576 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
25579 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
25582 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
25585 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
25588 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
25591 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
25593 case OPC_MULR_Q_df:
25594 tcg_gen_movi_i32(tdf, df + 1);
25595 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
25598 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
25600 case OPC_FMIN_A_df:
25601 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
25603 case OPC_MADDR_Q_df:
25604 tcg_gen_movi_i32(tdf, df + 1);
25605 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
25608 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
25611 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
25613 case OPC_MSUBR_Q_df:
25614 tcg_gen_movi_i32(tdf, df + 1);
25615 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
25618 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
25620 case OPC_FMAX_A_df:
25621 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
25624 MIPS_INVAL("MSA instruction");
25625 generate_exception_end(ctx, EXCP_RI);
25629 tcg_temp_free_i32(twd);
25630 tcg_temp_free_i32(tws);
25631 tcg_temp_free_i32(twt);
25632 tcg_temp_free_i32(tdf);
25635 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
25637 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
25638 (op & (0x7 << 18)))
25639 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25640 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25641 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25642 uint8_t df = (ctx->opcode >> 16) & 0x3;
25643 TCGv_i32 twd = tcg_const_i32(wd);
25644 TCGv_i32 tws = tcg_const_i32(ws);
25645 TCGv_i32 twt = tcg_const_i32(wt);
25646 TCGv_i32 tdf = tcg_const_i32(df);
25648 switch (MASK_MSA_2R(ctx->opcode)) {
25650 #if !defined(TARGET_MIPS64)
25651 /* Double format valid only for MIPS64 */
25652 if (df == DF_DOUBLE) {
25653 generate_exception_end(ctx, EXCP_RI);
25657 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
25660 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
25663 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
25666 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
25669 MIPS_INVAL("MSA instruction");
25670 generate_exception_end(ctx, EXCP_RI);
25674 tcg_temp_free_i32(twd);
25675 tcg_temp_free_i32(tws);
25676 tcg_temp_free_i32(twt);
25677 tcg_temp_free_i32(tdf);
25680 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
25682 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
25683 (op & (0xf << 17)))
25684 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25685 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25686 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25687 uint8_t df = (ctx->opcode >> 16) & 0x1;
25688 TCGv_i32 twd = tcg_const_i32(wd);
25689 TCGv_i32 tws = tcg_const_i32(ws);
25690 TCGv_i32 twt = tcg_const_i32(wt);
25691 /* adjust df value for floating-point instruction */
25692 TCGv_i32 tdf = tcg_const_i32(df + 2);
25694 switch (MASK_MSA_2RF(ctx->opcode)) {
25695 case OPC_FCLASS_df:
25696 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
25698 case OPC_FTRUNC_S_df:
25699 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
25701 case OPC_FTRUNC_U_df:
25702 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
25705 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
25707 case OPC_FRSQRT_df:
25708 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
25711 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
25714 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
25717 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
25719 case OPC_FEXUPL_df:
25720 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
25722 case OPC_FEXUPR_df:
25723 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
25726 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
25729 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
25731 case OPC_FTINT_S_df:
25732 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
25734 case OPC_FTINT_U_df:
25735 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
25737 case OPC_FFINT_S_df:
25738 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
25740 case OPC_FFINT_U_df:
25741 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
25745 tcg_temp_free_i32(twd);
25746 tcg_temp_free_i32(tws);
25747 tcg_temp_free_i32(twt);
25748 tcg_temp_free_i32(tdf);
25751 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
25753 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
25754 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25755 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25756 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25757 TCGv_i32 twd = tcg_const_i32(wd);
25758 TCGv_i32 tws = tcg_const_i32(ws);
25759 TCGv_i32 twt = tcg_const_i32(wt);
25761 switch (MASK_MSA_VEC(ctx->opcode)) {
25763 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
25766 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
25769 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
25772 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
25775 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
25778 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
25781 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
25784 MIPS_INVAL("MSA instruction");
25785 generate_exception_end(ctx, EXCP_RI);
25789 tcg_temp_free_i32(twd);
25790 tcg_temp_free_i32(tws);
25791 tcg_temp_free_i32(twt);
25794 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
25796 switch (MASK_MSA_VEC(ctx->opcode)) {
25804 gen_msa_vec_v(env, ctx);
25807 gen_msa_2r(env, ctx);
25810 gen_msa_2rf(env, ctx);
25813 MIPS_INVAL("MSA instruction");
25814 generate_exception_end(ctx, EXCP_RI);
25819 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
25821 uint32_t opcode = ctx->opcode;
25822 check_insn(ctx, ASE_MSA);
25823 check_msa_access(ctx);
25825 switch (MASK_MSA_MINOR(opcode)) {
25826 case OPC_MSA_I8_00:
25827 case OPC_MSA_I8_01:
25828 case OPC_MSA_I8_02:
25829 gen_msa_i8(env, ctx);
25831 case OPC_MSA_I5_06:
25832 case OPC_MSA_I5_07:
25833 gen_msa_i5(env, ctx);
25835 case OPC_MSA_BIT_09:
25836 case OPC_MSA_BIT_0A:
25837 gen_msa_bit(env, ctx);
25839 case OPC_MSA_3R_0D:
25840 case OPC_MSA_3R_0E:
25841 case OPC_MSA_3R_0F:
25842 case OPC_MSA_3R_10:
25843 case OPC_MSA_3R_11:
25844 case OPC_MSA_3R_12:
25845 case OPC_MSA_3R_13:
25846 case OPC_MSA_3R_14:
25847 case OPC_MSA_3R_15:
25848 gen_msa_3r(env, ctx);
25851 gen_msa_elm(env, ctx);
25853 case OPC_MSA_3RF_1A:
25854 case OPC_MSA_3RF_1B:
25855 case OPC_MSA_3RF_1C:
25856 gen_msa_3rf(env, ctx);
25859 gen_msa_vec(env, ctx);
25870 int32_t s10 = sextract32(ctx->opcode, 16, 10);
25871 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
25872 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25873 uint8_t df = (ctx->opcode >> 0) & 0x3;
25875 TCGv_i32 twd = tcg_const_i32(wd);
25876 TCGv taddr = tcg_temp_new();
25877 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
25879 switch (MASK_MSA_MINOR(opcode)) {
25881 gen_helper_msa_ld_b(cpu_env, twd, taddr);
25884 gen_helper_msa_ld_h(cpu_env, twd, taddr);
25887 gen_helper_msa_ld_w(cpu_env, twd, taddr);
25890 gen_helper_msa_ld_d(cpu_env, twd, taddr);
25893 gen_helper_msa_st_b(cpu_env, twd, taddr);
25896 gen_helper_msa_st_h(cpu_env, twd, taddr);
25899 gen_helper_msa_st_w(cpu_env, twd, taddr);
25902 gen_helper_msa_st_d(cpu_env, twd, taddr);
25906 tcg_temp_free_i32(twd);
25907 tcg_temp_free(taddr);
25911 MIPS_INVAL("MSA instruction");
25912 generate_exception_end(ctx, EXCP_RI);
25918 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
25921 int rs, rt, rd, sa;
25925 /* make sure instructions are on a word boundary */
25926 if (ctx->base.pc_next & 0x3) {
25927 env->CP0_BadVAddr = ctx->base.pc_next;
25928 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
25932 /* Handle blikely not taken case */
25933 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
25934 TCGLabel *l1 = gen_new_label();
25936 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
25937 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
25938 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
25942 op = MASK_OP_MAJOR(ctx->opcode);
25943 rs = (ctx->opcode >> 21) & 0x1f;
25944 rt = (ctx->opcode >> 16) & 0x1f;
25945 rd = (ctx->opcode >> 11) & 0x1f;
25946 sa = (ctx->opcode >> 6) & 0x1f;
25947 imm = (int16_t)ctx->opcode;
25950 decode_opc_special(env, ctx);
25953 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
25954 decode_tx79_mmi(env, ctx);
25956 decode_opc_special2_legacy(env, ctx);
25960 if (ctx->insn_flags & INSN_R5900) {
25961 decode_tx79_sq(env, ctx); /* TX79_SQ */
25963 decode_opc_special3(env, ctx);
25967 op1 = MASK_REGIMM(ctx->opcode);
25969 case OPC_BLTZL: /* REGIMM branches */
25973 check_insn(ctx, ISA_MIPS2);
25974 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25978 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25982 if (ctx->insn_flags & ISA_MIPS32R6) {
25984 /* OPC_NAL, OPC_BAL */
25985 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
25987 generate_exception_end(ctx, EXCP_RI);
25990 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25993 case OPC_TGEI: /* REGIMM traps */
26000 check_insn(ctx, ISA_MIPS2);
26001 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26002 gen_trap(ctx, op1, rs, -1, imm);
26005 check_insn(ctx, ISA_MIPS32R6);
26006 generate_exception_end(ctx, EXCP_RI);
26009 check_insn(ctx, ISA_MIPS32R2);
26010 /* Break the TB to be able to sync copied instructions
26012 ctx->base.is_jmp = DISAS_STOP;
26014 case OPC_BPOSGE32: /* MIPS DSP branch */
26015 #if defined(TARGET_MIPS64)
26019 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
26021 #if defined(TARGET_MIPS64)
26023 check_insn(ctx, ISA_MIPS32R6);
26024 check_mips_64(ctx);
26026 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
26030 check_insn(ctx, ISA_MIPS32R6);
26031 check_mips_64(ctx);
26033 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
26037 default: /* Invalid */
26038 MIPS_INVAL("regimm");
26039 generate_exception_end(ctx, EXCP_RI);
26044 check_cp0_enabled(ctx);
26045 op1 = MASK_CP0(ctx->opcode);
26053 #if defined(TARGET_MIPS64)
26057 #ifndef CONFIG_USER_ONLY
26058 gen_cp0(env, ctx, op1, rt, rd);
26059 #endif /* !CONFIG_USER_ONLY */
26077 #ifndef CONFIG_USER_ONLY
26078 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
26079 #endif /* !CONFIG_USER_ONLY */
26082 #ifndef CONFIG_USER_ONLY
26085 TCGv t0 = tcg_temp_new();
26087 op2 = MASK_MFMC0(ctx->opcode);
26091 gen_helper_dmt(t0);
26092 gen_store_gpr(t0, rt);
26096 gen_helper_emt(t0);
26097 gen_store_gpr(t0, rt);
26101 gen_helper_dvpe(t0, cpu_env);
26102 gen_store_gpr(t0, rt);
26106 gen_helper_evpe(t0, cpu_env);
26107 gen_store_gpr(t0, rt);
26110 check_insn(ctx, ISA_MIPS32R6);
26112 gen_helper_dvp(t0, cpu_env);
26113 gen_store_gpr(t0, rt);
26117 check_insn(ctx, ISA_MIPS32R6);
26119 gen_helper_evp(t0, cpu_env);
26120 gen_store_gpr(t0, rt);
26124 check_insn(ctx, ISA_MIPS32R2);
26125 save_cpu_state(ctx, 1);
26126 gen_helper_di(t0, cpu_env);
26127 gen_store_gpr(t0, rt);
26128 /* Stop translation as we may have switched
26129 the execution mode. */
26130 ctx->base.is_jmp = DISAS_STOP;
26133 check_insn(ctx, ISA_MIPS32R2);
26134 save_cpu_state(ctx, 1);
26135 gen_helper_ei(t0, cpu_env);
26136 gen_store_gpr(t0, rt);
26137 /* DISAS_STOP isn't sufficient, we need to ensure we break
26138 out of translated code to check for pending interrupts */
26139 gen_save_pc(ctx->base.pc_next + 4);
26140 ctx->base.is_jmp = DISAS_EXIT;
26142 default: /* Invalid */
26143 MIPS_INVAL("mfmc0");
26144 generate_exception_end(ctx, EXCP_RI);
26149 #endif /* !CONFIG_USER_ONLY */
26152 check_insn(ctx, ISA_MIPS32R2);
26153 gen_load_srsgpr(rt, rd);
26156 check_insn(ctx, ISA_MIPS32R2);
26157 gen_store_srsgpr(rt, rd);
26161 generate_exception_end(ctx, EXCP_RI);
26165 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
26166 if (ctx->insn_flags & ISA_MIPS32R6) {
26167 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
26168 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26171 /* Arithmetic with immediate opcode */
26172 gen_arith_imm(ctx, op, rt, rs, imm);
26176 gen_arith_imm(ctx, op, rt, rs, imm);
26178 case OPC_SLTI: /* Set on less than with immediate opcode */
26180 gen_slt_imm(ctx, op, rt, rs, imm);
26182 case OPC_ANDI: /* Arithmetic with immediate opcode */
26183 case OPC_LUI: /* OPC_AUI */
26186 gen_logic_imm(ctx, op, rt, rs, imm);
26188 case OPC_J: /* Jump */
26190 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
26191 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
26194 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
26195 if (ctx->insn_flags & ISA_MIPS32R6) {
26197 generate_exception_end(ctx, EXCP_RI);
26200 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
26201 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26204 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
26207 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
26208 if (ctx->insn_flags & ISA_MIPS32R6) {
26210 generate_exception_end(ctx, EXCP_RI);
26213 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
26214 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26217 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
26220 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
26223 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
26225 check_insn(ctx, ISA_MIPS32R6);
26226 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
26227 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26230 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
26233 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
26235 check_insn(ctx, ISA_MIPS32R6);
26236 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
26237 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26242 check_insn(ctx, ISA_MIPS2);
26243 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26247 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
26249 case OPC_LL: /* Load and stores */
26250 check_insn(ctx, ISA_MIPS2);
26254 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26262 gen_ld(ctx, op, rt, rs, imm);
26266 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26271 gen_st(ctx, op, rt, rs, imm);
26274 check_insn(ctx, ISA_MIPS2);
26275 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26276 gen_st_cond(ctx, op, rt, rs, imm);
26279 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26280 check_cp0_enabled(ctx);
26281 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
26282 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26283 gen_cache_operation(ctx, rt, rs, imm);
26285 /* Treat as NOP. */
26288 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26289 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
26290 /* Treat as NOP. */
26293 /* Floating point (COP1). */
26298 gen_cop1_ldst(ctx, op, rt, rs, imm);
26302 op1 = MASK_CP1(ctx->opcode);
26307 check_cp1_enabled(ctx);
26308 check_insn(ctx, ISA_MIPS32R2);
26314 check_cp1_enabled(ctx);
26315 gen_cp1(ctx, op1, rt, rd);
26317 #if defined(TARGET_MIPS64)
26320 check_cp1_enabled(ctx);
26321 check_insn(ctx, ISA_MIPS3);
26322 check_mips_64(ctx);
26323 gen_cp1(ctx, op1, rt, rd);
26326 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
26327 check_cp1_enabled(ctx);
26328 if (ctx->insn_flags & ISA_MIPS32R6) {
26330 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
26335 check_insn(ctx, ASE_MIPS3D);
26336 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
26337 (rt >> 2) & 0x7, imm << 2);
26341 check_cp1_enabled(ctx);
26342 check_insn(ctx, ISA_MIPS32R6);
26343 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
26347 check_cp1_enabled(ctx);
26348 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26350 check_insn(ctx, ASE_MIPS3D);
26353 check_cp1_enabled(ctx);
26354 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26355 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
26356 (rt >> 2) & 0x7, imm << 2);
26363 check_cp1_enabled(ctx);
26364 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
26370 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
26371 check_cp1_enabled(ctx);
26372 if (ctx->insn_flags & ISA_MIPS32R6) {
26374 case R6_OPC_CMP_AF_S:
26375 case R6_OPC_CMP_UN_S:
26376 case R6_OPC_CMP_EQ_S:
26377 case R6_OPC_CMP_UEQ_S:
26378 case R6_OPC_CMP_LT_S:
26379 case R6_OPC_CMP_ULT_S:
26380 case R6_OPC_CMP_LE_S:
26381 case R6_OPC_CMP_ULE_S:
26382 case R6_OPC_CMP_SAF_S:
26383 case R6_OPC_CMP_SUN_S:
26384 case R6_OPC_CMP_SEQ_S:
26385 case R6_OPC_CMP_SEUQ_S:
26386 case R6_OPC_CMP_SLT_S:
26387 case R6_OPC_CMP_SULT_S:
26388 case R6_OPC_CMP_SLE_S:
26389 case R6_OPC_CMP_SULE_S:
26390 case R6_OPC_CMP_OR_S:
26391 case R6_OPC_CMP_UNE_S:
26392 case R6_OPC_CMP_NE_S:
26393 case R6_OPC_CMP_SOR_S:
26394 case R6_OPC_CMP_SUNE_S:
26395 case R6_OPC_CMP_SNE_S:
26396 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
26398 case R6_OPC_CMP_AF_D:
26399 case R6_OPC_CMP_UN_D:
26400 case R6_OPC_CMP_EQ_D:
26401 case R6_OPC_CMP_UEQ_D:
26402 case R6_OPC_CMP_LT_D:
26403 case R6_OPC_CMP_ULT_D:
26404 case R6_OPC_CMP_LE_D:
26405 case R6_OPC_CMP_ULE_D:
26406 case R6_OPC_CMP_SAF_D:
26407 case R6_OPC_CMP_SUN_D:
26408 case R6_OPC_CMP_SEQ_D:
26409 case R6_OPC_CMP_SEUQ_D:
26410 case R6_OPC_CMP_SLT_D:
26411 case R6_OPC_CMP_SULT_D:
26412 case R6_OPC_CMP_SLE_D:
26413 case R6_OPC_CMP_SULE_D:
26414 case R6_OPC_CMP_OR_D:
26415 case R6_OPC_CMP_UNE_D:
26416 case R6_OPC_CMP_NE_D:
26417 case R6_OPC_CMP_SOR_D:
26418 case R6_OPC_CMP_SUNE_D:
26419 case R6_OPC_CMP_SNE_D:
26420 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
26423 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
26424 rt, rd, sa, (imm >> 8) & 0x7);
26429 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
26444 check_insn(ctx, ASE_MSA);
26445 gen_msa_branch(env, ctx, op1);
26449 generate_exception_end(ctx, EXCP_RI);
26454 /* Compact branches [R6] and COP2 [non-R6] */
26455 case OPC_BC: /* OPC_LWC2 */
26456 case OPC_BALC: /* OPC_SWC2 */
26457 if (ctx->insn_flags & ISA_MIPS32R6) {
26458 /* OPC_BC, OPC_BALC */
26459 gen_compute_compact_branch(ctx, op, 0, 0,
26460 sextract32(ctx->opcode << 2, 0, 28));
26462 /* OPC_LWC2, OPC_SWC2 */
26463 /* COP2: Not implemented. */
26464 generate_exception_err(ctx, EXCP_CpU, 2);
26467 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
26468 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
26469 if (ctx->insn_flags & ISA_MIPS32R6) {
26471 /* OPC_BEQZC, OPC_BNEZC */
26472 gen_compute_compact_branch(ctx, op, rs, 0,
26473 sextract32(ctx->opcode << 2, 0, 23));
26475 /* OPC_JIC, OPC_JIALC */
26476 gen_compute_compact_branch(ctx, op, 0, rt, imm);
26479 /* OPC_LWC2, OPC_SWC2 */
26480 /* COP2: Not implemented. */
26481 generate_exception_err(ctx, EXCP_CpU, 2);
26485 check_insn(ctx, INSN_LOONGSON2F);
26486 /* Note that these instructions use different fields. */
26487 gen_loongson_multimedia(ctx, sa, rd, rt);
26491 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26492 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26493 check_cp1_enabled(ctx);
26494 op1 = MASK_CP3(ctx->opcode);
26498 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
26504 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
26505 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
26508 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
26509 /* Treat as NOP. */
26512 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
26526 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
26527 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
26531 generate_exception_end(ctx, EXCP_RI);
26535 generate_exception_err(ctx, EXCP_CpU, 1);
26539 #if defined(TARGET_MIPS64)
26540 /* MIPS64 opcodes */
26544 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26548 check_insn(ctx, ISA_MIPS3);
26549 check_mips_64(ctx);
26550 gen_ld(ctx, op, rt, rs, imm);
26554 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26557 check_insn(ctx, ISA_MIPS3);
26558 check_mips_64(ctx);
26559 gen_st(ctx, op, rt, rs, imm);
26562 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26563 check_insn(ctx, ISA_MIPS3);
26564 check_mips_64(ctx);
26565 gen_st_cond(ctx, op, rt, rs, imm);
26567 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
26568 if (ctx->insn_flags & ISA_MIPS32R6) {
26569 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
26570 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26573 check_insn(ctx, ISA_MIPS3);
26574 check_mips_64(ctx);
26575 gen_arith_imm(ctx, op, rt, rs, imm);
26579 check_insn(ctx, ISA_MIPS3);
26580 check_mips_64(ctx);
26581 gen_arith_imm(ctx, op, rt, rs, imm);
26584 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
26585 if (ctx->insn_flags & ISA_MIPS32R6) {
26586 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26588 MIPS_INVAL("major opcode");
26589 generate_exception_end(ctx, EXCP_RI);
26593 case OPC_DAUI: /* OPC_JALX */
26594 if (ctx->insn_flags & ISA_MIPS32R6) {
26595 #if defined(TARGET_MIPS64)
26597 check_mips_64(ctx);
26599 generate_exception(ctx, EXCP_RI);
26600 } else if (rt != 0) {
26601 TCGv t0 = tcg_temp_new();
26602 gen_load_gpr(t0, rs);
26603 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
26607 generate_exception_end(ctx, EXCP_RI);
26608 MIPS_INVAL("major opcode");
26612 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
26613 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
26614 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
26617 case OPC_MSA: /* OPC_MDMX */
26618 if (ctx->insn_flags & INSN_R5900) {
26619 decode_tx79_lq(env, ctx); /* TX79_LQ */
26621 /* MDMX: Not implemented. */
26626 check_insn(ctx, ISA_MIPS32R6);
26627 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
26629 default: /* Invalid */
26630 MIPS_INVAL("major opcode");
26631 generate_exception_end(ctx, EXCP_RI);
26636 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
26638 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26639 CPUMIPSState *env = cs->env_ptr;
26641 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
26642 ctx->saved_pc = -1;
26643 ctx->insn_flags = env->insn_flags;
26644 ctx->CP0_Config1 = env->CP0_Config1;
26645 ctx->CP0_Config2 = env->CP0_Config2;
26646 ctx->CP0_Config3 = env->CP0_Config3;
26647 ctx->CP0_Config5 = env->CP0_Config5;
26649 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
26650 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
26651 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
26652 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
26653 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
26654 ctx->PAMask = env->PAMask;
26655 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
26656 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
26657 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
26658 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
26659 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
26660 /* Restore delay slot state from the tb context. */
26661 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
26662 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
26663 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
26664 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
26665 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
26666 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
26667 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
26668 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
26669 restore_cpu_state(env, ctx);
26670 #ifdef CONFIG_USER_ONLY
26671 ctx->mem_idx = MIPS_HFLAG_UM;
26673 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
26675 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
26676 MO_UNALN : MO_ALIGN;
26678 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
26682 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
26686 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
26688 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26690 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
26694 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
26695 const CPUBreakpoint *bp)
26697 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26699 save_cpu_state(ctx, 1);
26700 ctx->base.is_jmp = DISAS_NORETURN;
26701 gen_helper_raise_exception_debug(cpu_env);
26702 /* The address covered by the breakpoint must be included in
26703 [tb->pc, tb->pc + tb->size) in order to for it to be
26704 properly cleared -- thus we increment the PC here so that
26705 the logic setting tb->size below does the right thing. */
26706 ctx->base.pc_next += 4;
26710 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
26712 CPUMIPSState *env = cs->env_ptr;
26713 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26717 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
26718 if (ctx->insn_flags & ISA_NANOMIPS32) {
26719 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26720 insn_bytes = decode_nanomips_opc(env, ctx);
26721 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
26722 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
26724 decode_opc(env, ctx);
26725 } else if (ctx->insn_flags & ASE_MICROMIPS) {
26726 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26727 insn_bytes = decode_micromips_opc(env, ctx);
26728 } else if (ctx->insn_flags & ASE_MIPS16) {
26729 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26730 insn_bytes = decode_mips16_opc(env, ctx);
26732 generate_exception_end(ctx, EXCP_RI);
26733 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
26737 if (ctx->hflags & MIPS_HFLAG_BMASK) {
26738 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
26739 MIPS_HFLAG_FBNSLOT))) {
26740 /* force to generate branch as there is neither delay nor
26744 if ((ctx->hflags & MIPS_HFLAG_M16) &&
26745 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
26746 /* Force to generate branch as microMIPS R6 doesn't restrict
26747 branches in the forbidden slot. */
26752 gen_branch(ctx, insn_bytes);
26754 ctx->base.pc_next += insn_bytes;
26756 if (ctx->base.is_jmp != DISAS_NEXT) {
26759 /* Execute a branch and its delay slot as a single instruction.
26760 This is what GDB expects and is consistent with what the
26761 hardware does (e.g. if a delay slot instruction faults, the
26762 reported PC is the PC of the branch). */
26763 if (ctx->base.singlestep_enabled &&
26764 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
26765 ctx->base.is_jmp = DISAS_TOO_MANY;
26767 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
26768 ctx->base.is_jmp = DISAS_TOO_MANY;
26772 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
26774 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26776 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
26777 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
26778 gen_helper_raise_exception_debug(cpu_env);
26780 switch (ctx->base.is_jmp) {
26782 gen_save_pc(ctx->base.pc_next);
26783 tcg_gen_lookup_and_goto_ptr();
26786 case DISAS_TOO_MANY:
26787 save_cpu_state(ctx, 0);
26788 gen_goto_tb(ctx, 0, ctx->base.pc_next);
26791 tcg_gen_exit_tb(NULL, 0);
26793 case DISAS_NORETURN:
26796 g_assert_not_reached();
26801 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
26803 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
26804 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
26807 static const TranslatorOps mips_tr_ops = {
26808 .init_disas_context = mips_tr_init_disas_context,
26809 .tb_start = mips_tr_tb_start,
26810 .insn_start = mips_tr_insn_start,
26811 .breakpoint_check = mips_tr_breakpoint_check,
26812 .translate_insn = mips_tr_translate_insn,
26813 .tb_stop = mips_tr_tb_stop,
26814 .disas_log = mips_tr_disas_log,
26817 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
26821 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
26824 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
26828 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
26830 #define printfpr(fp) \
26833 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
26834 " fd:%13g fs:%13g psu: %13g\n", \
26835 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
26836 (double)(fp)->fd, \
26837 (double)(fp)->fs[FP_ENDIAN_IDX], \
26838 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
26841 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
26842 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
26843 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
26844 " fd:%13g fs:%13g psu:%13g\n", \
26845 tmp.w[FP_ENDIAN_IDX], tmp.d, \
26847 (double)tmp.fs[FP_ENDIAN_IDX], \
26848 (double)tmp.fs[!FP_ENDIAN_IDX]); \
26853 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
26854 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
26855 get_float_exception_flags(&env->active_fpu.fp_status));
26856 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
26857 fpu_fprintf(f, "%3s: ", fregnames[i]);
26858 printfpr(&env->active_fpu.fpr[i]);
26864 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
26867 MIPSCPU *cpu = MIPS_CPU(cs);
26868 CPUMIPSState *env = &cpu->env;
26871 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
26872 " LO=0x" TARGET_FMT_lx " ds %04x "
26873 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
26874 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
26875 env->hflags, env->btarget, env->bcond);
26876 for (i = 0; i < 32; i++) {
26878 cpu_fprintf(f, "GPR%02d:", i);
26879 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
26881 cpu_fprintf(f, "\n");
26884 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
26885 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
26886 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
26888 env->CP0_Config0, env->CP0_Config1, env->lladdr);
26889 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
26890 env->CP0_Config2, env->CP0_Config3);
26891 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
26892 env->CP0_Config4, env->CP0_Config5);
26893 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
26894 fpu_dump_state(env, f, cpu_fprintf, flags);
26898 void mips_tcg_init(void)
26903 for (i = 1; i < 32; i++)
26904 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
26905 offsetof(CPUMIPSState, active_tc.gpr[i]),
26908 for (i = 0; i < 32; i++) {
26909 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
26911 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
26912 /* The scalar floating-point unit (FPU) registers are mapped on
26913 * the MSA vector registers. */
26914 fpu_f64[i] = msa_wr_d[i * 2];
26915 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
26916 msa_wr_d[i * 2 + 1] =
26917 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
26920 cpu_PC = tcg_global_mem_new(cpu_env,
26921 offsetof(CPUMIPSState, active_tc.PC), "PC");
26922 for (i = 0; i < MIPS_DSP_ACC; i++) {
26923 cpu_HI[i] = tcg_global_mem_new(cpu_env,
26924 offsetof(CPUMIPSState, active_tc.HI[i]),
26926 cpu_LO[i] = tcg_global_mem_new(cpu_env,
26927 offsetof(CPUMIPSState, active_tc.LO[i]),
26930 cpu_dspctrl = tcg_global_mem_new(cpu_env,
26931 offsetof(CPUMIPSState, active_tc.DSPControl),
26933 bcond = tcg_global_mem_new(cpu_env,
26934 offsetof(CPUMIPSState, bcond), "bcond");
26935 btarget = tcg_global_mem_new(cpu_env,
26936 offsetof(CPUMIPSState, btarget), "btarget");
26937 hflags = tcg_global_mem_new_i32(cpu_env,
26938 offsetof(CPUMIPSState, hflags), "hflags");
26940 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
26941 offsetof(CPUMIPSState, active_fpu.fcr0),
26943 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
26944 offsetof(CPUMIPSState, active_fpu.fcr31),
26948 #include "translate_init.inc.c"
26950 void cpu_mips_realize_env(CPUMIPSState *env)
26952 env->exception_base = (int32_t)0xBFC00000;
26954 #ifndef CONFIG_USER_ONLY
26955 mmu_init(env, env->cpu_model);
26957 fpu_init(env, env->cpu_model);
26958 mvp_init(env, env->cpu_model);
26961 bool cpu_supports_cps_smp(const char *cpu_type)
26963 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26964 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
26967 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
26969 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26970 return (mcc->cpu_def->insn_flags & isa) != 0;
26973 void cpu_set_exception_base(int vp_index, target_ulong address)
26975 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
26976 vp->env.exception_base = address;
26979 void cpu_state_reset(CPUMIPSState *env)
26981 MIPSCPU *cpu = mips_env_get_cpu(env);
26982 CPUState *cs = CPU(cpu);
26984 /* Reset registers to their default values */
26985 env->CP0_PRid = env->cpu_model->CP0_PRid;
26986 env->CP0_Config0 = env->cpu_model->CP0_Config0;
26987 #ifdef TARGET_WORDS_BIGENDIAN
26988 env->CP0_Config0 |= (1 << CP0C0_BE);
26990 env->CP0_Config1 = env->cpu_model->CP0_Config1;
26991 env->CP0_Config2 = env->cpu_model->CP0_Config2;
26992 env->CP0_Config3 = env->cpu_model->CP0_Config3;
26993 env->CP0_Config4 = env->cpu_model->CP0_Config4;
26994 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
26995 env->CP0_Config5 = env->cpu_model->CP0_Config5;
26996 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
26997 env->CP0_Config6 = env->cpu_model->CP0_Config6;
26998 env->CP0_Config7 = env->cpu_model->CP0_Config7;
26999 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
27000 << env->cpu_model->CP0_LLAddr_shift;
27001 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
27002 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
27003 env->CCRes = env->cpu_model->CCRes;
27004 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
27005 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
27006 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
27007 env->current_tc = 0;
27008 env->SEGBITS = env->cpu_model->SEGBITS;
27009 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
27010 #if defined(TARGET_MIPS64)
27011 if (env->cpu_model->insn_flags & ISA_MIPS3) {
27012 env->SEGMask |= 3ULL << 62;
27015 env->PABITS = env->cpu_model->PABITS;
27016 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
27017 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
27018 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
27019 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
27020 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
27021 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
27022 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
27023 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
27024 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
27025 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
27026 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
27027 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
27028 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
27029 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
27030 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
27031 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
27032 env->msair = env->cpu_model->MSAIR;
27033 env->insn_flags = env->cpu_model->insn_flags;
27035 #if defined(CONFIG_USER_ONLY)
27036 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
27037 # ifdef TARGET_MIPS64
27038 /* Enable 64-bit register mode. */
27039 env->CP0_Status |= (1 << CP0St_PX);
27041 # ifdef TARGET_ABI_MIPSN64
27042 /* Enable 64-bit address mode. */
27043 env->CP0_Status |= (1 << CP0St_UX);
27045 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
27046 hardware registers. */
27047 env->CP0_HWREna |= 0x0000000F;
27048 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
27049 env->CP0_Status |= (1 << CP0St_CU1);
27051 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
27052 env->CP0_Status |= (1 << CP0St_MX);
27054 # if defined(TARGET_MIPS64)
27055 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
27056 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
27057 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
27058 env->CP0_Status |= (1 << CP0St_FR);
27062 if (env->hflags & MIPS_HFLAG_BMASK) {
27063 /* If the exception was raised from a delay slot,
27064 come back to the jump. */
27065 env->CP0_ErrorEPC = (env->active_tc.PC
27066 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
27068 env->CP0_ErrorEPC = env->active_tc.PC;
27070 env->active_tc.PC = env->exception_base;
27071 env->CP0_Random = env->tlb->nb_tlb - 1;
27072 env->tlb->tlb_in_use = env->tlb->nb_tlb;
27073 env->CP0_Wired = 0;
27074 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
27075 env->CP0_EBase = (cs->cpu_index & 0x3FF);
27076 if (mips_um_ksegs_enabled()) {
27077 env->CP0_EBase |= 0x40000000;
27079 env->CP0_EBase |= (int32_t)0x80000000;
27081 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
27082 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
27084 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
27086 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
27087 /* vectored interrupts not implemented, timer on int 7,
27088 no performance counters. */
27089 env->CP0_IntCtl = 0xe0000000;
27093 for (i = 0; i < 7; i++) {
27094 env->CP0_WatchLo[i] = 0;
27095 env->CP0_WatchHi[i] = 0x80000000;
27097 env->CP0_WatchLo[7] = 0;
27098 env->CP0_WatchHi[7] = 0;
27100 /* Count register increments in debug mode, EJTAG version 1 */
27101 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
27103 cpu_mips_store_count(env, 1);
27105 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
27108 /* Only TC0 on VPE 0 starts as active. */
27109 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
27110 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
27111 env->tcs[i].CP0_TCHalt = 1;
27113 env->active_tc.CP0_TCHalt = 1;
27116 if (cs->cpu_index == 0) {
27117 /* VPE0 starts up enabled. */
27118 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
27119 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
27121 /* TC0 starts up unhalted. */
27123 env->active_tc.CP0_TCHalt = 0;
27124 env->tcs[0].CP0_TCHalt = 0;
27125 /* With thread 0 active. */
27126 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
27127 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
27132 * Configure default legacy segmentation control. We use this regardless of
27133 * whether segmentation control is presented to the guest.
27135 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
27136 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
27137 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
27138 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
27139 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
27140 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
27142 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
27143 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
27144 (3 << CP0SC_C)) << 16;
27145 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
27146 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
27147 (1 << CP0SC_EU) | (2 << CP0SC_C);
27148 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
27149 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
27150 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
27151 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
27152 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
27154 if ((env->insn_flags & ISA_MIPS32R6) &&
27155 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
27156 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
27157 env->CP0_Status |= (1 << CP0St_FR);
27160 if (env->insn_flags & ISA_MIPS32R6) {
27162 env->CP0_PWSize = 0x40;
27168 env->CP0_PWField = 0x0C30C302;
27175 env->CP0_PWField = 0x02;
27178 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
27179 /* microMIPS on reset when Config3.ISA is 3 */
27180 env->hflags |= MIPS_HFLAG_M16;
27184 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
27188 compute_hflags(env);
27189 restore_fp_status(env);
27190 restore_pamask(env);
27191 cs->exception_index = EXCP_NONE;
27193 if (semihosting_get_argc()) {
27194 /* UHI interface can be used to obtain argc and argv */
27195 env->active_tc.gpr[4] = -1;
27199 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
27200 target_ulong *data)
27202 env->active_tc.PC = data[0];
27203 env->hflags &= ~MIPS_HFLAG_BMASK;
27204 env->hflags |= data[1];
27205 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
27206 case MIPS_HFLAG_BR:
27208 case MIPS_HFLAG_BC:
27209 case MIPS_HFLAG_BL:
27211 env->btarget = data[2];