2 * MIPS 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 (010.00 to 010.11) */
467 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
468 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
469 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
470 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
474 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
477 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
478 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
479 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
480 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
481 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
482 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
483 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
484 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
485 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
486 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
487 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
490 /* MIPS DSP REGIMM opcodes */
492 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
493 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
496 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
499 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
500 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
501 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
502 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
505 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
507 /* MIPS DSP Arithmetic Sub-class */
508 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
509 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
510 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
511 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
512 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
513 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
515 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
516 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
517 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
518 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
519 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
520 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
521 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
522 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
523 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
524 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
525 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
526 /* MIPS DSP Multiply Sub-class insns */
527 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
528 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
529 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
530 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
531 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
532 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
535 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
536 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
538 /* MIPS DSP Arithmetic Sub-class */
539 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
541 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
542 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
543 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
544 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
545 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
546 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
548 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
549 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
550 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
551 /* MIPS DSP Multiply Sub-class insns */
552 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
553 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
554 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
555 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
558 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
560 /* MIPS DSP Arithmetic Sub-class */
561 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
564 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
566 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
567 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
572 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
573 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
574 /* DSP Bit/Manipulation Sub-class */
575 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
576 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
577 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
578 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
579 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
582 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
584 /* MIPS DSP Arithmetic Sub-class */
585 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
592 /* DSP Compare-Pick Sub-class */
593 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
600 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
601 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
602 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
603 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
604 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
605 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
606 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
607 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
610 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
612 /* MIPS DSP GPR-Based Shift Sub-class */
613 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
627 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
628 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
629 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
630 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
631 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
632 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
633 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
634 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
637 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
639 /* MIPS DSP Multiply Sub-class insns */
640 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
646 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
649 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
652 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
654 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
655 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
656 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
657 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
658 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
659 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
660 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
661 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
664 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
666 /* DSP Bit/Manipulation Sub-class */
667 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
670 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
672 /* MIPS DSP Append Sub-class */
673 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
674 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
675 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
678 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
680 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
681 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
683 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
684 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
685 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
686 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
687 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
688 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
689 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
690 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
691 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
692 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
693 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
694 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
695 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
696 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
697 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
700 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
702 /* MIPS DSP Arithmetic Sub-class */
703 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
712 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
713 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
719 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
720 /* DSP Bit/Manipulation Sub-class */
721 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
722 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
723 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
724 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
725 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
726 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
729 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
731 /* MIPS DSP Multiply Sub-class insns */
732 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
733 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
734 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
735 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
736 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
737 /* MIPS DSP Arithmetic Sub-class */
738 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
739 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
740 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
741 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
742 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
743 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
744 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
745 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
746 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
747 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
748 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
749 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
750 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
751 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
752 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
753 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
754 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
755 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
756 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
757 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
758 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
761 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
763 /* DSP Compare-Pick Sub-class */
764 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
775 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
776 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
783 /* MIPS DSP Arithmetic Sub-class */
784 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
785 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
786 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
787 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
788 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
789 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
790 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
794 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
796 /* DSP Append Sub-class */
797 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
798 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
799 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
800 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
803 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
805 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
806 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
807 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
819 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
820 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
821 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
822 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
823 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
824 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
825 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
826 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
829 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
831 /* DSP Bit/Manipulation Sub-class */
832 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
835 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
837 /* MIPS DSP Multiply Sub-class insns */
838 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
856 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
857 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
858 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
859 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
860 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
861 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
862 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
863 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
866 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
868 /* MIPS DSP GPR-Based Shift Sub-class */
869 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
887 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
888 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
889 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
890 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
891 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
892 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
893 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
894 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
897 /* Coprocessor 0 (rs field) */
898 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
901 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
902 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
903 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
904 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
905 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
906 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
907 OPC_MFTR = (0x08 << 21) | OPC_CP0,
908 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
909 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
910 OPC_MTTR = (0x0C << 21) | OPC_CP0,
911 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
912 OPC_C0 = (0x10 << 21) | OPC_CP0,
913 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
914 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
915 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
916 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
917 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
918 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
919 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
920 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
921 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
922 OPC_C0_A = (0x1A << 21) | OPC_CP0,
923 OPC_C0_B = (0x1B << 21) | OPC_CP0,
924 OPC_C0_C = (0x1C << 21) | OPC_CP0,
925 OPC_C0_D = (0x1D << 21) | OPC_CP0,
926 OPC_C0_E = (0x1E << 21) | OPC_CP0,
927 OPC_C0_F = (0x1F << 21) | OPC_CP0,
931 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
934 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
935 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
936 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
937 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
938 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
939 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
940 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
941 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
944 /* Coprocessor 0 (with rs == C0) */
945 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
948 OPC_TLBR = 0x01 | OPC_C0,
949 OPC_TLBWI = 0x02 | OPC_C0,
950 OPC_TLBINV = 0x03 | OPC_C0,
951 OPC_TLBINVF = 0x04 | OPC_C0,
952 OPC_TLBWR = 0x06 | OPC_C0,
953 OPC_TLBP = 0x08 | OPC_C0,
954 OPC_RFE = 0x10 | OPC_C0,
955 OPC_ERET = 0x18 | OPC_C0,
956 OPC_DERET = 0x1F | OPC_C0,
957 OPC_WAIT = 0x20 | OPC_C0,
960 /* Coprocessor 1 (rs field) */
961 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
963 /* Values for the fmt field in FP instructions */
965 /* 0 - 15 are reserved */
966 FMT_S = 16, /* single fp */
967 FMT_D = 17, /* double fp */
968 FMT_E = 18, /* extended fp */
969 FMT_Q = 19, /* quad fp */
970 FMT_W = 20, /* 32-bit fixed */
971 FMT_L = 21, /* 64-bit fixed */
972 FMT_PS = 22, /* paired single fp */
973 /* 23 - 31 are reserved */
977 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
978 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
979 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
980 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
981 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
982 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
983 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
984 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
985 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
986 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
987 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
988 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
989 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
990 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
991 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
992 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
993 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
994 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
995 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
996 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
997 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
998 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
999 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
1000 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
1001 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
1002 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
1003 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
1004 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
1005 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
1006 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
1009 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1010 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1013 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1014 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1015 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1016 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1020 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1021 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1025 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1026 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1029 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1032 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1033 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1034 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1035 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1036 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1037 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1038 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1039 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1040 OPC_BC2 = (0x08 << 21) | OPC_CP2,
1041 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1042 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1045 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1048 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1049 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1050 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1051 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1052 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1053 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1054 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1055 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1057 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1058 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1059 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1060 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1061 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1062 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1063 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1064 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1066 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1067 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1068 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1069 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1070 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1071 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1072 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1073 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1075 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1076 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1077 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1078 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1079 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1080 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1081 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1082 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1084 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1085 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1086 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1087 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1088 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1089 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1091 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1092 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1093 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1094 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1095 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1096 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1098 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1099 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1100 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1101 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1102 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1103 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1105 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1106 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1107 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1108 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1109 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1110 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1112 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1113 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1114 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1115 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1116 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1117 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1119 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1120 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1121 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1122 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1123 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1124 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1126 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1127 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1128 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1129 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1130 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1131 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1133 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1134 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1135 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1136 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1137 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1138 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1142 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1145 OPC_LWXC1 = 0x00 | OPC_CP3,
1146 OPC_LDXC1 = 0x01 | OPC_CP3,
1147 OPC_LUXC1 = 0x05 | OPC_CP3,
1148 OPC_SWXC1 = 0x08 | OPC_CP3,
1149 OPC_SDXC1 = 0x09 | OPC_CP3,
1150 OPC_SUXC1 = 0x0D | OPC_CP3,
1151 OPC_PREFX = 0x0F | OPC_CP3,
1152 OPC_ALNV_PS = 0x1E | OPC_CP3,
1153 OPC_MADD_S = 0x20 | OPC_CP3,
1154 OPC_MADD_D = 0x21 | OPC_CP3,
1155 OPC_MADD_PS = 0x26 | OPC_CP3,
1156 OPC_MSUB_S = 0x28 | OPC_CP3,
1157 OPC_MSUB_D = 0x29 | OPC_CP3,
1158 OPC_MSUB_PS = 0x2E | OPC_CP3,
1159 OPC_NMADD_S = 0x30 | OPC_CP3,
1160 OPC_NMADD_D = 0x31 | OPC_CP3,
1161 OPC_NMADD_PS= 0x36 | OPC_CP3,
1162 OPC_NMSUB_S = 0x38 | OPC_CP3,
1163 OPC_NMSUB_D = 0x39 | OPC_CP3,
1164 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1168 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1170 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1171 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1172 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1173 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1174 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1175 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1176 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1177 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1178 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1179 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1180 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1181 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1182 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1183 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1184 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1185 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1186 OPC_MSA_ELM = 0x19 | OPC_MSA,
1187 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1188 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1189 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1190 OPC_MSA_VEC = 0x1E | OPC_MSA,
1192 /* MI10 instruction */
1193 OPC_LD_B = (0x20) | OPC_MSA,
1194 OPC_LD_H = (0x21) | OPC_MSA,
1195 OPC_LD_W = (0x22) | OPC_MSA,
1196 OPC_LD_D = (0x23) | OPC_MSA,
1197 OPC_ST_B = (0x24) | OPC_MSA,
1198 OPC_ST_H = (0x25) | OPC_MSA,
1199 OPC_ST_W = (0x26) | OPC_MSA,
1200 OPC_ST_D = (0x27) | OPC_MSA,
1204 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1205 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1206 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1207 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1208 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1209 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1210 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1211 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1212 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1213 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1214 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1215 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1216 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1218 /* I8 instruction */
1219 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1220 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1221 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1222 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1223 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1224 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1225 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1226 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1227 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1228 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1230 /* VEC/2R/2RF instruction */
1231 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1232 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1233 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1234 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1235 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1236 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1237 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1239 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1240 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1242 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1243 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1244 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1245 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1246 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1248 /* 2RF instruction df(bit 16) = _w, _d */
1249 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1250 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1251 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1252 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1253 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1254 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1255 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1256 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1257 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1258 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1259 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1260 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1261 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1262 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1263 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1264 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1266 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1267 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1268 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1269 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1270 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1271 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1272 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1273 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1274 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1275 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1276 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1277 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1278 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1279 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1280 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1281 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1282 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1283 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1284 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1285 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1286 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1287 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1288 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1289 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1290 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1291 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1292 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1293 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1294 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1295 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1296 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1297 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1298 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1299 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1300 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1301 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1302 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1303 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1304 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1305 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1306 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1307 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1308 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1309 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1310 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1311 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1312 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1313 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1314 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1315 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1316 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1317 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1318 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1319 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1320 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1321 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1322 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1323 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1324 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1325 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1326 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1327 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1328 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1329 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1331 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1332 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1334 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1335 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1336 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1337 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1338 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1339 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1342 /* 3RF instruction _df(bit 21) = _w, _d */
1343 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1345 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1346 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1347 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1348 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1349 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1350 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1351 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1352 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1353 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1356 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1357 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1358 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1359 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1361 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1362 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1363 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1364 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1365 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1366 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1367 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1368 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1369 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1370 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1372 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1373 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1374 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1375 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1376 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1377 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1378 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1379 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1380 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1381 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1382 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1383 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1385 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1386 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1387 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1388 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1389 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1390 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1391 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1392 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1393 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1394 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1395 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1396 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1397 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1402 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1403 * ============================================
1405 * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
1406 * instructions set. It is designed to fit the needs of signal, graphical and
1407 * video processing applications. MXU instruction set is used in Xburst family
1408 * of microprocessors by Ingenic.
1410 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1411 * the control register.
1413 * The notation used in MXU assembler mnemonics:
1415 * XRa, XRb, XRc, XRd - MXU registers
1416 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1417 * s12 - a subfield of an instruction code
1418 * strd2 - a subfield of an instruction code
1419 * eptn2 - a subfield of an instruction code
1420 * eptn3 - a subfield of an instruction code
1421 * optn2 - a subfield of an instruction code
1422 * optn3 - a subfield of an instruction code
1423 * sft4 - a subfield of an instruction code
1425 * Load/Store instructions Multiplication instructions
1426 * ----------------------- ---------------------------
1428 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1429 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1430 * S32LDDV XRa, Rb, rc, strd2 S32SUB XRa, XRd, Rs, Rt
1431 * S32STDV XRa, Rb, rc, strd2 S32SUBU XRa, XRd, Rs, Rt
1432 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1433 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1434 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1435 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1436 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1437 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1438 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1439 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1440 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1441 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1442 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1443 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1444 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1445 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1446 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1447 * S16SDI XRa, Rb, s10, eptn2
1448 * S8LDD XRa, Rb, s8, eptn3
1449 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1450 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1451 * S8SDI XRa, Rb, s8, eptn3
1452 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1453 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1454 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1455 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1456 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1457 * S32CPS XRa, XRb, XRc
1458 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1459 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1460 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1461 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1462 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1463 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1464 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1465 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1466 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1467 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1468 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1469 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1470 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1471 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1472 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1473 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1474 * Q8SLT XRa, XRb, XRc
1475 * Q8SLTU XRa, XRb, XRc
1476 * Q8MOVZ XRa, XRb, XRc Shift instructions
1477 * Q8MOVN XRa, XRb, XRc ------------------
1479 * D32SLL XRa, XRb, XRc, XRd, sft4
1480 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1481 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1482 * D32SARL XRa, XRb, XRc, sft4
1483 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1484 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1485 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1486 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1487 * Q16SLL XRa, XRb, XRc, XRd, sft4
1488 * Q16SLR XRa, XRb, XRc, XRd, sft4
1489 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1490 * ------------------------- Q16SLLV XRa, XRb, Rb
1491 * Q16SLRV XRa, XRb, Rb
1492 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1493 * S32ALN XRa, XRb, XRc, Rb
1494 * S32ALNI XRa, XRb, XRc, s3
1495 * S32LUI XRa, s8, optn3 Move instructions
1496 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1497 * S32EXTRV XRa, XRb, Rs, Rt
1498 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1499 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1505 * ┌─ 000000 ─ OPC_MXU_S32MADD
1506 * ├─ 000001 ─ OPC_MXU_S32MADDU
1507 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1510 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1511 * │ ├─ 001 ─ OPC_MXU_S32MIN
1512 * │ ├─ 010 ─ OPC_MXU_D16MAX
1513 * │ ├─ 011 ─ OPC_MXU_D16MIN
1514 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1515 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1516 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1517 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1518 * ├─ 000100 ─ OPC_MXU_S32MSUB
1519 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1520 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1521 * │ ├─ 001 ─ OPC_MXU_D16SLT
1522 * │ ├─ 010 ─ OPC_MXU_D16AVG
1523 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1524 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1525 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1526 * │ └─ 111 ─ OPC_MXU_Q8ADD
1529 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1530 * │ ├─ 010 ─ OPC_MXU_D16CPS
1531 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1532 * │ └─ 110 ─ OPC_MXU_Q16SAT
1533 * ├─ 001000 ─ OPC_MXU_D16MUL
1535 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1536 * │ └─ 01 ─ OPC_MXU_D16MULE
1537 * ├─ 001010 ─ OPC_MXU_D16MAC
1538 * ├─ 001011 ─ OPC_MXU_D16MACF
1539 * ├─ 001100 ─ OPC_MXU_D16MADL
1540 * ├─ 001101 ─ OPC_MXU_S16MAD
1541 * ├─ 001110 ─ OPC_MXU_Q16ADD
1542 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1543 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1544 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1547 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1548 * │ └─ 1 ─ OPC_MXU_S32STDR
1551 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1552 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1555 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1556 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1559 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1560 * │ └─ 1 ─ OPC_MXU_S32LDIR
1563 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1564 * │ └─ 1 ─ OPC_MXU_S32SDIR
1567 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1568 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1571 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1572 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1573 * ├─ 011000 ─ OPC_MXU_D32ADD
1575 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1576 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1577 * │ └─ 10 ─ OPC_MXU_D32ASUM
1578 * ├─ 011010 ─ <not assigned>
1580 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1581 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1582 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1585 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1586 * │ ├─ 01 ─ OPC_MXU_D8SUM
1587 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1588 * ├─ 011110 ─ <not assigned>
1589 * ├─ 011111 ─ <not assigned>
1590 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1591 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1592 * ├─ 100010 ─ OPC_MXU_S8LDD
1593 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1594 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1595 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1596 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1597 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1600 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1601 * │ ├─ 001 ─ OPC_MXU_S32ALN
1602 * ├─ 101000 ─ OPC_MXU_LXB ├─ 010 ─ OPC_MXU_S32ALNI
1603 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_S32NOR
1604 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_S32AND
1605 * ├─ 101011 ─ OPC_MXU_S16STD ├─ 101 ─ OPC_MXU_S32OR
1606 * ├─ 101100 ─ OPC_MXU_S16LDI ├─ 110 ─ OPC_MXU_S32XOR
1607 * ├─ 101101 ─ OPC_MXU_S16SDI └─ 111 ─ OPC_MXU_S32LUI
1608 * ├─ 101110 ─ OPC_MXU_S32M2I
1609 * ├─ 101111 ─ OPC_MXU_S32I2M
1610 * ├─ 110000 ─ OPC_MXU_D32SLL
1611 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1612 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1613 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1614 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1615 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1616 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1617 * ├─ 110110 ─ OPC_MXU__POOL17 ─┴─ 101 ─ OPC_MXU_Q16SARV
1619 * ├─ 110111 ─ OPC_MXU_Q16SAR
1621 * ├─ 111000 ─ OPC_MXU__POOL18 ─┬─ 00 ─ OPC_MXU_Q8MUL
1622 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1625 * ├─ 111001 ─ OPC_MXU__POOL19 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1626 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1627 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1628 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1629 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1630 * │ └─ 101 ─ OPC_MXU_S32MOV
1633 * ├─ 111010 ─ OPC_MXU__POOL20 ─┬─ 00 ─ OPC_MXU_Q8MAC
1634 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1635 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1636 * ├─ 111100 ─ OPC_MXU_Q8MADL
1637 * ├─ 111101 ─ OPC_MXU_S32SFL
1638 * ├─ 111110 ─ OPC_MXU_Q8SAD
1639 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1644 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1645 * Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1649 OPC_MXU_S32MADD = 0x00,
1650 OPC_MXU_S32MADDU = 0x01,
1651 OPC__MXU_MUL = 0x02,
1652 OPC_MXU__POOL00 = 0x03,
1653 OPC_MXU_S32MSUB = 0x04,
1654 OPC_MXU_S32MSUBU = 0x05,
1655 OPC_MXU__POOL01 = 0x06,
1656 OPC_MXU__POOL02 = 0x07,
1657 OPC_MXU_D16MUL = 0x08,
1658 OPC_MXU__POOL03 = 0x09,
1659 OPC_MXU_D16MAC = 0x0A,
1660 OPC_MXU_D16MACF = 0x0B,
1661 OPC_MXU_D16MADL = 0x0C,
1662 OPC_MXU_S16MAD = 0x0D,
1663 OPC_MXU_Q16ADD = 0x0E,
1664 OPC_MXU_D16MACE = 0x0F,
1665 OPC_MXU__POOL04 = 0x10,
1666 OPC_MXU__POOL05 = 0x11,
1667 OPC_MXU__POOL06 = 0x12,
1668 OPC_MXU__POOL07 = 0x13,
1669 OPC_MXU__POOL08 = 0x14,
1670 OPC_MXU__POOL09 = 0x15,
1671 OPC_MXU__POOL10 = 0x16,
1672 OPC_MXU__POOL11 = 0x17,
1673 OPC_MXU_D32ADD = 0x18,
1674 OPC_MXU__POOL12 = 0x19,
1675 /* not assigned 0x1A */
1676 OPC_MXU__POOL13 = 0x1B,
1677 OPC_MXU__POOL14 = 0x1C,
1678 OPC_MXU_Q8ACCE = 0x1D,
1679 /* not assigned 0x1E */
1680 /* not assigned 0x1F */
1681 /* not assigned 0x20 */
1682 /* not assigned 0x21 */
1683 OPC_MXU_S8LDD = 0x22,
1684 OPC_MXU_S8STD = 0x23,
1685 OPC_MXU_S8LDI = 0x24,
1686 OPC_MXU_S8SDI = 0x25,
1687 OPC_MXU__POOL15 = 0x26,
1688 OPC_MXU__POOL16 = 0x27,
1690 /* not assigned 0x29 */
1691 OPC_MXU_S16LDD = 0x2A,
1692 OPC_MXU_S16STD = 0x2B,
1693 OPC_MXU_S16LDI = 0x2C,
1694 OPC_MXU_S16SDI = 0x2D,
1695 OPC_MXU_S32M2I = 0x2E,
1696 OPC_MXU_S32I2M = 0x2F,
1697 OPC_MXU_D32SLL = 0x30,
1698 OPC_MXU_D32SLR = 0x31,
1699 OPC_MXU_D32SARL = 0x32,
1700 OPC_MXU_D32SAR = 0x33,
1701 OPC_MXU_Q16SLL = 0x34,
1702 OPC_MXU_Q16SLR = 0x35,
1703 OPC_MXU__POOL17 = 0x36,
1704 OPC_MXU_Q16SAR = 0x37,
1705 OPC_MXU__POOL18 = 0x38,
1706 OPC_MXU__POOL19 = 0x39,
1707 OPC_MXU__POOL20 = 0x3A,
1708 OPC_MXU_Q16SCOP = 0x3B,
1709 OPC_MXU_Q8MADL = 0x3C,
1710 OPC_MXU_S32SFL = 0x3D,
1711 OPC_MXU_Q8SAD = 0x3E,
1712 /* not assigned 0x3F */
1720 OPC_MXU_S32MAX = 0x00,
1721 OPC_MXU_S32MIN = 0x01,
1722 OPC_MXU_D16MAX = 0x02,
1723 OPC_MXU_D16MIN = 0x03,
1724 OPC_MXU_Q8MAX = 0x04,
1725 OPC_MXU_Q8MIN = 0x05,
1726 OPC_MXU_Q8SLT = 0x06,
1727 OPC_MXU_Q8SLTU = 0x07,
1734 OPC_MXU_S32SLT = 0x00,
1735 OPC_MXU_D16SLT = 0x01,
1736 OPC_MXU_D16AVG = 0x02,
1737 OPC_MXU_D16AVGR = 0x03,
1738 OPC_MXU_Q8AVG = 0x04,
1739 OPC_MXU_Q8AVGR = 0x05,
1740 OPC_MXU_Q8ADD = 0x07,
1747 OPC_MXU_S32CPS = 0x00,
1748 OPC_MXU_D16CPS = 0x02,
1749 OPC_MXU_Q8ABD = 0x04,
1750 OPC_MXU_Q16SAT = 0x06,
1757 OPC_MXU_D16MULF = 0x00,
1758 OPC_MXU_D16MULE = 0x01,
1765 OPC_MXU_S32LDD = 0x00,
1766 OPC_MXU_S32LDDR = 0x01,
1773 OPC_MXU_S32STD = 0x00,
1774 OPC_MXU_S32STDR = 0x01,
1781 OPC_MXU_S32LDDV = 0x00,
1782 OPC_MXU_S32LDDVR = 0x01,
1789 OPC_MXU_S32STDV = 0x00,
1790 OPC_MXU_S32STDVR = 0x01,
1797 OPC_MXU_S32LDI = 0x00,
1798 OPC_MXU_S32LDIR = 0x01,
1805 OPC_MXU_S32SDI = 0x00,
1806 OPC_MXU_S32SDIR = 0x01,
1813 OPC_MXU_S32LDIV = 0x00,
1814 OPC_MXU_S32LDIVR = 0x01,
1821 OPC_MXU_S32SDIV = 0x00,
1822 OPC_MXU_S32SDIVR = 0x01,
1829 OPC_MXU_D32ACC = 0x00,
1830 OPC_MXU_D32ACCM = 0x01,
1831 OPC_MXU_D32ASUM = 0x02,
1838 OPC_MXU_Q16ACC = 0x00,
1839 OPC_MXU_Q16ACCM = 0x01,
1840 OPC_MXU_Q16ASUM = 0x02,
1847 OPC_MXU_Q8ADDE = 0x00,
1848 OPC_MXU_D8SUM = 0x01,
1849 OPC_MXU_D8SUMC = 0x02,
1856 OPC_MXU_S32MUL = 0x00,
1857 OPC_MXU_S32MULU = 0x01,
1858 OPC_MXU_S32EXTR = 0x02,
1859 OPC_MXU_S32EXTRV = 0x03,
1866 OPC_MXU_D32SARW = 0x00,
1867 OPC_MXU_S32ALN = 0x01,
1868 OPC_MXU_S32ALNI = 0x02,
1869 OPC_MXU_S32NOR = 0x03,
1870 OPC_MXU_S32AND = 0x04,
1871 OPC_MXU_S32OR = 0x05,
1872 OPC_MXU_S32XOR = 0x06,
1873 OPC_MXU_S32LUI = 0x07,
1880 OPC_MXU_D32SLLV = 0x00,
1881 OPC_MXU_D32SLRV = 0x01,
1882 OPC_MXU_D32SARV = 0x03,
1883 OPC_MXU_Q16SLLV = 0x04,
1884 OPC_MXU_Q16SLRV = 0x05,
1885 OPC_MXU_Q16SARV = 0x07,
1892 OPC_MXU_Q8MUL = 0x00,
1893 OPC_MXU_Q8MULSU = 0x01,
1900 OPC_MXU_Q8MOVZ = 0x00,
1901 OPC_MXU_Q8MOVN = 0x01,
1902 OPC_MXU_D16MOVZ = 0x02,
1903 OPC_MXU_D16MOVN = 0x03,
1904 OPC_MXU_S32MOVZ = 0x04,
1905 OPC_MXU_S32MOVN = 0x05,
1912 OPC_MXU_Q8MAC = 0x00,
1913 OPC_MXU_Q8MACSU = 0x01,
1917 * Overview of the TX79-specific instruction set
1918 * =============================================
1920 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1921 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1922 * instructions and certain multimedia instructions (MMIs). These MMIs
1923 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1924 * or sixteen 8-bit paths.
1928 * The Toshiba TX System RISC TX79 Core Architecture manual,
1929 * https://wiki.qemu.org/File:C790.pdf
1931 * Three-Operand Multiply and Multiply-Add (4 instructions)
1932 * --------------------------------------------------------
1933 * MADD [rd,] rs, rt Multiply/Add
1934 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1935 * MULT [rd,] rs, rt Multiply (3-operand)
1936 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1938 * Multiply Instructions for Pipeline 1 (10 instructions)
1939 * ------------------------------------------------------
1940 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1941 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1942 * DIV1 rs, rt Divide Pipeline 1
1943 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1944 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1945 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1946 * MFHI1 rd Move From HI1 Register
1947 * MFLO1 rd Move From LO1 Register
1948 * MTHI1 rs Move To HI1 Register
1949 * MTLO1 rs Move To LO1 Register
1951 * Arithmetic (19 instructions)
1952 * ----------------------------
1953 * PADDB rd, rs, rt Parallel Add Byte
1954 * PSUBB rd, rs, rt Parallel Subtract Byte
1955 * PADDH rd, rs, rt Parallel Add Halfword
1956 * PSUBH rd, rs, rt Parallel Subtract Halfword
1957 * PADDW rd, rs, rt Parallel Add Word
1958 * PSUBW rd, rs, rt Parallel Subtract Word
1959 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1960 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1961 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1962 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1963 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1964 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1965 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1966 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1967 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1968 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1969 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1970 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1971 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1973 * Min/Max (4 instructions)
1974 * ------------------------
1975 * PMAXH rd, rs, rt Parallel Maximum Halfword
1976 * PMINH rd, rs, rt Parallel Minimum Halfword
1977 * PMAXW rd, rs, rt Parallel Maximum Word
1978 * PMINW rd, rs, rt Parallel Minimum Word
1980 * Absolute (2 instructions)
1981 * -------------------------
1982 * PABSH rd, rt Parallel Absolute Halfword
1983 * PABSW rd, rt Parallel Absolute Word
1985 * Logical (4 instructions)
1986 * ------------------------
1987 * PAND rd, rs, rt Parallel AND
1988 * POR rd, rs, rt Parallel OR
1989 * PXOR rd, rs, rt Parallel XOR
1990 * PNOR rd, rs, rt Parallel NOR
1992 * Shift (9 instructions)
1993 * ----------------------
1994 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
1995 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
1996 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
1997 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
1998 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
1999 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2000 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2001 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2002 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2004 * Compare (6 instructions)
2005 * ------------------------
2006 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2007 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2008 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2009 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2010 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2011 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2013 * LZC (1 instruction)
2014 * -------------------
2015 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2017 * Quadword Load and Store (2 instructions)
2018 * ----------------------------------------
2019 * LQ rt, offset(base) Load Quadword
2020 * SQ rt, offset(base) Store Quadword
2022 * Multiply and Divide (19 instructions)
2023 * -------------------------------------
2024 * PMULTW rd, rs, rt Parallel Multiply Word
2025 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2026 * PDIVW rs, rt Parallel Divide Word
2027 * PDIVUW rs, rt Parallel Divide Unsigned Word
2028 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2029 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2030 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2031 * PMULTH rd, rs, rt Parallel Multiply Halfword
2032 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2033 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2034 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2035 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2036 * PDIVBW rs, rt Parallel Divide Broadcast Word
2037 * PMFHI rd Parallel Move From HI Register
2038 * PMFLO rd Parallel Move From LO Register
2039 * PMTHI rs Parallel Move To HI Register
2040 * PMTLO rs Parallel Move To LO Register
2041 * PMFHL rd Parallel Move From HI/LO Register
2042 * PMTHL rs Parallel Move To HI/LO Register
2044 * Pack/Extend (11 instructions)
2045 * -----------------------------
2046 * PPAC5 rd, rt Parallel Pack to 5 bits
2047 * PPACB rd, rs, rt Parallel Pack to Byte
2048 * PPACH rd, rs, rt Parallel Pack to Halfword
2049 * PPACW rd, rs, rt Parallel Pack to Word
2050 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2051 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2052 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2053 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2054 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2055 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2056 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2058 * Others (16 instructions)
2059 * ------------------------
2060 * PCPYH rd, rt Parallel Copy Halfword
2061 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2062 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2063 * PREVH rd, rt Parallel Reverse Halfword
2064 * PINTH rd, rs, rt Parallel Interleave Halfword
2065 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2066 * PEXEH rd, rt Parallel Exchange Even Halfword
2067 * PEXCH rd, rt Parallel Exchange Center Halfword
2068 * PEXEW rd, rt Parallel Exchange Even Word
2069 * PEXCW rd, rt Parallel Exchange Center Word
2070 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2071 * MFSA rd Move from Shift Amount Register
2072 * MTSA rs Move to Shift Amount Register
2073 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2074 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2075 * PROT3W rd, rt Parallel Rotate 3 Words
2077 * The TX79-specific Multimedia Instruction encodings
2078 * ==================================================
2080 * TX79 Multimedia Instruction encoding table keys:
2082 * * This code is reserved for future use. An attempt to execute it
2083 * causes a Reserved Instruction exception.
2084 * % This code indicates an instruction class. The instruction word
2085 * must be further decoded by examining additional tables that show
2086 * the values for other instruction fields.
2087 * # This code is reserved for the unsupported instructions DMULT,
2088 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2089 * to execute it causes a Reserved Instruction exception.
2091 * TX79 Multimedia Instructions encoded by opcode field (MMI, LQ, SQ):
2094 * +--------+----------------------------------------+
2096 * +--------+----------------------------------------+
2098 * opcode bits 28..26
2099 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2100 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2101 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2102 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2103 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2104 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2105 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2106 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2107 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2108 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2109 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2113 TX79_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2114 TX79_LQ = 0x1E << 26, /* Same as OPC_MSA */
2115 TX79_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
2119 * TX79 Multimedia Instructions with opcode field = MMI:
2122 * +--------+-------------------------------+--------+
2123 * | MMI | |function|
2124 * +--------+-------------------------------+--------+
2126 * function bits 2..0
2127 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2128 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2129 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2130 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2131 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2132 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2133 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2134 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2135 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2136 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2137 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2140 #define MASK_TX79_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2142 TX79_MMI_MADD = 0x00 | TX79_CLASS_MMI, /* Same as OPC_MADD */
2143 TX79_MMI_MADDU = 0x01 | TX79_CLASS_MMI, /* Same as OPC_MADDU */
2144 TX79_MMI_PLZCW = 0x04 | TX79_CLASS_MMI,
2145 TX79_MMI_CLASS_MMI0 = 0x08 | TX79_CLASS_MMI,
2146 TX79_MMI_CLASS_MMI2 = 0x09 | TX79_CLASS_MMI,
2147 TX79_MMI_MFHI1 = 0x10 | TX79_CLASS_MMI, /* Same minor as OPC_MFHI */
2148 TX79_MMI_MTHI1 = 0x11 | TX79_CLASS_MMI, /* Same minor as OPC_MTHI */
2149 TX79_MMI_MFLO1 = 0x12 | TX79_CLASS_MMI, /* Same minor as OPC_MFLO */
2150 TX79_MMI_MTLO1 = 0x13 | TX79_CLASS_MMI, /* Same minor as OPC_MTLO */
2151 TX79_MMI_MULT1 = 0x18 | TX79_CLASS_MMI, /* Same minor as OPC_MULT */
2152 TX79_MMI_MULTU1 = 0x19 | TX79_CLASS_MMI, /* Same minor as OPC_MULTU */
2153 TX79_MMI_DIV1 = 0x1A | TX79_CLASS_MMI, /* Same minor as OPC_DIV */
2154 TX79_MMI_DIVU1 = 0x1B | TX79_CLASS_MMI, /* Same minor as OPC_DIVU */
2155 TX79_MMI_MADD1 = 0x20 | TX79_CLASS_MMI,
2156 TX79_MMI_MADDU1 = 0x21 | TX79_CLASS_MMI,
2157 TX79_MMI_CLASS_MMI1 = 0x28 | TX79_CLASS_MMI,
2158 TX79_MMI_CLASS_MMI3 = 0x29 | TX79_CLASS_MMI,
2159 TX79_MMI_PMFHL = 0x30 | TX79_CLASS_MMI,
2160 TX79_MMI_PMTHL = 0x31 | TX79_CLASS_MMI,
2161 TX79_MMI_PSLLH = 0x34 | TX79_CLASS_MMI,
2162 TX79_MMI_PSRLH = 0x36 | TX79_CLASS_MMI,
2163 TX79_MMI_PSRAH = 0x37 | TX79_CLASS_MMI,
2164 TX79_MMI_PSLLW = 0x3C | TX79_CLASS_MMI,
2165 TX79_MMI_PSRLW = 0x3E | TX79_CLASS_MMI,
2166 TX79_MMI_PSRAW = 0x3F | TX79_CLASS_MMI,
2170 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI0:
2173 * +--------+----------------------+--------+--------+
2174 * | MMI | |function| MMI0 |
2175 * +--------+----------------------+--------+--------+
2177 * function bits 7..6
2178 * bits | 0 | 1 | 2 | 3
2179 * 10..8 | 00 | 01 | 10 | 11
2180 * -------+-------+-------+-------+-------
2181 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2182 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2183 * 2 010 | PADDB | PSUBB | PCGTB | *
2184 * 3 011 | * | * | * | *
2185 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2186 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2187 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2188 * 7 111 | * | * | PEXT5 | PPAC5
2191 #define MASK_TX79_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2193 TX79_MMI0_PADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI0,
2194 TX79_MMI0_PSUBW = (0x01 << 6) | TX79_MMI_CLASS_MMI0,
2195 TX79_MMI0_PCGTW = (0x02 << 6) | TX79_MMI_CLASS_MMI0,
2196 TX79_MMI0_PMAXW = (0x03 << 6) | TX79_MMI_CLASS_MMI0,
2197 TX79_MMI0_PADDH = (0x04 << 6) | TX79_MMI_CLASS_MMI0,
2198 TX79_MMI0_PSUBH = (0x05 << 6) | TX79_MMI_CLASS_MMI0,
2199 TX79_MMI0_PCGTH = (0x06 << 6) | TX79_MMI_CLASS_MMI0,
2200 TX79_MMI0_PMAXH = (0x07 << 6) | TX79_MMI_CLASS_MMI0,
2201 TX79_MMI0_PADDB = (0x08 << 6) | TX79_MMI_CLASS_MMI0,
2202 TX79_MMI0_PSUBB = (0x09 << 6) | TX79_MMI_CLASS_MMI0,
2203 TX79_MMI0_PCGTB = (0x0A << 6) | TX79_MMI_CLASS_MMI0,
2204 TX79_MMI0_PADDSW = (0x10 << 6) | TX79_MMI_CLASS_MMI0,
2205 TX79_MMI0_PSUBSW = (0x11 << 6) | TX79_MMI_CLASS_MMI0,
2206 TX79_MMI0_PEXTLW = (0x12 << 6) | TX79_MMI_CLASS_MMI0,
2207 TX79_MMI0_PPACW = (0x13 << 6) | TX79_MMI_CLASS_MMI0,
2208 TX79_MMI0_PADDSH = (0x14 << 6) | TX79_MMI_CLASS_MMI0,
2209 TX79_MMI0_PSUBSH = (0x15 << 6) | TX79_MMI_CLASS_MMI0,
2210 TX79_MMI0_PEXTLH = (0x16 << 6) | TX79_MMI_CLASS_MMI0,
2211 TX79_MMI0_PPACH = (0x17 << 6) | TX79_MMI_CLASS_MMI0,
2212 TX79_MMI0_PADDSB = (0x18 << 6) | TX79_MMI_CLASS_MMI0,
2213 TX79_MMI0_PSUBSB = (0x19 << 6) | TX79_MMI_CLASS_MMI0,
2214 TX79_MMI0_PEXTLB = (0x1A << 6) | TX79_MMI_CLASS_MMI0,
2215 TX79_MMI0_PPACB = (0x1B << 6) | TX79_MMI_CLASS_MMI0,
2216 TX79_MMI0_PEXT5 = (0x1E << 6) | TX79_MMI_CLASS_MMI0,
2217 TX79_MMI0_PPAC5 = (0x1F << 6) | TX79_MMI_CLASS_MMI0,
2221 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI1:
2224 * +--------+----------------------+--------+--------+
2225 * | MMI | |function| MMI1 |
2226 * +--------+----------------------+--------+--------+
2228 * function bits 7..6
2229 * bits | 0 | 1 | 2 | 3
2230 * 10..8 | 00 | 01 | 10 | 11
2231 * -------+-------+-------+-------+-------
2232 * 0 000 | * | PABSW | PCEQW | PMINW
2233 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2234 * 2 010 | * | * | PCEQB | *
2235 * 3 011 | * | * | * | *
2236 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2237 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2238 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2239 * 7 111 | * | * | * | *
2242 #define MASK_TX79_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2244 TX79_MMI1_PABSW = (0x01 << 6) | TX79_MMI_CLASS_MMI1,
2245 TX79_MMI1_PCEQW = (0x02 << 6) | TX79_MMI_CLASS_MMI1,
2246 TX79_MMI1_PMINW = (0x03 << 6) | TX79_MMI_CLASS_MMI1,
2247 TX79_MMI1_PADSBH = (0x04 << 6) | TX79_MMI_CLASS_MMI1,
2248 TX79_MMI1_PABSH = (0x05 << 6) | TX79_MMI_CLASS_MMI1,
2249 TX79_MMI1_PCEQH = (0x06 << 6) | TX79_MMI_CLASS_MMI1,
2250 TX79_MMI1_PMINH = (0x07 << 6) | TX79_MMI_CLASS_MMI1,
2251 TX79_MMI1_PCEQB = (0x0A << 6) | TX79_MMI_CLASS_MMI1,
2252 TX79_MMI1_PADDUW = (0x10 << 6) | TX79_MMI_CLASS_MMI1,
2253 TX79_MMI1_PSUBUW = (0x11 << 6) | TX79_MMI_CLASS_MMI1,
2254 TX79_MMI1_PEXTUW = (0x12 << 6) | TX79_MMI_CLASS_MMI1,
2255 TX79_MMI1_PADDUH = (0x14 << 6) | TX79_MMI_CLASS_MMI1,
2256 TX79_MMI1_PSUBUH = (0x15 << 6) | TX79_MMI_CLASS_MMI1,
2257 TX79_MMI1_PEXTUH = (0x16 << 6) | TX79_MMI_CLASS_MMI1,
2258 TX79_MMI1_PADDUB = (0x18 << 6) | TX79_MMI_CLASS_MMI1,
2259 TX79_MMI1_PSUBUB = (0x19 << 6) | TX79_MMI_CLASS_MMI1,
2260 TX79_MMI1_PEXTUB = (0x1A << 6) | TX79_MMI_CLASS_MMI1,
2261 TX79_MMI1_QFSRV = (0x1B << 6) | TX79_MMI_CLASS_MMI1,
2265 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI2:
2268 * +--------+----------------------+--------+--------+
2269 * | MMI | |function| MMI2 |
2270 * +--------+----------------------+--------+--------+
2272 * function bits 7..6
2273 * bits | 0 | 1 | 2 | 3
2274 * 10..8 | 00 | 01 | 10 | 11
2275 * -------+-------+-------+-------+-------
2276 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2277 * 1 001 | PMSUBW| * | * | *
2278 * 2 010 | PMFHI | PMFLO | PINTH | *
2279 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2280 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2281 * 5 101 | PMSUBH| PHMSBH| * | *
2282 * 6 110 | * | * | PEXEH | PREVH
2283 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2286 #define MASK_TX79_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2288 TX79_MMI2_PMADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI2,
2289 TX79_MMI2_PSLLVW = (0x02 << 6) | TX79_MMI_CLASS_MMI2,
2290 TX79_MMI2_PSRLVW = (0x03 << 6) | TX79_MMI_CLASS_MMI2,
2291 TX79_MMI2_PMSUBW = (0x04 << 6) | TX79_MMI_CLASS_MMI2,
2292 TX79_MMI2_PMFHI = (0x08 << 6) | TX79_MMI_CLASS_MMI2,
2293 TX79_MMI2_PMFLO = (0x09 << 6) | TX79_MMI_CLASS_MMI2,
2294 TX79_MMI2_PINTH = (0x0A << 6) | TX79_MMI_CLASS_MMI2,
2295 TX79_MMI2_PMULTW = (0x0C << 6) | TX79_MMI_CLASS_MMI2,
2296 TX79_MMI2_PDIVW = (0x0D << 6) | TX79_MMI_CLASS_MMI2,
2297 TX79_MMI2_PCPYLD = (0x0E << 6) | TX79_MMI_CLASS_MMI2,
2298 TX79_MMI2_PMADDH = (0x10 << 6) | TX79_MMI_CLASS_MMI2,
2299 TX79_MMI2_PHMADH = (0x11 << 6) | TX79_MMI_CLASS_MMI2,
2300 TX79_MMI2_PAND = (0x12 << 6) | TX79_MMI_CLASS_MMI2,
2301 TX79_MMI2_PXOR = (0x13 << 6) | TX79_MMI_CLASS_MMI2,
2302 TX79_MMI2_PMSUBH = (0x14 << 6) | TX79_MMI_CLASS_MMI2,
2303 TX79_MMI2_PHMSBH = (0x15 << 6) | TX79_MMI_CLASS_MMI2,
2304 TX79_MMI2_PEXEH = (0x1A << 6) | TX79_MMI_CLASS_MMI2,
2305 TX79_MMI2_PREVH = (0x1B << 6) | TX79_MMI_CLASS_MMI2,
2306 TX79_MMI2_PMULTH = (0x1C << 6) | TX79_MMI_CLASS_MMI2,
2307 TX79_MMI2_PDIVBW = (0x1D << 6) | TX79_MMI_CLASS_MMI2,
2308 TX79_MMI2_PEXEW = (0x1E << 6) | TX79_MMI_CLASS_MMI2,
2309 TX79_MMI2_PROT3W = (0x1F << 6) | TX79_MMI_CLASS_MMI2,
2313 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI3:
2316 * +--------+----------------------+--------+--------+
2317 * | MMI | |function| MMI3 |
2318 * +--------+----------------------+--------+--------+
2320 * function bits 7..6
2321 * bits | 0 | 1 | 2 | 3
2322 * 10..8 | 00 | 01 | 10 | 11
2323 * -------+-------+-------+-------+-------
2324 * 0 000 |PMADDUW| * | * | PSRAVW
2325 * 1 001 | * | * | * | *
2326 * 2 010 | PMTHI | PMTLO | PINTEH| *
2327 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2328 * 4 100 | * | * | POR | PNOR
2329 * 5 101 | * | * | * | *
2330 * 6 110 | * | * | PEXCH | PCPYH
2331 * 7 111 | * | * | PEXCW | *
2334 #define MASK_TX79_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2336 TX79_MMI3_PMADDUW = (0x00 << 6) | TX79_MMI_CLASS_MMI3,
2337 TX79_MMI3_PSRAVW = (0x03 << 6) | TX79_MMI_CLASS_MMI3,
2338 TX79_MMI3_PMTHI = (0x08 << 6) | TX79_MMI_CLASS_MMI3,
2339 TX79_MMI3_PMTLO = (0x09 << 6) | TX79_MMI_CLASS_MMI3,
2340 TX79_MMI3_PINTEH = (0x0A << 6) | TX79_MMI_CLASS_MMI3,
2341 TX79_MMI3_PMULTUW = (0x0C << 6) | TX79_MMI_CLASS_MMI3,
2342 TX79_MMI3_PDIVUW = (0x0D << 6) | TX79_MMI_CLASS_MMI3,
2343 TX79_MMI3_PCPYUD = (0x0E << 6) | TX79_MMI_CLASS_MMI3,
2344 TX79_MMI3_POR = (0x12 << 6) | TX79_MMI_CLASS_MMI3,
2345 TX79_MMI3_PNOR = (0x13 << 6) | TX79_MMI_CLASS_MMI3,
2346 TX79_MMI3_PEXCH = (0x1A << 6) | TX79_MMI_CLASS_MMI3,
2347 TX79_MMI3_PCPYH = (0x1B << 6) | TX79_MMI_CLASS_MMI3,
2348 TX79_MMI3_PEXCW = (0x1E << 6) | TX79_MMI_CLASS_MMI3,
2351 /* global register indices */
2352 static TCGv cpu_gpr[32], cpu_PC;
2353 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2354 static TCGv cpu_dspctrl, btarget, bcond;
2355 static TCGv_i32 hflags;
2356 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2357 static TCGv_i64 fpu_f64[32];
2358 static TCGv_i64 msa_wr_d[64];
2361 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2364 #include "exec/gen-icount.h"
2366 #define gen_helper_0e0i(name, arg) do { \
2367 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2368 gen_helper_##name(cpu_env, helper_tmp); \
2369 tcg_temp_free_i32(helper_tmp); \
2372 #define gen_helper_0e1i(name, arg1, arg2) do { \
2373 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2374 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2375 tcg_temp_free_i32(helper_tmp); \
2378 #define gen_helper_1e0i(name, ret, arg1) do { \
2379 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2380 gen_helper_##name(ret, cpu_env, helper_tmp); \
2381 tcg_temp_free_i32(helper_tmp); \
2384 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2385 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2386 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2387 tcg_temp_free_i32(helper_tmp); \
2390 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2391 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2392 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2393 tcg_temp_free_i32(helper_tmp); \
2396 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2397 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2398 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2399 tcg_temp_free_i32(helper_tmp); \
2402 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2403 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2404 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2405 tcg_temp_free_i32(helper_tmp); \
2408 typedef struct DisasContext {
2409 DisasContextBase base;
2410 target_ulong saved_pc;
2411 target_ulong page_start;
2413 uint64_t insn_flags;
2414 int32_t CP0_Config1;
2415 int32_t CP0_Config2;
2416 int32_t CP0_Config3;
2417 int32_t CP0_Config5;
2418 /* Routine used to access memory */
2420 TCGMemOp default_tcg_memop_mask;
2421 uint32_t hflags, saved_hflags;
2422 target_ulong btarget;
2433 int CP0_LLAddr_shift;
2442 #define DISAS_STOP DISAS_TARGET_0
2443 #define DISAS_EXIT DISAS_TARGET_1
2445 static const char * const regnames[] = {
2446 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2447 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2448 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2449 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2452 static const char * const regnames_HI[] = {
2453 "HI0", "HI1", "HI2", "HI3",
2456 static const char * const regnames_LO[] = {
2457 "LO0", "LO1", "LO2", "LO3",
2460 static const char * const fregnames[] = {
2461 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2462 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2463 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2464 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2467 static const char * const msaregnames[] = {
2468 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2469 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2470 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2471 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2472 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2473 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2474 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2475 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2476 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2477 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2478 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2479 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2480 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2481 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2482 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2483 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2486 static const char * const mxuregnames[] = {
2487 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2488 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2491 #define LOG_DISAS(...) \
2493 if (MIPS_DEBUG_DISAS) { \
2494 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2498 #define MIPS_INVAL(op) \
2500 if (MIPS_DEBUG_DISAS) { \
2501 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2502 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2503 ctx->base.pc_next, ctx->opcode, op, \
2504 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2505 ((ctx->opcode >> 16) & 0x1F)); \
2509 /* General purpose registers moves. */
2510 static inline void gen_load_gpr (TCGv t, int reg)
2513 tcg_gen_movi_tl(t, 0);
2515 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2518 static inline void gen_store_gpr (TCGv t, int reg)
2521 tcg_gen_mov_tl(cpu_gpr[reg], t);
2524 /* Moves to/from shadow registers. */
2525 static inline void gen_load_srsgpr (int from, int to)
2527 TCGv t0 = tcg_temp_new();
2530 tcg_gen_movi_tl(t0, 0);
2532 TCGv_i32 t2 = tcg_temp_new_i32();
2533 TCGv_ptr addr = tcg_temp_new_ptr();
2535 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2536 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2537 tcg_gen_andi_i32(t2, t2, 0xf);
2538 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2539 tcg_gen_ext_i32_ptr(addr, t2);
2540 tcg_gen_add_ptr(addr, cpu_env, addr);
2542 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2543 tcg_temp_free_ptr(addr);
2544 tcg_temp_free_i32(t2);
2546 gen_store_gpr(t0, to);
2550 static inline void gen_store_srsgpr (int from, int to)
2553 TCGv t0 = tcg_temp_new();
2554 TCGv_i32 t2 = tcg_temp_new_i32();
2555 TCGv_ptr addr = tcg_temp_new_ptr();
2557 gen_load_gpr(t0, from);
2558 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2559 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2560 tcg_gen_andi_i32(t2, t2, 0xf);
2561 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2562 tcg_gen_ext_i32_ptr(addr, t2);
2563 tcg_gen_add_ptr(addr, cpu_env, addr);
2565 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2566 tcg_temp_free_ptr(addr);
2567 tcg_temp_free_i32(t2);
2572 /* MXU General purpose registers moves. */
2573 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2576 tcg_gen_movi_tl(t, 0);
2577 } else if (reg <= 15) {
2578 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2582 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2584 if (reg > 0 && reg <= 15) {
2585 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2589 /* MXU control register moves. */
2590 static inline void gen_load_mxu_cr(TCGv t)
2592 tcg_gen_mov_tl(t, mxu_CR);
2595 static inline void gen_store_mxu_cr(TCGv t)
2597 /* TODO: Add handling of RW rules for MXU_CR. */
2598 tcg_gen_mov_tl(mxu_CR, t);
2603 static inline void gen_save_pc(target_ulong pc)
2605 tcg_gen_movi_tl(cpu_PC, pc);
2608 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2610 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2611 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2612 gen_save_pc(ctx->base.pc_next);
2613 ctx->saved_pc = ctx->base.pc_next;
2615 if (ctx->hflags != ctx->saved_hflags) {
2616 tcg_gen_movi_i32(hflags, ctx->hflags);
2617 ctx->saved_hflags = ctx->hflags;
2618 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2624 tcg_gen_movi_tl(btarget, ctx->btarget);
2630 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2632 ctx->saved_hflags = ctx->hflags;
2633 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2639 ctx->btarget = env->btarget;
2644 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2646 TCGv_i32 texcp = tcg_const_i32(excp);
2647 TCGv_i32 terr = tcg_const_i32(err);
2648 save_cpu_state(ctx, 1);
2649 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2650 tcg_temp_free_i32(terr);
2651 tcg_temp_free_i32(texcp);
2652 ctx->base.is_jmp = DISAS_NORETURN;
2655 static inline void generate_exception(DisasContext *ctx, int excp)
2657 gen_helper_0e0i(raise_exception, excp);
2660 static inline void generate_exception_end(DisasContext *ctx, int excp)
2662 generate_exception_err(ctx, excp, 0);
2665 /* Floating point register moves. */
2666 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2668 if (ctx->hflags & MIPS_HFLAG_FRE) {
2669 generate_exception(ctx, EXCP_RI);
2671 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2674 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2677 if (ctx->hflags & MIPS_HFLAG_FRE) {
2678 generate_exception(ctx, EXCP_RI);
2680 t64 = tcg_temp_new_i64();
2681 tcg_gen_extu_i32_i64(t64, t);
2682 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2683 tcg_temp_free_i64(t64);
2686 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2688 if (ctx->hflags & MIPS_HFLAG_F64) {
2689 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2691 gen_load_fpr32(ctx, t, reg | 1);
2695 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2697 if (ctx->hflags & MIPS_HFLAG_F64) {
2698 TCGv_i64 t64 = tcg_temp_new_i64();
2699 tcg_gen_extu_i32_i64(t64, t);
2700 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2701 tcg_temp_free_i64(t64);
2703 gen_store_fpr32(ctx, t, reg | 1);
2707 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2709 if (ctx->hflags & MIPS_HFLAG_F64) {
2710 tcg_gen_mov_i64(t, fpu_f64[reg]);
2712 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2716 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2718 if (ctx->hflags & MIPS_HFLAG_F64) {
2719 tcg_gen_mov_i64(fpu_f64[reg], t);
2722 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2723 t0 = tcg_temp_new_i64();
2724 tcg_gen_shri_i64(t0, t, 32);
2725 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2726 tcg_temp_free_i64(t0);
2730 static inline int get_fp_bit (int cc)
2738 /* Addresses computation */
2739 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2741 tcg_gen_add_tl(ret, arg0, arg1);
2743 #if defined(TARGET_MIPS64)
2744 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2745 tcg_gen_ext32s_i64(ret, ret);
2750 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2753 tcg_gen_addi_tl(ret, base, ofs);
2755 #if defined(TARGET_MIPS64)
2756 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2757 tcg_gen_ext32s_i64(ret, ret);
2762 /* Addresses computation (translation time) */
2763 static target_long addr_add(DisasContext *ctx, target_long base,
2766 target_long sum = base + offset;
2768 #if defined(TARGET_MIPS64)
2769 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2776 /* Sign-extract the low 32-bits to a target_long. */
2777 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2779 #if defined(TARGET_MIPS64)
2780 tcg_gen_ext32s_i64(ret, arg);
2782 tcg_gen_extrl_i64_i32(ret, arg);
2786 /* Sign-extract the high 32-bits to a target_long. */
2787 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2789 #if defined(TARGET_MIPS64)
2790 tcg_gen_sari_i64(ret, arg, 32);
2792 tcg_gen_extrh_i64_i32(ret, arg);
2796 static inline void check_cp0_enabled(DisasContext *ctx)
2798 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2799 generate_exception_err(ctx, EXCP_CpU, 0);
2802 static inline void check_cp1_enabled(DisasContext *ctx)
2804 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2805 generate_exception_err(ctx, EXCP_CpU, 1);
2808 /* Verify that the processor is running with COP1X instructions enabled.
2809 This is associated with the nabla symbol in the MIPS32 and MIPS64
2812 static inline void check_cop1x(DisasContext *ctx)
2814 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2815 generate_exception_end(ctx, EXCP_RI);
2818 /* Verify that the processor is running with 64-bit floating-point
2819 operations enabled. */
2821 static inline void check_cp1_64bitmode(DisasContext *ctx)
2823 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2824 generate_exception_end(ctx, EXCP_RI);
2828 * Verify if floating point register is valid; an operation is not defined
2829 * if bit 0 of any register specification is set and the FR bit in the
2830 * Status register equals zero, since the register numbers specify an
2831 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2832 * in the Status register equals one, both even and odd register numbers
2833 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2835 * Multiple 64 bit wide registers can be checked by calling
2836 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2838 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2840 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2841 generate_exception_end(ctx, EXCP_RI);
2844 /* Verify that the processor is running with DSP instructions enabled.
2845 This is enabled by CP0 Status register MX(24) bit.
2848 static inline void check_dsp(DisasContext *ctx)
2850 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2851 if (ctx->insn_flags & ASE_DSP) {
2852 generate_exception_end(ctx, EXCP_DSPDIS);
2854 generate_exception_end(ctx, EXCP_RI);
2859 static inline void check_dsp_r2(DisasContext *ctx)
2861 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2862 if (ctx->insn_flags & ASE_DSP) {
2863 generate_exception_end(ctx, EXCP_DSPDIS);
2865 generate_exception_end(ctx, EXCP_RI);
2870 static inline void check_dsp_r3(DisasContext *ctx)
2872 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2873 if (ctx->insn_flags & ASE_DSP) {
2874 generate_exception_end(ctx, EXCP_DSPDIS);
2876 generate_exception_end(ctx, EXCP_RI);
2881 /* This code generates a "reserved instruction" exception if the
2882 CPU does not support the instruction set corresponding to flags. */
2883 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2885 if (unlikely(!(ctx->insn_flags & flags))) {
2886 generate_exception_end(ctx, EXCP_RI);
2890 /* This code generates a "reserved instruction" exception if the
2891 CPU has corresponding flag set which indicates that the instruction
2892 has been removed. */
2893 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2895 if (unlikely(ctx->insn_flags & flags)) {
2896 generate_exception_end(ctx, EXCP_RI);
2901 * The Linux kernel traps certain reserved instruction exceptions to
2902 * emulate the corresponding instructions. QEMU is the kernel in user
2903 * mode, so those traps are emulated by accepting the instructions.
2905 * A reserved instruction exception is generated for flagged CPUs if
2906 * QEMU runs in system mode.
2908 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
2910 #ifndef CONFIG_USER_ONLY
2911 check_insn_opc_removed(ctx, flags);
2915 /* This code generates a "reserved instruction" exception if the
2916 CPU does not support 64-bit paired-single (PS) floating point data type */
2917 static inline void check_ps(DisasContext *ctx)
2919 if (unlikely(!ctx->ps)) {
2920 generate_exception(ctx, EXCP_RI);
2922 check_cp1_64bitmode(ctx);
2925 #ifdef TARGET_MIPS64
2926 /* This code generates a "reserved instruction" exception if 64-bit
2927 instructions are not enabled. */
2928 static inline void check_mips_64(DisasContext *ctx)
2930 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
2931 generate_exception_end(ctx, EXCP_RI);
2935 #ifndef CONFIG_USER_ONLY
2936 static inline void check_mvh(DisasContext *ctx)
2938 if (unlikely(!ctx->mvh)) {
2939 generate_exception(ctx, EXCP_RI);
2945 * This code generates a "reserved instruction" exception if the
2946 * Config5 XNP bit is set.
2948 static inline void check_xnp(DisasContext *ctx)
2950 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2951 generate_exception_end(ctx, EXCP_RI);
2955 #ifndef CONFIG_USER_ONLY
2957 * This code generates a "reserved instruction" exception if the
2958 * Config3 PW bit is NOT set.
2960 static inline void check_pw(DisasContext *ctx)
2962 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
2963 generate_exception_end(ctx, EXCP_RI);
2969 * This code generates a "reserved instruction" exception if the
2970 * Config3 MT bit is NOT set.
2972 static inline void check_mt(DisasContext *ctx)
2974 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2975 generate_exception_end(ctx, EXCP_RI);
2979 #ifndef CONFIG_USER_ONLY
2981 * This code generates a "coprocessor unusable" exception if CP0 is not
2982 * available, and, if that is not the case, generates a "reserved instruction"
2983 * exception if the Config5 MT bit is NOT set. This is needed for availability
2984 * control of some of MT ASE instructions.
2986 static inline void check_cp0_mt(DisasContext *ctx)
2988 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2989 generate_exception_err(ctx, EXCP_CpU, 0);
2991 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2992 generate_exception_err(ctx, EXCP_RI, 0);
2999 * This code generates a "reserved instruction" exception if the
3000 * Config5 NMS bit is set.
3002 static inline void check_nms(DisasContext *ctx)
3004 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3005 generate_exception_end(ctx, EXCP_RI);
3010 * This code generates a "reserved instruction" exception if the
3011 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3012 * Config2 TL, and Config5 L2C are unset.
3014 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3016 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3017 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3018 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3019 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3020 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3021 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3023 generate_exception_end(ctx, EXCP_RI);
3028 * This code generates a "reserved instruction" exception if the
3029 * Config5 EVA bit is NOT set.
3031 static inline void check_eva(DisasContext *ctx)
3033 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3034 generate_exception_end(ctx, EXCP_RI);
3039 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3040 calling interface for 32 and 64-bit FPRs. No sense in changing
3041 all callers for gen_load_fpr32 when we need the CTX parameter for
3043 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3044 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3045 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3046 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3047 int ft, int fs, int cc) \
3049 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3050 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3059 check_cp1_registers(ctx, fs | ft); \
3067 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3068 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3070 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3071 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3072 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3073 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3074 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3075 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3076 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3077 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3078 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3079 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3080 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3081 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3082 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3083 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3084 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3085 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
3088 tcg_temp_free_i##bits (fp0); \
3089 tcg_temp_free_i##bits (fp1); \
3092 FOP_CONDS(, 0, d, FMT_D, 64)
3093 FOP_CONDS(abs, 1, d, FMT_D, 64)
3094 FOP_CONDS(, 0, s, FMT_S, 32)
3095 FOP_CONDS(abs, 1, s, FMT_S, 32)
3096 FOP_CONDS(, 0, ps, FMT_PS, 64)
3097 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3100 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3101 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3102 int ft, int fs, int fd) \
3104 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3105 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3106 if (ifmt == FMT_D) { \
3107 check_cp1_registers(ctx, fs | ft | fd); \
3109 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3110 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3113 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3116 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3119 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3122 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3125 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3128 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3131 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3134 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3137 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3140 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3143 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3146 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3149 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3152 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3155 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3158 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3161 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3164 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3167 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3170 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3173 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3176 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3182 tcg_temp_free_i ## bits (fp0); \
3183 tcg_temp_free_i ## bits (fp1); \
3186 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3187 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3189 #undef gen_ldcmp_fpr32
3190 #undef gen_ldcmp_fpr64
3192 /* load/store instructions. */
3193 #ifdef CONFIG_USER_ONLY
3194 #define OP_LD_ATOMIC(insn,fname) \
3195 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3196 DisasContext *ctx) \
3198 TCGv t0 = tcg_temp_new(); \
3199 tcg_gen_mov_tl(t0, arg1); \
3200 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3201 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3202 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3203 tcg_temp_free(t0); \
3206 #define OP_LD_ATOMIC(insn,fname) \
3207 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3208 DisasContext *ctx) \
3210 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3213 OP_LD_ATOMIC(ll,ld32s);
3214 #if defined(TARGET_MIPS64)
3215 OP_LD_ATOMIC(lld,ld64);
3219 #ifdef CONFIG_USER_ONLY
3220 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
3221 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3222 DisasContext *ctx) \
3224 TCGv t0 = tcg_temp_new(); \
3225 TCGLabel *l1 = gen_new_label(); \
3226 TCGLabel *l2 = gen_new_label(); \
3228 tcg_gen_andi_tl(t0, arg2, almask); \
3229 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
3230 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
3231 generate_exception(ctx, EXCP_AdES); \
3232 gen_set_label(l1); \
3233 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3234 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
3235 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
3236 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
3237 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
3238 generate_exception_end(ctx, EXCP_SC); \
3239 gen_set_label(l2); \
3240 tcg_gen_movi_tl(t0, 0); \
3241 gen_store_gpr(t0, rt); \
3242 tcg_temp_free(t0); \
3245 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
3246 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3247 DisasContext *ctx) \
3249 TCGv t0 = tcg_temp_new(); \
3250 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
3251 gen_store_gpr(t0, rt); \
3252 tcg_temp_free(t0); \
3255 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
3256 #if defined(TARGET_MIPS64)
3257 OP_ST_ATOMIC(scd,st64,ld64,0x7);
3261 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3262 int base, int offset)
3265 tcg_gen_movi_tl(addr, offset);
3266 } else if (offset == 0) {
3267 gen_load_gpr(addr, base);
3269 tcg_gen_movi_tl(addr, offset);
3270 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3274 static target_ulong pc_relative_pc (DisasContext *ctx)
3276 target_ulong pc = ctx->base.pc_next;
3278 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3279 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3284 pc &= ~(target_ulong)3;
3289 static void gen_ld(DisasContext *ctx, uint32_t opc,
3290 int rt, int base, int offset)
3293 int mem_idx = ctx->mem_idx;
3295 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3296 /* Loongson CPU uses a load to zero register for prefetch.
3297 We emulate it as a NOP. On other CPU we must perform the
3298 actual memory access. */
3302 t0 = tcg_temp_new();
3303 gen_base_offset_addr(ctx, t0, base, offset);
3306 #if defined(TARGET_MIPS64)
3308 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3309 ctx->default_tcg_memop_mask);
3310 gen_store_gpr(t0, rt);
3313 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3314 ctx->default_tcg_memop_mask);
3315 gen_store_gpr(t0, rt);
3319 op_ld_lld(t0, t0, mem_idx, ctx);
3320 gen_store_gpr(t0, rt);
3323 t1 = tcg_temp_new();
3324 /* Do a byte access to possibly trigger a page
3325 fault with the unaligned address. */
3326 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3327 tcg_gen_andi_tl(t1, t0, 7);
3328 #ifndef TARGET_WORDS_BIGENDIAN
3329 tcg_gen_xori_tl(t1, t1, 7);
3331 tcg_gen_shli_tl(t1, t1, 3);
3332 tcg_gen_andi_tl(t0, t0, ~7);
3333 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3334 tcg_gen_shl_tl(t0, t0, t1);
3335 t2 = tcg_const_tl(-1);
3336 tcg_gen_shl_tl(t2, t2, t1);
3337 gen_load_gpr(t1, rt);
3338 tcg_gen_andc_tl(t1, t1, t2);
3340 tcg_gen_or_tl(t0, t0, t1);
3342 gen_store_gpr(t0, rt);
3345 t1 = tcg_temp_new();
3346 /* Do a byte access to possibly trigger a page
3347 fault with the unaligned address. */
3348 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3349 tcg_gen_andi_tl(t1, t0, 7);
3350 #ifdef TARGET_WORDS_BIGENDIAN
3351 tcg_gen_xori_tl(t1, t1, 7);
3353 tcg_gen_shli_tl(t1, t1, 3);
3354 tcg_gen_andi_tl(t0, t0, ~7);
3355 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3356 tcg_gen_shr_tl(t0, t0, t1);
3357 tcg_gen_xori_tl(t1, t1, 63);
3358 t2 = tcg_const_tl(0xfffffffffffffffeull);
3359 tcg_gen_shl_tl(t2, t2, t1);
3360 gen_load_gpr(t1, rt);
3361 tcg_gen_and_tl(t1, t1, t2);
3363 tcg_gen_or_tl(t0, t0, t1);
3365 gen_store_gpr(t0, rt);
3368 t1 = tcg_const_tl(pc_relative_pc(ctx));
3369 gen_op_addr_add(ctx, t0, t0, t1);
3371 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3372 gen_store_gpr(t0, rt);
3376 t1 = tcg_const_tl(pc_relative_pc(ctx));
3377 gen_op_addr_add(ctx, t0, t0, t1);
3379 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3380 gen_store_gpr(t0, rt);
3383 mem_idx = MIPS_HFLAG_UM;
3386 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3387 ctx->default_tcg_memop_mask);
3388 gen_store_gpr(t0, rt);
3391 mem_idx = MIPS_HFLAG_UM;
3394 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3395 ctx->default_tcg_memop_mask);
3396 gen_store_gpr(t0, rt);
3399 mem_idx = MIPS_HFLAG_UM;
3402 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3403 ctx->default_tcg_memop_mask);
3404 gen_store_gpr(t0, rt);
3407 mem_idx = MIPS_HFLAG_UM;
3410 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3411 gen_store_gpr(t0, rt);
3414 mem_idx = MIPS_HFLAG_UM;
3417 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3418 gen_store_gpr(t0, rt);
3421 mem_idx = MIPS_HFLAG_UM;
3424 t1 = tcg_temp_new();
3425 /* Do a byte access to possibly trigger a page
3426 fault with the unaligned address. */
3427 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3428 tcg_gen_andi_tl(t1, t0, 3);
3429 #ifndef TARGET_WORDS_BIGENDIAN
3430 tcg_gen_xori_tl(t1, t1, 3);
3432 tcg_gen_shli_tl(t1, t1, 3);
3433 tcg_gen_andi_tl(t0, t0, ~3);
3434 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3435 tcg_gen_shl_tl(t0, t0, t1);
3436 t2 = tcg_const_tl(-1);
3437 tcg_gen_shl_tl(t2, t2, t1);
3438 gen_load_gpr(t1, rt);
3439 tcg_gen_andc_tl(t1, t1, t2);
3441 tcg_gen_or_tl(t0, t0, t1);
3443 tcg_gen_ext32s_tl(t0, t0);
3444 gen_store_gpr(t0, rt);
3447 mem_idx = MIPS_HFLAG_UM;
3450 t1 = tcg_temp_new();
3451 /* Do a byte access to possibly trigger a page
3452 fault with the unaligned address. */
3453 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3454 tcg_gen_andi_tl(t1, t0, 3);
3455 #ifdef TARGET_WORDS_BIGENDIAN
3456 tcg_gen_xori_tl(t1, t1, 3);
3458 tcg_gen_shli_tl(t1, t1, 3);
3459 tcg_gen_andi_tl(t0, t0, ~3);
3460 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3461 tcg_gen_shr_tl(t0, t0, t1);
3462 tcg_gen_xori_tl(t1, t1, 31);
3463 t2 = tcg_const_tl(0xfffffffeull);
3464 tcg_gen_shl_tl(t2, t2, t1);
3465 gen_load_gpr(t1, rt);
3466 tcg_gen_and_tl(t1, t1, t2);
3468 tcg_gen_or_tl(t0, t0, t1);
3470 tcg_gen_ext32s_tl(t0, t0);
3471 gen_store_gpr(t0, rt);
3474 mem_idx = MIPS_HFLAG_UM;
3478 op_ld_ll(t0, t0, mem_idx, ctx);
3479 gen_store_gpr(t0, rt);
3485 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3486 uint32_t reg1, uint32_t reg2)
3488 TCGv taddr = tcg_temp_new();
3489 TCGv_i64 tval = tcg_temp_new_i64();
3490 TCGv tmp1 = tcg_temp_new();
3491 TCGv tmp2 = tcg_temp_new();
3493 gen_base_offset_addr(ctx, taddr, base, offset);
3494 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3495 #ifdef TARGET_WORDS_BIGENDIAN
3496 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3498 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3500 gen_store_gpr(tmp1, reg1);
3501 tcg_temp_free(tmp1);
3502 gen_store_gpr(tmp2, reg2);
3503 tcg_temp_free(tmp2);
3504 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3505 tcg_temp_free_i64(tval);
3506 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3507 tcg_temp_free(taddr);
3511 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3512 int base, int offset)
3514 TCGv t0 = tcg_temp_new();
3515 TCGv t1 = tcg_temp_new();
3516 int mem_idx = ctx->mem_idx;
3518 gen_base_offset_addr(ctx, t0, base, offset);
3519 gen_load_gpr(t1, rt);
3521 #if defined(TARGET_MIPS64)
3523 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3524 ctx->default_tcg_memop_mask);
3527 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3530 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3534 mem_idx = MIPS_HFLAG_UM;
3537 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3538 ctx->default_tcg_memop_mask);
3541 mem_idx = MIPS_HFLAG_UM;
3544 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3545 ctx->default_tcg_memop_mask);
3548 mem_idx = MIPS_HFLAG_UM;
3551 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3554 mem_idx = MIPS_HFLAG_UM;
3557 gen_helper_0e2i(swl, t1, t0, mem_idx);
3560 mem_idx = MIPS_HFLAG_UM;
3563 gen_helper_0e2i(swr, t1, t0, mem_idx);
3571 /* Store conditional */
3572 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3573 int base, int16_t offset)
3576 int mem_idx = ctx->mem_idx;
3578 #ifdef CONFIG_USER_ONLY
3579 t0 = tcg_temp_local_new();
3580 t1 = tcg_temp_local_new();
3582 t0 = tcg_temp_new();
3583 t1 = tcg_temp_new();
3585 gen_base_offset_addr(ctx, t0, base, offset);
3586 gen_load_gpr(t1, rt);
3588 #if defined(TARGET_MIPS64)
3591 op_st_scd(t1, t0, rt, mem_idx, ctx);
3595 mem_idx = MIPS_HFLAG_UM;
3599 op_st_sc(t1, t0, rt, mem_idx, ctx);
3606 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3607 uint32_t reg1, uint32_t reg2)
3609 TCGv taddr = tcg_temp_local_new();
3610 TCGv lladdr = tcg_temp_local_new();
3611 TCGv_i64 tval = tcg_temp_new_i64();
3612 TCGv_i64 llval = tcg_temp_new_i64();
3613 TCGv_i64 val = tcg_temp_new_i64();
3614 TCGv tmp1 = tcg_temp_new();
3615 TCGv tmp2 = tcg_temp_new();
3616 TCGLabel *lab_fail = gen_new_label();
3617 TCGLabel *lab_done = gen_new_label();
3619 gen_base_offset_addr(ctx, taddr, base, offset);
3621 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3622 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3624 gen_load_gpr(tmp1, reg1);
3625 gen_load_gpr(tmp2, reg2);
3627 #ifdef TARGET_WORDS_BIGENDIAN
3628 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3630 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3633 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3634 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3635 ctx->mem_idx, MO_64);
3637 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3639 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3641 gen_set_label(lab_fail);
3644 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3646 gen_set_label(lab_done);
3647 tcg_gen_movi_tl(lladdr, -1);
3648 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3651 /* Load and store */
3652 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3655 /* Don't do NOP if destination is zero: we must perform the actual
3660 TCGv_i32 fp0 = tcg_temp_new_i32();
3661 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3662 ctx->default_tcg_memop_mask);
3663 gen_store_fpr32(ctx, fp0, ft);
3664 tcg_temp_free_i32(fp0);
3669 TCGv_i32 fp0 = tcg_temp_new_i32();
3670 gen_load_fpr32(ctx, fp0, ft);
3671 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3672 ctx->default_tcg_memop_mask);
3673 tcg_temp_free_i32(fp0);
3678 TCGv_i64 fp0 = tcg_temp_new_i64();
3679 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3680 ctx->default_tcg_memop_mask);
3681 gen_store_fpr64(ctx, fp0, ft);
3682 tcg_temp_free_i64(fp0);
3687 TCGv_i64 fp0 = tcg_temp_new_i64();
3688 gen_load_fpr64(ctx, fp0, ft);
3689 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3690 ctx->default_tcg_memop_mask);
3691 tcg_temp_free_i64(fp0);
3695 MIPS_INVAL("flt_ldst");
3696 generate_exception_end(ctx, EXCP_RI);
3701 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3702 int rs, int16_t imm)
3704 TCGv t0 = tcg_temp_new();
3706 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3707 check_cp1_enabled(ctx);
3711 check_insn(ctx, ISA_MIPS2);
3714 gen_base_offset_addr(ctx, t0, rs, imm);
3715 gen_flt_ldst(ctx, op, rt, t0);
3718 generate_exception_err(ctx, EXCP_CpU, 1);
3723 /* Arithmetic with immediate operand */
3724 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3725 int rt, int rs, int imm)
3727 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3729 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3730 /* If no destination, treat it as a NOP.
3731 For addi, we must generate the overflow exception when needed. */
3737 TCGv t0 = tcg_temp_local_new();
3738 TCGv t1 = tcg_temp_new();
3739 TCGv t2 = tcg_temp_new();
3740 TCGLabel *l1 = gen_new_label();
3742 gen_load_gpr(t1, rs);
3743 tcg_gen_addi_tl(t0, t1, uimm);
3744 tcg_gen_ext32s_tl(t0, t0);
3746 tcg_gen_xori_tl(t1, t1, ~uimm);
3747 tcg_gen_xori_tl(t2, t0, uimm);
3748 tcg_gen_and_tl(t1, t1, t2);
3750 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3752 /* operands of same sign, result different sign */
3753 generate_exception(ctx, EXCP_OVERFLOW);
3755 tcg_gen_ext32s_tl(t0, t0);
3756 gen_store_gpr(t0, rt);
3762 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3763 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3765 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3768 #if defined(TARGET_MIPS64)
3771 TCGv t0 = tcg_temp_local_new();
3772 TCGv t1 = tcg_temp_new();
3773 TCGv t2 = tcg_temp_new();
3774 TCGLabel *l1 = gen_new_label();
3776 gen_load_gpr(t1, rs);
3777 tcg_gen_addi_tl(t0, t1, uimm);
3779 tcg_gen_xori_tl(t1, t1, ~uimm);
3780 tcg_gen_xori_tl(t2, t0, uimm);
3781 tcg_gen_and_tl(t1, t1, t2);
3783 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3785 /* operands of same sign, result different sign */
3786 generate_exception(ctx, EXCP_OVERFLOW);
3788 gen_store_gpr(t0, rt);
3794 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3796 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3803 /* Logic with immediate operand */
3804 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3805 int rt, int rs, int16_t imm)
3810 /* If no destination, treat it as a NOP. */
3813 uimm = (uint16_t)imm;
3816 if (likely(rs != 0))
3817 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3819 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3823 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3825 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3828 if (likely(rs != 0))
3829 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3831 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3834 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3836 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3837 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3839 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3848 /* Set on less than with immediate operand */
3849 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3850 int rt, int rs, int16_t imm)
3852 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3856 /* If no destination, treat it as a NOP. */
3859 t0 = tcg_temp_new();
3860 gen_load_gpr(t0, rs);
3863 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3866 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3872 /* Shifts with immediate operand */
3873 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3874 int rt, int rs, int16_t imm)
3876 target_ulong uimm = ((uint16_t)imm) & 0x1f;
3880 /* If no destination, treat it as a NOP. */
3884 t0 = tcg_temp_new();
3885 gen_load_gpr(t0, rs);
3888 tcg_gen_shli_tl(t0, t0, uimm);
3889 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3892 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3896 tcg_gen_ext32u_tl(t0, t0);
3897 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3899 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3904 TCGv_i32 t1 = tcg_temp_new_i32();
3906 tcg_gen_trunc_tl_i32(t1, t0);
3907 tcg_gen_rotri_i32(t1, t1, uimm);
3908 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3909 tcg_temp_free_i32(t1);
3911 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3914 #if defined(TARGET_MIPS64)
3916 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3919 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3922 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3926 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3928 tcg_gen_mov_tl(cpu_gpr[rt], t0);
3932 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3935 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
3938 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
3941 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
3949 static void gen_arith(DisasContext *ctx, uint32_t opc,
3950 int rd, int rs, int rt)
3952 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3953 && opc != OPC_DADD && opc != OPC_DSUB) {
3954 /* If no destination, treat it as a NOP.
3955 For add & sub, we must generate the overflow exception when needed. */
3962 TCGv t0 = tcg_temp_local_new();
3963 TCGv t1 = tcg_temp_new();
3964 TCGv t2 = tcg_temp_new();
3965 TCGLabel *l1 = gen_new_label();
3967 gen_load_gpr(t1, rs);
3968 gen_load_gpr(t2, rt);
3969 tcg_gen_add_tl(t0, t1, t2);
3970 tcg_gen_ext32s_tl(t0, t0);
3971 tcg_gen_xor_tl(t1, t1, t2);
3972 tcg_gen_xor_tl(t2, t0, t2);
3973 tcg_gen_andc_tl(t1, t2, t1);
3975 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3977 /* operands of same sign, result different sign */
3978 generate_exception(ctx, EXCP_OVERFLOW);
3980 gen_store_gpr(t0, rd);
3985 if (rs != 0 && rt != 0) {
3986 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3987 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3988 } else if (rs == 0 && rt != 0) {
3989 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3990 } else if (rs != 0 && rt == 0) {
3991 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3993 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3998 TCGv t0 = tcg_temp_local_new();
3999 TCGv t1 = tcg_temp_new();
4000 TCGv t2 = tcg_temp_new();
4001 TCGLabel *l1 = gen_new_label();
4003 gen_load_gpr(t1, rs);
4004 gen_load_gpr(t2, rt);
4005 tcg_gen_sub_tl(t0, t1, t2);
4006 tcg_gen_ext32s_tl(t0, t0);
4007 tcg_gen_xor_tl(t2, t1, t2);
4008 tcg_gen_xor_tl(t1, t0, t1);
4009 tcg_gen_and_tl(t1, t1, t2);
4011 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4013 /* operands of different sign, first operand and result different sign */
4014 generate_exception(ctx, EXCP_OVERFLOW);
4016 gen_store_gpr(t0, rd);
4021 if (rs != 0 && rt != 0) {
4022 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4023 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4024 } else if (rs == 0 && rt != 0) {
4025 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4026 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
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);
4033 #if defined(TARGET_MIPS64)
4036 TCGv t0 = tcg_temp_local_new();
4037 TCGv t1 = tcg_temp_new();
4038 TCGv t2 = tcg_temp_new();
4039 TCGLabel *l1 = gen_new_label();
4041 gen_load_gpr(t1, rs);
4042 gen_load_gpr(t2, rt);
4043 tcg_gen_add_tl(t0, t1, t2);
4044 tcg_gen_xor_tl(t1, t1, t2);
4045 tcg_gen_xor_tl(t2, t0, t2);
4046 tcg_gen_andc_tl(t1, t2, t1);
4048 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4050 /* operands of same sign, result different sign */
4051 generate_exception(ctx, EXCP_OVERFLOW);
4053 gen_store_gpr(t0, rd);
4058 if (rs != 0 && rt != 0) {
4059 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4060 } else if (rs == 0 && rt != 0) {
4061 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4062 } else if (rs != 0 && rt == 0) {
4063 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4065 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4070 TCGv t0 = tcg_temp_local_new();
4071 TCGv t1 = tcg_temp_new();
4072 TCGv t2 = tcg_temp_new();
4073 TCGLabel *l1 = gen_new_label();
4075 gen_load_gpr(t1, rs);
4076 gen_load_gpr(t2, rt);
4077 tcg_gen_sub_tl(t0, t1, t2);
4078 tcg_gen_xor_tl(t2, t1, t2);
4079 tcg_gen_xor_tl(t1, t0, t1);
4080 tcg_gen_and_tl(t1, t1, t2);
4082 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4084 /* operands of different sign, first operand and result different sign */
4085 generate_exception(ctx, EXCP_OVERFLOW);
4087 gen_store_gpr(t0, rd);
4092 if (rs != 0 && rt != 0) {
4093 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4094 } else if (rs == 0 && rt != 0) {
4095 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4096 } else if (rs != 0 && rt == 0) {
4097 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4099 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4104 if (likely(rs != 0 && rt != 0)) {
4105 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4106 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4108 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4114 /* Conditional move */
4115 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4116 int rd, int rs, int rt)
4121 /* If no destination, treat it as a NOP. */
4125 t0 = tcg_temp_new();
4126 gen_load_gpr(t0, rt);
4127 t1 = tcg_const_tl(0);
4128 t2 = tcg_temp_new();
4129 gen_load_gpr(t2, rs);
4132 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4135 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4138 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4141 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4150 static void gen_logic(DisasContext *ctx, uint32_t opc,
4151 int rd, int rs, int rt)
4154 /* If no destination, treat it as a NOP. */
4160 if (likely(rs != 0 && rt != 0)) {
4161 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4163 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4167 if (rs != 0 && rt != 0) {
4168 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4169 } else if (rs == 0 && rt != 0) {
4170 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4171 } else if (rs != 0 && rt == 0) {
4172 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4174 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4178 if (likely(rs != 0 && rt != 0)) {
4179 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4180 } else if (rs == 0 && rt != 0) {
4181 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4182 } else if (rs != 0 && rt == 0) {
4183 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4185 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4189 if (likely(rs != 0 && rt != 0)) {
4190 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4191 } else if (rs == 0 && rt != 0) {
4192 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4193 } else if (rs != 0 && rt == 0) {
4194 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4196 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4202 /* Set on lower than */
4203 static void gen_slt(DisasContext *ctx, uint32_t opc,
4204 int rd, int rs, int rt)
4209 /* If no destination, treat it as a NOP. */
4213 t0 = tcg_temp_new();
4214 t1 = tcg_temp_new();
4215 gen_load_gpr(t0, rs);
4216 gen_load_gpr(t1, rt);
4219 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4222 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4230 static void gen_shift(DisasContext *ctx, uint32_t opc,
4231 int rd, int rs, int rt)
4236 /* If no destination, treat it as a NOP.
4237 For add & sub, we must generate the overflow exception when needed. */
4241 t0 = tcg_temp_new();
4242 t1 = tcg_temp_new();
4243 gen_load_gpr(t0, rs);
4244 gen_load_gpr(t1, rt);
4247 tcg_gen_andi_tl(t0, t0, 0x1f);
4248 tcg_gen_shl_tl(t0, t1, t0);
4249 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4252 tcg_gen_andi_tl(t0, t0, 0x1f);
4253 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4256 tcg_gen_ext32u_tl(t1, t1);
4257 tcg_gen_andi_tl(t0, t0, 0x1f);
4258 tcg_gen_shr_tl(t0, t1, t0);
4259 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4263 TCGv_i32 t2 = tcg_temp_new_i32();
4264 TCGv_i32 t3 = tcg_temp_new_i32();
4266 tcg_gen_trunc_tl_i32(t2, t0);
4267 tcg_gen_trunc_tl_i32(t3, t1);
4268 tcg_gen_andi_i32(t2, t2, 0x1f);
4269 tcg_gen_rotr_i32(t2, t3, t2);
4270 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4271 tcg_temp_free_i32(t2);
4272 tcg_temp_free_i32(t3);
4275 #if defined(TARGET_MIPS64)
4277 tcg_gen_andi_tl(t0, t0, 0x3f);
4278 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4281 tcg_gen_andi_tl(t0, t0, 0x3f);
4282 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4285 tcg_gen_andi_tl(t0, t0, 0x3f);
4286 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4289 tcg_gen_andi_tl(t0, t0, 0x3f);
4290 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4298 /* Arithmetic on HI/LO registers */
4299 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4301 if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 ||
4302 opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) {
4308 if (!(ctx->insn_flags & INSN_R5900)) {
4315 case TX79_MMI_MFHI1:
4316 #if defined(TARGET_MIPS64)
4318 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4322 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4326 case TX79_MMI_MFLO1:
4327 #if defined(TARGET_MIPS64)
4329 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4333 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4337 case TX79_MMI_MTHI1:
4339 #if defined(TARGET_MIPS64)
4341 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4345 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4348 tcg_gen_movi_tl(cpu_HI[acc], 0);
4352 case TX79_MMI_MTLO1:
4354 #if defined(TARGET_MIPS64)
4356 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4360 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4363 tcg_gen_movi_tl(cpu_LO[acc], 0);
4369 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4372 TCGv t0 = tcg_const_tl(addr);
4373 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4374 gen_store_gpr(t0, reg);
4378 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4384 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4387 offset = sextract32(ctx->opcode << 2, 0, 21);
4388 addr = addr_add(ctx, pc, offset);
4389 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4393 offset = sextract32(ctx->opcode << 2, 0, 21);
4394 addr = addr_add(ctx, pc, offset);
4395 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4397 #if defined(TARGET_MIPS64)
4400 offset = sextract32(ctx->opcode << 2, 0, 21);
4401 addr = addr_add(ctx, pc, offset);
4402 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4406 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4409 offset = sextract32(ctx->opcode, 0, 16) << 16;
4410 addr = addr_add(ctx, pc, offset);
4411 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4416 offset = sextract32(ctx->opcode, 0, 16) << 16;
4417 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4418 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4421 #if defined(TARGET_MIPS64)
4422 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4423 case R6_OPC_LDPC + (1 << 16):
4424 case R6_OPC_LDPC + (2 << 16):
4425 case R6_OPC_LDPC + (3 << 16):
4427 offset = sextract32(ctx->opcode << 3, 0, 21);
4428 addr = addr_add(ctx, (pc & ~0x7), offset);
4429 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4433 MIPS_INVAL("OPC_PCREL");
4434 generate_exception_end(ctx, EXCP_RI);
4441 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4450 t0 = tcg_temp_new();
4451 t1 = tcg_temp_new();
4453 gen_load_gpr(t0, rs);
4454 gen_load_gpr(t1, rt);
4459 TCGv t2 = tcg_temp_new();
4460 TCGv t3 = tcg_temp_new();
4461 tcg_gen_ext32s_tl(t0, t0);
4462 tcg_gen_ext32s_tl(t1, t1);
4463 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4464 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4465 tcg_gen_and_tl(t2, t2, t3);
4466 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4467 tcg_gen_or_tl(t2, t2, t3);
4468 tcg_gen_movi_tl(t3, 0);
4469 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4470 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4471 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4478 TCGv t2 = tcg_temp_new();
4479 TCGv t3 = tcg_temp_new();
4480 tcg_gen_ext32s_tl(t0, t0);
4481 tcg_gen_ext32s_tl(t1, t1);
4482 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4483 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4484 tcg_gen_and_tl(t2, t2, t3);
4485 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4486 tcg_gen_or_tl(t2, t2, t3);
4487 tcg_gen_movi_tl(t3, 0);
4488 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4489 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4490 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4497 TCGv t2 = tcg_const_tl(0);
4498 TCGv t3 = tcg_const_tl(1);
4499 tcg_gen_ext32u_tl(t0, t0);
4500 tcg_gen_ext32u_tl(t1, t1);
4501 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4502 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4503 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4510 TCGv t2 = tcg_const_tl(0);
4511 TCGv t3 = tcg_const_tl(1);
4512 tcg_gen_ext32u_tl(t0, t0);
4513 tcg_gen_ext32u_tl(t1, t1);
4514 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4515 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4516 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4523 TCGv_i32 t2 = tcg_temp_new_i32();
4524 TCGv_i32 t3 = tcg_temp_new_i32();
4525 tcg_gen_trunc_tl_i32(t2, t0);
4526 tcg_gen_trunc_tl_i32(t3, t1);
4527 tcg_gen_mul_i32(t2, t2, t3);
4528 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4529 tcg_temp_free_i32(t2);
4530 tcg_temp_free_i32(t3);
4535 TCGv_i32 t2 = tcg_temp_new_i32();
4536 TCGv_i32 t3 = tcg_temp_new_i32();
4537 tcg_gen_trunc_tl_i32(t2, t0);
4538 tcg_gen_trunc_tl_i32(t3, t1);
4539 tcg_gen_muls2_i32(t2, t3, t2, t3);
4540 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4541 tcg_temp_free_i32(t2);
4542 tcg_temp_free_i32(t3);
4547 TCGv_i32 t2 = tcg_temp_new_i32();
4548 TCGv_i32 t3 = tcg_temp_new_i32();
4549 tcg_gen_trunc_tl_i32(t2, t0);
4550 tcg_gen_trunc_tl_i32(t3, t1);
4551 tcg_gen_mul_i32(t2, t2, t3);
4552 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4553 tcg_temp_free_i32(t2);
4554 tcg_temp_free_i32(t3);
4559 TCGv_i32 t2 = tcg_temp_new_i32();
4560 TCGv_i32 t3 = tcg_temp_new_i32();
4561 tcg_gen_trunc_tl_i32(t2, t0);
4562 tcg_gen_trunc_tl_i32(t3, t1);
4563 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4564 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4565 tcg_temp_free_i32(t2);
4566 tcg_temp_free_i32(t3);
4569 #if defined(TARGET_MIPS64)
4572 TCGv t2 = tcg_temp_new();
4573 TCGv t3 = tcg_temp_new();
4574 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4575 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4576 tcg_gen_and_tl(t2, t2, t3);
4577 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4578 tcg_gen_or_tl(t2, t2, t3);
4579 tcg_gen_movi_tl(t3, 0);
4580 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4581 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4588 TCGv t2 = tcg_temp_new();
4589 TCGv t3 = tcg_temp_new();
4590 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4591 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4592 tcg_gen_and_tl(t2, t2, t3);
4593 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4594 tcg_gen_or_tl(t2, t2, t3);
4595 tcg_gen_movi_tl(t3, 0);
4596 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4597 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4604 TCGv t2 = tcg_const_tl(0);
4605 TCGv t3 = tcg_const_tl(1);
4606 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4607 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4614 TCGv t2 = tcg_const_tl(0);
4615 TCGv t3 = tcg_const_tl(1);
4616 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4617 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4623 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4627 TCGv t2 = tcg_temp_new();
4628 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4633 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4637 TCGv t2 = tcg_temp_new();
4638 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4644 MIPS_INVAL("r6 mul/div");
4645 generate_exception_end(ctx, EXCP_RI);
4653 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4654 int acc, int rs, int rt)
4658 t0 = tcg_temp_new();
4659 t1 = tcg_temp_new();
4661 gen_load_gpr(t0, rs);
4662 gen_load_gpr(t1, rt);
4665 if (!(ctx->insn_flags & INSN_R5900)) {
4674 TCGv t2 = tcg_temp_new();
4675 TCGv t3 = tcg_temp_new();
4676 tcg_gen_ext32s_tl(t0, t0);
4677 tcg_gen_ext32s_tl(t1, t1);
4678 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4679 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4680 tcg_gen_and_tl(t2, t2, t3);
4681 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4682 tcg_gen_or_tl(t2, t2, t3);
4683 tcg_gen_movi_tl(t3, 0);
4684 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4685 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4686 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4687 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4688 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4694 case TX79_MMI_DIVU1:
4696 TCGv t2 = tcg_const_tl(0);
4697 TCGv t3 = tcg_const_tl(1);
4698 tcg_gen_ext32u_tl(t0, t0);
4699 tcg_gen_ext32u_tl(t1, t1);
4700 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4701 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4702 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4703 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4704 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4711 TCGv_i32 t2 = tcg_temp_new_i32();
4712 TCGv_i32 t3 = tcg_temp_new_i32();
4713 tcg_gen_trunc_tl_i32(t2, t0);
4714 tcg_gen_trunc_tl_i32(t3, t1);
4715 tcg_gen_muls2_i32(t2, t3, t2, t3);
4716 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4717 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4718 tcg_temp_free_i32(t2);
4719 tcg_temp_free_i32(t3);
4724 TCGv_i32 t2 = tcg_temp_new_i32();
4725 TCGv_i32 t3 = tcg_temp_new_i32();
4726 tcg_gen_trunc_tl_i32(t2, t0);
4727 tcg_gen_trunc_tl_i32(t3, t1);
4728 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4729 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4730 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4731 tcg_temp_free_i32(t2);
4732 tcg_temp_free_i32(t3);
4735 #if defined(TARGET_MIPS64)
4738 TCGv t2 = tcg_temp_new();
4739 TCGv t3 = tcg_temp_new();
4740 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4741 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4742 tcg_gen_and_tl(t2, t2, t3);
4743 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4744 tcg_gen_or_tl(t2, t2, t3);
4745 tcg_gen_movi_tl(t3, 0);
4746 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4747 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4748 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4755 TCGv t2 = tcg_const_tl(0);
4756 TCGv t3 = tcg_const_tl(1);
4757 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4758 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4759 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4765 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4768 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4773 TCGv_i64 t2 = tcg_temp_new_i64();
4774 TCGv_i64 t3 = tcg_temp_new_i64();
4776 tcg_gen_ext_tl_i64(t2, t0);
4777 tcg_gen_ext_tl_i64(t3, t1);
4778 tcg_gen_mul_i64(t2, t2, t3);
4779 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4780 tcg_gen_add_i64(t2, t2, t3);
4781 tcg_temp_free_i64(t3);
4782 gen_move_low32(cpu_LO[acc], t2);
4783 gen_move_high32(cpu_HI[acc], t2);
4784 tcg_temp_free_i64(t2);
4789 TCGv_i64 t2 = tcg_temp_new_i64();
4790 TCGv_i64 t3 = tcg_temp_new_i64();
4792 tcg_gen_ext32u_tl(t0, t0);
4793 tcg_gen_ext32u_tl(t1, t1);
4794 tcg_gen_extu_tl_i64(t2, t0);
4795 tcg_gen_extu_tl_i64(t3, t1);
4796 tcg_gen_mul_i64(t2, t2, t3);
4797 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4798 tcg_gen_add_i64(t2, t2, t3);
4799 tcg_temp_free_i64(t3);
4800 gen_move_low32(cpu_LO[acc], t2);
4801 gen_move_high32(cpu_HI[acc], t2);
4802 tcg_temp_free_i64(t2);
4807 TCGv_i64 t2 = tcg_temp_new_i64();
4808 TCGv_i64 t3 = tcg_temp_new_i64();
4810 tcg_gen_ext_tl_i64(t2, t0);
4811 tcg_gen_ext_tl_i64(t3, t1);
4812 tcg_gen_mul_i64(t2, t2, t3);
4813 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4814 tcg_gen_sub_i64(t2, t3, t2);
4815 tcg_temp_free_i64(t3);
4816 gen_move_low32(cpu_LO[acc], t2);
4817 gen_move_high32(cpu_HI[acc], t2);
4818 tcg_temp_free_i64(t2);
4823 TCGv_i64 t2 = tcg_temp_new_i64();
4824 TCGv_i64 t3 = tcg_temp_new_i64();
4826 tcg_gen_ext32u_tl(t0, t0);
4827 tcg_gen_ext32u_tl(t1, t1);
4828 tcg_gen_extu_tl_i64(t2, t0);
4829 tcg_gen_extu_tl_i64(t3, t1);
4830 tcg_gen_mul_i64(t2, t2, t3);
4831 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4832 tcg_gen_sub_i64(t2, t3, t2);
4833 tcg_temp_free_i64(t3);
4834 gen_move_low32(cpu_LO[acc], t2);
4835 gen_move_high32(cpu_HI[acc], t2);
4836 tcg_temp_free_i64(t2);
4840 MIPS_INVAL("mul/div");
4841 generate_exception_end(ctx, EXCP_RI);
4850 * These MULT and MULTU instructions implemented in for example the
4851 * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
4852 * architectures are special three-operand variants with the syntax
4854 * MULT[U][1] rd, rs, rt
4858 * (rd, LO, HI) <- rs * rt
4860 * where the low-order 32-bits of the result is placed into both the
4861 * GPR rd and the special register LO. The high-order 32-bits of the
4862 * result is placed into the special register HI.
4864 * If the GPR rd is omitted in assembly language, it is taken to be 0,
4865 * which is the zero register that always reads as 0.
4867 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
4868 int rd, int rs, int rt)
4870 TCGv t0 = tcg_temp_new();
4871 TCGv t1 = tcg_temp_new();
4874 gen_load_gpr(t0, rs);
4875 gen_load_gpr(t1, rt);
4878 case TX79_MMI_MULT1:
4883 TCGv_i32 t2 = tcg_temp_new_i32();
4884 TCGv_i32 t3 = tcg_temp_new_i32();
4885 tcg_gen_trunc_tl_i32(t2, t0);
4886 tcg_gen_trunc_tl_i32(t3, t1);
4887 tcg_gen_muls2_i32(t2, t3, t2, t3);
4889 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4891 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4892 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4893 tcg_temp_free_i32(t2);
4894 tcg_temp_free_i32(t3);
4897 case TX79_MMI_MULTU1:
4902 TCGv_i32 t2 = tcg_temp_new_i32();
4903 TCGv_i32 t3 = tcg_temp_new_i32();
4904 tcg_gen_trunc_tl_i32(t2, t0);
4905 tcg_gen_trunc_tl_i32(t3, t1);
4906 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4908 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4910 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4911 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4912 tcg_temp_free_i32(t2);
4913 tcg_temp_free_i32(t3);
4917 MIPS_INVAL("mul TXx9");
4918 generate_exception_end(ctx, EXCP_RI);
4927 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4928 int rd, int rs, int rt)
4930 TCGv t0 = tcg_temp_new();
4931 TCGv t1 = tcg_temp_new();
4933 gen_load_gpr(t0, rs);
4934 gen_load_gpr(t1, rt);
4937 case OPC_VR54XX_MULS:
4938 gen_helper_muls(t0, cpu_env, t0, t1);
4940 case OPC_VR54XX_MULSU:
4941 gen_helper_mulsu(t0, cpu_env, t0, t1);
4943 case OPC_VR54XX_MACC:
4944 gen_helper_macc(t0, cpu_env, t0, t1);
4946 case OPC_VR54XX_MACCU:
4947 gen_helper_maccu(t0, cpu_env, t0, t1);
4949 case OPC_VR54XX_MSAC:
4950 gen_helper_msac(t0, cpu_env, t0, t1);
4952 case OPC_VR54XX_MSACU:
4953 gen_helper_msacu(t0, cpu_env, t0, t1);
4955 case OPC_VR54XX_MULHI:
4956 gen_helper_mulhi(t0, cpu_env, t0, t1);
4958 case OPC_VR54XX_MULHIU:
4959 gen_helper_mulhiu(t0, cpu_env, t0, t1);
4961 case OPC_VR54XX_MULSHI:
4962 gen_helper_mulshi(t0, cpu_env, t0, t1);
4964 case OPC_VR54XX_MULSHIU:
4965 gen_helper_mulshiu(t0, cpu_env, t0, t1);
4967 case OPC_VR54XX_MACCHI:
4968 gen_helper_macchi(t0, cpu_env, t0, t1);
4970 case OPC_VR54XX_MACCHIU:
4971 gen_helper_macchiu(t0, cpu_env, t0, t1);
4973 case OPC_VR54XX_MSACHI:
4974 gen_helper_msachi(t0, cpu_env, t0, t1);
4976 case OPC_VR54XX_MSACHIU:
4977 gen_helper_msachiu(t0, cpu_env, t0, t1);
4980 MIPS_INVAL("mul vr54xx");
4981 generate_exception_end(ctx, EXCP_RI);
4984 gen_store_gpr(t0, rd);
4991 static void gen_cl (DisasContext *ctx, uint32_t opc,
5001 gen_load_gpr(t0, rs);
5006 #if defined(TARGET_MIPS64)
5010 tcg_gen_not_tl(t0, t0);
5019 tcg_gen_ext32u_tl(t0, t0);
5020 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5021 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5023 #if defined(TARGET_MIPS64)
5028 tcg_gen_clzi_i64(t0, t0, 64);
5034 /* Godson integer instructions */
5035 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5036 int rd, int rs, int rt)
5048 case OPC_MULTU_G_2E:
5049 case OPC_MULTU_G_2F:
5050 #if defined(TARGET_MIPS64)
5051 case OPC_DMULT_G_2E:
5052 case OPC_DMULT_G_2F:
5053 case OPC_DMULTU_G_2E:
5054 case OPC_DMULTU_G_2F:
5056 t0 = tcg_temp_new();
5057 t1 = tcg_temp_new();
5060 t0 = tcg_temp_local_new();
5061 t1 = tcg_temp_local_new();
5065 gen_load_gpr(t0, rs);
5066 gen_load_gpr(t1, rt);
5071 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5072 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5074 case OPC_MULTU_G_2E:
5075 case OPC_MULTU_G_2F:
5076 tcg_gen_ext32u_tl(t0, t0);
5077 tcg_gen_ext32u_tl(t1, t1);
5078 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5079 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5084 TCGLabel *l1 = gen_new_label();
5085 TCGLabel *l2 = gen_new_label();
5086 TCGLabel *l3 = gen_new_label();
5087 tcg_gen_ext32s_tl(t0, t0);
5088 tcg_gen_ext32s_tl(t1, t1);
5089 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5090 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5093 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5094 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5095 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5098 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5099 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5106 TCGLabel *l1 = gen_new_label();
5107 TCGLabel *l2 = gen_new_label();
5108 tcg_gen_ext32u_tl(t0, t0);
5109 tcg_gen_ext32u_tl(t1, t1);
5110 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5111 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5114 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5115 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5122 TCGLabel *l1 = gen_new_label();
5123 TCGLabel *l2 = gen_new_label();
5124 TCGLabel *l3 = gen_new_label();
5125 tcg_gen_ext32u_tl(t0, t0);
5126 tcg_gen_ext32u_tl(t1, t1);
5127 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5128 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5129 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5131 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5134 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5135 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5142 TCGLabel *l1 = gen_new_label();
5143 TCGLabel *l2 = gen_new_label();
5144 tcg_gen_ext32u_tl(t0, t0);
5145 tcg_gen_ext32u_tl(t1, t1);
5146 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5147 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5150 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5151 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5155 #if defined(TARGET_MIPS64)
5156 case OPC_DMULT_G_2E:
5157 case OPC_DMULT_G_2F:
5158 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5160 case OPC_DMULTU_G_2E:
5161 case OPC_DMULTU_G_2F:
5162 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5167 TCGLabel *l1 = gen_new_label();
5168 TCGLabel *l2 = gen_new_label();
5169 TCGLabel *l3 = gen_new_label();
5170 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5171 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5174 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5175 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5176 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5179 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5183 case OPC_DDIVU_G_2E:
5184 case OPC_DDIVU_G_2F:
5186 TCGLabel *l1 = gen_new_label();
5187 TCGLabel *l2 = gen_new_label();
5188 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5189 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5192 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5199 TCGLabel *l1 = gen_new_label();
5200 TCGLabel *l2 = gen_new_label();
5201 TCGLabel *l3 = gen_new_label();
5202 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5203 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5204 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5206 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5209 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5213 case OPC_DMODU_G_2E:
5214 case OPC_DMODU_G_2F:
5216 TCGLabel *l1 = gen_new_label();
5217 TCGLabel *l2 = gen_new_label();
5218 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5219 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5222 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5233 /* Loongson multimedia instructions */
5234 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5236 uint32_t opc, shift_max;
5239 opc = MASK_LMI(ctx->opcode);
5245 t0 = tcg_temp_local_new_i64();
5246 t1 = tcg_temp_local_new_i64();
5249 t0 = tcg_temp_new_i64();
5250 t1 = tcg_temp_new_i64();
5254 check_cp1_enabled(ctx);
5255 gen_load_fpr64(ctx, t0, rs);
5256 gen_load_fpr64(ctx, t1, rt);
5258 #define LMI_HELPER(UP, LO) \
5259 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5260 #define LMI_HELPER_1(UP, LO) \
5261 case OPC_##UP: gen_helper_##LO(t0, t0); break
5262 #define LMI_DIRECT(UP, LO, OP) \
5263 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5266 LMI_HELPER(PADDSH, paddsh);
5267 LMI_HELPER(PADDUSH, paddush);
5268 LMI_HELPER(PADDH, paddh);
5269 LMI_HELPER(PADDW, paddw);
5270 LMI_HELPER(PADDSB, paddsb);
5271 LMI_HELPER(PADDUSB, paddusb);
5272 LMI_HELPER(PADDB, paddb);
5274 LMI_HELPER(PSUBSH, psubsh);
5275 LMI_HELPER(PSUBUSH, psubush);
5276 LMI_HELPER(PSUBH, psubh);
5277 LMI_HELPER(PSUBW, psubw);
5278 LMI_HELPER(PSUBSB, psubsb);
5279 LMI_HELPER(PSUBUSB, psubusb);
5280 LMI_HELPER(PSUBB, psubb);
5282 LMI_HELPER(PSHUFH, pshufh);
5283 LMI_HELPER(PACKSSWH, packsswh);
5284 LMI_HELPER(PACKSSHB, packsshb);
5285 LMI_HELPER(PACKUSHB, packushb);
5287 LMI_HELPER(PUNPCKLHW, punpcklhw);
5288 LMI_HELPER(PUNPCKHHW, punpckhhw);
5289 LMI_HELPER(PUNPCKLBH, punpcklbh);
5290 LMI_HELPER(PUNPCKHBH, punpckhbh);
5291 LMI_HELPER(PUNPCKLWD, punpcklwd);
5292 LMI_HELPER(PUNPCKHWD, punpckhwd);
5294 LMI_HELPER(PAVGH, pavgh);
5295 LMI_HELPER(PAVGB, pavgb);
5296 LMI_HELPER(PMAXSH, pmaxsh);
5297 LMI_HELPER(PMINSH, pminsh);
5298 LMI_HELPER(PMAXUB, pmaxub);
5299 LMI_HELPER(PMINUB, pminub);
5301 LMI_HELPER(PCMPEQW, pcmpeqw);
5302 LMI_HELPER(PCMPGTW, pcmpgtw);
5303 LMI_HELPER(PCMPEQH, pcmpeqh);
5304 LMI_HELPER(PCMPGTH, pcmpgth);
5305 LMI_HELPER(PCMPEQB, pcmpeqb);
5306 LMI_HELPER(PCMPGTB, pcmpgtb);
5308 LMI_HELPER(PSLLW, psllw);
5309 LMI_HELPER(PSLLH, psllh);
5310 LMI_HELPER(PSRLW, psrlw);
5311 LMI_HELPER(PSRLH, psrlh);
5312 LMI_HELPER(PSRAW, psraw);
5313 LMI_HELPER(PSRAH, psrah);
5315 LMI_HELPER(PMULLH, pmullh);
5316 LMI_HELPER(PMULHH, pmulhh);
5317 LMI_HELPER(PMULHUH, pmulhuh);
5318 LMI_HELPER(PMADDHW, pmaddhw);
5320 LMI_HELPER(PASUBUB, pasubub);
5321 LMI_HELPER_1(BIADD, biadd);
5322 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5324 LMI_DIRECT(PADDD, paddd, add);
5325 LMI_DIRECT(PSUBD, psubd, sub);
5326 LMI_DIRECT(XOR_CP2, xor, xor);
5327 LMI_DIRECT(NOR_CP2, nor, nor);
5328 LMI_DIRECT(AND_CP2, and, and);
5329 LMI_DIRECT(OR_CP2, or, or);
5332 tcg_gen_andc_i64(t0, t1, t0);
5336 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5339 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5342 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5345 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5349 tcg_gen_andi_i64(t1, t1, 3);
5350 tcg_gen_shli_i64(t1, t1, 4);
5351 tcg_gen_shr_i64(t0, t0, t1);
5352 tcg_gen_ext16u_i64(t0, t0);
5356 tcg_gen_add_i64(t0, t0, t1);
5357 tcg_gen_ext32s_i64(t0, t0);
5360 tcg_gen_sub_i64(t0, t0, t1);
5361 tcg_gen_ext32s_i64(t0, t0);
5383 /* Make sure shift count isn't TCG undefined behaviour. */
5384 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5389 tcg_gen_shl_i64(t0, t0, t1);
5393 /* Since SRA is UndefinedResult without sign-extended inputs,
5394 we can treat SRA and DSRA the same. */
5395 tcg_gen_sar_i64(t0, t0, t1);
5398 /* We want to shift in zeros for SRL; zero-extend first. */
5399 tcg_gen_ext32u_i64(t0, t0);
5402 tcg_gen_shr_i64(t0, t0, t1);
5406 if (shift_max == 32) {
5407 tcg_gen_ext32s_i64(t0, t0);
5410 /* Shifts larger than MAX produce zero. */
5411 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5412 tcg_gen_neg_i64(t1, t1);
5413 tcg_gen_and_i64(t0, t0, t1);
5419 TCGv_i64 t2 = tcg_temp_new_i64();
5420 TCGLabel *lab = gen_new_label();
5422 tcg_gen_mov_i64(t2, t0);
5423 tcg_gen_add_i64(t0, t1, t2);
5424 if (opc == OPC_ADD_CP2) {
5425 tcg_gen_ext32s_i64(t0, t0);
5427 tcg_gen_xor_i64(t1, t1, t2);
5428 tcg_gen_xor_i64(t2, t2, t0);
5429 tcg_gen_andc_i64(t1, t2, t1);
5430 tcg_temp_free_i64(t2);
5431 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5432 generate_exception(ctx, EXCP_OVERFLOW);
5440 TCGv_i64 t2 = tcg_temp_new_i64();
5441 TCGLabel *lab = gen_new_label();
5443 tcg_gen_mov_i64(t2, t0);
5444 tcg_gen_sub_i64(t0, t1, t2);
5445 if (opc == OPC_SUB_CP2) {
5446 tcg_gen_ext32s_i64(t0, t0);
5448 tcg_gen_xor_i64(t1, t1, t2);
5449 tcg_gen_xor_i64(t2, t2, t0);
5450 tcg_gen_and_i64(t1, t1, t2);
5451 tcg_temp_free_i64(t2);
5452 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5453 generate_exception(ctx, EXCP_OVERFLOW);
5459 tcg_gen_ext32u_i64(t0, t0);
5460 tcg_gen_ext32u_i64(t1, t1);
5461 tcg_gen_mul_i64(t0, t0, t1);
5470 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5471 FD field is the CC field? */
5473 MIPS_INVAL("loongson_cp2");
5474 generate_exception_end(ctx, EXCP_RI);
5481 gen_store_fpr64(ctx, t0, rd);
5483 tcg_temp_free_i64(t0);
5484 tcg_temp_free_i64(t1);
5488 static void gen_trap (DisasContext *ctx, uint32_t opc,
5489 int rs, int rt, int16_t imm)
5492 TCGv t0 = tcg_temp_new();
5493 TCGv t1 = tcg_temp_new();
5496 /* Load needed operands */
5504 /* Compare two registers */
5506 gen_load_gpr(t0, rs);
5507 gen_load_gpr(t1, rt);
5517 /* Compare register to immediate */
5518 if (rs != 0 || imm != 0) {
5519 gen_load_gpr(t0, rs);
5520 tcg_gen_movi_tl(t1, (int32_t)imm);
5527 case OPC_TEQ: /* rs == rs */
5528 case OPC_TEQI: /* r0 == 0 */
5529 case OPC_TGE: /* rs >= rs */
5530 case OPC_TGEI: /* r0 >= 0 */
5531 case OPC_TGEU: /* rs >= rs unsigned */
5532 case OPC_TGEIU: /* r0 >= 0 unsigned */
5534 generate_exception_end(ctx, EXCP_TRAP);
5536 case OPC_TLT: /* rs < rs */
5537 case OPC_TLTI: /* r0 < 0 */
5538 case OPC_TLTU: /* rs < rs unsigned */
5539 case OPC_TLTIU: /* r0 < 0 unsigned */
5540 case OPC_TNE: /* rs != rs */
5541 case OPC_TNEI: /* r0 != 0 */
5542 /* Never trap: treat as NOP. */
5546 TCGLabel *l1 = gen_new_label();
5551 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5555 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5559 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5563 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5567 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5571 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5574 generate_exception(ctx, EXCP_TRAP);
5581 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5583 if (unlikely(ctx->base.singlestep_enabled)) {
5587 #ifndef CONFIG_USER_ONLY
5588 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5594 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5596 if (use_goto_tb(ctx, dest)) {
5599 tcg_gen_exit_tb(ctx->base.tb, n);
5602 if (ctx->base.singlestep_enabled) {
5603 save_cpu_state(ctx, 0);
5604 gen_helper_raise_exception_debug(cpu_env);
5606 tcg_gen_lookup_and_goto_ptr();
5610 /* Branches (before delay slot) */
5611 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5613 int rs, int rt, int32_t offset,
5616 target_ulong btgt = -1;
5618 int bcond_compute = 0;
5619 TCGv t0 = tcg_temp_new();
5620 TCGv t1 = tcg_temp_new();
5622 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5623 #ifdef MIPS_DEBUG_DISAS
5624 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5625 TARGET_FMT_lx "\n", ctx->base.pc_next);
5627 generate_exception_end(ctx, EXCP_RI);
5631 /* Load needed operands */
5637 /* Compare two registers */
5639 gen_load_gpr(t0, rs);
5640 gen_load_gpr(t1, rt);
5643 btgt = ctx->base.pc_next + insn_bytes + offset;
5657 /* Compare to zero */
5659 gen_load_gpr(t0, rs);
5662 btgt = ctx->base.pc_next + insn_bytes + offset;
5665 #if defined(TARGET_MIPS64)
5667 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5669 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5672 btgt = ctx->base.pc_next + insn_bytes + offset;
5677 /* Jump to immediate */
5678 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5683 /* Jump to register */
5684 if (offset != 0 && offset != 16) {
5685 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5686 others are reserved. */
5687 MIPS_INVAL("jump hint");
5688 generate_exception_end(ctx, EXCP_RI);
5691 gen_load_gpr(btarget, rs);
5694 MIPS_INVAL("branch/jump");
5695 generate_exception_end(ctx, EXCP_RI);
5698 if (bcond_compute == 0) {
5699 /* No condition to be computed */
5701 case OPC_BEQ: /* rx == rx */
5702 case OPC_BEQL: /* rx == rx likely */
5703 case OPC_BGEZ: /* 0 >= 0 */
5704 case OPC_BGEZL: /* 0 >= 0 likely */
5705 case OPC_BLEZ: /* 0 <= 0 */
5706 case OPC_BLEZL: /* 0 <= 0 likely */
5708 ctx->hflags |= MIPS_HFLAG_B;
5710 case OPC_BGEZAL: /* 0 >= 0 */
5711 case OPC_BGEZALL: /* 0 >= 0 likely */
5712 /* Always take and link */
5714 ctx->hflags |= MIPS_HFLAG_B;
5716 case OPC_BNE: /* rx != rx */
5717 case OPC_BGTZ: /* 0 > 0 */
5718 case OPC_BLTZ: /* 0 < 0 */
5721 case OPC_BLTZAL: /* 0 < 0 */
5722 /* Handle as an unconditional branch to get correct delay
5725 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5726 ctx->hflags |= MIPS_HFLAG_B;
5728 case OPC_BLTZALL: /* 0 < 0 likely */
5729 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5730 /* Skip the instruction in the delay slot */
5731 ctx->base.pc_next += 4;
5733 case OPC_BNEL: /* rx != rx likely */
5734 case OPC_BGTZL: /* 0 > 0 likely */
5735 case OPC_BLTZL: /* 0 < 0 likely */
5736 /* Skip the instruction in the delay slot */
5737 ctx->base.pc_next += 4;
5740 ctx->hflags |= MIPS_HFLAG_B;
5743 ctx->hflags |= MIPS_HFLAG_BX;
5747 ctx->hflags |= MIPS_HFLAG_B;
5750 ctx->hflags |= MIPS_HFLAG_BR;
5754 ctx->hflags |= MIPS_HFLAG_BR;
5757 MIPS_INVAL("branch/jump");
5758 generate_exception_end(ctx, EXCP_RI);
5764 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5767 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5770 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5773 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5776 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5779 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5782 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5786 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5790 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5793 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5796 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5799 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5802 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5805 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5808 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5810 #if defined(TARGET_MIPS64)
5812 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5816 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5819 ctx->hflags |= MIPS_HFLAG_BC;
5822 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5825 ctx->hflags |= MIPS_HFLAG_BL;
5828 MIPS_INVAL("conditional branch/jump");
5829 generate_exception_end(ctx, EXCP_RI);
5834 ctx->btarget = btgt;
5836 switch (delayslot_size) {
5838 ctx->hflags |= MIPS_HFLAG_BDS16;
5841 ctx->hflags |= MIPS_HFLAG_BDS32;
5846 int post_delay = insn_bytes + delayslot_size;
5847 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5849 tcg_gen_movi_tl(cpu_gpr[blink],
5850 ctx->base.pc_next + post_delay + lowbit);
5854 if (insn_bytes == 2)
5855 ctx->hflags |= MIPS_HFLAG_B16;
5861 /* nanoMIPS Branches */
5862 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5864 int rs, int rt, int32_t offset)
5866 target_ulong btgt = -1;
5867 int bcond_compute = 0;
5868 TCGv t0 = tcg_temp_new();
5869 TCGv t1 = tcg_temp_new();
5871 /* Load needed operands */
5875 /* Compare two registers */
5877 gen_load_gpr(t0, rs);
5878 gen_load_gpr(t1, rt);
5881 btgt = ctx->base.pc_next + insn_bytes + offset;
5884 /* Compare to zero */
5886 gen_load_gpr(t0, rs);
5889 btgt = ctx->base.pc_next + insn_bytes + offset;
5892 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5894 btgt = ctx->base.pc_next + insn_bytes + offset;
5898 /* Jump to register */
5899 if (offset != 0 && offset != 16) {
5900 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5901 others are reserved. */
5902 MIPS_INVAL("jump hint");
5903 generate_exception_end(ctx, EXCP_RI);
5906 gen_load_gpr(btarget, rs);
5909 MIPS_INVAL("branch/jump");
5910 generate_exception_end(ctx, EXCP_RI);
5913 if (bcond_compute == 0) {
5914 /* No condition to be computed */
5916 case OPC_BEQ: /* rx == rx */
5918 ctx->hflags |= MIPS_HFLAG_B;
5920 case OPC_BGEZAL: /* 0 >= 0 */
5921 /* Always take and link */
5922 tcg_gen_movi_tl(cpu_gpr[31],
5923 ctx->base.pc_next + insn_bytes);
5924 ctx->hflags |= MIPS_HFLAG_B;
5926 case OPC_BNE: /* rx != rx */
5927 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5928 /* Skip the instruction in the delay slot */
5929 ctx->base.pc_next += 4;
5932 ctx->hflags |= MIPS_HFLAG_BR;
5936 tcg_gen_movi_tl(cpu_gpr[rt],
5937 ctx->base.pc_next + insn_bytes);
5939 ctx->hflags |= MIPS_HFLAG_BR;
5942 MIPS_INVAL("branch/jump");
5943 generate_exception_end(ctx, EXCP_RI);
5949 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5952 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5955 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5956 tcg_gen_movi_tl(cpu_gpr[31],
5957 ctx->base.pc_next + insn_bytes);
5960 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5962 ctx->hflags |= MIPS_HFLAG_BC;
5965 MIPS_INVAL("conditional branch/jump");
5966 generate_exception_end(ctx, EXCP_RI);
5971 ctx->btarget = btgt;
5974 if (insn_bytes == 2) {
5975 ctx->hflags |= MIPS_HFLAG_B16;
5982 /* special3 bitfield operations */
5983 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
5984 int rs, int lsb, int msb)
5986 TCGv t0 = tcg_temp_new();
5987 TCGv t1 = tcg_temp_new();
5989 gen_load_gpr(t1, rs);
5992 if (lsb + msb > 31) {
5996 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5998 /* The two checks together imply that lsb == 0,
5999 so this is a simple sign-extension. */
6000 tcg_gen_ext32s_tl(t0, t1);
6003 #if defined(TARGET_MIPS64)
6012 if (lsb + msb > 63) {
6015 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6022 gen_load_gpr(t0, rt);
6023 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6024 tcg_gen_ext32s_tl(t0, t0);
6026 #if defined(TARGET_MIPS64)
6037 gen_load_gpr(t0, rt);
6038 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6043 MIPS_INVAL("bitops");
6044 generate_exception_end(ctx, EXCP_RI);
6049 gen_store_gpr(t0, rt);
6054 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6059 /* If no destination, treat it as a NOP. */
6063 t0 = tcg_temp_new();
6064 gen_load_gpr(t0, rt);
6068 TCGv t1 = tcg_temp_new();
6069 TCGv t2 = tcg_const_tl(0x00FF00FF);
6071 tcg_gen_shri_tl(t1, t0, 8);
6072 tcg_gen_and_tl(t1, t1, t2);
6073 tcg_gen_and_tl(t0, t0, t2);
6074 tcg_gen_shli_tl(t0, t0, 8);
6075 tcg_gen_or_tl(t0, t0, t1);
6078 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6082 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6085 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6087 #if defined(TARGET_MIPS64)
6090 TCGv t1 = tcg_temp_new();
6091 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6093 tcg_gen_shri_tl(t1, t0, 8);
6094 tcg_gen_and_tl(t1, t1, t2);
6095 tcg_gen_and_tl(t0, t0, t2);
6096 tcg_gen_shli_tl(t0, t0, 8);
6097 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6104 TCGv t1 = tcg_temp_new();
6105 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6107 tcg_gen_shri_tl(t1, t0, 16);
6108 tcg_gen_and_tl(t1, t1, t2);
6109 tcg_gen_and_tl(t0, t0, t2);
6110 tcg_gen_shli_tl(t0, t0, 16);
6111 tcg_gen_or_tl(t0, t0, t1);
6112 tcg_gen_shri_tl(t1, t0, 32);
6113 tcg_gen_shli_tl(t0, t0, 32);
6114 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6121 MIPS_INVAL("bsfhl");
6122 generate_exception_end(ctx, EXCP_RI);
6129 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6138 t0 = tcg_temp_new();
6139 t1 = tcg_temp_new();
6140 gen_load_gpr(t0, rs);
6141 gen_load_gpr(t1, rt);
6142 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6143 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6144 if (opc == OPC_LSA) {
6145 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6154 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6162 t0 = tcg_temp_new();
6163 if (bits == 0 || bits == wordsz) {
6165 gen_load_gpr(t0, rt);
6167 gen_load_gpr(t0, rs);
6171 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6173 #if defined(TARGET_MIPS64)
6175 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6180 TCGv t1 = tcg_temp_new();
6181 gen_load_gpr(t0, rt);
6182 gen_load_gpr(t1, rs);
6186 TCGv_i64 t2 = tcg_temp_new_i64();
6187 tcg_gen_concat_tl_i64(t2, t1, t0);
6188 tcg_gen_shri_i64(t2, t2, 32 - bits);
6189 gen_move_low32(cpu_gpr[rd], t2);
6190 tcg_temp_free_i64(t2);
6193 #if defined(TARGET_MIPS64)
6195 tcg_gen_shli_tl(t0, t0, bits);
6196 tcg_gen_shri_tl(t1, t1, 64 - bits);
6197 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6207 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6210 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6213 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6216 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6219 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6226 t0 = tcg_temp_new();
6227 gen_load_gpr(t0, rt);
6230 gen_helper_bitswap(cpu_gpr[rd], t0);
6232 #if defined(TARGET_MIPS64)
6234 gen_helper_dbitswap(cpu_gpr[rd], t0);
6241 #ifndef CONFIG_USER_ONLY
6242 /* CP0 (MMU and control) */
6243 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6245 TCGv_i64 t0 = tcg_temp_new_i64();
6246 TCGv_i64 t1 = tcg_temp_new_i64();
6248 tcg_gen_ext_tl_i64(t0, arg);
6249 tcg_gen_ld_i64(t1, cpu_env, off);
6250 #if defined(TARGET_MIPS64)
6251 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6253 tcg_gen_concat32_i64(t1, t1, t0);
6255 tcg_gen_st_i64(t1, cpu_env, off);
6256 tcg_temp_free_i64(t1);
6257 tcg_temp_free_i64(t0);
6260 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6262 TCGv_i64 t0 = tcg_temp_new_i64();
6263 TCGv_i64 t1 = tcg_temp_new_i64();
6265 tcg_gen_ext_tl_i64(t0, arg);
6266 tcg_gen_ld_i64(t1, cpu_env, off);
6267 tcg_gen_concat32_i64(t1, t1, t0);
6268 tcg_gen_st_i64(t1, cpu_env, off);
6269 tcg_temp_free_i64(t1);
6270 tcg_temp_free_i64(t0);
6273 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6275 TCGv_i64 t0 = tcg_temp_new_i64();
6277 tcg_gen_ld_i64(t0, cpu_env, off);
6278 #if defined(TARGET_MIPS64)
6279 tcg_gen_shri_i64(t0, t0, 30);
6281 tcg_gen_shri_i64(t0, t0, 32);
6283 gen_move_low32(arg, t0);
6284 tcg_temp_free_i64(t0);
6287 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6289 TCGv_i64 t0 = tcg_temp_new_i64();
6291 tcg_gen_ld_i64(t0, cpu_env, off);
6292 tcg_gen_shri_i64(t0, t0, 32 + shift);
6293 gen_move_low32(arg, t0);
6294 tcg_temp_free_i64(t0);
6297 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6299 TCGv_i32 t0 = tcg_temp_new_i32();
6301 tcg_gen_ld_i32(t0, cpu_env, off);
6302 tcg_gen_ext_i32_tl(arg, t0);
6303 tcg_temp_free_i32(t0);
6306 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6308 tcg_gen_ld_tl(arg, cpu_env, off);
6309 tcg_gen_ext32s_tl(arg, arg);
6312 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6314 TCGv_i32 t0 = tcg_temp_new_i32();
6316 tcg_gen_trunc_tl_i32(t0, arg);
6317 tcg_gen_st_i32(t0, cpu_env, off);
6318 tcg_temp_free_i32(t0);
6321 #define CP0_CHECK(c) \
6324 goto cp0_unimplemented; \
6328 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6330 const char *rn = "invalid";
6336 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6337 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6341 goto cp0_unimplemented;
6347 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6348 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6352 goto cp0_unimplemented;
6358 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6359 ctx->CP0_LLAddr_shift);
6363 CP0_CHECK(ctx->mrp);
6364 gen_helper_mfhc0_maar(arg, cpu_env);
6368 goto cp0_unimplemented;
6377 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6381 goto cp0_unimplemented;
6385 goto cp0_unimplemented;
6387 trace_mips_translate_c0("mfhc0", rn, reg, sel);
6391 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
6392 tcg_gen_movi_tl(arg, 0);
6395 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6397 const char *rn = "invalid";
6398 uint64_t mask = ctx->PAMask >> 36;
6404 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6405 tcg_gen_andi_tl(arg, arg, mask);
6406 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6410 goto cp0_unimplemented;
6416 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6417 tcg_gen_andi_tl(arg, arg, mask);
6418 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6422 goto cp0_unimplemented;
6428 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6429 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6430 relevant for modern MIPS cores supporting MTHC0, therefore
6431 treating MTHC0 to LLAddr as NOP. */
6435 CP0_CHECK(ctx->mrp);
6436 gen_helper_mthc0_maar(cpu_env, arg);
6440 goto cp0_unimplemented;
6449 tcg_gen_andi_tl(arg, arg, mask);
6450 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6454 goto cp0_unimplemented;
6458 goto cp0_unimplemented;
6460 trace_mips_translate_c0("mthc0", rn, reg, sel);
6463 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
6466 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6468 if (ctx->insn_flags & ISA_MIPS32R6) {
6469 tcg_gen_movi_tl(arg, 0);
6471 tcg_gen_movi_tl(arg, ~0);
6475 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6477 const char *rn = "invalid";
6480 check_insn(ctx, ISA_MIPS32);
6486 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6490 CP0_CHECK(ctx->insn_flags & ASE_MT);
6491 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6495 CP0_CHECK(ctx->insn_flags & ASE_MT);
6496 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6500 CP0_CHECK(ctx->insn_flags & ASE_MT);
6501 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6506 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6510 goto cp0_unimplemented;
6516 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6517 gen_helper_mfc0_random(arg, cpu_env);
6521 CP0_CHECK(ctx->insn_flags & ASE_MT);
6522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6526 CP0_CHECK(ctx->insn_flags & ASE_MT);
6527 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6531 CP0_CHECK(ctx->insn_flags & ASE_MT);
6532 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6536 CP0_CHECK(ctx->insn_flags & ASE_MT);
6537 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6541 CP0_CHECK(ctx->insn_flags & ASE_MT);
6542 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6546 CP0_CHECK(ctx->insn_flags & ASE_MT);
6547 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6548 rn = "VPEScheFBack";
6551 CP0_CHECK(ctx->insn_flags & ASE_MT);
6552 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6556 goto cp0_unimplemented;
6563 TCGv_i64 tmp = tcg_temp_new_i64();
6564 tcg_gen_ld_i64(tmp, cpu_env,
6565 offsetof(CPUMIPSState, CP0_EntryLo0));
6566 #if defined(TARGET_MIPS64)
6568 /* Move RI/XI fields to bits 31:30 */
6569 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6570 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6573 gen_move_low32(arg, tmp);
6574 tcg_temp_free_i64(tmp);
6579 CP0_CHECK(ctx->insn_flags & ASE_MT);
6580 gen_helper_mfc0_tcstatus(arg, cpu_env);
6584 CP0_CHECK(ctx->insn_flags & ASE_MT);
6585 gen_helper_mfc0_tcbind(arg, cpu_env);
6589 CP0_CHECK(ctx->insn_flags & ASE_MT);
6590 gen_helper_mfc0_tcrestart(arg, cpu_env);
6594 CP0_CHECK(ctx->insn_flags & ASE_MT);
6595 gen_helper_mfc0_tchalt(arg, cpu_env);
6599 CP0_CHECK(ctx->insn_flags & ASE_MT);
6600 gen_helper_mfc0_tccontext(arg, cpu_env);
6604 CP0_CHECK(ctx->insn_flags & ASE_MT);
6605 gen_helper_mfc0_tcschedule(arg, cpu_env);
6609 CP0_CHECK(ctx->insn_flags & ASE_MT);
6610 gen_helper_mfc0_tcschefback(arg, cpu_env);
6614 goto cp0_unimplemented;
6621 TCGv_i64 tmp = tcg_temp_new_i64();
6622 tcg_gen_ld_i64(tmp, cpu_env,
6623 offsetof(CPUMIPSState, CP0_EntryLo1));
6624 #if defined(TARGET_MIPS64)
6626 /* Move RI/XI fields to bits 31:30 */
6627 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6628 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6631 gen_move_low32(arg, tmp);
6632 tcg_temp_free_i64(tmp);
6638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6639 rn = "GlobalNumber";
6642 goto cp0_unimplemented;
6648 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6649 tcg_gen_ext32s_tl(arg, arg);
6653 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6654 rn = "ContextConfig";
6655 goto cp0_unimplemented;
6657 CP0_CHECK(ctx->ulri);
6658 tcg_gen_ld_tl(arg, cpu_env,
6659 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6660 tcg_gen_ext32s_tl(arg, arg);
6664 goto cp0_unimplemented;
6670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6674 check_insn(ctx, ISA_MIPS32R2);
6675 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6680 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6681 tcg_gen_ext32s_tl(arg, arg);
6686 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6687 tcg_gen_ext32s_tl(arg, arg);
6692 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6693 tcg_gen_ext32s_tl(arg, arg);
6698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6703 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6708 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6712 goto cp0_unimplemented;
6718 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6722 check_insn(ctx, ISA_MIPS32R2);
6723 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6727 check_insn(ctx, ISA_MIPS32R2);
6728 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6732 check_insn(ctx, ISA_MIPS32R2);
6733 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6737 check_insn(ctx, ISA_MIPS32R2);
6738 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6742 check_insn(ctx, ISA_MIPS32R2);
6743 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6748 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6752 goto cp0_unimplemented;
6758 check_insn(ctx, ISA_MIPS32R2);
6759 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6763 goto cp0_unimplemented;
6769 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6770 tcg_gen_ext32s_tl(arg, arg);
6775 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6780 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6785 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6786 tcg_gen_andi_tl(arg, arg, ~0xffff);
6790 goto cp0_unimplemented;
6796 /* Mark as an IO operation because we read the time. */
6797 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6800 gen_helper_mfc0_count(arg, cpu_env);
6801 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6804 /* Break the TB to be able to take timer interrupts immediately
6805 after reading count. DISAS_STOP isn't sufficient, we need to
6806 ensure we break completely out of translated code. */
6807 gen_save_pc(ctx->base.pc_next + 4);
6808 ctx->base.is_jmp = DISAS_EXIT;
6811 /* 6,7 are implementation dependent */
6813 goto cp0_unimplemented;
6819 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6820 tcg_gen_ext32s_tl(arg, arg);
6824 goto cp0_unimplemented;
6830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6833 /* 6,7 are implementation dependent */
6835 goto cp0_unimplemented;
6841 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6845 check_insn(ctx, ISA_MIPS32R2);
6846 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6850 check_insn(ctx, ISA_MIPS32R2);
6851 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6855 check_insn(ctx, ISA_MIPS32R2);
6856 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6860 goto cp0_unimplemented;
6866 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6870 goto cp0_unimplemented;
6876 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6877 tcg_gen_ext32s_tl(arg, arg);
6881 goto cp0_unimplemented;
6887 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6891 check_insn(ctx, ISA_MIPS32R2);
6892 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6893 tcg_gen_ext32s_tl(arg, arg);
6897 check_insn(ctx, ISA_MIPS32R2);
6898 CP0_CHECK(ctx->cmgcr);
6899 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6900 tcg_gen_ext32s_tl(arg, arg);
6904 goto cp0_unimplemented;
6910 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6918 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6922 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6926 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6930 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6933 /* 6,7 are implementation dependent */
6935 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6939 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6943 goto cp0_unimplemented;
6949 gen_helper_mfc0_lladdr(arg, cpu_env);
6953 CP0_CHECK(ctx->mrp);
6954 gen_helper_mfc0_maar(arg, cpu_env);
6958 CP0_CHECK(ctx->mrp);
6959 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6963 goto cp0_unimplemented;
6976 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6977 gen_helper_1e0i(mfc0_watchlo, arg, sel);
6981 goto cp0_unimplemented;
6994 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6995 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6999 goto cp0_unimplemented;
7005 #if defined(TARGET_MIPS64)
7006 check_insn(ctx, ISA_MIPS3);
7007 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7008 tcg_gen_ext32s_tl(arg, arg);
7013 goto cp0_unimplemented;
7017 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7018 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7021 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7025 goto cp0_unimplemented;
7029 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7030 rn = "'Diagnostic"; /* implementation dependent */
7035 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7039 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7040 rn = "TraceControl";
7041 goto cp0_unimplemented;
7043 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7044 rn = "TraceControl2";
7045 goto cp0_unimplemented;
7047 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7048 rn = "UserTraceData";
7049 goto cp0_unimplemented;
7051 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7053 goto cp0_unimplemented;
7055 goto cp0_unimplemented;
7062 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7063 tcg_gen_ext32s_tl(arg, arg);
7067 goto cp0_unimplemented;
7073 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7074 rn = "Performance0";
7077 // gen_helper_mfc0_performance1(arg);
7078 rn = "Performance1";
7079 goto cp0_unimplemented;
7081 // gen_helper_mfc0_performance2(arg);
7082 rn = "Performance2";
7083 goto cp0_unimplemented;
7085 // gen_helper_mfc0_performance3(arg);
7086 rn = "Performance3";
7087 goto cp0_unimplemented;
7089 // gen_helper_mfc0_performance4(arg);
7090 rn = "Performance4";
7091 goto cp0_unimplemented;
7093 // gen_helper_mfc0_performance5(arg);
7094 rn = "Performance5";
7095 goto cp0_unimplemented;
7097 // gen_helper_mfc0_performance6(arg);
7098 rn = "Performance6";
7099 goto cp0_unimplemented;
7101 // gen_helper_mfc0_performance7(arg);
7102 rn = "Performance7";
7103 goto cp0_unimplemented;
7105 goto cp0_unimplemented;
7111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7115 goto cp0_unimplemented;
7124 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7128 goto cp0_unimplemented;
7138 TCGv_i64 tmp = tcg_temp_new_i64();
7139 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7140 gen_move_low32(arg, tmp);
7141 tcg_temp_free_i64(tmp);
7149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7153 goto cp0_unimplemented;
7162 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7173 goto cp0_unimplemented;
7179 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7180 tcg_gen_ext32s_tl(arg, arg);
7184 goto cp0_unimplemented;
7191 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7200 CP0_CHECK(ctx->kscrexist & (1 << sel));
7201 tcg_gen_ld_tl(arg, cpu_env,
7202 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7203 tcg_gen_ext32s_tl(arg, arg);
7207 goto cp0_unimplemented;
7211 goto cp0_unimplemented;
7213 trace_mips_translate_c0("mfc0", rn, reg, sel);
7217 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
7218 gen_mfc0_unimplemented(ctx, arg);
7221 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7223 const char *rn = "invalid";
7226 check_insn(ctx, ISA_MIPS32);
7228 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7236 gen_helper_mtc0_index(cpu_env, arg);
7240 CP0_CHECK(ctx->insn_flags & ASE_MT);
7241 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7245 CP0_CHECK(ctx->insn_flags & ASE_MT);
7250 CP0_CHECK(ctx->insn_flags & ASE_MT);
7260 goto cp0_unimplemented;
7270 CP0_CHECK(ctx->insn_flags & ASE_MT);
7271 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7275 CP0_CHECK(ctx->insn_flags & ASE_MT);
7276 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7280 CP0_CHECK(ctx->insn_flags & ASE_MT);
7281 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7285 CP0_CHECK(ctx->insn_flags & ASE_MT);
7286 gen_helper_mtc0_yqmask(cpu_env, arg);
7290 CP0_CHECK(ctx->insn_flags & ASE_MT);
7291 tcg_gen_st_tl(arg, cpu_env,
7292 offsetof(CPUMIPSState, CP0_VPESchedule));
7296 CP0_CHECK(ctx->insn_flags & ASE_MT);
7297 tcg_gen_st_tl(arg, cpu_env,
7298 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7299 rn = "VPEScheFBack";
7302 CP0_CHECK(ctx->insn_flags & ASE_MT);
7303 gen_helper_mtc0_vpeopt(cpu_env, arg);
7307 goto cp0_unimplemented;
7313 gen_helper_mtc0_entrylo0(cpu_env, arg);
7317 CP0_CHECK(ctx->insn_flags & ASE_MT);
7318 gen_helper_mtc0_tcstatus(cpu_env, arg);
7322 CP0_CHECK(ctx->insn_flags & ASE_MT);
7323 gen_helper_mtc0_tcbind(cpu_env, arg);
7327 CP0_CHECK(ctx->insn_flags & ASE_MT);
7328 gen_helper_mtc0_tcrestart(cpu_env, arg);
7332 CP0_CHECK(ctx->insn_flags & ASE_MT);
7333 gen_helper_mtc0_tchalt(cpu_env, arg);
7337 CP0_CHECK(ctx->insn_flags & ASE_MT);
7338 gen_helper_mtc0_tccontext(cpu_env, arg);
7342 CP0_CHECK(ctx->insn_flags & ASE_MT);
7343 gen_helper_mtc0_tcschedule(cpu_env, arg);
7347 CP0_CHECK(ctx->insn_flags & ASE_MT);
7348 gen_helper_mtc0_tcschefback(cpu_env, arg);
7352 goto cp0_unimplemented;
7358 gen_helper_mtc0_entrylo1(cpu_env, arg);
7364 rn = "GlobalNumber";
7367 goto cp0_unimplemented;
7373 gen_helper_mtc0_context(cpu_env, arg);
7377 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7378 rn = "ContextConfig";
7379 goto cp0_unimplemented;
7381 CP0_CHECK(ctx->ulri);
7382 tcg_gen_st_tl(arg, cpu_env,
7383 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7387 goto cp0_unimplemented;
7393 gen_helper_mtc0_pagemask(cpu_env, arg);
7397 check_insn(ctx, ISA_MIPS32R2);
7398 gen_helper_mtc0_pagegrain(cpu_env, arg);
7400 ctx->base.is_jmp = DISAS_STOP;
7404 gen_helper_mtc0_segctl0(cpu_env, arg);
7409 gen_helper_mtc0_segctl1(cpu_env, arg);
7414 gen_helper_mtc0_segctl2(cpu_env, arg);
7419 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7424 gen_helper_mtc0_pwfield(cpu_env, arg);
7429 gen_helper_mtc0_pwsize(cpu_env, arg);
7433 goto cp0_unimplemented;
7439 gen_helper_mtc0_wired(cpu_env, arg);
7443 check_insn(ctx, ISA_MIPS32R2);
7444 gen_helper_mtc0_srsconf0(cpu_env, arg);
7448 check_insn(ctx, ISA_MIPS32R2);
7449 gen_helper_mtc0_srsconf1(cpu_env, arg);
7453 check_insn(ctx, ISA_MIPS32R2);
7454 gen_helper_mtc0_srsconf2(cpu_env, arg);
7458 check_insn(ctx, ISA_MIPS32R2);
7459 gen_helper_mtc0_srsconf3(cpu_env, arg);
7463 check_insn(ctx, ISA_MIPS32R2);
7464 gen_helper_mtc0_srsconf4(cpu_env, arg);
7469 gen_helper_mtc0_pwctl(cpu_env, arg);
7473 goto cp0_unimplemented;
7479 check_insn(ctx, ISA_MIPS32R2);
7480 gen_helper_mtc0_hwrena(cpu_env, arg);
7481 ctx->base.is_jmp = DISAS_STOP;
7485 goto cp0_unimplemented;
7507 goto cp0_unimplemented;
7513 gen_helper_mtc0_count(cpu_env, arg);
7516 /* 6,7 are implementation dependent */
7518 goto cp0_unimplemented;
7524 gen_helper_mtc0_entryhi(cpu_env, arg);
7528 goto cp0_unimplemented;
7534 gen_helper_mtc0_compare(cpu_env, arg);
7537 /* 6,7 are implementation dependent */
7539 goto cp0_unimplemented;
7545 save_cpu_state(ctx, 1);
7546 gen_helper_mtc0_status(cpu_env, arg);
7547 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7548 gen_save_pc(ctx->base.pc_next + 4);
7549 ctx->base.is_jmp = DISAS_EXIT;
7553 check_insn(ctx, ISA_MIPS32R2);
7554 gen_helper_mtc0_intctl(cpu_env, arg);
7555 /* Stop translation as we may have switched the execution mode */
7556 ctx->base.is_jmp = DISAS_STOP;
7560 check_insn(ctx, ISA_MIPS32R2);
7561 gen_helper_mtc0_srsctl(cpu_env, arg);
7562 /* Stop translation as we may have switched the execution mode */
7563 ctx->base.is_jmp = DISAS_STOP;
7567 check_insn(ctx, ISA_MIPS32R2);
7568 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7569 /* Stop translation as we may have switched the execution mode */
7570 ctx->base.is_jmp = DISAS_STOP;
7574 goto cp0_unimplemented;
7580 save_cpu_state(ctx, 1);
7581 gen_helper_mtc0_cause(cpu_env, arg);
7582 /* Stop translation as we may have triggered an interrupt.
7583 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7584 * translated code to check for pending interrupts. */
7585 gen_save_pc(ctx->base.pc_next + 4);
7586 ctx->base.is_jmp = DISAS_EXIT;
7590 goto cp0_unimplemented;
7596 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7600 goto cp0_unimplemented;
7610 check_insn(ctx, ISA_MIPS32R2);
7611 gen_helper_mtc0_ebase(cpu_env, arg);
7615 goto cp0_unimplemented;
7621 gen_helper_mtc0_config0(cpu_env, arg);
7623 /* Stop translation as we may have switched the execution mode */
7624 ctx->base.is_jmp = DISAS_STOP;
7627 /* ignored, read only */
7631 gen_helper_mtc0_config2(cpu_env, arg);
7633 /* Stop translation as we may have switched the execution mode */
7634 ctx->base.is_jmp = DISAS_STOP;
7637 gen_helper_mtc0_config3(cpu_env, arg);
7639 /* Stop translation as we may have switched the execution mode */
7640 ctx->base.is_jmp = DISAS_STOP;
7643 gen_helper_mtc0_config4(cpu_env, arg);
7645 ctx->base.is_jmp = DISAS_STOP;
7648 gen_helper_mtc0_config5(cpu_env, arg);
7650 /* Stop translation as we may have switched the execution mode */
7651 ctx->base.is_jmp = DISAS_STOP;
7653 /* 6,7 are implementation dependent */
7663 rn = "Invalid config selector";
7664 goto cp0_unimplemented;
7670 gen_helper_mtc0_lladdr(cpu_env, arg);
7674 CP0_CHECK(ctx->mrp);
7675 gen_helper_mtc0_maar(cpu_env, arg);
7679 CP0_CHECK(ctx->mrp);
7680 gen_helper_mtc0_maari(cpu_env, arg);
7684 goto cp0_unimplemented;
7697 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7698 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7702 goto cp0_unimplemented;
7715 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7716 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7720 goto cp0_unimplemented;
7726 #if defined(TARGET_MIPS64)
7727 check_insn(ctx, ISA_MIPS3);
7728 gen_helper_mtc0_xcontext(cpu_env, arg);
7733 goto cp0_unimplemented;
7737 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7738 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7741 gen_helper_mtc0_framemask(cpu_env, arg);
7745 goto cp0_unimplemented;
7750 rn = "Diagnostic"; /* implementation dependent */
7755 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7756 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7757 gen_save_pc(ctx->base.pc_next + 4);
7758 ctx->base.is_jmp = DISAS_EXIT;
7762 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7763 rn = "TraceControl";
7764 /* Stop translation as we may have switched the execution mode */
7765 ctx->base.is_jmp = DISAS_STOP;
7766 goto cp0_unimplemented;
7768 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7769 rn = "TraceControl2";
7770 /* Stop translation as we may have switched the execution mode */
7771 ctx->base.is_jmp = DISAS_STOP;
7772 goto cp0_unimplemented;
7774 /* Stop translation as we may have switched the execution mode */
7775 ctx->base.is_jmp = DISAS_STOP;
7776 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7777 rn = "UserTraceData";
7778 /* Stop translation as we may have switched the execution mode */
7779 ctx->base.is_jmp = DISAS_STOP;
7780 goto cp0_unimplemented;
7782 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7783 /* Stop translation as we may have switched the execution mode */
7784 ctx->base.is_jmp = DISAS_STOP;
7786 goto cp0_unimplemented;
7788 goto cp0_unimplemented;
7795 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7799 goto cp0_unimplemented;
7805 gen_helper_mtc0_performance0(cpu_env, arg);
7806 rn = "Performance0";
7809 // gen_helper_mtc0_performance1(arg);
7810 rn = "Performance1";
7811 goto cp0_unimplemented;
7813 // gen_helper_mtc0_performance2(arg);
7814 rn = "Performance2";
7815 goto cp0_unimplemented;
7817 // gen_helper_mtc0_performance3(arg);
7818 rn = "Performance3";
7819 goto cp0_unimplemented;
7821 // gen_helper_mtc0_performance4(arg);
7822 rn = "Performance4";
7823 goto cp0_unimplemented;
7825 // gen_helper_mtc0_performance5(arg);
7826 rn = "Performance5";
7827 goto cp0_unimplemented;
7829 // gen_helper_mtc0_performance6(arg);
7830 rn = "Performance6";
7831 goto cp0_unimplemented;
7833 // gen_helper_mtc0_performance7(arg);
7834 rn = "Performance7";
7835 goto cp0_unimplemented;
7837 goto cp0_unimplemented;
7843 gen_helper_mtc0_errctl(cpu_env, arg);
7844 ctx->base.is_jmp = DISAS_STOP;
7848 goto cp0_unimplemented;
7861 goto cp0_unimplemented;
7870 gen_helper_mtc0_taglo(cpu_env, arg);
7877 gen_helper_mtc0_datalo(cpu_env, arg);
7881 goto cp0_unimplemented;
7890 gen_helper_mtc0_taghi(cpu_env, arg);
7897 gen_helper_mtc0_datahi(cpu_env, arg);
7902 goto cp0_unimplemented;
7908 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7912 goto cp0_unimplemented;
7919 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7928 CP0_CHECK(ctx->kscrexist & (1 << sel));
7929 tcg_gen_st_tl(arg, cpu_env,
7930 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7934 goto cp0_unimplemented;
7938 goto cp0_unimplemented;
7940 trace_mips_translate_c0("mtc0", rn, reg, sel);
7942 /* For simplicity assume that all writes can cause interrupts. */
7943 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7945 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
7946 * translated code to check for pending interrupts. */
7947 gen_save_pc(ctx->base.pc_next + 4);
7948 ctx->base.is_jmp = DISAS_EXIT;
7953 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7956 #if defined(TARGET_MIPS64)
7957 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7959 const char *rn = "invalid";
7962 check_insn(ctx, ISA_MIPS64);
7968 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7972 CP0_CHECK(ctx->insn_flags & ASE_MT);
7973 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7977 CP0_CHECK(ctx->insn_flags & ASE_MT);
7978 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7982 CP0_CHECK(ctx->insn_flags & ASE_MT);
7983 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7988 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7992 goto cp0_unimplemented;
7998 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7999 gen_helper_mfc0_random(arg, cpu_env);
8003 CP0_CHECK(ctx->insn_flags & ASE_MT);
8004 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8008 CP0_CHECK(ctx->insn_flags & ASE_MT);
8009 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8013 CP0_CHECK(ctx->insn_flags & ASE_MT);
8014 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8018 CP0_CHECK(ctx->insn_flags & ASE_MT);
8019 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8023 CP0_CHECK(ctx->insn_flags & ASE_MT);
8024 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8028 CP0_CHECK(ctx->insn_flags & ASE_MT);
8029 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8030 rn = "VPEScheFBack";
8033 CP0_CHECK(ctx->insn_flags & ASE_MT);
8034 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8038 goto cp0_unimplemented;
8044 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8048 CP0_CHECK(ctx->insn_flags & ASE_MT);
8049 gen_helper_mfc0_tcstatus(arg, cpu_env);
8053 CP0_CHECK(ctx->insn_flags & ASE_MT);
8054 gen_helper_mfc0_tcbind(arg, cpu_env);
8058 CP0_CHECK(ctx->insn_flags & ASE_MT);
8059 gen_helper_dmfc0_tcrestart(arg, cpu_env);
8063 CP0_CHECK(ctx->insn_flags & ASE_MT);
8064 gen_helper_dmfc0_tchalt(arg, cpu_env);
8068 CP0_CHECK(ctx->insn_flags & ASE_MT);
8069 gen_helper_dmfc0_tccontext(arg, cpu_env);
8073 CP0_CHECK(ctx->insn_flags & ASE_MT);
8074 gen_helper_dmfc0_tcschedule(arg, cpu_env);
8078 CP0_CHECK(ctx->insn_flags & ASE_MT);
8079 gen_helper_dmfc0_tcschefback(arg, cpu_env);
8083 goto cp0_unimplemented;
8089 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8094 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8095 rn = "GlobalNumber";
8098 goto cp0_unimplemented;
8104 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8108 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8109 rn = "ContextConfig";
8110 goto cp0_unimplemented;
8112 CP0_CHECK(ctx->ulri);
8113 tcg_gen_ld_tl(arg, cpu_env,
8114 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8118 goto cp0_unimplemented;
8124 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8128 check_insn(ctx, ISA_MIPS32R2);
8129 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8134 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8139 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8144 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8149 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8154 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8159 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8163 goto cp0_unimplemented;
8169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8173 check_insn(ctx, ISA_MIPS32R2);
8174 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8178 check_insn(ctx, ISA_MIPS32R2);
8179 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8183 check_insn(ctx, ISA_MIPS32R2);
8184 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8188 check_insn(ctx, ISA_MIPS32R2);
8189 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8193 check_insn(ctx, ISA_MIPS32R2);
8194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8203 goto cp0_unimplemented;
8209 check_insn(ctx, ISA_MIPS32R2);
8210 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8214 goto cp0_unimplemented;
8220 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8235 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8236 tcg_gen_andi_tl(arg, arg, ~0xffff);
8240 goto cp0_unimplemented;
8246 /* Mark as an IO operation because we read the time. */
8247 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8250 gen_helper_mfc0_count(arg, cpu_env);
8251 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8254 /* Break the TB to be able to take timer interrupts immediately
8255 after reading count. DISAS_STOP isn't sufficient, we need to
8256 ensure we break completely out of translated code. */
8257 gen_save_pc(ctx->base.pc_next + 4);
8258 ctx->base.is_jmp = DISAS_EXIT;
8261 /* 6,7 are implementation dependent */
8263 goto cp0_unimplemented;
8269 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8273 goto cp0_unimplemented;
8279 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8282 /* 6,7 are implementation dependent */
8284 goto cp0_unimplemented;
8290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8294 check_insn(ctx, ISA_MIPS32R2);
8295 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8299 check_insn(ctx, ISA_MIPS32R2);
8300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8304 check_insn(ctx, ISA_MIPS32R2);
8305 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8309 goto cp0_unimplemented;
8315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8319 goto cp0_unimplemented;
8325 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8329 goto cp0_unimplemented;
8335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8339 check_insn(ctx, ISA_MIPS32R2);
8340 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8344 check_insn(ctx, ISA_MIPS32R2);
8345 CP0_CHECK(ctx->cmgcr);
8346 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8350 goto cp0_unimplemented;
8356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8360 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8379 /* 6,7 are implementation dependent */
8381 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8385 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8389 goto cp0_unimplemented;
8395 gen_helper_dmfc0_lladdr(arg, cpu_env);
8399 CP0_CHECK(ctx->mrp);
8400 gen_helper_dmfc0_maar(arg, cpu_env);
8404 CP0_CHECK(ctx->mrp);
8405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8409 goto cp0_unimplemented;
8422 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8423 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8427 goto cp0_unimplemented;
8440 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8441 gen_helper_1e0i(mfc0_watchhi, arg, sel);
8445 goto cp0_unimplemented;
8451 check_insn(ctx, ISA_MIPS3);
8452 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8456 goto cp0_unimplemented;
8460 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8461 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8468 goto cp0_unimplemented;
8472 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8473 rn = "'Diagnostic"; /* implementation dependent */
8478 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8482 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8483 rn = "TraceControl";
8484 goto cp0_unimplemented;
8486 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8487 rn = "TraceControl2";
8488 goto cp0_unimplemented;
8490 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8491 rn = "UserTraceData";
8492 goto cp0_unimplemented;
8494 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8496 goto cp0_unimplemented;
8498 goto cp0_unimplemented;
8505 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8509 goto cp0_unimplemented;
8515 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8516 rn = "Performance0";
8519 // gen_helper_dmfc0_performance1(arg);
8520 rn = "Performance1";
8521 goto cp0_unimplemented;
8523 // gen_helper_dmfc0_performance2(arg);
8524 rn = "Performance2";
8525 goto cp0_unimplemented;
8527 // gen_helper_dmfc0_performance3(arg);
8528 rn = "Performance3";
8529 goto cp0_unimplemented;
8531 // gen_helper_dmfc0_performance4(arg);
8532 rn = "Performance4";
8533 goto cp0_unimplemented;
8535 // gen_helper_dmfc0_performance5(arg);
8536 rn = "Performance5";
8537 goto cp0_unimplemented;
8539 // gen_helper_dmfc0_performance6(arg);
8540 rn = "Performance6";
8541 goto cp0_unimplemented;
8543 // gen_helper_dmfc0_performance7(arg);
8544 rn = "Performance7";
8545 goto cp0_unimplemented;
8547 goto cp0_unimplemented;
8553 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8557 goto cp0_unimplemented;
8567 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8571 goto cp0_unimplemented;
8580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8591 goto cp0_unimplemented;
8600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8611 goto cp0_unimplemented;
8617 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8621 goto cp0_unimplemented;
8628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8637 CP0_CHECK(ctx->kscrexist & (1 << sel));
8638 tcg_gen_ld_tl(arg, cpu_env,
8639 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8643 goto cp0_unimplemented;
8647 goto cp0_unimplemented;
8649 trace_mips_translate_c0("dmfc0", rn, reg, sel);
8653 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
8654 gen_mfc0_unimplemented(ctx, arg);
8657 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8659 const char *rn = "invalid";
8662 check_insn(ctx, ISA_MIPS64);
8664 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8672 gen_helper_mtc0_index(cpu_env, arg);
8676 CP0_CHECK(ctx->insn_flags & ASE_MT);
8677 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8681 CP0_CHECK(ctx->insn_flags & ASE_MT);
8686 CP0_CHECK(ctx->insn_flags & ASE_MT);
8696 goto cp0_unimplemented;
8706 CP0_CHECK(ctx->insn_flags & ASE_MT);
8707 gen_helper_mtc0_vpecontrol(cpu_env, arg);
8711 CP0_CHECK(ctx->insn_flags & ASE_MT);
8712 gen_helper_mtc0_vpeconf0(cpu_env, arg);
8716 CP0_CHECK(ctx->insn_flags & ASE_MT);
8717 gen_helper_mtc0_vpeconf1(cpu_env, arg);
8721 CP0_CHECK(ctx->insn_flags & ASE_MT);
8722 gen_helper_mtc0_yqmask(cpu_env, arg);
8726 CP0_CHECK(ctx->insn_flags & ASE_MT);
8727 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8731 CP0_CHECK(ctx->insn_flags & ASE_MT);
8732 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8733 rn = "VPEScheFBack";
8736 CP0_CHECK(ctx->insn_flags & ASE_MT);
8737 gen_helper_mtc0_vpeopt(cpu_env, arg);
8741 goto cp0_unimplemented;
8747 gen_helper_dmtc0_entrylo0(cpu_env, arg);
8751 CP0_CHECK(ctx->insn_flags & ASE_MT);
8752 gen_helper_mtc0_tcstatus(cpu_env, arg);
8756 CP0_CHECK(ctx->insn_flags & ASE_MT);
8757 gen_helper_mtc0_tcbind(cpu_env, arg);
8761 CP0_CHECK(ctx->insn_flags & ASE_MT);
8762 gen_helper_mtc0_tcrestart(cpu_env, arg);
8766 CP0_CHECK(ctx->insn_flags & ASE_MT);
8767 gen_helper_mtc0_tchalt(cpu_env, arg);
8771 CP0_CHECK(ctx->insn_flags & ASE_MT);
8772 gen_helper_mtc0_tccontext(cpu_env, arg);
8776 CP0_CHECK(ctx->insn_flags & ASE_MT);
8777 gen_helper_mtc0_tcschedule(cpu_env, arg);
8781 CP0_CHECK(ctx->insn_flags & ASE_MT);
8782 gen_helper_mtc0_tcschefback(cpu_env, arg);
8786 goto cp0_unimplemented;
8792 gen_helper_dmtc0_entrylo1(cpu_env, arg);
8798 rn = "GlobalNumber";
8801 goto cp0_unimplemented;
8807 gen_helper_mtc0_context(cpu_env, arg);
8811 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8812 rn = "ContextConfig";
8813 goto cp0_unimplemented;
8815 CP0_CHECK(ctx->ulri);
8816 tcg_gen_st_tl(arg, cpu_env,
8817 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8821 goto cp0_unimplemented;
8827 gen_helper_mtc0_pagemask(cpu_env, arg);
8831 check_insn(ctx, ISA_MIPS32R2);
8832 gen_helper_mtc0_pagegrain(cpu_env, arg);
8837 gen_helper_mtc0_segctl0(cpu_env, arg);
8842 gen_helper_mtc0_segctl1(cpu_env, arg);
8847 gen_helper_mtc0_segctl2(cpu_env, arg);
8852 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8857 gen_helper_mtc0_pwfield(cpu_env, arg);
8862 gen_helper_mtc0_pwsize(cpu_env, arg);
8866 goto cp0_unimplemented;
8872 gen_helper_mtc0_wired(cpu_env, arg);
8876 check_insn(ctx, ISA_MIPS32R2);
8877 gen_helper_mtc0_srsconf0(cpu_env, arg);
8881 check_insn(ctx, ISA_MIPS32R2);
8882 gen_helper_mtc0_srsconf1(cpu_env, arg);
8886 check_insn(ctx, ISA_MIPS32R2);
8887 gen_helper_mtc0_srsconf2(cpu_env, arg);
8891 check_insn(ctx, ISA_MIPS32R2);
8892 gen_helper_mtc0_srsconf3(cpu_env, arg);
8896 check_insn(ctx, ISA_MIPS32R2);
8897 gen_helper_mtc0_srsconf4(cpu_env, arg);
8902 gen_helper_mtc0_pwctl(cpu_env, arg);
8906 goto cp0_unimplemented;
8912 check_insn(ctx, ISA_MIPS32R2);
8913 gen_helper_mtc0_hwrena(cpu_env, arg);
8914 ctx->base.is_jmp = DISAS_STOP;
8918 goto cp0_unimplemented;
8940 goto cp0_unimplemented;
8946 gen_helper_mtc0_count(cpu_env, arg);
8949 /* 6,7 are implementation dependent */
8951 goto cp0_unimplemented;
8953 /* Stop translation as we may have switched the execution mode */
8954 ctx->base.is_jmp = DISAS_STOP;
8959 gen_helper_mtc0_entryhi(cpu_env, arg);
8963 goto cp0_unimplemented;
8969 gen_helper_mtc0_compare(cpu_env, arg);
8972 /* 6,7 are implementation dependent */
8974 goto cp0_unimplemented;
8976 /* Stop translation as we may have switched the execution mode */
8977 ctx->base.is_jmp = DISAS_STOP;
8982 save_cpu_state(ctx, 1);
8983 gen_helper_mtc0_status(cpu_env, arg);
8984 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8985 gen_save_pc(ctx->base.pc_next + 4);
8986 ctx->base.is_jmp = DISAS_EXIT;
8990 check_insn(ctx, ISA_MIPS32R2);
8991 gen_helper_mtc0_intctl(cpu_env, arg);
8992 /* Stop translation as we may have switched the execution mode */
8993 ctx->base.is_jmp = DISAS_STOP;
8997 check_insn(ctx, ISA_MIPS32R2);
8998 gen_helper_mtc0_srsctl(cpu_env, arg);
8999 /* Stop translation as we may have switched the execution mode */
9000 ctx->base.is_jmp = DISAS_STOP;
9004 check_insn(ctx, ISA_MIPS32R2);
9005 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9006 /* Stop translation as we may have switched the execution mode */
9007 ctx->base.is_jmp = DISAS_STOP;
9011 goto cp0_unimplemented;
9017 save_cpu_state(ctx, 1);
9018 gen_helper_mtc0_cause(cpu_env, arg);
9019 /* Stop translation as we may have triggered an interrupt.
9020 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9021 * translated code to check for pending interrupts. */
9022 gen_save_pc(ctx->base.pc_next + 4);
9023 ctx->base.is_jmp = DISAS_EXIT;
9027 goto cp0_unimplemented;
9033 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9037 goto cp0_unimplemented;
9047 check_insn(ctx, ISA_MIPS32R2);
9048 gen_helper_mtc0_ebase(cpu_env, arg);
9052 goto cp0_unimplemented;
9058 gen_helper_mtc0_config0(cpu_env, arg);
9060 /* Stop translation as we may have switched the execution mode */
9061 ctx->base.is_jmp = DISAS_STOP;
9064 /* ignored, read only */
9068 gen_helper_mtc0_config2(cpu_env, arg);
9070 /* Stop translation as we may have switched the execution mode */
9071 ctx->base.is_jmp = DISAS_STOP;
9074 gen_helper_mtc0_config3(cpu_env, arg);
9076 /* Stop translation as we may have switched the execution mode */
9077 ctx->base.is_jmp = DISAS_STOP;
9080 /* currently ignored */
9084 gen_helper_mtc0_config5(cpu_env, arg);
9086 /* Stop translation as we may have switched the execution mode */
9087 ctx->base.is_jmp = DISAS_STOP;
9089 /* 6,7 are implementation dependent */
9091 rn = "Invalid config selector";
9092 goto cp0_unimplemented;
9098 gen_helper_mtc0_lladdr(cpu_env, arg);
9102 CP0_CHECK(ctx->mrp);
9103 gen_helper_mtc0_maar(cpu_env, arg);
9107 CP0_CHECK(ctx->mrp);
9108 gen_helper_mtc0_maari(cpu_env, arg);
9112 goto cp0_unimplemented;
9125 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9126 gen_helper_0e1i(mtc0_watchlo, arg, sel);
9130 goto cp0_unimplemented;
9143 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9144 gen_helper_0e1i(mtc0_watchhi, arg, sel);
9148 goto cp0_unimplemented;
9154 check_insn(ctx, ISA_MIPS3);
9155 gen_helper_mtc0_xcontext(cpu_env, arg);
9159 goto cp0_unimplemented;
9163 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9164 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9167 gen_helper_mtc0_framemask(cpu_env, arg);
9171 goto cp0_unimplemented;
9176 rn = "Diagnostic"; /* implementation dependent */
9181 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9182 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9183 gen_save_pc(ctx->base.pc_next + 4);
9184 ctx->base.is_jmp = DISAS_EXIT;
9188 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9189 /* Stop translation as we may have switched the execution mode */
9190 ctx->base.is_jmp = DISAS_STOP;
9191 rn = "TraceControl";
9192 goto cp0_unimplemented;
9194 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9195 /* Stop translation as we may have switched the execution mode */
9196 ctx->base.is_jmp = DISAS_STOP;
9197 rn = "TraceControl2";
9198 goto cp0_unimplemented;
9200 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9201 /* Stop translation as we may have switched the execution mode */
9202 ctx->base.is_jmp = DISAS_STOP;
9203 rn = "UserTraceData";
9204 goto cp0_unimplemented;
9206 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9207 /* Stop translation as we may have switched the execution mode */
9208 ctx->base.is_jmp = DISAS_STOP;
9210 goto cp0_unimplemented;
9212 goto cp0_unimplemented;
9219 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9223 goto cp0_unimplemented;
9229 gen_helper_mtc0_performance0(cpu_env, arg);
9230 rn = "Performance0";
9233 // gen_helper_mtc0_performance1(cpu_env, arg);
9234 rn = "Performance1";
9235 goto cp0_unimplemented;
9237 // gen_helper_mtc0_performance2(cpu_env, arg);
9238 rn = "Performance2";
9239 goto cp0_unimplemented;
9241 // gen_helper_mtc0_performance3(cpu_env, arg);
9242 rn = "Performance3";
9243 goto cp0_unimplemented;
9245 // gen_helper_mtc0_performance4(cpu_env, arg);
9246 rn = "Performance4";
9247 goto cp0_unimplemented;
9249 // gen_helper_mtc0_performance5(cpu_env, arg);
9250 rn = "Performance5";
9251 goto cp0_unimplemented;
9253 // gen_helper_mtc0_performance6(cpu_env, arg);
9254 rn = "Performance6";
9255 goto cp0_unimplemented;
9257 // gen_helper_mtc0_performance7(cpu_env, arg);
9258 rn = "Performance7";
9259 goto cp0_unimplemented;
9261 goto cp0_unimplemented;
9267 gen_helper_mtc0_errctl(cpu_env, arg);
9268 ctx->base.is_jmp = DISAS_STOP;
9272 goto cp0_unimplemented;
9285 goto cp0_unimplemented;
9294 gen_helper_mtc0_taglo(cpu_env, arg);
9301 gen_helper_mtc0_datalo(cpu_env, arg);
9305 goto cp0_unimplemented;
9314 gen_helper_mtc0_taghi(cpu_env, arg);
9321 gen_helper_mtc0_datahi(cpu_env, arg);
9326 goto cp0_unimplemented;
9332 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9336 goto cp0_unimplemented;
9343 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9352 CP0_CHECK(ctx->kscrexist & (1 << sel));
9353 tcg_gen_st_tl(arg, cpu_env,
9354 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9358 goto cp0_unimplemented;
9362 goto cp0_unimplemented;
9364 trace_mips_translate_c0("dmtc0", rn, reg, sel);
9366 /* For simplicity assume that all writes can cause interrupts. */
9367 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9369 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9370 * translated code to check for pending interrupts. */
9371 gen_save_pc(ctx->base.pc_next + 4);
9372 ctx->base.is_jmp = DISAS_EXIT;
9377 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9379 #endif /* TARGET_MIPS64 */
9381 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9382 int u, int sel, int h)
9384 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9385 TCGv t0 = tcg_temp_local_new();
9387 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9388 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9389 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9390 tcg_gen_movi_tl(t0, -1);
9391 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9392 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9393 tcg_gen_movi_tl(t0, -1);
9399 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9402 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9412 gen_helper_mftc0_tcstatus(t0, cpu_env);
9415 gen_helper_mftc0_tcbind(t0, cpu_env);
9418 gen_helper_mftc0_tcrestart(t0, cpu_env);
9421 gen_helper_mftc0_tchalt(t0, cpu_env);
9424 gen_helper_mftc0_tccontext(t0, cpu_env);
9427 gen_helper_mftc0_tcschedule(t0, cpu_env);
9430 gen_helper_mftc0_tcschefback(t0, cpu_env);
9433 gen_mfc0(ctx, t0, rt, sel);
9440 gen_helper_mftc0_entryhi(t0, cpu_env);
9443 gen_mfc0(ctx, t0, rt, sel);
9449 gen_helper_mftc0_status(t0, cpu_env);
9452 gen_mfc0(ctx, t0, rt, sel);
9458 gen_helper_mftc0_cause(t0, cpu_env);
9468 gen_helper_mftc0_epc(t0, cpu_env);
9478 gen_helper_mftc0_ebase(t0, cpu_env);
9495 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9505 gen_helper_mftc0_debug(t0, cpu_env);
9508 gen_mfc0(ctx, t0, rt, sel);
9513 gen_mfc0(ctx, t0, rt, sel);
9515 } else switch (sel) {
9516 /* GPR registers. */
9518 gen_helper_1e0i(mftgpr, t0, rt);
9520 /* Auxiliary CPU registers */
9524 gen_helper_1e0i(mftlo, t0, 0);
9527 gen_helper_1e0i(mfthi, t0, 0);
9530 gen_helper_1e0i(mftacx, t0, 0);
9533 gen_helper_1e0i(mftlo, t0, 1);
9536 gen_helper_1e0i(mfthi, t0, 1);
9539 gen_helper_1e0i(mftacx, t0, 1);
9542 gen_helper_1e0i(mftlo, t0, 2);
9545 gen_helper_1e0i(mfthi, t0, 2);
9548 gen_helper_1e0i(mftacx, t0, 2);
9551 gen_helper_1e0i(mftlo, t0, 3);
9554 gen_helper_1e0i(mfthi, t0, 3);
9557 gen_helper_1e0i(mftacx, t0, 3);
9560 gen_helper_mftdsp(t0, cpu_env);
9566 /* Floating point (COP1). */
9568 /* XXX: For now we support only a single FPU context. */
9570 TCGv_i32 fp0 = tcg_temp_new_i32();
9572 gen_load_fpr32(ctx, fp0, rt);
9573 tcg_gen_ext_i32_tl(t0, fp0);
9574 tcg_temp_free_i32(fp0);
9576 TCGv_i32 fp0 = tcg_temp_new_i32();
9578 gen_load_fpr32h(ctx, fp0, rt);
9579 tcg_gen_ext_i32_tl(t0, fp0);
9580 tcg_temp_free_i32(fp0);
9584 /* XXX: For now we support only a single FPU context. */
9585 gen_helper_1e0i(cfc1, t0, rt);
9587 /* COP2: Not implemented. */
9594 trace_mips_translate_tr("mftr", rt, u, sel, h);
9595 gen_store_gpr(t0, rd);
9601 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9602 generate_exception_end(ctx, EXCP_RI);
9605 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9606 int u, int sel, int h)
9608 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9609 TCGv t0 = tcg_temp_local_new();
9611 gen_load_gpr(t0, rt);
9612 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9613 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9614 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9616 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9617 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9624 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9627 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9637 gen_helper_mttc0_tcstatus(cpu_env, t0);
9640 gen_helper_mttc0_tcbind(cpu_env, t0);
9643 gen_helper_mttc0_tcrestart(cpu_env, t0);
9646 gen_helper_mttc0_tchalt(cpu_env, t0);
9649 gen_helper_mttc0_tccontext(cpu_env, t0);
9652 gen_helper_mttc0_tcschedule(cpu_env, t0);
9655 gen_helper_mttc0_tcschefback(cpu_env, t0);
9658 gen_mtc0(ctx, t0, rd, sel);
9665 gen_helper_mttc0_entryhi(cpu_env, t0);
9668 gen_mtc0(ctx, t0, rd, sel);
9674 gen_helper_mttc0_status(cpu_env, t0);
9677 gen_mtc0(ctx, t0, rd, sel);
9683 gen_helper_mttc0_cause(cpu_env, t0);
9693 gen_helper_mttc0_ebase(cpu_env, t0);
9703 gen_helper_mttc0_debug(cpu_env, t0);
9706 gen_mtc0(ctx, t0, rd, sel);
9711 gen_mtc0(ctx, t0, rd, sel);
9713 } else switch (sel) {
9714 /* GPR registers. */
9716 gen_helper_0e1i(mttgpr, t0, rd);
9718 /* Auxiliary CPU registers */
9722 gen_helper_0e1i(mttlo, t0, 0);
9725 gen_helper_0e1i(mtthi, t0, 0);
9728 gen_helper_0e1i(mttacx, t0, 0);
9731 gen_helper_0e1i(mttlo, t0, 1);
9734 gen_helper_0e1i(mtthi, t0, 1);
9737 gen_helper_0e1i(mttacx, t0, 1);
9740 gen_helper_0e1i(mttlo, t0, 2);
9743 gen_helper_0e1i(mtthi, t0, 2);
9746 gen_helper_0e1i(mttacx, t0, 2);
9749 gen_helper_0e1i(mttlo, t0, 3);
9752 gen_helper_0e1i(mtthi, t0, 3);
9755 gen_helper_0e1i(mttacx, t0, 3);
9758 gen_helper_mttdsp(cpu_env, t0);
9764 /* Floating point (COP1). */
9766 /* XXX: For now we support only a single FPU context. */
9768 TCGv_i32 fp0 = tcg_temp_new_i32();
9770 tcg_gen_trunc_tl_i32(fp0, t0);
9771 gen_store_fpr32(ctx, fp0, rd);
9772 tcg_temp_free_i32(fp0);
9774 TCGv_i32 fp0 = tcg_temp_new_i32();
9776 tcg_gen_trunc_tl_i32(fp0, t0);
9777 gen_store_fpr32h(ctx, fp0, rd);
9778 tcg_temp_free_i32(fp0);
9782 /* XXX: For now we support only a single FPU context. */
9784 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9786 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9787 tcg_temp_free_i32(fs_tmp);
9789 /* Stop translation as we may have changed hflags */
9790 ctx->base.is_jmp = DISAS_STOP;
9792 /* COP2: Not implemented. */
9799 trace_mips_translate_tr("mttr", rd, u, sel, h);
9805 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9806 generate_exception_end(ctx, EXCP_RI);
9809 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9811 const char *opn = "ldst";
9813 check_cp0_enabled(ctx);
9820 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9825 TCGv t0 = tcg_temp_new();
9827 gen_load_gpr(t0, rt);
9828 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9833 #if defined(TARGET_MIPS64)
9835 check_insn(ctx, ISA_MIPS3);
9840 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9844 check_insn(ctx, ISA_MIPS3);
9846 TCGv t0 = tcg_temp_new();
9848 gen_load_gpr(t0, rt);
9849 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9861 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9867 TCGv t0 = tcg_temp_new();
9868 gen_load_gpr(t0, rt);
9869 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9875 check_cp0_enabled(ctx);
9880 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9881 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9885 check_cp0_enabled(ctx);
9886 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9887 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9892 if (!env->tlb->helper_tlbwi)
9894 gen_helper_tlbwi(cpu_env);
9899 if (!env->tlb->helper_tlbinv) {
9902 gen_helper_tlbinv(cpu_env);
9903 } /* treat as nop if TLBINV not supported */
9908 if (!env->tlb->helper_tlbinvf) {
9911 gen_helper_tlbinvf(cpu_env);
9912 } /* treat as nop if TLBINV not supported */
9916 if (!env->tlb->helper_tlbwr)
9918 gen_helper_tlbwr(cpu_env);
9922 if (!env->tlb->helper_tlbp)
9924 gen_helper_tlbp(cpu_env);
9928 if (!env->tlb->helper_tlbr)
9930 gen_helper_tlbr(cpu_env);
9932 case OPC_ERET: /* OPC_ERETNC */
9933 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9934 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9937 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9938 if (ctx->opcode & (1 << bit_shift)) {
9941 check_insn(ctx, ISA_MIPS32R5);
9942 gen_helper_eretnc(cpu_env);
9946 check_insn(ctx, ISA_MIPS2);
9947 gen_helper_eret(cpu_env);
9949 ctx->base.is_jmp = DISAS_EXIT;
9954 check_insn(ctx, ISA_MIPS32);
9955 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9956 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9959 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9961 generate_exception_end(ctx, EXCP_RI);
9963 gen_helper_deret(cpu_env);
9964 ctx->base.is_jmp = DISAS_EXIT;
9969 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
9970 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9971 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9974 /* If we get an exception, we want to restart at next instruction */
9975 ctx->base.pc_next += 4;
9976 save_cpu_state(ctx, 1);
9977 ctx->base.pc_next -= 4;
9978 gen_helper_wait(cpu_env);
9979 ctx->base.is_jmp = DISAS_NORETURN;
9984 generate_exception_end(ctx, EXCP_RI);
9987 (void)opn; /* avoid a compiler warning */
9989 #endif /* !CONFIG_USER_ONLY */
9991 /* CP1 Branches (before delay slot) */
9992 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9993 int32_t cc, int32_t offset)
9995 target_ulong btarget;
9996 TCGv_i32 t0 = tcg_temp_new_i32();
9998 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9999 generate_exception_end(ctx, EXCP_RI);
10004 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10006 btarget = ctx->base.pc_next + 4 + offset;
10010 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10011 tcg_gen_not_i32(t0, t0);
10012 tcg_gen_andi_i32(t0, t0, 1);
10013 tcg_gen_extu_i32_tl(bcond, t0);
10016 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10017 tcg_gen_not_i32(t0, t0);
10018 tcg_gen_andi_i32(t0, t0, 1);
10019 tcg_gen_extu_i32_tl(bcond, t0);
10022 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10023 tcg_gen_andi_i32(t0, t0, 1);
10024 tcg_gen_extu_i32_tl(bcond, t0);
10027 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10028 tcg_gen_andi_i32(t0, t0, 1);
10029 tcg_gen_extu_i32_tl(bcond, t0);
10031 ctx->hflags |= MIPS_HFLAG_BL;
10035 TCGv_i32 t1 = tcg_temp_new_i32();
10036 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10037 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10038 tcg_gen_nand_i32(t0, t0, t1);
10039 tcg_temp_free_i32(t1);
10040 tcg_gen_andi_i32(t0, t0, 1);
10041 tcg_gen_extu_i32_tl(bcond, t0);
10046 TCGv_i32 t1 = tcg_temp_new_i32();
10047 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10048 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10049 tcg_gen_or_i32(t0, t0, t1);
10050 tcg_temp_free_i32(t1);
10051 tcg_gen_andi_i32(t0, t0, 1);
10052 tcg_gen_extu_i32_tl(bcond, t0);
10057 TCGv_i32 t1 = tcg_temp_new_i32();
10058 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10060 tcg_gen_and_i32(t0, t0, t1);
10061 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10062 tcg_gen_and_i32(t0, t0, t1);
10063 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10064 tcg_gen_nand_i32(t0, t0, t1);
10065 tcg_temp_free_i32(t1);
10066 tcg_gen_andi_i32(t0, t0, 1);
10067 tcg_gen_extu_i32_tl(bcond, t0);
10072 TCGv_i32 t1 = tcg_temp_new_i32();
10073 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10074 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10075 tcg_gen_or_i32(t0, t0, t1);
10076 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10077 tcg_gen_or_i32(t0, t0, t1);
10078 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10079 tcg_gen_or_i32(t0, t0, t1);
10080 tcg_temp_free_i32(t1);
10081 tcg_gen_andi_i32(t0, t0, 1);
10082 tcg_gen_extu_i32_tl(bcond, t0);
10085 ctx->hflags |= MIPS_HFLAG_BC;
10088 MIPS_INVAL("cp1 cond branch");
10089 generate_exception_end(ctx, EXCP_RI);
10092 ctx->btarget = btarget;
10093 ctx->hflags |= MIPS_HFLAG_BDS32;
10095 tcg_temp_free_i32(t0);
10098 /* R6 CP1 Branches */
10099 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10100 int32_t ft, int32_t offset,
10101 int delayslot_size)
10103 target_ulong btarget;
10104 TCGv_i64 t0 = tcg_temp_new_i64();
10106 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10107 #ifdef MIPS_DEBUG_DISAS
10108 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10109 "\n", ctx->base.pc_next);
10111 generate_exception_end(ctx, EXCP_RI);
10115 gen_load_fpr64(ctx, t0, ft);
10116 tcg_gen_andi_i64(t0, t0, 1);
10118 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10122 tcg_gen_xori_i64(t0, t0, 1);
10123 ctx->hflags |= MIPS_HFLAG_BC;
10126 /* t0 already set */
10127 ctx->hflags |= MIPS_HFLAG_BC;
10130 MIPS_INVAL("cp1 cond branch");
10131 generate_exception_end(ctx, EXCP_RI);
10135 tcg_gen_trunc_i64_tl(bcond, t0);
10137 ctx->btarget = btarget;
10139 switch (delayslot_size) {
10141 ctx->hflags |= MIPS_HFLAG_BDS16;
10144 ctx->hflags |= MIPS_HFLAG_BDS32;
10149 tcg_temp_free_i64(t0);
10152 /* Coprocessor 1 (FPU) */
10154 #define FOP(func, fmt) (((fmt) << 21) | (func))
10157 OPC_ADD_S = FOP(0, FMT_S),
10158 OPC_SUB_S = FOP(1, FMT_S),
10159 OPC_MUL_S = FOP(2, FMT_S),
10160 OPC_DIV_S = FOP(3, FMT_S),
10161 OPC_SQRT_S = FOP(4, FMT_S),
10162 OPC_ABS_S = FOP(5, FMT_S),
10163 OPC_MOV_S = FOP(6, FMT_S),
10164 OPC_NEG_S = FOP(7, FMT_S),
10165 OPC_ROUND_L_S = FOP(8, FMT_S),
10166 OPC_TRUNC_L_S = FOP(9, FMT_S),
10167 OPC_CEIL_L_S = FOP(10, FMT_S),
10168 OPC_FLOOR_L_S = FOP(11, FMT_S),
10169 OPC_ROUND_W_S = FOP(12, FMT_S),
10170 OPC_TRUNC_W_S = FOP(13, FMT_S),
10171 OPC_CEIL_W_S = FOP(14, FMT_S),
10172 OPC_FLOOR_W_S = FOP(15, FMT_S),
10173 OPC_SEL_S = FOP(16, FMT_S),
10174 OPC_MOVCF_S = FOP(17, FMT_S),
10175 OPC_MOVZ_S = FOP(18, FMT_S),
10176 OPC_MOVN_S = FOP(19, FMT_S),
10177 OPC_SELEQZ_S = FOP(20, FMT_S),
10178 OPC_RECIP_S = FOP(21, FMT_S),
10179 OPC_RSQRT_S = FOP(22, FMT_S),
10180 OPC_SELNEZ_S = FOP(23, FMT_S),
10181 OPC_MADDF_S = FOP(24, FMT_S),
10182 OPC_MSUBF_S = FOP(25, FMT_S),
10183 OPC_RINT_S = FOP(26, FMT_S),
10184 OPC_CLASS_S = FOP(27, FMT_S),
10185 OPC_MIN_S = FOP(28, FMT_S),
10186 OPC_RECIP2_S = FOP(28, FMT_S),
10187 OPC_MINA_S = FOP(29, FMT_S),
10188 OPC_RECIP1_S = FOP(29, FMT_S),
10189 OPC_MAX_S = FOP(30, FMT_S),
10190 OPC_RSQRT1_S = FOP(30, FMT_S),
10191 OPC_MAXA_S = FOP(31, FMT_S),
10192 OPC_RSQRT2_S = FOP(31, FMT_S),
10193 OPC_CVT_D_S = FOP(33, FMT_S),
10194 OPC_CVT_W_S = FOP(36, FMT_S),
10195 OPC_CVT_L_S = FOP(37, FMT_S),
10196 OPC_CVT_PS_S = FOP(38, FMT_S),
10197 OPC_CMP_F_S = FOP (48, FMT_S),
10198 OPC_CMP_UN_S = FOP (49, FMT_S),
10199 OPC_CMP_EQ_S = FOP (50, FMT_S),
10200 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10201 OPC_CMP_OLT_S = FOP (52, FMT_S),
10202 OPC_CMP_ULT_S = FOP (53, FMT_S),
10203 OPC_CMP_OLE_S = FOP (54, FMT_S),
10204 OPC_CMP_ULE_S = FOP (55, FMT_S),
10205 OPC_CMP_SF_S = FOP (56, FMT_S),
10206 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10207 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10208 OPC_CMP_NGL_S = FOP (59, FMT_S),
10209 OPC_CMP_LT_S = FOP (60, FMT_S),
10210 OPC_CMP_NGE_S = FOP (61, FMT_S),
10211 OPC_CMP_LE_S = FOP (62, FMT_S),
10212 OPC_CMP_NGT_S = FOP (63, FMT_S),
10214 OPC_ADD_D = FOP(0, FMT_D),
10215 OPC_SUB_D = FOP(1, FMT_D),
10216 OPC_MUL_D = FOP(2, FMT_D),
10217 OPC_DIV_D = FOP(3, FMT_D),
10218 OPC_SQRT_D = FOP(4, FMT_D),
10219 OPC_ABS_D = FOP(5, FMT_D),
10220 OPC_MOV_D = FOP(6, FMT_D),
10221 OPC_NEG_D = FOP(7, FMT_D),
10222 OPC_ROUND_L_D = FOP(8, FMT_D),
10223 OPC_TRUNC_L_D = FOP(9, FMT_D),
10224 OPC_CEIL_L_D = FOP(10, FMT_D),
10225 OPC_FLOOR_L_D = FOP(11, FMT_D),
10226 OPC_ROUND_W_D = FOP(12, FMT_D),
10227 OPC_TRUNC_W_D = FOP(13, FMT_D),
10228 OPC_CEIL_W_D = FOP(14, FMT_D),
10229 OPC_FLOOR_W_D = FOP(15, FMT_D),
10230 OPC_SEL_D = FOP(16, FMT_D),
10231 OPC_MOVCF_D = FOP(17, FMT_D),
10232 OPC_MOVZ_D = FOP(18, FMT_D),
10233 OPC_MOVN_D = FOP(19, FMT_D),
10234 OPC_SELEQZ_D = FOP(20, FMT_D),
10235 OPC_RECIP_D = FOP(21, FMT_D),
10236 OPC_RSQRT_D = FOP(22, FMT_D),
10237 OPC_SELNEZ_D = FOP(23, FMT_D),
10238 OPC_MADDF_D = FOP(24, FMT_D),
10239 OPC_MSUBF_D = FOP(25, FMT_D),
10240 OPC_RINT_D = FOP(26, FMT_D),
10241 OPC_CLASS_D = FOP(27, FMT_D),
10242 OPC_MIN_D = FOP(28, FMT_D),
10243 OPC_RECIP2_D = FOP(28, FMT_D),
10244 OPC_MINA_D = FOP(29, FMT_D),
10245 OPC_RECIP1_D = FOP(29, FMT_D),
10246 OPC_MAX_D = FOP(30, FMT_D),
10247 OPC_RSQRT1_D = FOP(30, FMT_D),
10248 OPC_MAXA_D = FOP(31, FMT_D),
10249 OPC_RSQRT2_D = FOP(31, FMT_D),
10250 OPC_CVT_S_D = FOP(32, FMT_D),
10251 OPC_CVT_W_D = FOP(36, FMT_D),
10252 OPC_CVT_L_D = FOP(37, FMT_D),
10253 OPC_CMP_F_D = FOP (48, FMT_D),
10254 OPC_CMP_UN_D = FOP (49, FMT_D),
10255 OPC_CMP_EQ_D = FOP (50, FMT_D),
10256 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10257 OPC_CMP_OLT_D = FOP (52, FMT_D),
10258 OPC_CMP_ULT_D = FOP (53, FMT_D),
10259 OPC_CMP_OLE_D = FOP (54, FMT_D),
10260 OPC_CMP_ULE_D = FOP (55, FMT_D),
10261 OPC_CMP_SF_D = FOP (56, FMT_D),
10262 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10263 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10264 OPC_CMP_NGL_D = FOP (59, FMT_D),
10265 OPC_CMP_LT_D = FOP (60, FMT_D),
10266 OPC_CMP_NGE_D = FOP (61, FMT_D),
10267 OPC_CMP_LE_D = FOP (62, FMT_D),
10268 OPC_CMP_NGT_D = FOP (63, FMT_D),
10270 OPC_CVT_S_W = FOP(32, FMT_W),
10271 OPC_CVT_D_W = FOP(33, FMT_W),
10272 OPC_CVT_S_L = FOP(32, FMT_L),
10273 OPC_CVT_D_L = FOP(33, FMT_L),
10274 OPC_CVT_PS_PW = FOP(38, FMT_W),
10276 OPC_ADD_PS = FOP(0, FMT_PS),
10277 OPC_SUB_PS = FOP(1, FMT_PS),
10278 OPC_MUL_PS = FOP(2, FMT_PS),
10279 OPC_DIV_PS = FOP(3, FMT_PS),
10280 OPC_ABS_PS = FOP(5, FMT_PS),
10281 OPC_MOV_PS = FOP(6, FMT_PS),
10282 OPC_NEG_PS = FOP(7, FMT_PS),
10283 OPC_MOVCF_PS = FOP(17, FMT_PS),
10284 OPC_MOVZ_PS = FOP(18, FMT_PS),
10285 OPC_MOVN_PS = FOP(19, FMT_PS),
10286 OPC_ADDR_PS = FOP(24, FMT_PS),
10287 OPC_MULR_PS = FOP(26, FMT_PS),
10288 OPC_RECIP2_PS = FOP(28, FMT_PS),
10289 OPC_RECIP1_PS = FOP(29, FMT_PS),
10290 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10291 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10293 OPC_CVT_S_PU = FOP(32, FMT_PS),
10294 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10295 OPC_CVT_S_PL = FOP(40, FMT_PS),
10296 OPC_PLL_PS = FOP(44, FMT_PS),
10297 OPC_PLU_PS = FOP(45, FMT_PS),
10298 OPC_PUL_PS = FOP(46, FMT_PS),
10299 OPC_PUU_PS = FOP(47, FMT_PS),
10300 OPC_CMP_F_PS = FOP (48, FMT_PS),
10301 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10302 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10303 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10304 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10305 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10306 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10307 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10308 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10309 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10310 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10311 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10312 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10313 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10314 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10315 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10319 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10320 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10321 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10322 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10323 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10324 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10325 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10326 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10327 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10328 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10329 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10330 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10331 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10332 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10333 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10334 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10335 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10336 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10337 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10338 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10339 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10340 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10342 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10343 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10344 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10345 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10346 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10347 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10348 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10349 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10350 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10351 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10352 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10353 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10354 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10355 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10356 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10357 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10358 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10359 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10360 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10361 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10362 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10363 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10365 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10367 TCGv t0 = tcg_temp_new();
10372 TCGv_i32 fp0 = tcg_temp_new_i32();
10374 gen_load_fpr32(ctx, fp0, fs);
10375 tcg_gen_ext_i32_tl(t0, fp0);
10376 tcg_temp_free_i32(fp0);
10378 gen_store_gpr(t0, rt);
10381 gen_load_gpr(t0, rt);
10383 TCGv_i32 fp0 = tcg_temp_new_i32();
10385 tcg_gen_trunc_tl_i32(fp0, t0);
10386 gen_store_fpr32(ctx, fp0, fs);
10387 tcg_temp_free_i32(fp0);
10391 gen_helper_1e0i(cfc1, t0, fs);
10392 gen_store_gpr(t0, rt);
10395 gen_load_gpr(t0, rt);
10396 save_cpu_state(ctx, 0);
10398 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10400 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10401 tcg_temp_free_i32(fs_tmp);
10403 /* Stop translation as we may have changed hflags */
10404 ctx->base.is_jmp = DISAS_STOP;
10406 #if defined(TARGET_MIPS64)
10408 gen_load_fpr64(ctx, t0, fs);
10409 gen_store_gpr(t0, rt);
10412 gen_load_gpr(t0, rt);
10413 gen_store_fpr64(ctx, t0, fs);
10418 TCGv_i32 fp0 = tcg_temp_new_i32();
10420 gen_load_fpr32h(ctx, fp0, fs);
10421 tcg_gen_ext_i32_tl(t0, fp0);
10422 tcg_temp_free_i32(fp0);
10424 gen_store_gpr(t0, rt);
10427 gen_load_gpr(t0, rt);
10429 TCGv_i32 fp0 = tcg_temp_new_i32();
10431 tcg_gen_trunc_tl_i32(fp0, t0);
10432 gen_store_fpr32h(ctx, fp0, fs);
10433 tcg_temp_free_i32(fp0);
10437 MIPS_INVAL("cp1 move");
10438 generate_exception_end(ctx, EXCP_RI);
10446 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10453 /* Treat as NOP. */
10458 cond = TCG_COND_EQ;
10460 cond = TCG_COND_NE;
10462 l1 = gen_new_label();
10463 t0 = tcg_temp_new_i32();
10464 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10465 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10466 tcg_temp_free_i32(t0);
10468 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10470 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10475 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10479 TCGv_i32 t0 = tcg_temp_new_i32();
10480 TCGLabel *l1 = gen_new_label();
10483 cond = TCG_COND_EQ;
10485 cond = TCG_COND_NE;
10487 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10488 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10489 gen_load_fpr32(ctx, t0, fs);
10490 gen_store_fpr32(ctx, t0, fd);
10492 tcg_temp_free_i32(t0);
10495 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10498 TCGv_i32 t0 = tcg_temp_new_i32();
10500 TCGLabel *l1 = gen_new_label();
10503 cond = TCG_COND_EQ;
10505 cond = TCG_COND_NE;
10507 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10508 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10509 tcg_temp_free_i32(t0);
10510 fp0 = tcg_temp_new_i64();
10511 gen_load_fpr64(ctx, fp0, fs);
10512 gen_store_fpr64(ctx, fp0, fd);
10513 tcg_temp_free_i64(fp0);
10517 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10521 TCGv_i32 t0 = tcg_temp_new_i32();
10522 TCGLabel *l1 = gen_new_label();
10523 TCGLabel *l2 = gen_new_label();
10526 cond = TCG_COND_EQ;
10528 cond = TCG_COND_NE;
10530 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10531 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10532 gen_load_fpr32(ctx, t0, fs);
10533 gen_store_fpr32(ctx, t0, fd);
10536 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10537 tcg_gen_brcondi_i32(cond, t0, 0, l2);
10538 gen_load_fpr32h(ctx, t0, fs);
10539 gen_store_fpr32h(ctx, t0, fd);
10540 tcg_temp_free_i32(t0);
10544 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10547 TCGv_i32 t1 = tcg_const_i32(0);
10548 TCGv_i32 fp0 = tcg_temp_new_i32();
10549 TCGv_i32 fp1 = tcg_temp_new_i32();
10550 TCGv_i32 fp2 = tcg_temp_new_i32();
10551 gen_load_fpr32(ctx, fp0, fd);
10552 gen_load_fpr32(ctx, fp1, ft);
10553 gen_load_fpr32(ctx, fp2, fs);
10557 tcg_gen_andi_i32(fp0, fp0, 1);
10558 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10561 tcg_gen_andi_i32(fp1, fp1, 1);
10562 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10565 tcg_gen_andi_i32(fp1, fp1, 1);
10566 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10569 MIPS_INVAL("gen_sel_s");
10570 generate_exception_end(ctx, EXCP_RI);
10574 gen_store_fpr32(ctx, fp0, fd);
10575 tcg_temp_free_i32(fp2);
10576 tcg_temp_free_i32(fp1);
10577 tcg_temp_free_i32(fp0);
10578 tcg_temp_free_i32(t1);
10581 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10584 TCGv_i64 t1 = tcg_const_i64(0);
10585 TCGv_i64 fp0 = tcg_temp_new_i64();
10586 TCGv_i64 fp1 = tcg_temp_new_i64();
10587 TCGv_i64 fp2 = tcg_temp_new_i64();
10588 gen_load_fpr64(ctx, fp0, fd);
10589 gen_load_fpr64(ctx, fp1, ft);
10590 gen_load_fpr64(ctx, fp2, fs);
10594 tcg_gen_andi_i64(fp0, fp0, 1);
10595 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10598 tcg_gen_andi_i64(fp1, fp1, 1);
10599 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10602 tcg_gen_andi_i64(fp1, fp1, 1);
10603 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10606 MIPS_INVAL("gen_sel_d");
10607 generate_exception_end(ctx, EXCP_RI);
10611 gen_store_fpr64(ctx, fp0, fd);
10612 tcg_temp_free_i64(fp2);
10613 tcg_temp_free_i64(fp1);
10614 tcg_temp_free_i64(fp0);
10615 tcg_temp_free_i64(t1);
10618 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10619 int ft, int fs, int fd, int cc)
10621 uint32_t func = ctx->opcode & 0x3f;
10625 TCGv_i32 fp0 = tcg_temp_new_i32();
10626 TCGv_i32 fp1 = tcg_temp_new_i32();
10628 gen_load_fpr32(ctx, fp0, fs);
10629 gen_load_fpr32(ctx, fp1, ft);
10630 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10631 tcg_temp_free_i32(fp1);
10632 gen_store_fpr32(ctx, fp0, fd);
10633 tcg_temp_free_i32(fp0);
10638 TCGv_i32 fp0 = tcg_temp_new_i32();
10639 TCGv_i32 fp1 = tcg_temp_new_i32();
10641 gen_load_fpr32(ctx, fp0, fs);
10642 gen_load_fpr32(ctx, fp1, ft);
10643 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10644 tcg_temp_free_i32(fp1);
10645 gen_store_fpr32(ctx, fp0, fd);
10646 tcg_temp_free_i32(fp0);
10651 TCGv_i32 fp0 = tcg_temp_new_i32();
10652 TCGv_i32 fp1 = tcg_temp_new_i32();
10654 gen_load_fpr32(ctx, fp0, fs);
10655 gen_load_fpr32(ctx, fp1, ft);
10656 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10657 tcg_temp_free_i32(fp1);
10658 gen_store_fpr32(ctx, fp0, fd);
10659 tcg_temp_free_i32(fp0);
10664 TCGv_i32 fp0 = tcg_temp_new_i32();
10665 TCGv_i32 fp1 = tcg_temp_new_i32();
10667 gen_load_fpr32(ctx, fp0, fs);
10668 gen_load_fpr32(ctx, fp1, ft);
10669 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10670 tcg_temp_free_i32(fp1);
10671 gen_store_fpr32(ctx, fp0, fd);
10672 tcg_temp_free_i32(fp0);
10677 TCGv_i32 fp0 = tcg_temp_new_i32();
10679 gen_load_fpr32(ctx, fp0, fs);
10680 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10681 gen_store_fpr32(ctx, fp0, fd);
10682 tcg_temp_free_i32(fp0);
10687 TCGv_i32 fp0 = tcg_temp_new_i32();
10689 gen_load_fpr32(ctx, fp0, fs);
10690 if (ctx->abs2008) {
10691 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10693 gen_helper_float_abs_s(fp0, fp0);
10695 gen_store_fpr32(ctx, fp0, fd);
10696 tcg_temp_free_i32(fp0);
10701 TCGv_i32 fp0 = tcg_temp_new_i32();
10703 gen_load_fpr32(ctx, fp0, fs);
10704 gen_store_fpr32(ctx, fp0, fd);
10705 tcg_temp_free_i32(fp0);
10710 TCGv_i32 fp0 = tcg_temp_new_i32();
10712 gen_load_fpr32(ctx, fp0, fs);
10713 if (ctx->abs2008) {
10714 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10716 gen_helper_float_chs_s(fp0, fp0);
10718 gen_store_fpr32(ctx, fp0, fd);
10719 tcg_temp_free_i32(fp0);
10722 case OPC_ROUND_L_S:
10723 check_cp1_64bitmode(ctx);
10725 TCGv_i32 fp32 = tcg_temp_new_i32();
10726 TCGv_i64 fp64 = tcg_temp_new_i64();
10728 gen_load_fpr32(ctx, fp32, fs);
10729 if (ctx->nan2008) {
10730 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10732 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10734 tcg_temp_free_i32(fp32);
10735 gen_store_fpr64(ctx, fp64, fd);
10736 tcg_temp_free_i64(fp64);
10739 case OPC_TRUNC_L_S:
10740 check_cp1_64bitmode(ctx);
10742 TCGv_i32 fp32 = tcg_temp_new_i32();
10743 TCGv_i64 fp64 = tcg_temp_new_i64();
10745 gen_load_fpr32(ctx, fp32, fs);
10746 if (ctx->nan2008) {
10747 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10749 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10751 tcg_temp_free_i32(fp32);
10752 gen_store_fpr64(ctx, fp64, fd);
10753 tcg_temp_free_i64(fp64);
10757 check_cp1_64bitmode(ctx);
10759 TCGv_i32 fp32 = tcg_temp_new_i32();
10760 TCGv_i64 fp64 = tcg_temp_new_i64();
10762 gen_load_fpr32(ctx, fp32, fs);
10763 if (ctx->nan2008) {
10764 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10766 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10768 tcg_temp_free_i32(fp32);
10769 gen_store_fpr64(ctx, fp64, fd);
10770 tcg_temp_free_i64(fp64);
10773 case OPC_FLOOR_L_S:
10774 check_cp1_64bitmode(ctx);
10776 TCGv_i32 fp32 = tcg_temp_new_i32();
10777 TCGv_i64 fp64 = tcg_temp_new_i64();
10779 gen_load_fpr32(ctx, fp32, fs);
10780 if (ctx->nan2008) {
10781 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10783 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10785 tcg_temp_free_i32(fp32);
10786 gen_store_fpr64(ctx, fp64, fd);
10787 tcg_temp_free_i64(fp64);
10790 case OPC_ROUND_W_S:
10792 TCGv_i32 fp0 = tcg_temp_new_i32();
10794 gen_load_fpr32(ctx, fp0, fs);
10795 if (ctx->nan2008) {
10796 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10798 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10800 gen_store_fpr32(ctx, fp0, fd);
10801 tcg_temp_free_i32(fp0);
10804 case OPC_TRUNC_W_S:
10806 TCGv_i32 fp0 = tcg_temp_new_i32();
10808 gen_load_fpr32(ctx, fp0, fs);
10809 if (ctx->nan2008) {
10810 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10812 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10814 gen_store_fpr32(ctx, fp0, fd);
10815 tcg_temp_free_i32(fp0);
10820 TCGv_i32 fp0 = tcg_temp_new_i32();
10822 gen_load_fpr32(ctx, fp0, fs);
10823 if (ctx->nan2008) {
10824 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10826 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10828 gen_store_fpr32(ctx, fp0, fd);
10829 tcg_temp_free_i32(fp0);
10832 case OPC_FLOOR_W_S:
10834 TCGv_i32 fp0 = tcg_temp_new_i32();
10836 gen_load_fpr32(ctx, fp0, fs);
10837 if (ctx->nan2008) {
10838 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10840 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10842 gen_store_fpr32(ctx, fp0, fd);
10843 tcg_temp_free_i32(fp0);
10847 check_insn(ctx, ISA_MIPS32R6);
10848 gen_sel_s(ctx, op1, fd, ft, fs);
10851 check_insn(ctx, ISA_MIPS32R6);
10852 gen_sel_s(ctx, op1, fd, ft, fs);
10855 check_insn(ctx, ISA_MIPS32R6);
10856 gen_sel_s(ctx, op1, fd, ft, fs);
10859 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10860 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10865 TCGLabel *l1 = gen_new_label();
10869 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10871 fp0 = tcg_temp_new_i32();
10872 gen_load_fpr32(ctx, fp0, fs);
10873 gen_store_fpr32(ctx, fp0, fd);
10874 tcg_temp_free_i32(fp0);
10879 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10881 TCGLabel *l1 = gen_new_label();
10885 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10886 fp0 = tcg_temp_new_i32();
10887 gen_load_fpr32(ctx, fp0, fs);
10888 gen_store_fpr32(ctx, fp0, fd);
10889 tcg_temp_free_i32(fp0);
10896 TCGv_i32 fp0 = tcg_temp_new_i32();
10898 gen_load_fpr32(ctx, fp0, fs);
10899 gen_helper_float_recip_s(fp0, cpu_env, fp0);
10900 gen_store_fpr32(ctx, fp0, fd);
10901 tcg_temp_free_i32(fp0);
10906 TCGv_i32 fp0 = tcg_temp_new_i32();
10908 gen_load_fpr32(ctx, fp0, fs);
10909 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10910 gen_store_fpr32(ctx, fp0, fd);
10911 tcg_temp_free_i32(fp0);
10915 check_insn(ctx, ISA_MIPS32R6);
10917 TCGv_i32 fp0 = tcg_temp_new_i32();
10918 TCGv_i32 fp1 = tcg_temp_new_i32();
10919 TCGv_i32 fp2 = tcg_temp_new_i32();
10920 gen_load_fpr32(ctx, fp0, fs);
10921 gen_load_fpr32(ctx, fp1, ft);
10922 gen_load_fpr32(ctx, fp2, fd);
10923 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10924 gen_store_fpr32(ctx, fp2, fd);
10925 tcg_temp_free_i32(fp2);
10926 tcg_temp_free_i32(fp1);
10927 tcg_temp_free_i32(fp0);
10931 check_insn(ctx, ISA_MIPS32R6);
10933 TCGv_i32 fp0 = tcg_temp_new_i32();
10934 TCGv_i32 fp1 = tcg_temp_new_i32();
10935 TCGv_i32 fp2 = tcg_temp_new_i32();
10936 gen_load_fpr32(ctx, fp0, fs);
10937 gen_load_fpr32(ctx, fp1, ft);
10938 gen_load_fpr32(ctx, fp2, fd);
10939 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10940 gen_store_fpr32(ctx, fp2, fd);
10941 tcg_temp_free_i32(fp2);
10942 tcg_temp_free_i32(fp1);
10943 tcg_temp_free_i32(fp0);
10947 check_insn(ctx, ISA_MIPS32R6);
10949 TCGv_i32 fp0 = tcg_temp_new_i32();
10950 gen_load_fpr32(ctx, fp0, fs);
10951 gen_helper_float_rint_s(fp0, cpu_env, fp0);
10952 gen_store_fpr32(ctx, fp0, fd);
10953 tcg_temp_free_i32(fp0);
10957 check_insn(ctx, ISA_MIPS32R6);
10959 TCGv_i32 fp0 = tcg_temp_new_i32();
10960 gen_load_fpr32(ctx, fp0, fs);
10961 gen_helper_float_class_s(fp0, cpu_env, fp0);
10962 gen_store_fpr32(ctx, fp0, fd);
10963 tcg_temp_free_i32(fp0);
10966 case OPC_MIN_S: /* OPC_RECIP2_S */
10967 if (ctx->insn_flags & ISA_MIPS32R6) {
10969 TCGv_i32 fp0 = tcg_temp_new_i32();
10970 TCGv_i32 fp1 = tcg_temp_new_i32();
10971 TCGv_i32 fp2 = tcg_temp_new_i32();
10972 gen_load_fpr32(ctx, fp0, fs);
10973 gen_load_fpr32(ctx, fp1, ft);
10974 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10975 gen_store_fpr32(ctx, fp2, fd);
10976 tcg_temp_free_i32(fp2);
10977 tcg_temp_free_i32(fp1);
10978 tcg_temp_free_i32(fp0);
10981 check_cp1_64bitmode(ctx);
10983 TCGv_i32 fp0 = tcg_temp_new_i32();
10984 TCGv_i32 fp1 = tcg_temp_new_i32();
10986 gen_load_fpr32(ctx, fp0, fs);
10987 gen_load_fpr32(ctx, fp1, ft);
10988 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10989 tcg_temp_free_i32(fp1);
10990 gen_store_fpr32(ctx, fp0, fd);
10991 tcg_temp_free_i32(fp0);
10995 case OPC_MINA_S: /* OPC_RECIP1_S */
10996 if (ctx->insn_flags & ISA_MIPS32R6) {
10998 TCGv_i32 fp0 = tcg_temp_new_i32();
10999 TCGv_i32 fp1 = tcg_temp_new_i32();
11000 TCGv_i32 fp2 = tcg_temp_new_i32();
11001 gen_load_fpr32(ctx, fp0, fs);
11002 gen_load_fpr32(ctx, fp1, ft);
11003 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11004 gen_store_fpr32(ctx, fp2, fd);
11005 tcg_temp_free_i32(fp2);
11006 tcg_temp_free_i32(fp1);
11007 tcg_temp_free_i32(fp0);
11010 check_cp1_64bitmode(ctx);
11012 TCGv_i32 fp0 = tcg_temp_new_i32();
11014 gen_load_fpr32(ctx, fp0, fs);
11015 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11016 gen_store_fpr32(ctx, fp0, fd);
11017 tcg_temp_free_i32(fp0);
11021 case OPC_MAX_S: /* OPC_RSQRT1_S */
11022 if (ctx->insn_flags & ISA_MIPS32R6) {
11024 TCGv_i32 fp0 = tcg_temp_new_i32();
11025 TCGv_i32 fp1 = tcg_temp_new_i32();
11026 gen_load_fpr32(ctx, fp0, fs);
11027 gen_load_fpr32(ctx, fp1, ft);
11028 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11029 gen_store_fpr32(ctx, fp1, fd);
11030 tcg_temp_free_i32(fp1);
11031 tcg_temp_free_i32(fp0);
11034 check_cp1_64bitmode(ctx);
11036 TCGv_i32 fp0 = tcg_temp_new_i32();
11038 gen_load_fpr32(ctx, fp0, fs);
11039 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11040 gen_store_fpr32(ctx, fp0, fd);
11041 tcg_temp_free_i32(fp0);
11045 case OPC_MAXA_S: /* OPC_RSQRT2_S */
11046 if (ctx->insn_flags & ISA_MIPS32R6) {
11048 TCGv_i32 fp0 = tcg_temp_new_i32();
11049 TCGv_i32 fp1 = tcg_temp_new_i32();
11050 gen_load_fpr32(ctx, fp0, fs);
11051 gen_load_fpr32(ctx, fp1, ft);
11052 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11053 gen_store_fpr32(ctx, fp1, fd);
11054 tcg_temp_free_i32(fp1);
11055 tcg_temp_free_i32(fp0);
11058 check_cp1_64bitmode(ctx);
11060 TCGv_i32 fp0 = tcg_temp_new_i32();
11061 TCGv_i32 fp1 = tcg_temp_new_i32();
11063 gen_load_fpr32(ctx, fp0, fs);
11064 gen_load_fpr32(ctx, fp1, ft);
11065 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11066 tcg_temp_free_i32(fp1);
11067 gen_store_fpr32(ctx, fp0, fd);
11068 tcg_temp_free_i32(fp0);
11073 check_cp1_registers(ctx, fd);
11075 TCGv_i32 fp32 = tcg_temp_new_i32();
11076 TCGv_i64 fp64 = tcg_temp_new_i64();
11078 gen_load_fpr32(ctx, fp32, fs);
11079 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11080 tcg_temp_free_i32(fp32);
11081 gen_store_fpr64(ctx, fp64, fd);
11082 tcg_temp_free_i64(fp64);
11087 TCGv_i32 fp0 = tcg_temp_new_i32();
11089 gen_load_fpr32(ctx, fp0, fs);
11090 if (ctx->nan2008) {
11091 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11093 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11095 gen_store_fpr32(ctx, fp0, fd);
11096 tcg_temp_free_i32(fp0);
11100 check_cp1_64bitmode(ctx);
11102 TCGv_i32 fp32 = tcg_temp_new_i32();
11103 TCGv_i64 fp64 = tcg_temp_new_i64();
11105 gen_load_fpr32(ctx, fp32, fs);
11106 if (ctx->nan2008) {
11107 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11109 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11111 tcg_temp_free_i32(fp32);
11112 gen_store_fpr64(ctx, fp64, fd);
11113 tcg_temp_free_i64(fp64);
11119 TCGv_i64 fp64 = tcg_temp_new_i64();
11120 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11121 TCGv_i32 fp32_1 = tcg_temp_new_i32();
11123 gen_load_fpr32(ctx, fp32_0, fs);
11124 gen_load_fpr32(ctx, fp32_1, ft);
11125 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11126 tcg_temp_free_i32(fp32_1);
11127 tcg_temp_free_i32(fp32_0);
11128 gen_store_fpr64(ctx, fp64, fd);
11129 tcg_temp_free_i64(fp64);
11135 case OPC_CMP_UEQ_S:
11136 case OPC_CMP_OLT_S:
11137 case OPC_CMP_ULT_S:
11138 case OPC_CMP_OLE_S:
11139 case OPC_CMP_ULE_S:
11141 case OPC_CMP_NGLE_S:
11142 case OPC_CMP_SEQ_S:
11143 case OPC_CMP_NGL_S:
11145 case OPC_CMP_NGE_S:
11147 case OPC_CMP_NGT_S:
11148 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11149 if (ctx->opcode & (1 << 6)) {
11150 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11152 gen_cmp_s(ctx, func-48, ft, fs, cc);
11156 check_cp1_registers(ctx, fs | ft | fd);
11158 TCGv_i64 fp0 = tcg_temp_new_i64();
11159 TCGv_i64 fp1 = tcg_temp_new_i64();
11161 gen_load_fpr64(ctx, fp0, fs);
11162 gen_load_fpr64(ctx, fp1, ft);
11163 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11164 tcg_temp_free_i64(fp1);
11165 gen_store_fpr64(ctx, fp0, fd);
11166 tcg_temp_free_i64(fp0);
11170 check_cp1_registers(ctx, fs | ft | fd);
11172 TCGv_i64 fp0 = tcg_temp_new_i64();
11173 TCGv_i64 fp1 = tcg_temp_new_i64();
11175 gen_load_fpr64(ctx, fp0, fs);
11176 gen_load_fpr64(ctx, fp1, ft);
11177 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11178 tcg_temp_free_i64(fp1);
11179 gen_store_fpr64(ctx, fp0, fd);
11180 tcg_temp_free_i64(fp0);
11184 check_cp1_registers(ctx, fs | ft | fd);
11186 TCGv_i64 fp0 = tcg_temp_new_i64();
11187 TCGv_i64 fp1 = tcg_temp_new_i64();
11189 gen_load_fpr64(ctx, fp0, fs);
11190 gen_load_fpr64(ctx, fp1, ft);
11191 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11192 tcg_temp_free_i64(fp1);
11193 gen_store_fpr64(ctx, fp0, fd);
11194 tcg_temp_free_i64(fp0);
11198 check_cp1_registers(ctx, fs | ft | fd);
11200 TCGv_i64 fp0 = tcg_temp_new_i64();
11201 TCGv_i64 fp1 = tcg_temp_new_i64();
11203 gen_load_fpr64(ctx, fp0, fs);
11204 gen_load_fpr64(ctx, fp1, ft);
11205 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11206 tcg_temp_free_i64(fp1);
11207 gen_store_fpr64(ctx, fp0, fd);
11208 tcg_temp_free_i64(fp0);
11212 check_cp1_registers(ctx, fs | fd);
11214 TCGv_i64 fp0 = tcg_temp_new_i64();
11216 gen_load_fpr64(ctx, fp0, fs);
11217 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11218 gen_store_fpr64(ctx, fp0, fd);
11219 tcg_temp_free_i64(fp0);
11223 check_cp1_registers(ctx, fs | fd);
11225 TCGv_i64 fp0 = tcg_temp_new_i64();
11227 gen_load_fpr64(ctx, fp0, fs);
11228 if (ctx->abs2008) {
11229 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11231 gen_helper_float_abs_d(fp0, fp0);
11233 gen_store_fpr64(ctx, fp0, fd);
11234 tcg_temp_free_i64(fp0);
11238 check_cp1_registers(ctx, fs | fd);
11240 TCGv_i64 fp0 = tcg_temp_new_i64();
11242 gen_load_fpr64(ctx, fp0, fs);
11243 gen_store_fpr64(ctx, fp0, fd);
11244 tcg_temp_free_i64(fp0);
11248 check_cp1_registers(ctx, fs | fd);
11250 TCGv_i64 fp0 = tcg_temp_new_i64();
11252 gen_load_fpr64(ctx, fp0, fs);
11253 if (ctx->abs2008) {
11254 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11256 gen_helper_float_chs_d(fp0, fp0);
11258 gen_store_fpr64(ctx, fp0, fd);
11259 tcg_temp_free_i64(fp0);
11262 case OPC_ROUND_L_D:
11263 check_cp1_64bitmode(ctx);
11265 TCGv_i64 fp0 = tcg_temp_new_i64();
11267 gen_load_fpr64(ctx, fp0, fs);
11268 if (ctx->nan2008) {
11269 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11271 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11273 gen_store_fpr64(ctx, fp0, fd);
11274 tcg_temp_free_i64(fp0);
11277 case OPC_TRUNC_L_D:
11278 check_cp1_64bitmode(ctx);
11280 TCGv_i64 fp0 = tcg_temp_new_i64();
11282 gen_load_fpr64(ctx, fp0, fs);
11283 if (ctx->nan2008) {
11284 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11286 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11288 gen_store_fpr64(ctx, fp0, fd);
11289 tcg_temp_free_i64(fp0);
11293 check_cp1_64bitmode(ctx);
11295 TCGv_i64 fp0 = tcg_temp_new_i64();
11297 gen_load_fpr64(ctx, fp0, fs);
11298 if (ctx->nan2008) {
11299 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11301 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11303 gen_store_fpr64(ctx, fp0, fd);
11304 tcg_temp_free_i64(fp0);
11307 case OPC_FLOOR_L_D:
11308 check_cp1_64bitmode(ctx);
11310 TCGv_i64 fp0 = tcg_temp_new_i64();
11312 gen_load_fpr64(ctx, fp0, fs);
11313 if (ctx->nan2008) {
11314 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11316 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11318 gen_store_fpr64(ctx, fp0, fd);
11319 tcg_temp_free_i64(fp0);
11322 case OPC_ROUND_W_D:
11323 check_cp1_registers(ctx, fs);
11325 TCGv_i32 fp32 = tcg_temp_new_i32();
11326 TCGv_i64 fp64 = tcg_temp_new_i64();
11328 gen_load_fpr64(ctx, fp64, fs);
11329 if (ctx->nan2008) {
11330 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11332 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11334 tcg_temp_free_i64(fp64);
11335 gen_store_fpr32(ctx, fp32, fd);
11336 tcg_temp_free_i32(fp32);
11339 case OPC_TRUNC_W_D:
11340 check_cp1_registers(ctx, fs);
11342 TCGv_i32 fp32 = tcg_temp_new_i32();
11343 TCGv_i64 fp64 = tcg_temp_new_i64();
11345 gen_load_fpr64(ctx, fp64, fs);
11346 if (ctx->nan2008) {
11347 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11349 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11351 tcg_temp_free_i64(fp64);
11352 gen_store_fpr32(ctx, fp32, fd);
11353 tcg_temp_free_i32(fp32);
11357 check_cp1_registers(ctx, fs);
11359 TCGv_i32 fp32 = tcg_temp_new_i32();
11360 TCGv_i64 fp64 = tcg_temp_new_i64();
11362 gen_load_fpr64(ctx, fp64, fs);
11363 if (ctx->nan2008) {
11364 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11366 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11368 tcg_temp_free_i64(fp64);
11369 gen_store_fpr32(ctx, fp32, fd);
11370 tcg_temp_free_i32(fp32);
11373 case OPC_FLOOR_W_D:
11374 check_cp1_registers(ctx, fs);
11376 TCGv_i32 fp32 = tcg_temp_new_i32();
11377 TCGv_i64 fp64 = tcg_temp_new_i64();
11379 gen_load_fpr64(ctx, fp64, fs);
11380 if (ctx->nan2008) {
11381 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11383 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11385 tcg_temp_free_i64(fp64);
11386 gen_store_fpr32(ctx, fp32, fd);
11387 tcg_temp_free_i32(fp32);
11391 check_insn(ctx, ISA_MIPS32R6);
11392 gen_sel_d(ctx, op1, fd, ft, fs);
11395 check_insn(ctx, ISA_MIPS32R6);
11396 gen_sel_d(ctx, op1, fd, ft, fs);
11399 check_insn(ctx, ISA_MIPS32R6);
11400 gen_sel_d(ctx, op1, fd, ft, fs);
11403 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11404 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11407 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11409 TCGLabel *l1 = gen_new_label();
11413 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11415 fp0 = tcg_temp_new_i64();
11416 gen_load_fpr64(ctx, fp0, fs);
11417 gen_store_fpr64(ctx, fp0, fd);
11418 tcg_temp_free_i64(fp0);
11423 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11425 TCGLabel *l1 = gen_new_label();
11429 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11430 fp0 = tcg_temp_new_i64();
11431 gen_load_fpr64(ctx, fp0, fs);
11432 gen_store_fpr64(ctx, fp0, fd);
11433 tcg_temp_free_i64(fp0);
11439 check_cp1_registers(ctx, fs | fd);
11441 TCGv_i64 fp0 = tcg_temp_new_i64();
11443 gen_load_fpr64(ctx, fp0, fs);
11444 gen_helper_float_recip_d(fp0, cpu_env, fp0);
11445 gen_store_fpr64(ctx, fp0, fd);
11446 tcg_temp_free_i64(fp0);
11450 check_cp1_registers(ctx, fs | fd);
11452 TCGv_i64 fp0 = tcg_temp_new_i64();
11454 gen_load_fpr64(ctx, fp0, fs);
11455 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11456 gen_store_fpr64(ctx, fp0, fd);
11457 tcg_temp_free_i64(fp0);
11461 check_insn(ctx, ISA_MIPS32R6);
11463 TCGv_i64 fp0 = tcg_temp_new_i64();
11464 TCGv_i64 fp1 = tcg_temp_new_i64();
11465 TCGv_i64 fp2 = tcg_temp_new_i64();
11466 gen_load_fpr64(ctx, fp0, fs);
11467 gen_load_fpr64(ctx, fp1, ft);
11468 gen_load_fpr64(ctx, fp2, fd);
11469 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11470 gen_store_fpr64(ctx, fp2, fd);
11471 tcg_temp_free_i64(fp2);
11472 tcg_temp_free_i64(fp1);
11473 tcg_temp_free_i64(fp0);
11477 check_insn(ctx, ISA_MIPS32R6);
11479 TCGv_i64 fp0 = tcg_temp_new_i64();
11480 TCGv_i64 fp1 = tcg_temp_new_i64();
11481 TCGv_i64 fp2 = tcg_temp_new_i64();
11482 gen_load_fpr64(ctx, fp0, fs);
11483 gen_load_fpr64(ctx, fp1, ft);
11484 gen_load_fpr64(ctx, fp2, fd);
11485 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11486 gen_store_fpr64(ctx, fp2, fd);
11487 tcg_temp_free_i64(fp2);
11488 tcg_temp_free_i64(fp1);
11489 tcg_temp_free_i64(fp0);
11493 check_insn(ctx, ISA_MIPS32R6);
11495 TCGv_i64 fp0 = tcg_temp_new_i64();
11496 gen_load_fpr64(ctx, fp0, fs);
11497 gen_helper_float_rint_d(fp0, cpu_env, fp0);
11498 gen_store_fpr64(ctx, fp0, fd);
11499 tcg_temp_free_i64(fp0);
11503 check_insn(ctx, ISA_MIPS32R6);
11505 TCGv_i64 fp0 = tcg_temp_new_i64();
11506 gen_load_fpr64(ctx, fp0, fs);
11507 gen_helper_float_class_d(fp0, cpu_env, fp0);
11508 gen_store_fpr64(ctx, fp0, fd);
11509 tcg_temp_free_i64(fp0);
11512 case OPC_MIN_D: /* OPC_RECIP2_D */
11513 if (ctx->insn_flags & ISA_MIPS32R6) {
11515 TCGv_i64 fp0 = tcg_temp_new_i64();
11516 TCGv_i64 fp1 = tcg_temp_new_i64();
11517 gen_load_fpr64(ctx, fp0, fs);
11518 gen_load_fpr64(ctx, fp1, ft);
11519 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11520 gen_store_fpr64(ctx, fp1, fd);
11521 tcg_temp_free_i64(fp1);
11522 tcg_temp_free_i64(fp0);
11525 check_cp1_64bitmode(ctx);
11527 TCGv_i64 fp0 = tcg_temp_new_i64();
11528 TCGv_i64 fp1 = tcg_temp_new_i64();
11530 gen_load_fpr64(ctx, fp0, fs);
11531 gen_load_fpr64(ctx, fp1, ft);
11532 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11533 tcg_temp_free_i64(fp1);
11534 gen_store_fpr64(ctx, fp0, fd);
11535 tcg_temp_free_i64(fp0);
11539 case OPC_MINA_D: /* OPC_RECIP1_D */
11540 if (ctx->insn_flags & ISA_MIPS32R6) {
11542 TCGv_i64 fp0 = tcg_temp_new_i64();
11543 TCGv_i64 fp1 = tcg_temp_new_i64();
11544 gen_load_fpr64(ctx, fp0, fs);
11545 gen_load_fpr64(ctx, fp1, ft);
11546 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11547 gen_store_fpr64(ctx, fp1, fd);
11548 tcg_temp_free_i64(fp1);
11549 tcg_temp_free_i64(fp0);
11552 check_cp1_64bitmode(ctx);
11554 TCGv_i64 fp0 = tcg_temp_new_i64();
11556 gen_load_fpr64(ctx, fp0, fs);
11557 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11558 gen_store_fpr64(ctx, fp0, fd);
11559 tcg_temp_free_i64(fp0);
11563 case OPC_MAX_D: /* OPC_RSQRT1_D */
11564 if (ctx->insn_flags & ISA_MIPS32R6) {
11566 TCGv_i64 fp0 = tcg_temp_new_i64();
11567 TCGv_i64 fp1 = tcg_temp_new_i64();
11568 gen_load_fpr64(ctx, fp0, fs);
11569 gen_load_fpr64(ctx, fp1, ft);
11570 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11571 gen_store_fpr64(ctx, fp1, fd);
11572 tcg_temp_free_i64(fp1);
11573 tcg_temp_free_i64(fp0);
11576 check_cp1_64bitmode(ctx);
11578 TCGv_i64 fp0 = tcg_temp_new_i64();
11580 gen_load_fpr64(ctx, fp0, fs);
11581 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11582 gen_store_fpr64(ctx, fp0, fd);
11583 tcg_temp_free_i64(fp0);
11587 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11588 if (ctx->insn_flags & ISA_MIPS32R6) {
11590 TCGv_i64 fp0 = tcg_temp_new_i64();
11591 TCGv_i64 fp1 = tcg_temp_new_i64();
11592 gen_load_fpr64(ctx, fp0, fs);
11593 gen_load_fpr64(ctx, fp1, ft);
11594 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11595 gen_store_fpr64(ctx, fp1, fd);
11596 tcg_temp_free_i64(fp1);
11597 tcg_temp_free_i64(fp0);
11600 check_cp1_64bitmode(ctx);
11602 TCGv_i64 fp0 = tcg_temp_new_i64();
11603 TCGv_i64 fp1 = tcg_temp_new_i64();
11605 gen_load_fpr64(ctx, fp0, fs);
11606 gen_load_fpr64(ctx, fp1, ft);
11607 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11608 tcg_temp_free_i64(fp1);
11609 gen_store_fpr64(ctx, fp0, fd);
11610 tcg_temp_free_i64(fp0);
11617 case OPC_CMP_UEQ_D:
11618 case OPC_CMP_OLT_D:
11619 case OPC_CMP_ULT_D:
11620 case OPC_CMP_OLE_D:
11621 case OPC_CMP_ULE_D:
11623 case OPC_CMP_NGLE_D:
11624 case OPC_CMP_SEQ_D:
11625 case OPC_CMP_NGL_D:
11627 case OPC_CMP_NGE_D:
11629 case OPC_CMP_NGT_D:
11630 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11631 if (ctx->opcode & (1 << 6)) {
11632 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11634 gen_cmp_d(ctx, func-48, ft, fs, cc);
11638 check_cp1_registers(ctx, fs);
11640 TCGv_i32 fp32 = tcg_temp_new_i32();
11641 TCGv_i64 fp64 = tcg_temp_new_i64();
11643 gen_load_fpr64(ctx, fp64, fs);
11644 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11645 tcg_temp_free_i64(fp64);
11646 gen_store_fpr32(ctx, fp32, fd);
11647 tcg_temp_free_i32(fp32);
11651 check_cp1_registers(ctx, fs);
11653 TCGv_i32 fp32 = tcg_temp_new_i32();
11654 TCGv_i64 fp64 = tcg_temp_new_i64();
11656 gen_load_fpr64(ctx, fp64, fs);
11657 if (ctx->nan2008) {
11658 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11660 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11662 tcg_temp_free_i64(fp64);
11663 gen_store_fpr32(ctx, fp32, fd);
11664 tcg_temp_free_i32(fp32);
11668 check_cp1_64bitmode(ctx);
11670 TCGv_i64 fp0 = tcg_temp_new_i64();
11672 gen_load_fpr64(ctx, fp0, fs);
11673 if (ctx->nan2008) {
11674 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11676 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11678 gen_store_fpr64(ctx, fp0, fd);
11679 tcg_temp_free_i64(fp0);
11684 TCGv_i32 fp0 = tcg_temp_new_i32();
11686 gen_load_fpr32(ctx, fp0, fs);
11687 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11688 gen_store_fpr32(ctx, fp0, fd);
11689 tcg_temp_free_i32(fp0);
11693 check_cp1_registers(ctx, fd);
11695 TCGv_i32 fp32 = tcg_temp_new_i32();
11696 TCGv_i64 fp64 = tcg_temp_new_i64();
11698 gen_load_fpr32(ctx, fp32, fs);
11699 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11700 tcg_temp_free_i32(fp32);
11701 gen_store_fpr64(ctx, fp64, fd);
11702 tcg_temp_free_i64(fp64);
11706 check_cp1_64bitmode(ctx);
11708 TCGv_i32 fp32 = tcg_temp_new_i32();
11709 TCGv_i64 fp64 = tcg_temp_new_i64();
11711 gen_load_fpr64(ctx, fp64, fs);
11712 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11713 tcg_temp_free_i64(fp64);
11714 gen_store_fpr32(ctx, fp32, fd);
11715 tcg_temp_free_i32(fp32);
11719 check_cp1_64bitmode(ctx);
11721 TCGv_i64 fp0 = tcg_temp_new_i64();
11723 gen_load_fpr64(ctx, fp0, fs);
11724 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11725 gen_store_fpr64(ctx, fp0, fd);
11726 tcg_temp_free_i64(fp0);
11729 case OPC_CVT_PS_PW:
11732 TCGv_i64 fp0 = tcg_temp_new_i64();
11734 gen_load_fpr64(ctx, fp0, fs);
11735 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11736 gen_store_fpr64(ctx, fp0, fd);
11737 tcg_temp_free_i64(fp0);
11743 TCGv_i64 fp0 = tcg_temp_new_i64();
11744 TCGv_i64 fp1 = tcg_temp_new_i64();
11746 gen_load_fpr64(ctx, fp0, fs);
11747 gen_load_fpr64(ctx, fp1, ft);
11748 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11749 tcg_temp_free_i64(fp1);
11750 gen_store_fpr64(ctx, fp0, fd);
11751 tcg_temp_free_i64(fp0);
11757 TCGv_i64 fp0 = tcg_temp_new_i64();
11758 TCGv_i64 fp1 = tcg_temp_new_i64();
11760 gen_load_fpr64(ctx, fp0, fs);
11761 gen_load_fpr64(ctx, fp1, ft);
11762 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11763 tcg_temp_free_i64(fp1);
11764 gen_store_fpr64(ctx, fp0, fd);
11765 tcg_temp_free_i64(fp0);
11771 TCGv_i64 fp0 = tcg_temp_new_i64();
11772 TCGv_i64 fp1 = tcg_temp_new_i64();
11774 gen_load_fpr64(ctx, fp0, fs);
11775 gen_load_fpr64(ctx, fp1, ft);
11776 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11777 tcg_temp_free_i64(fp1);
11778 gen_store_fpr64(ctx, fp0, fd);
11779 tcg_temp_free_i64(fp0);
11785 TCGv_i64 fp0 = tcg_temp_new_i64();
11787 gen_load_fpr64(ctx, fp0, fs);
11788 gen_helper_float_abs_ps(fp0, fp0);
11789 gen_store_fpr64(ctx, fp0, fd);
11790 tcg_temp_free_i64(fp0);
11796 TCGv_i64 fp0 = tcg_temp_new_i64();
11798 gen_load_fpr64(ctx, fp0, fs);
11799 gen_store_fpr64(ctx, fp0, fd);
11800 tcg_temp_free_i64(fp0);
11806 TCGv_i64 fp0 = tcg_temp_new_i64();
11808 gen_load_fpr64(ctx, fp0, fs);
11809 gen_helper_float_chs_ps(fp0, fp0);
11810 gen_store_fpr64(ctx, fp0, fd);
11811 tcg_temp_free_i64(fp0);
11816 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11821 TCGLabel *l1 = gen_new_label();
11825 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11826 fp0 = tcg_temp_new_i64();
11827 gen_load_fpr64(ctx, fp0, fs);
11828 gen_store_fpr64(ctx, fp0, fd);
11829 tcg_temp_free_i64(fp0);
11836 TCGLabel *l1 = gen_new_label();
11840 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11841 fp0 = tcg_temp_new_i64();
11842 gen_load_fpr64(ctx, fp0, fs);
11843 gen_store_fpr64(ctx, fp0, fd);
11844 tcg_temp_free_i64(fp0);
11852 TCGv_i64 fp0 = tcg_temp_new_i64();
11853 TCGv_i64 fp1 = tcg_temp_new_i64();
11855 gen_load_fpr64(ctx, fp0, ft);
11856 gen_load_fpr64(ctx, fp1, fs);
11857 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11858 tcg_temp_free_i64(fp1);
11859 gen_store_fpr64(ctx, fp0, fd);
11860 tcg_temp_free_i64(fp0);
11866 TCGv_i64 fp0 = tcg_temp_new_i64();
11867 TCGv_i64 fp1 = tcg_temp_new_i64();
11869 gen_load_fpr64(ctx, fp0, ft);
11870 gen_load_fpr64(ctx, fp1, fs);
11871 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11872 tcg_temp_free_i64(fp1);
11873 gen_store_fpr64(ctx, fp0, fd);
11874 tcg_temp_free_i64(fp0);
11877 case OPC_RECIP2_PS:
11880 TCGv_i64 fp0 = tcg_temp_new_i64();
11881 TCGv_i64 fp1 = tcg_temp_new_i64();
11883 gen_load_fpr64(ctx, fp0, fs);
11884 gen_load_fpr64(ctx, fp1, ft);
11885 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11886 tcg_temp_free_i64(fp1);
11887 gen_store_fpr64(ctx, fp0, fd);
11888 tcg_temp_free_i64(fp0);
11891 case OPC_RECIP1_PS:
11894 TCGv_i64 fp0 = tcg_temp_new_i64();
11896 gen_load_fpr64(ctx, fp0, fs);
11897 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11898 gen_store_fpr64(ctx, fp0, fd);
11899 tcg_temp_free_i64(fp0);
11902 case OPC_RSQRT1_PS:
11905 TCGv_i64 fp0 = tcg_temp_new_i64();
11907 gen_load_fpr64(ctx, fp0, fs);
11908 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11909 gen_store_fpr64(ctx, fp0, fd);
11910 tcg_temp_free_i64(fp0);
11913 case OPC_RSQRT2_PS:
11916 TCGv_i64 fp0 = tcg_temp_new_i64();
11917 TCGv_i64 fp1 = tcg_temp_new_i64();
11919 gen_load_fpr64(ctx, fp0, fs);
11920 gen_load_fpr64(ctx, fp1, ft);
11921 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11922 tcg_temp_free_i64(fp1);
11923 gen_store_fpr64(ctx, fp0, fd);
11924 tcg_temp_free_i64(fp0);
11928 check_cp1_64bitmode(ctx);
11930 TCGv_i32 fp0 = tcg_temp_new_i32();
11932 gen_load_fpr32h(ctx, fp0, fs);
11933 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11934 gen_store_fpr32(ctx, fp0, fd);
11935 tcg_temp_free_i32(fp0);
11938 case OPC_CVT_PW_PS:
11941 TCGv_i64 fp0 = tcg_temp_new_i64();
11943 gen_load_fpr64(ctx, fp0, fs);
11944 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11945 gen_store_fpr64(ctx, fp0, fd);
11946 tcg_temp_free_i64(fp0);
11950 check_cp1_64bitmode(ctx);
11952 TCGv_i32 fp0 = tcg_temp_new_i32();
11954 gen_load_fpr32(ctx, fp0, fs);
11955 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11956 gen_store_fpr32(ctx, fp0, fd);
11957 tcg_temp_free_i32(fp0);
11963 TCGv_i32 fp0 = tcg_temp_new_i32();
11964 TCGv_i32 fp1 = tcg_temp_new_i32();
11966 gen_load_fpr32(ctx, fp0, fs);
11967 gen_load_fpr32(ctx, fp1, ft);
11968 gen_store_fpr32h(ctx, fp0, fd);
11969 gen_store_fpr32(ctx, fp1, fd);
11970 tcg_temp_free_i32(fp0);
11971 tcg_temp_free_i32(fp1);
11977 TCGv_i32 fp0 = tcg_temp_new_i32();
11978 TCGv_i32 fp1 = tcg_temp_new_i32();
11980 gen_load_fpr32(ctx, fp0, fs);
11981 gen_load_fpr32h(ctx, fp1, ft);
11982 gen_store_fpr32(ctx, fp1, fd);
11983 gen_store_fpr32h(ctx, fp0, fd);
11984 tcg_temp_free_i32(fp0);
11985 tcg_temp_free_i32(fp1);
11991 TCGv_i32 fp0 = tcg_temp_new_i32();
11992 TCGv_i32 fp1 = tcg_temp_new_i32();
11994 gen_load_fpr32h(ctx, fp0, fs);
11995 gen_load_fpr32(ctx, fp1, ft);
11996 gen_store_fpr32(ctx, fp1, fd);
11997 gen_store_fpr32h(ctx, fp0, fd);
11998 tcg_temp_free_i32(fp0);
11999 tcg_temp_free_i32(fp1);
12005 TCGv_i32 fp0 = tcg_temp_new_i32();
12006 TCGv_i32 fp1 = tcg_temp_new_i32();
12008 gen_load_fpr32h(ctx, fp0, fs);
12009 gen_load_fpr32h(ctx, fp1, ft);
12010 gen_store_fpr32(ctx, fp1, fd);
12011 gen_store_fpr32h(ctx, fp0, fd);
12012 tcg_temp_free_i32(fp0);
12013 tcg_temp_free_i32(fp1);
12017 case OPC_CMP_UN_PS:
12018 case OPC_CMP_EQ_PS:
12019 case OPC_CMP_UEQ_PS:
12020 case OPC_CMP_OLT_PS:
12021 case OPC_CMP_ULT_PS:
12022 case OPC_CMP_OLE_PS:
12023 case OPC_CMP_ULE_PS:
12024 case OPC_CMP_SF_PS:
12025 case OPC_CMP_NGLE_PS:
12026 case OPC_CMP_SEQ_PS:
12027 case OPC_CMP_NGL_PS:
12028 case OPC_CMP_LT_PS:
12029 case OPC_CMP_NGE_PS:
12030 case OPC_CMP_LE_PS:
12031 case OPC_CMP_NGT_PS:
12032 if (ctx->opcode & (1 << 6)) {
12033 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12035 gen_cmp_ps(ctx, func-48, ft, fs, cc);
12039 MIPS_INVAL("farith");
12040 generate_exception_end(ctx, EXCP_RI);
12045 /* Coprocessor 3 (FPU) */
12046 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12047 int fd, int fs, int base, int index)
12049 TCGv t0 = tcg_temp_new();
12052 gen_load_gpr(t0, index);
12053 } else if (index == 0) {
12054 gen_load_gpr(t0, base);
12056 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12058 /* Don't do NOP if destination is zero: we must perform the actual
12064 TCGv_i32 fp0 = tcg_temp_new_i32();
12066 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12067 tcg_gen_trunc_tl_i32(fp0, t0);
12068 gen_store_fpr32(ctx, fp0, fd);
12069 tcg_temp_free_i32(fp0);
12074 check_cp1_registers(ctx, fd);
12076 TCGv_i64 fp0 = tcg_temp_new_i64();
12077 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12078 gen_store_fpr64(ctx, fp0, fd);
12079 tcg_temp_free_i64(fp0);
12083 check_cp1_64bitmode(ctx);
12084 tcg_gen_andi_tl(t0, t0, ~0x7);
12086 TCGv_i64 fp0 = tcg_temp_new_i64();
12088 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12089 gen_store_fpr64(ctx, fp0, fd);
12090 tcg_temp_free_i64(fp0);
12096 TCGv_i32 fp0 = tcg_temp_new_i32();
12097 gen_load_fpr32(ctx, fp0, fs);
12098 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12099 tcg_temp_free_i32(fp0);
12104 check_cp1_registers(ctx, fs);
12106 TCGv_i64 fp0 = tcg_temp_new_i64();
12107 gen_load_fpr64(ctx, fp0, fs);
12108 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12109 tcg_temp_free_i64(fp0);
12113 check_cp1_64bitmode(ctx);
12114 tcg_gen_andi_tl(t0, t0, ~0x7);
12116 TCGv_i64 fp0 = tcg_temp_new_i64();
12117 gen_load_fpr64(ctx, fp0, fs);
12118 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12119 tcg_temp_free_i64(fp0);
12126 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12127 int fd, int fr, int fs, int ft)
12133 TCGv t0 = tcg_temp_local_new();
12134 TCGv_i32 fp = tcg_temp_new_i32();
12135 TCGv_i32 fph = tcg_temp_new_i32();
12136 TCGLabel *l1 = gen_new_label();
12137 TCGLabel *l2 = gen_new_label();
12139 gen_load_gpr(t0, fr);
12140 tcg_gen_andi_tl(t0, t0, 0x7);
12142 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12143 gen_load_fpr32(ctx, fp, fs);
12144 gen_load_fpr32h(ctx, fph, fs);
12145 gen_store_fpr32(ctx, fp, fd);
12146 gen_store_fpr32h(ctx, fph, fd);
12149 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12151 #ifdef TARGET_WORDS_BIGENDIAN
12152 gen_load_fpr32(ctx, fp, fs);
12153 gen_load_fpr32h(ctx, fph, ft);
12154 gen_store_fpr32h(ctx, fp, fd);
12155 gen_store_fpr32(ctx, fph, fd);
12157 gen_load_fpr32h(ctx, fph, fs);
12158 gen_load_fpr32(ctx, fp, ft);
12159 gen_store_fpr32(ctx, fph, fd);
12160 gen_store_fpr32h(ctx, fp, fd);
12163 tcg_temp_free_i32(fp);
12164 tcg_temp_free_i32(fph);
12170 TCGv_i32 fp0 = tcg_temp_new_i32();
12171 TCGv_i32 fp1 = tcg_temp_new_i32();
12172 TCGv_i32 fp2 = tcg_temp_new_i32();
12174 gen_load_fpr32(ctx, fp0, fs);
12175 gen_load_fpr32(ctx, fp1, ft);
12176 gen_load_fpr32(ctx, fp2, fr);
12177 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12178 tcg_temp_free_i32(fp0);
12179 tcg_temp_free_i32(fp1);
12180 gen_store_fpr32(ctx, fp2, fd);
12181 tcg_temp_free_i32(fp2);
12186 check_cp1_registers(ctx, fd | fs | ft | fr);
12188 TCGv_i64 fp0 = tcg_temp_new_i64();
12189 TCGv_i64 fp1 = tcg_temp_new_i64();
12190 TCGv_i64 fp2 = tcg_temp_new_i64();
12192 gen_load_fpr64(ctx, fp0, fs);
12193 gen_load_fpr64(ctx, fp1, ft);
12194 gen_load_fpr64(ctx, fp2, fr);
12195 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12196 tcg_temp_free_i64(fp0);
12197 tcg_temp_free_i64(fp1);
12198 gen_store_fpr64(ctx, fp2, fd);
12199 tcg_temp_free_i64(fp2);
12205 TCGv_i64 fp0 = tcg_temp_new_i64();
12206 TCGv_i64 fp1 = tcg_temp_new_i64();
12207 TCGv_i64 fp2 = tcg_temp_new_i64();
12209 gen_load_fpr64(ctx, fp0, fs);
12210 gen_load_fpr64(ctx, fp1, ft);
12211 gen_load_fpr64(ctx, fp2, fr);
12212 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12213 tcg_temp_free_i64(fp0);
12214 tcg_temp_free_i64(fp1);
12215 gen_store_fpr64(ctx, fp2, fd);
12216 tcg_temp_free_i64(fp2);
12222 TCGv_i32 fp0 = tcg_temp_new_i32();
12223 TCGv_i32 fp1 = tcg_temp_new_i32();
12224 TCGv_i32 fp2 = tcg_temp_new_i32();
12226 gen_load_fpr32(ctx, fp0, fs);
12227 gen_load_fpr32(ctx, fp1, ft);
12228 gen_load_fpr32(ctx, fp2, fr);
12229 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12230 tcg_temp_free_i32(fp0);
12231 tcg_temp_free_i32(fp1);
12232 gen_store_fpr32(ctx, fp2, fd);
12233 tcg_temp_free_i32(fp2);
12238 check_cp1_registers(ctx, fd | fs | ft | fr);
12240 TCGv_i64 fp0 = tcg_temp_new_i64();
12241 TCGv_i64 fp1 = tcg_temp_new_i64();
12242 TCGv_i64 fp2 = tcg_temp_new_i64();
12244 gen_load_fpr64(ctx, fp0, fs);
12245 gen_load_fpr64(ctx, fp1, ft);
12246 gen_load_fpr64(ctx, fp2, fr);
12247 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12248 tcg_temp_free_i64(fp0);
12249 tcg_temp_free_i64(fp1);
12250 gen_store_fpr64(ctx, fp2, fd);
12251 tcg_temp_free_i64(fp2);
12257 TCGv_i64 fp0 = tcg_temp_new_i64();
12258 TCGv_i64 fp1 = tcg_temp_new_i64();
12259 TCGv_i64 fp2 = tcg_temp_new_i64();
12261 gen_load_fpr64(ctx, fp0, fs);
12262 gen_load_fpr64(ctx, fp1, ft);
12263 gen_load_fpr64(ctx, fp2, fr);
12264 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12265 tcg_temp_free_i64(fp0);
12266 tcg_temp_free_i64(fp1);
12267 gen_store_fpr64(ctx, fp2, fd);
12268 tcg_temp_free_i64(fp2);
12274 TCGv_i32 fp0 = tcg_temp_new_i32();
12275 TCGv_i32 fp1 = tcg_temp_new_i32();
12276 TCGv_i32 fp2 = tcg_temp_new_i32();
12278 gen_load_fpr32(ctx, fp0, fs);
12279 gen_load_fpr32(ctx, fp1, ft);
12280 gen_load_fpr32(ctx, fp2, fr);
12281 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12282 tcg_temp_free_i32(fp0);
12283 tcg_temp_free_i32(fp1);
12284 gen_store_fpr32(ctx, fp2, fd);
12285 tcg_temp_free_i32(fp2);
12290 check_cp1_registers(ctx, fd | fs | ft | fr);
12292 TCGv_i64 fp0 = tcg_temp_new_i64();
12293 TCGv_i64 fp1 = tcg_temp_new_i64();
12294 TCGv_i64 fp2 = tcg_temp_new_i64();
12296 gen_load_fpr64(ctx, fp0, fs);
12297 gen_load_fpr64(ctx, fp1, ft);
12298 gen_load_fpr64(ctx, fp2, fr);
12299 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12300 tcg_temp_free_i64(fp0);
12301 tcg_temp_free_i64(fp1);
12302 gen_store_fpr64(ctx, fp2, fd);
12303 tcg_temp_free_i64(fp2);
12309 TCGv_i64 fp0 = tcg_temp_new_i64();
12310 TCGv_i64 fp1 = tcg_temp_new_i64();
12311 TCGv_i64 fp2 = tcg_temp_new_i64();
12313 gen_load_fpr64(ctx, fp0, fs);
12314 gen_load_fpr64(ctx, fp1, ft);
12315 gen_load_fpr64(ctx, fp2, fr);
12316 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12317 tcg_temp_free_i64(fp0);
12318 tcg_temp_free_i64(fp1);
12319 gen_store_fpr64(ctx, fp2, fd);
12320 tcg_temp_free_i64(fp2);
12326 TCGv_i32 fp0 = tcg_temp_new_i32();
12327 TCGv_i32 fp1 = tcg_temp_new_i32();
12328 TCGv_i32 fp2 = tcg_temp_new_i32();
12330 gen_load_fpr32(ctx, fp0, fs);
12331 gen_load_fpr32(ctx, fp1, ft);
12332 gen_load_fpr32(ctx, fp2, fr);
12333 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12334 tcg_temp_free_i32(fp0);
12335 tcg_temp_free_i32(fp1);
12336 gen_store_fpr32(ctx, fp2, fd);
12337 tcg_temp_free_i32(fp2);
12342 check_cp1_registers(ctx, fd | fs | ft | fr);
12344 TCGv_i64 fp0 = tcg_temp_new_i64();
12345 TCGv_i64 fp1 = tcg_temp_new_i64();
12346 TCGv_i64 fp2 = tcg_temp_new_i64();
12348 gen_load_fpr64(ctx, fp0, fs);
12349 gen_load_fpr64(ctx, fp1, ft);
12350 gen_load_fpr64(ctx, fp2, fr);
12351 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12352 tcg_temp_free_i64(fp0);
12353 tcg_temp_free_i64(fp1);
12354 gen_store_fpr64(ctx, fp2, fd);
12355 tcg_temp_free_i64(fp2);
12361 TCGv_i64 fp0 = tcg_temp_new_i64();
12362 TCGv_i64 fp1 = tcg_temp_new_i64();
12363 TCGv_i64 fp2 = tcg_temp_new_i64();
12365 gen_load_fpr64(ctx, fp0, fs);
12366 gen_load_fpr64(ctx, fp1, ft);
12367 gen_load_fpr64(ctx, fp2, fr);
12368 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12369 tcg_temp_free_i64(fp0);
12370 tcg_temp_free_i64(fp1);
12371 gen_store_fpr64(ctx, fp2, fd);
12372 tcg_temp_free_i64(fp2);
12376 MIPS_INVAL("flt3_arith");
12377 generate_exception_end(ctx, EXCP_RI);
12382 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12386 #if !defined(CONFIG_USER_ONLY)
12387 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12388 Therefore only check the ISA in system mode. */
12389 check_insn(ctx, ISA_MIPS32R2);
12391 t0 = tcg_temp_new();
12395 gen_helper_rdhwr_cpunum(t0, cpu_env);
12396 gen_store_gpr(t0, rt);
12399 gen_helper_rdhwr_synci_step(t0, cpu_env);
12400 gen_store_gpr(t0, rt);
12403 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12406 gen_helper_rdhwr_cc(t0, cpu_env);
12407 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12410 gen_store_gpr(t0, rt);
12411 /* Break the TB to be able to take timer interrupts immediately
12412 after reading count. DISAS_STOP isn't sufficient, we need to ensure
12413 we break completely out of translated code. */
12414 gen_save_pc(ctx->base.pc_next + 4);
12415 ctx->base.is_jmp = DISAS_EXIT;
12418 gen_helper_rdhwr_ccres(t0, cpu_env);
12419 gen_store_gpr(t0, rt);
12422 check_insn(ctx, ISA_MIPS32R6);
12424 /* Performance counter registers are not implemented other than
12425 * control register 0.
12427 generate_exception(ctx, EXCP_RI);
12429 gen_helper_rdhwr_performance(t0, cpu_env);
12430 gen_store_gpr(t0, rt);
12433 check_insn(ctx, ISA_MIPS32R6);
12434 gen_helper_rdhwr_xnp(t0, cpu_env);
12435 gen_store_gpr(t0, rt);
12438 #if defined(CONFIG_USER_ONLY)
12439 tcg_gen_ld_tl(t0, cpu_env,
12440 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12441 gen_store_gpr(t0, rt);
12444 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12445 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12446 tcg_gen_ld_tl(t0, cpu_env,
12447 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12448 gen_store_gpr(t0, rt);
12450 generate_exception_end(ctx, EXCP_RI);
12454 default: /* Invalid */
12455 MIPS_INVAL("rdhwr");
12456 generate_exception_end(ctx, EXCP_RI);
12462 static inline void clear_branch_hflags(DisasContext *ctx)
12464 ctx->hflags &= ~MIPS_HFLAG_BMASK;
12465 if (ctx->base.is_jmp == DISAS_NEXT) {
12466 save_cpu_state(ctx, 0);
12468 /* it is not safe to save ctx->hflags as hflags may be changed
12469 in execution time by the instruction in delay / forbidden slot. */
12470 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12474 static void gen_branch(DisasContext *ctx, int insn_bytes)
12476 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12477 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12478 /* Branches completion */
12479 clear_branch_hflags(ctx);
12480 ctx->base.is_jmp = DISAS_NORETURN;
12481 /* FIXME: Need to clear can_do_io. */
12482 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12483 case MIPS_HFLAG_FBNSLOT:
12484 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12487 /* unconditional branch */
12488 if (proc_hflags & MIPS_HFLAG_BX) {
12489 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12491 gen_goto_tb(ctx, 0, ctx->btarget);
12493 case MIPS_HFLAG_BL:
12494 /* blikely taken case */
12495 gen_goto_tb(ctx, 0, ctx->btarget);
12497 case MIPS_HFLAG_BC:
12498 /* Conditional branch */
12500 TCGLabel *l1 = gen_new_label();
12502 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12503 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12505 gen_goto_tb(ctx, 0, ctx->btarget);
12508 case MIPS_HFLAG_BR:
12509 /* unconditional branch to register */
12510 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12511 TCGv t0 = tcg_temp_new();
12512 TCGv_i32 t1 = tcg_temp_new_i32();
12514 tcg_gen_andi_tl(t0, btarget, 0x1);
12515 tcg_gen_trunc_tl_i32(t1, t0);
12517 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12518 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12519 tcg_gen_or_i32(hflags, hflags, t1);
12520 tcg_temp_free_i32(t1);
12522 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12524 tcg_gen_mov_tl(cpu_PC, btarget);
12526 if (ctx->base.singlestep_enabled) {
12527 save_cpu_state(ctx, 0);
12528 gen_helper_raise_exception_debug(cpu_env);
12530 tcg_gen_lookup_and_goto_ptr();
12533 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12539 /* Compact Branches */
12540 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12541 int rs, int rt, int32_t offset)
12543 int bcond_compute = 0;
12544 TCGv t0 = tcg_temp_new();
12545 TCGv t1 = tcg_temp_new();
12546 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12548 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12549 #ifdef MIPS_DEBUG_DISAS
12550 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12551 "\n", ctx->base.pc_next);
12553 generate_exception_end(ctx, EXCP_RI);
12557 /* Load needed operands and calculate btarget */
12559 /* compact branch */
12560 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12561 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12562 gen_load_gpr(t0, rs);
12563 gen_load_gpr(t1, rt);
12565 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12566 if (rs <= rt && rs == 0) {
12567 /* OPC_BEQZALC, OPC_BNEZALC */
12568 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12571 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12572 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12573 gen_load_gpr(t0, rs);
12574 gen_load_gpr(t1, rt);
12576 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12578 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12579 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12580 if (rs == 0 || rs == rt) {
12581 /* OPC_BLEZALC, OPC_BGEZALC */
12582 /* OPC_BGTZALC, OPC_BLTZALC */
12583 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12585 gen_load_gpr(t0, rs);
12586 gen_load_gpr(t1, rt);
12588 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12592 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12597 /* OPC_BEQZC, OPC_BNEZC */
12598 gen_load_gpr(t0, rs);
12600 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12602 /* OPC_JIC, OPC_JIALC */
12603 TCGv tbase = tcg_temp_new();
12604 TCGv toffset = tcg_temp_new();
12606 gen_load_gpr(tbase, rt);
12607 tcg_gen_movi_tl(toffset, offset);
12608 gen_op_addr_add(ctx, btarget, tbase, toffset);
12609 tcg_temp_free(tbase);
12610 tcg_temp_free(toffset);
12614 MIPS_INVAL("Compact branch/jump");
12615 generate_exception_end(ctx, EXCP_RI);
12619 if (bcond_compute == 0) {
12620 /* Uncoditional compact branch */
12623 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12626 ctx->hflags |= MIPS_HFLAG_BR;
12629 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12632 ctx->hflags |= MIPS_HFLAG_B;
12635 MIPS_INVAL("Compact branch/jump");
12636 generate_exception_end(ctx, EXCP_RI);
12640 /* Generating branch here as compact branches don't have delay slot */
12641 gen_branch(ctx, 4);
12643 /* Conditional compact branch */
12644 TCGLabel *fs = gen_new_label();
12645 save_cpu_state(ctx, 0);
12648 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12649 if (rs == 0 && rt != 0) {
12651 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12652 } else if (rs != 0 && rt != 0 && rs == rt) {
12654 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12657 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12660 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12661 if (rs == 0 && rt != 0) {
12663 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12664 } else if (rs != 0 && rt != 0 && rs == rt) {
12666 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12669 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12672 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12673 if (rs == 0 && rt != 0) {
12675 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12676 } else if (rs != 0 && rt != 0 && rs == rt) {
12678 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12681 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12684 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12685 if (rs == 0 && rt != 0) {
12687 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12688 } else if (rs != 0 && rt != 0 && rs == rt) {
12690 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12693 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12696 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12697 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12699 /* OPC_BOVC, OPC_BNVC */
12700 TCGv t2 = tcg_temp_new();
12701 TCGv t3 = tcg_temp_new();
12702 TCGv t4 = tcg_temp_new();
12703 TCGv input_overflow = tcg_temp_new();
12705 gen_load_gpr(t0, rs);
12706 gen_load_gpr(t1, rt);
12707 tcg_gen_ext32s_tl(t2, t0);
12708 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12709 tcg_gen_ext32s_tl(t3, t1);
12710 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12711 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12713 tcg_gen_add_tl(t4, t2, t3);
12714 tcg_gen_ext32s_tl(t4, t4);
12715 tcg_gen_xor_tl(t2, t2, t3);
12716 tcg_gen_xor_tl(t3, t4, t3);
12717 tcg_gen_andc_tl(t2, t3, t2);
12718 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12719 tcg_gen_or_tl(t4, t4, input_overflow);
12720 if (opc == OPC_BOVC) {
12722 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12725 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12727 tcg_temp_free(input_overflow);
12731 } else if (rs < rt && rs == 0) {
12732 /* OPC_BEQZALC, OPC_BNEZALC */
12733 if (opc == OPC_BEQZALC) {
12735 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12738 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12741 /* OPC_BEQC, OPC_BNEC */
12742 if (opc == OPC_BEQC) {
12744 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12747 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12752 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12755 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12758 MIPS_INVAL("Compact conditional branch/jump");
12759 generate_exception_end(ctx, EXCP_RI);
12763 /* Generating branch here as compact branches don't have delay slot */
12764 gen_goto_tb(ctx, 1, ctx->btarget);
12767 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12775 /* ISA extensions (ASEs) */
12776 /* MIPS16 extension to MIPS32 */
12778 /* MIPS16 major opcodes */
12780 M16_OPC_ADDIUSP = 0x00,
12781 M16_OPC_ADDIUPC = 0x01,
12783 M16_OPC_JAL = 0x03,
12784 M16_OPC_BEQZ = 0x04,
12785 M16_OPC_BNEQZ = 0x05,
12786 M16_OPC_SHIFT = 0x06,
12788 M16_OPC_RRIA = 0x08,
12789 M16_OPC_ADDIU8 = 0x09,
12790 M16_OPC_SLTI = 0x0a,
12791 M16_OPC_SLTIU = 0x0b,
12794 M16_OPC_CMPI = 0x0e,
12798 M16_OPC_LWSP = 0x12,
12800 M16_OPC_LBU = 0x14,
12801 M16_OPC_LHU = 0x15,
12802 M16_OPC_LWPC = 0x16,
12803 M16_OPC_LWU = 0x17,
12806 M16_OPC_SWSP = 0x1a,
12808 M16_OPC_RRR = 0x1c,
12810 M16_OPC_EXTEND = 0x1e,
12814 /* I8 funct field */
12833 /* RR funct field */
12867 /* I64 funct field */
12875 I64_DADDIUPC = 0x6,
12879 /* RR ry field for CNVT */
12881 RR_RY_CNVT_ZEB = 0x0,
12882 RR_RY_CNVT_ZEH = 0x1,
12883 RR_RY_CNVT_ZEW = 0x2,
12884 RR_RY_CNVT_SEB = 0x4,
12885 RR_RY_CNVT_SEH = 0x5,
12886 RR_RY_CNVT_SEW = 0x6,
12889 static int xlat (int r)
12891 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12896 static void gen_mips16_save (DisasContext *ctx,
12897 int xsregs, int aregs,
12898 int do_ra, int do_s0, int do_s1,
12901 TCGv t0 = tcg_temp_new();
12902 TCGv t1 = tcg_temp_new();
12903 TCGv t2 = tcg_temp_new();
12933 generate_exception_end(ctx, EXCP_RI);
12939 gen_base_offset_addr(ctx, t0, 29, 12);
12940 gen_load_gpr(t1, 7);
12941 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12944 gen_base_offset_addr(ctx, t0, 29, 8);
12945 gen_load_gpr(t1, 6);
12946 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12949 gen_base_offset_addr(ctx, t0, 29, 4);
12950 gen_load_gpr(t1, 5);
12951 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12954 gen_base_offset_addr(ctx, t0, 29, 0);
12955 gen_load_gpr(t1, 4);
12956 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12959 gen_load_gpr(t0, 29);
12961 #define DECR_AND_STORE(reg) do { \
12962 tcg_gen_movi_tl(t2, -4); \
12963 gen_op_addr_add(ctx, t0, t0, t2); \
12964 gen_load_gpr(t1, reg); \
12965 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12969 DECR_AND_STORE(31);
12974 DECR_AND_STORE(30);
12977 DECR_AND_STORE(23);
12980 DECR_AND_STORE(22);
12983 DECR_AND_STORE(21);
12986 DECR_AND_STORE(20);
12989 DECR_AND_STORE(19);
12992 DECR_AND_STORE(18);
12996 DECR_AND_STORE(17);
12999 DECR_AND_STORE(16);
13029 generate_exception_end(ctx, EXCP_RI);
13045 #undef DECR_AND_STORE
13047 tcg_gen_movi_tl(t2, -framesize);
13048 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13054 static void gen_mips16_restore (DisasContext *ctx,
13055 int xsregs, int aregs,
13056 int do_ra, int do_s0, int do_s1,
13060 TCGv t0 = tcg_temp_new();
13061 TCGv t1 = tcg_temp_new();
13062 TCGv t2 = tcg_temp_new();
13064 tcg_gen_movi_tl(t2, framesize);
13065 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13067 #define DECR_AND_LOAD(reg) do { \
13068 tcg_gen_movi_tl(t2, -4); \
13069 gen_op_addr_add(ctx, t0, t0, t2); \
13070 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13071 gen_store_gpr(t1, reg); \
13135 generate_exception_end(ctx, EXCP_RI);
13151 #undef DECR_AND_LOAD
13153 tcg_gen_movi_tl(t2, framesize);
13154 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13160 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13161 int is_64_bit, int extended)
13165 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13166 generate_exception_end(ctx, EXCP_RI);
13170 t0 = tcg_temp_new();
13172 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13173 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13175 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13181 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13184 TCGv_i32 t0 = tcg_const_i32(op);
13185 TCGv t1 = tcg_temp_new();
13186 gen_base_offset_addr(ctx, t1, base, offset);
13187 gen_helper_cache(cpu_env, t1, t0);
13190 #if defined(TARGET_MIPS64)
13191 static void decode_i64_mips16 (DisasContext *ctx,
13192 int ry, int funct, int16_t offset,
13197 check_insn(ctx, ISA_MIPS3);
13198 check_mips_64(ctx);
13199 offset = extended ? offset : offset << 3;
13200 gen_ld(ctx, OPC_LD, ry, 29, offset);
13203 check_insn(ctx, ISA_MIPS3);
13204 check_mips_64(ctx);
13205 offset = extended ? offset : offset << 3;
13206 gen_st(ctx, OPC_SD, ry, 29, offset);
13209 check_insn(ctx, ISA_MIPS3);
13210 check_mips_64(ctx);
13211 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13212 gen_st(ctx, OPC_SD, 31, 29, offset);
13215 check_insn(ctx, ISA_MIPS3);
13216 check_mips_64(ctx);
13217 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13218 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13221 check_insn(ctx, ISA_MIPS3);
13222 check_mips_64(ctx);
13223 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13224 generate_exception_end(ctx, EXCP_RI);
13226 offset = extended ? offset : offset << 3;
13227 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13231 check_insn(ctx, ISA_MIPS3);
13232 check_mips_64(ctx);
13233 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13234 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13237 check_insn(ctx, ISA_MIPS3);
13238 check_mips_64(ctx);
13239 offset = extended ? offset : offset << 2;
13240 gen_addiupc(ctx, ry, offset, 1, extended);
13243 check_insn(ctx, ISA_MIPS3);
13244 check_mips_64(ctx);
13245 offset = extended ? offset : offset << 2;
13246 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13252 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13254 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13255 int op, rx, ry, funct, sa;
13256 int16_t imm, offset;
13258 ctx->opcode = (ctx->opcode << 16) | extend;
13259 op = (ctx->opcode >> 11) & 0x1f;
13260 sa = (ctx->opcode >> 22) & 0x1f;
13261 funct = (ctx->opcode >> 8) & 0x7;
13262 rx = xlat((ctx->opcode >> 8) & 0x7);
13263 ry = xlat((ctx->opcode >> 5) & 0x7);
13264 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13265 | ((ctx->opcode >> 21) & 0x3f) << 5
13266 | (ctx->opcode & 0x1f));
13268 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13271 case M16_OPC_ADDIUSP:
13272 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13274 case M16_OPC_ADDIUPC:
13275 gen_addiupc(ctx, rx, imm, 0, 1);
13278 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13279 /* No delay slot, so just process as a normal instruction */
13282 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13283 /* No delay slot, so just process as a normal instruction */
13285 case M16_OPC_BNEQZ:
13286 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13287 /* No delay slot, so just process as a normal instruction */
13289 case M16_OPC_SHIFT:
13290 switch (ctx->opcode & 0x3) {
13292 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13295 #if defined(TARGET_MIPS64)
13296 check_mips_64(ctx);
13297 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13299 generate_exception_end(ctx, EXCP_RI);
13303 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13306 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13310 #if defined(TARGET_MIPS64)
13312 check_insn(ctx, ISA_MIPS3);
13313 check_mips_64(ctx);
13314 gen_ld(ctx, OPC_LD, ry, rx, offset);
13318 imm = ctx->opcode & 0xf;
13319 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13320 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13321 imm = (int16_t) (imm << 1) >> 1;
13322 if ((ctx->opcode >> 4) & 0x1) {
13323 #if defined(TARGET_MIPS64)
13324 check_mips_64(ctx);
13325 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13327 generate_exception_end(ctx, EXCP_RI);
13330 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13333 case M16_OPC_ADDIU8:
13334 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13337 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13339 case M16_OPC_SLTIU:
13340 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13345 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13348 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13351 gen_st(ctx, OPC_SW, 31, 29, imm);
13354 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13357 check_insn(ctx, ISA_MIPS32);
13359 int xsregs = (ctx->opcode >> 24) & 0x7;
13360 int aregs = (ctx->opcode >> 16) & 0xf;
13361 int do_ra = (ctx->opcode >> 6) & 0x1;
13362 int do_s0 = (ctx->opcode >> 5) & 0x1;
13363 int do_s1 = (ctx->opcode >> 4) & 0x1;
13364 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13365 | (ctx->opcode & 0xf)) << 3;
13367 if (ctx->opcode & (1 << 7)) {
13368 gen_mips16_save(ctx, xsregs, aregs,
13369 do_ra, do_s0, do_s1,
13372 gen_mips16_restore(ctx, xsregs, aregs,
13373 do_ra, do_s0, do_s1,
13379 generate_exception_end(ctx, EXCP_RI);
13384 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13387 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13389 #if defined(TARGET_MIPS64)
13391 check_insn(ctx, ISA_MIPS3);
13392 check_mips_64(ctx);
13393 gen_st(ctx, OPC_SD, ry, rx, offset);
13397 gen_ld(ctx, OPC_LB, ry, rx, offset);
13400 gen_ld(ctx, OPC_LH, ry, rx, offset);
13403 gen_ld(ctx, OPC_LW, rx, 29, offset);
13406 gen_ld(ctx, OPC_LW, ry, rx, offset);
13409 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13412 gen_ld(ctx, OPC_LHU, ry, rx, offset);
13415 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13417 #if defined(TARGET_MIPS64)
13419 check_insn(ctx, ISA_MIPS3);
13420 check_mips_64(ctx);
13421 gen_ld(ctx, OPC_LWU, ry, rx, offset);
13425 gen_st(ctx, OPC_SB, ry, rx, offset);
13428 gen_st(ctx, OPC_SH, ry, rx, offset);
13431 gen_st(ctx, OPC_SW, rx, 29, offset);
13434 gen_st(ctx, OPC_SW, ry, rx, offset);
13436 #if defined(TARGET_MIPS64)
13438 decode_i64_mips16(ctx, ry, funct, offset, 1);
13442 generate_exception_end(ctx, EXCP_RI);
13449 static inline bool is_uhi(int sdbbp_code)
13451 #ifdef CONFIG_USER_ONLY
13454 return semihosting_enabled() && sdbbp_code == 1;
13458 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13462 int op, cnvt_op, op1, offset;
13466 op = (ctx->opcode >> 11) & 0x1f;
13467 sa = (ctx->opcode >> 2) & 0x7;
13468 sa = sa == 0 ? 8 : sa;
13469 rx = xlat((ctx->opcode >> 8) & 0x7);
13470 cnvt_op = (ctx->opcode >> 5) & 0x7;
13471 ry = xlat((ctx->opcode >> 5) & 0x7);
13472 op1 = offset = ctx->opcode & 0x1f;
13477 case M16_OPC_ADDIUSP:
13479 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13481 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13484 case M16_OPC_ADDIUPC:
13485 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13488 offset = (ctx->opcode & 0x7ff) << 1;
13489 offset = (int16_t)(offset << 4) >> 4;
13490 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13491 /* No delay slot, so just process as a normal instruction */
13494 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13495 offset = (((ctx->opcode & 0x1f) << 21)
13496 | ((ctx->opcode >> 5) & 0x1f) << 16
13498 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13499 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13503 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13504 ((int8_t)ctx->opcode) << 1, 0);
13505 /* No delay slot, so just process as a normal instruction */
13507 case M16_OPC_BNEQZ:
13508 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13509 ((int8_t)ctx->opcode) << 1, 0);
13510 /* No delay slot, so just process as a normal instruction */
13512 case M16_OPC_SHIFT:
13513 switch (ctx->opcode & 0x3) {
13515 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13518 #if defined(TARGET_MIPS64)
13519 check_insn(ctx, ISA_MIPS3);
13520 check_mips_64(ctx);
13521 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13523 generate_exception_end(ctx, EXCP_RI);
13527 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13530 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13534 #if defined(TARGET_MIPS64)
13536 check_insn(ctx, ISA_MIPS3);
13537 check_mips_64(ctx);
13538 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13543 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13545 if ((ctx->opcode >> 4) & 1) {
13546 #if defined(TARGET_MIPS64)
13547 check_insn(ctx, ISA_MIPS3);
13548 check_mips_64(ctx);
13549 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13551 generate_exception_end(ctx, EXCP_RI);
13554 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13558 case M16_OPC_ADDIU8:
13560 int16_t imm = (int8_t) ctx->opcode;
13562 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13567 int16_t imm = (uint8_t) ctx->opcode;
13568 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13571 case M16_OPC_SLTIU:
13573 int16_t imm = (uint8_t) ctx->opcode;
13574 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13581 funct = (ctx->opcode >> 8) & 0x7;
13584 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13585 ((int8_t)ctx->opcode) << 1, 0);
13588 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13589 ((int8_t)ctx->opcode) << 1, 0);
13592 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13595 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13596 ((int8_t)ctx->opcode) << 3);
13599 check_insn(ctx, ISA_MIPS32);
13601 int do_ra = ctx->opcode & (1 << 6);
13602 int do_s0 = ctx->opcode & (1 << 5);
13603 int do_s1 = ctx->opcode & (1 << 4);
13604 int framesize = ctx->opcode & 0xf;
13606 if (framesize == 0) {
13609 framesize = framesize << 3;
13612 if (ctx->opcode & (1 << 7)) {
13613 gen_mips16_save(ctx, 0, 0,
13614 do_ra, do_s0, do_s1, framesize);
13616 gen_mips16_restore(ctx, 0, 0,
13617 do_ra, do_s0, do_s1, framesize);
13623 int rz = xlat(ctx->opcode & 0x7);
13625 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13626 ((ctx->opcode >> 5) & 0x7);
13627 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13631 reg32 = ctx->opcode & 0x1f;
13632 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13635 generate_exception_end(ctx, EXCP_RI);
13642 int16_t imm = (uint8_t) ctx->opcode;
13644 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13649 int16_t imm = (uint8_t) ctx->opcode;
13650 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13653 #if defined(TARGET_MIPS64)
13655 check_insn(ctx, ISA_MIPS3);
13656 check_mips_64(ctx);
13657 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13661 gen_ld(ctx, OPC_LB, ry, rx, offset);
13664 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13667 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13670 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13673 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13676 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13679 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13681 #if defined (TARGET_MIPS64)
13683 check_insn(ctx, ISA_MIPS3);
13684 check_mips_64(ctx);
13685 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13689 gen_st(ctx, OPC_SB, ry, rx, offset);
13692 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13695 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13698 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13702 int rz = xlat((ctx->opcode >> 2) & 0x7);
13705 switch (ctx->opcode & 0x3) {
13707 mips32_op = OPC_ADDU;
13710 mips32_op = OPC_SUBU;
13712 #if defined(TARGET_MIPS64)
13714 mips32_op = OPC_DADDU;
13715 check_insn(ctx, ISA_MIPS3);
13716 check_mips_64(ctx);
13719 mips32_op = OPC_DSUBU;
13720 check_insn(ctx, ISA_MIPS3);
13721 check_mips_64(ctx);
13725 generate_exception_end(ctx, EXCP_RI);
13729 gen_arith(ctx, mips32_op, rz, rx, ry);
13738 int nd = (ctx->opcode >> 7) & 0x1;
13739 int link = (ctx->opcode >> 6) & 0x1;
13740 int ra = (ctx->opcode >> 5) & 0x1;
13743 check_insn(ctx, ISA_MIPS32);
13752 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13757 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13758 gen_helper_do_semihosting(cpu_env);
13760 /* XXX: not clear which exception should be raised
13761 * when in debug mode...
13763 check_insn(ctx, ISA_MIPS32);
13764 generate_exception_end(ctx, EXCP_DBp);
13768 gen_slt(ctx, OPC_SLT, 24, rx, ry);
13771 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13774 generate_exception_end(ctx, EXCP_BREAK);
13777 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13780 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13783 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13785 #if defined (TARGET_MIPS64)
13787 check_insn(ctx, ISA_MIPS3);
13788 check_mips_64(ctx);
13789 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13793 gen_logic(ctx, OPC_XOR, 24, rx, ry);
13796 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13799 gen_logic(ctx, OPC_AND, rx, rx, ry);
13802 gen_logic(ctx, OPC_OR, rx, rx, ry);
13805 gen_logic(ctx, OPC_XOR, rx, rx, ry);
13808 gen_logic(ctx, OPC_NOR, rx, ry, 0);
13811 gen_HILO(ctx, OPC_MFHI, 0, rx);
13814 check_insn(ctx, ISA_MIPS32);
13816 case RR_RY_CNVT_ZEB:
13817 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13819 case RR_RY_CNVT_ZEH:
13820 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13822 case RR_RY_CNVT_SEB:
13823 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13825 case RR_RY_CNVT_SEH:
13826 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13828 #if defined (TARGET_MIPS64)
13829 case RR_RY_CNVT_ZEW:
13830 check_insn(ctx, ISA_MIPS64);
13831 check_mips_64(ctx);
13832 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13834 case RR_RY_CNVT_SEW:
13835 check_insn(ctx, ISA_MIPS64);
13836 check_mips_64(ctx);
13837 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13841 generate_exception_end(ctx, EXCP_RI);
13846 gen_HILO(ctx, OPC_MFLO, 0, rx);
13848 #if defined (TARGET_MIPS64)
13850 check_insn(ctx, ISA_MIPS3);
13851 check_mips_64(ctx);
13852 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13855 check_insn(ctx, ISA_MIPS3);
13856 check_mips_64(ctx);
13857 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
13860 check_insn(ctx, ISA_MIPS3);
13861 check_mips_64(ctx);
13862 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
13865 check_insn(ctx, ISA_MIPS3);
13866 check_mips_64(ctx);
13867 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
13871 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
13874 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
13877 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
13880 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
13882 #if defined (TARGET_MIPS64)
13884 check_insn(ctx, ISA_MIPS3);
13885 check_mips_64(ctx);
13886 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
13889 check_insn(ctx, ISA_MIPS3);
13890 check_mips_64(ctx);
13891 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
13894 check_insn(ctx, ISA_MIPS3);
13895 check_mips_64(ctx);
13896 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
13899 check_insn(ctx, ISA_MIPS3);
13900 check_mips_64(ctx);
13901 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
13905 generate_exception_end(ctx, EXCP_RI);
13909 case M16_OPC_EXTEND:
13910 decode_extended_mips16_opc(env, ctx);
13913 #if defined(TARGET_MIPS64)
13915 funct = (ctx->opcode >> 8) & 0x7;
13916 decode_i64_mips16(ctx, ry, funct, offset, 0);
13920 generate_exception_end(ctx, EXCP_RI);
13927 /* microMIPS extension to MIPS32/MIPS64 */
13930 * microMIPS32/microMIPS64 major opcodes
13932 * 1. MIPS Architecture for Programmers Volume II-B:
13933 * The microMIPS32 Instruction Set (Revision 3.05)
13935 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13937 * 2. MIPS Architecture For Programmers Volume II-A:
13938 * The MIPS64 Instruction Set (Revision 3.51)
13968 POOL32S = 0x16, /* MIPS64 */
13969 DADDIU32 = 0x17, /* MIPS64 */
13998 /* 0x29 is reserved */
14011 /* 0x31 is reserved */
14024 SD32 = 0x36, /* MIPS64 */
14025 LD32 = 0x37, /* MIPS64 */
14027 /* 0x39 is reserved */
14043 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14065 /* POOL32A encoding of minor opcode field */
14068 /* These opcodes are distinguished only by bits 9..6; those bits are
14069 * what are recorded below. */
14106 /* The following can be distinguished by their lower 6 bits. */
14116 /* POOL32AXF encoding of minor opcode field extension */
14119 * 1. MIPS Architecture for Programmers Volume II-B:
14120 * The microMIPS32 Instruction Set (Revision 3.05)
14122 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14124 * 2. MIPS Architecture for Programmers VolumeIV-e:
14125 * The MIPS DSP Application-Specific Extension
14126 * to the microMIPS32 Architecture (Revision 2.34)
14128 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14143 /* begin of microMIPS32 DSP */
14145 /* bits 13..12 for 0x01 */
14151 /* bits 13..12 for 0x2a */
14157 /* bits 13..12 for 0x32 */
14161 /* end of microMIPS32 DSP */
14163 /* bits 15..12 for 0x2c */
14180 /* bits 15..12 for 0x34 */
14188 /* bits 15..12 for 0x3c */
14190 JR = 0x0, /* alias */
14198 /* bits 15..12 for 0x05 */
14202 /* bits 15..12 for 0x0d */
14214 /* bits 15..12 for 0x15 */
14220 /* bits 15..12 for 0x1d */
14224 /* bits 15..12 for 0x2d */
14229 /* bits 15..12 for 0x35 */
14236 /* POOL32B encoding of minor opcode field (bits 15..12) */
14252 /* POOL32C encoding of minor opcode field (bits 15..12) */
14273 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14286 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14299 /* POOL32F encoding of minor opcode field (bits 5..0) */
14302 /* These are the bit 7..6 values */
14311 /* These are the bit 8..6 values */
14336 MOVZ_FMT_05 = 0x05,
14370 CABS_COND_FMT = 0x1c, /* MIPS3D */
14377 /* POOL32Fxf encoding of minor opcode extension field */
14415 /* POOL32I encoding of minor opcode field (bits 25..21) */
14445 /* These overlap and are distinguished by bit16 of the instruction */
14454 /* POOL16A encoding of minor opcode field */
14461 /* POOL16B encoding of minor opcode field */
14468 /* POOL16C encoding of minor opcode field */
14488 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14512 /* POOL16D encoding of minor opcode field */
14519 /* POOL16E encoding of minor opcode field */
14526 static int mmreg (int r)
14528 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14533 /* Used for 16-bit store instructions. */
14534 static int mmreg2 (int r)
14536 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14541 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14542 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14543 #define uMIPS_RS2(op) uMIPS_RS(op)
14544 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14545 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14546 #define uMIPS_RS5(op) (op & 0x1f)
14548 /* Signed immediate */
14549 #define SIMM(op, start, width) \
14550 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14553 /* Zero-extended immediate */
14554 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14556 static void gen_addiur1sp(DisasContext *ctx)
14558 int rd = mmreg(uMIPS_RD(ctx->opcode));
14560 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14563 static void gen_addiur2(DisasContext *ctx)
14565 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14566 int rd = mmreg(uMIPS_RD(ctx->opcode));
14567 int rs = mmreg(uMIPS_RS(ctx->opcode));
14569 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14572 static void gen_addiusp(DisasContext *ctx)
14574 int encoded = ZIMM(ctx->opcode, 1, 9);
14577 if (encoded <= 1) {
14578 decoded = 256 + encoded;
14579 } else if (encoded <= 255) {
14581 } else if (encoded <= 509) {
14582 decoded = encoded - 512;
14584 decoded = encoded - 768;
14587 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14590 static void gen_addius5(DisasContext *ctx)
14592 int imm = SIMM(ctx->opcode, 1, 4);
14593 int rd = (ctx->opcode >> 5) & 0x1f;
14595 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14598 static void gen_andi16(DisasContext *ctx)
14600 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14601 31, 32, 63, 64, 255, 32768, 65535 };
14602 int rd = mmreg(uMIPS_RD(ctx->opcode));
14603 int rs = mmreg(uMIPS_RS(ctx->opcode));
14604 int encoded = ZIMM(ctx->opcode, 0, 4);
14606 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14609 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14610 int base, int16_t offset)
14615 if (ctx->hflags & MIPS_HFLAG_BMASK) {
14616 generate_exception_end(ctx, EXCP_RI);
14620 t0 = tcg_temp_new();
14622 gen_base_offset_addr(ctx, t0, base, offset);
14624 t1 = tcg_const_tl(reglist);
14625 t2 = tcg_const_i32(ctx->mem_idx);
14627 save_cpu_state(ctx, 1);
14630 gen_helper_lwm(cpu_env, t0, t1, t2);
14633 gen_helper_swm(cpu_env, t0, t1, t2);
14635 #ifdef TARGET_MIPS64
14637 gen_helper_ldm(cpu_env, t0, t1, t2);
14640 gen_helper_sdm(cpu_env, t0, t1, t2);
14646 tcg_temp_free_i32(t2);
14650 static void gen_pool16c_insn(DisasContext *ctx)
14652 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14653 int rs = mmreg(ctx->opcode & 0x7);
14655 switch (((ctx->opcode) >> 4) & 0x3f) {
14660 gen_logic(ctx, OPC_NOR, rd, rs, 0);
14666 gen_logic(ctx, OPC_XOR, rd, rd, rs);
14672 gen_logic(ctx, OPC_AND, rd, rd, rs);
14678 gen_logic(ctx, OPC_OR, rd, rd, rs);
14685 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14686 int offset = ZIMM(ctx->opcode, 0, 4);
14688 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14697 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14698 int offset = ZIMM(ctx->opcode, 0, 4);
14700 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14707 int reg = ctx->opcode & 0x1f;
14709 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14715 int reg = ctx->opcode & 0x1f;
14716 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14717 /* Let normal delay slot handling in our caller take us
14718 to the branch target. */
14723 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14724 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14728 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14729 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14733 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14737 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14740 generate_exception_end(ctx, EXCP_BREAK);
14743 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14744 gen_helper_do_semihosting(cpu_env);
14746 /* XXX: not clear which exception should be raised
14747 * when in debug mode...
14749 check_insn(ctx, ISA_MIPS32);
14750 generate_exception_end(ctx, EXCP_DBp);
14753 case JRADDIUSP + 0:
14754 case JRADDIUSP + 1:
14756 int imm = ZIMM(ctx->opcode, 0, 5);
14757 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14758 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14759 /* Let normal delay slot handling in our caller take us
14760 to the branch target. */
14764 generate_exception_end(ctx, EXCP_RI);
14769 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14772 int rd, rs, re, rt;
14773 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14774 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14775 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14776 rd = rd_enc[enc_dest];
14777 re = re_enc[enc_dest];
14778 rs = rs_rt_enc[enc_rs];
14779 rt = rs_rt_enc[enc_rt];
14781 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14783 tcg_gen_movi_tl(cpu_gpr[rd], 0);
14786 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14788 tcg_gen_movi_tl(cpu_gpr[re], 0);
14792 static void gen_pool16c_r6_insn(DisasContext *ctx)
14794 int rt = mmreg((ctx->opcode >> 7) & 0x7);
14795 int rs = mmreg((ctx->opcode >> 4) & 0x7);
14797 switch (ctx->opcode & 0xf) {
14799 gen_logic(ctx, OPC_NOR, rt, rs, 0);
14802 gen_logic(ctx, OPC_AND, rt, rt, rs);
14806 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14807 int offset = extract32(ctx->opcode, 4, 4);
14808 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14811 case R6_JRC16: /* JRCADDIUSP */
14812 if ((ctx->opcode >> 4) & 1) {
14814 int imm = extract32(ctx->opcode, 5, 5);
14815 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14816 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14819 rs = extract32(ctx->opcode, 5, 5);
14820 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14832 int enc_dest = uMIPS_RD(ctx->opcode);
14833 int enc_rt = uMIPS_RS2(ctx->opcode);
14834 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14835 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14839 gen_logic(ctx, OPC_XOR, rt, rt, rs);
14842 gen_logic(ctx, OPC_OR, rt, rt, rs);
14846 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14847 int offset = extract32(ctx->opcode, 4, 4);
14848 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14851 case JALRC16: /* BREAK16, SDBBP16 */
14852 switch (ctx->opcode & 0x3f) {
14854 case JALRC16 + 0x20:
14856 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14861 generate_exception(ctx, EXCP_BREAK);
14865 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14866 gen_helper_do_semihosting(cpu_env);
14868 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14869 generate_exception(ctx, EXCP_RI);
14871 generate_exception(ctx, EXCP_DBp);
14878 generate_exception(ctx, EXCP_RI);
14883 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14885 TCGv t0 = tcg_temp_new();
14886 TCGv t1 = tcg_temp_new();
14888 gen_load_gpr(t0, base);
14891 gen_load_gpr(t1, index);
14892 tcg_gen_shli_tl(t1, t1, 2);
14893 gen_op_addr_add(ctx, t0, t1, t0);
14896 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14897 gen_store_gpr(t1, rd);
14903 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14904 int base, int16_t offset)
14908 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
14909 generate_exception_end(ctx, EXCP_RI);
14913 t0 = tcg_temp_new();
14914 t1 = tcg_temp_new();
14916 gen_base_offset_addr(ctx, t0, base, offset);
14921 generate_exception_end(ctx, EXCP_RI);
14924 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14925 gen_store_gpr(t1, rd);
14926 tcg_gen_movi_tl(t1, 4);
14927 gen_op_addr_add(ctx, t0, t0, t1);
14928 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14929 gen_store_gpr(t1, rd+1);
14932 gen_load_gpr(t1, rd);
14933 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14934 tcg_gen_movi_tl(t1, 4);
14935 gen_op_addr_add(ctx, t0, t0, t1);
14936 gen_load_gpr(t1, rd+1);
14937 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14939 #ifdef TARGET_MIPS64
14942 generate_exception_end(ctx, EXCP_RI);
14945 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14946 gen_store_gpr(t1, rd);
14947 tcg_gen_movi_tl(t1, 8);
14948 gen_op_addr_add(ctx, t0, t0, t1);
14949 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14950 gen_store_gpr(t1, rd+1);
14953 gen_load_gpr(t1, rd);
14954 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14955 tcg_gen_movi_tl(t1, 8);
14956 gen_op_addr_add(ctx, t0, t0, t1);
14957 gen_load_gpr(t1, rd+1);
14958 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14966 static void gen_sync(int stype)
14968 TCGBar tcg_mo = TCG_BAR_SC;
14971 case 0x4: /* SYNC_WMB */
14972 tcg_mo |= TCG_MO_ST_ST;
14974 case 0x10: /* SYNC_MB */
14975 tcg_mo |= TCG_MO_ALL;
14977 case 0x11: /* SYNC_ACQUIRE */
14978 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14980 case 0x12: /* SYNC_RELEASE */
14981 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14983 case 0x13: /* SYNC_RMB */
14984 tcg_mo |= TCG_MO_LD_LD;
14987 tcg_mo |= TCG_MO_ALL;
14991 tcg_gen_mb(tcg_mo);
14994 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
14996 int extension = (ctx->opcode >> 6) & 0x3f;
14997 int minor = (ctx->opcode >> 12) & 0xf;
14998 uint32_t mips32_op;
15000 switch (extension) {
15002 mips32_op = OPC_TEQ;
15005 mips32_op = OPC_TGE;
15008 mips32_op = OPC_TGEU;
15011 mips32_op = OPC_TLT;
15014 mips32_op = OPC_TLTU;
15017 mips32_op = OPC_TNE;
15019 gen_trap(ctx, mips32_op, rs, rt, -1);
15021 #ifndef CONFIG_USER_ONLY
15024 check_cp0_enabled(ctx);
15026 /* Treat as NOP. */
15029 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15033 check_cp0_enabled(ctx);
15035 TCGv t0 = tcg_temp_new();
15037 gen_load_gpr(t0, rt);
15038 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15044 switch (minor & 3) {
15046 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15049 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15052 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15055 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15058 goto pool32axf_invalid;
15062 switch (minor & 3) {
15064 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15067 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15070 goto pool32axf_invalid;
15076 check_insn(ctx, ISA_MIPS32R6);
15077 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15080 gen_bshfl(ctx, OPC_SEB, rs, rt);
15083 gen_bshfl(ctx, OPC_SEH, rs, rt);
15086 mips32_op = OPC_CLO;
15089 mips32_op = OPC_CLZ;
15091 check_insn(ctx, ISA_MIPS32);
15092 gen_cl(ctx, mips32_op, rt, rs);
15095 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15096 gen_rdhwr(ctx, rt, rs, 0);
15099 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15102 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15103 mips32_op = OPC_MULT;
15106 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15107 mips32_op = OPC_MULTU;
15110 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15111 mips32_op = OPC_DIV;
15114 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15115 mips32_op = OPC_DIVU;
15118 check_insn(ctx, ISA_MIPS32);
15119 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15122 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15123 mips32_op = OPC_MADD;
15126 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15127 mips32_op = OPC_MADDU;
15130 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15131 mips32_op = OPC_MSUB;
15134 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15135 mips32_op = OPC_MSUBU;
15137 check_insn(ctx, ISA_MIPS32);
15138 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15141 goto pool32axf_invalid;
15152 generate_exception_err(ctx, EXCP_CpU, 2);
15155 goto pool32axf_invalid;
15160 case JALR: /* JALRC */
15161 case JALR_HB: /* JALRC_HB */
15162 if (ctx->insn_flags & ISA_MIPS32R6) {
15163 /* JALRC, JALRC_HB */
15164 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15166 /* JALR, JALR_HB */
15167 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15168 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15173 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15174 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15175 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15178 goto pool32axf_invalid;
15184 check_cp0_enabled(ctx);
15185 check_insn(ctx, ISA_MIPS32R2);
15186 gen_load_srsgpr(rs, rt);
15189 check_cp0_enabled(ctx);
15190 check_insn(ctx, ISA_MIPS32R2);
15191 gen_store_srsgpr(rs, rt);
15194 goto pool32axf_invalid;
15197 #ifndef CONFIG_USER_ONLY
15201 mips32_op = OPC_TLBP;
15204 mips32_op = OPC_TLBR;
15207 mips32_op = OPC_TLBWI;
15210 mips32_op = OPC_TLBWR;
15213 mips32_op = OPC_TLBINV;
15216 mips32_op = OPC_TLBINVF;
15219 mips32_op = OPC_WAIT;
15222 mips32_op = OPC_DERET;
15225 mips32_op = OPC_ERET;
15227 gen_cp0(env, ctx, mips32_op, rt, rs);
15230 goto pool32axf_invalid;
15236 check_cp0_enabled(ctx);
15238 TCGv t0 = tcg_temp_new();
15240 save_cpu_state(ctx, 1);
15241 gen_helper_di(t0, cpu_env);
15242 gen_store_gpr(t0, rs);
15243 /* Stop translation as we may have switched the execution mode */
15244 ctx->base.is_jmp = DISAS_STOP;
15249 check_cp0_enabled(ctx);
15251 TCGv t0 = tcg_temp_new();
15253 save_cpu_state(ctx, 1);
15254 gen_helper_ei(t0, cpu_env);
15255 gen_store_gpr(t0, rs);
15256 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15257 of translated code to check for pending interrupts. */
15258 gen_save_pc(ctx->base.pc_next + 4);
15259 ctx->base.is_jmp = DISAS_EXIT;
15264 goto pool32axf_invalid;
15271 gen_sync(extract32(ctx->opcode, 16, 5));
15274 generate_exception_end(ctx, EXCP_SYSCALL);
15277 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15278 gen_helper_do_semihosting(cpu_env);
15280 check_insn(ctx, ISA_MIPS32);
15281 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15282 generate_exception_end(ctx, EXCP_RI);
15284 generate_exception_end(ctx, EXCP_DBp);
15289 goto pool32axf_invalid;
15293 switch (minor & 3) {
15295 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15298 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15301 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15304 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15307 goto pool32axf_invalid;
15311 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15314 gen_HILO(ctx, OPC_MFHI, 0, rs);
15317 gen_HILO(ctx, OPC_MFLO, 0, rs);
15320 gen_HILO(ctx, OPC_MTHI, 0, rs);
15323 gen_HILO(ctx, OPC_MTLO, 0, rs);
15326 goto pool32axf_invalid;
15331 MIPS_INVAL("pool32axf");
15332 generate_exception_end(ctx, EXCP_RI);
15337 /* Values for microMIPS fmt field. Variable-width, depending on which
15338 formats the instruction supports. */
15357 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15359 int extension = (ctx->opcode >> 6) & 0x3ff;
15360 uint32_t mips32_op;
15362 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15363 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15364 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15366 switch (extension) {
15367 case FLOAT_1BIT_FMT(CFC1, 0):
15368 mips32_op = OPC_CFC1;
15370 case FLOAT_1BIT_FMT(CTC1, 0):
15371 mips32_op = OPC_CTC1;
15373 case FLOAT_1BIT_FMT(MFC1, 0):
15374 mips32_op = OPC_MFC1;
15376 case FLOAT_1BIT_FMT(MTC1, 0):
15377 mips32_op = OPC_MTC1;
15379 case FLOAT_1BIT_FMT(MFHC1, 0):
15380 mips32_op = OPC_MFHC1;
15382 case FLOAT_1BIT_FMT(MTHC1, 0):
15383 mips32_op = OPC_MTHC1;
15385 gen_cp1(ctx, mips32_op, rt, rs);
15388 /* Reciprocal square root */
15389 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15390 mips32_op = OPC_RSQRT_S;
15392 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15393 mips32_op = OPC_RSQRT_D;
15397 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15398 mips32_op = OPC_SQRT_S;
15400 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15401 mips32_op = OPC_SQRT_D;
15405 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15406 mips32_op = OPC_RECIP_S;
15408 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15409 mips32_op = OPC_RECIP_D;
15413 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15414 mips32_op = OPC_FLOOR_L_S;
15416 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15417 mips32_op = OPC_FLOOR_L_D;
15419 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15420 mips32_op = OPC_FLOOR_W_S;
15422 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15423 mips32_op = OPC_FLOOR_W_D;
15427 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15428 mips32_op = OPC_CEIL_L_S;
15430 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15431 mips32_op = OPC_CEIL_L_D;
15433 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15434 mips32_op = OPC_CEIL_W_S;
15436 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15437 mips32_op = OPC_CEIL_W_D;
15441 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15442 mips32_op = OPC_TRUNC_L_S;
15444 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15445 mips32_op = OPC_TRUNC_L_D;
15447 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15448 mips32_op = OPC_TRUNC_W_S;
15450 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15451 mips32_op = OPC_TRUNC_W_D;
15455 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15456 mips32_op = OPC_ROUND_L_S;
15458 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15459 mips32_op = OPC_ROUND_L_D;
15461 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15462 mips32_op = OPC_ROUND_W_S;
15464 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15465 mips32_op = OPC_ROUND_W_D;
15468 /* Integer to floating-point conversion */
15469 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15470 mips32_op = OPC_CVT_L_S;
15472 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15473 mips32_op = OPC_CVT_L_D;
15475 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15476 mips32_op = OPC_CVT_W_S;
15478 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15479 mips32_op = OPC_CVT_W_D;
15482 /* Paired-foo conversions */
15483 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15484 mips32_op = OPC_CVT_S_PL;
15486 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15487 mips32_op = OPC_CVT_S_PU;
15489 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15490 mips32_op = OPC_CVT_PW_PS;
15492 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15493 mips32_op = OPC_CVT_PS_PW;
15496 /* Floating-point moves */
15497 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15498 mips32_op = OPC_MOV_S;
15500 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15501 mips32_op = OPC_MOV_D;
15503 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15504 mips32_op = OPC_MOV_PS;
15507 /* Absolute value */
15508 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15509 mips32_op = OPC_ABS_S;
15511 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15512 mips32_op = OPC_ABS_D;
15514 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15515 mips32_op = OPC_ABS_PS;
15519 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15520 mips32_op = OPC_NEG_S;
15522 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15523 mips32_op = OPC_NEG_D;
15525 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15526 mips32_op = OPC_NEG_PS;
15529 /* Reciprocal square root step */
15530 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15531 mips32_op = OPC_RSQRT1_S;
15533 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15534 mips32_op = OPC_RSQRT1_D;
15536 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15537 mips32_op = OPC_RSQRT1_PS;
15540 /* Reciprocal step */
15541 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15542 mips32_op = OPC_RECIP1_S;
15544 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15545 mips32_op = OPC_RECIP1_S;
15547 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15548 mips32_op = OPC_RECIP1_PS;
15551 /* Conversions from double */
15552 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15553 mips32_op = OPC_CVT_D_S;
15555 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15556 mips32_op = OPC_CVT_D_W;
15558 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15559 mips32_op = OPC_CVT_D_L;
15562 /* Conversions from single */
15563 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15564 mips32_op = OPC_CVT_S_D;
15566 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15567 mips32_op = OPC_CVT_S_W;
15569 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15570 mips32_op = OPC_CVT_S_L;
15572 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15575 /* Conditional moves on floating-point codes */
15576 case COND_FLOAT_MOV(MOVT, 0):
15577 case COND_FLOAT_MOV(MOVT, 1):
15578 case COND_FLOAT_MOV(MOVT, 2):
15579 case COND_FLOAT_MOV(MOVT, 3):
15580 case COND_FLOAT_MOV(MOVT, 4):
15581 case COND_FLOAT_MOV(MOVT, 5):
15582 case COND_FLOAT_MOV(MOVT, 6):
15583 case COND_FLOAT_MOV(MOVT, 7):
15584 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15585 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15587 case COND_FLOAT_MOV(MOVF, 0):
15588 case COND_FLOAT_MOV(MOVF, 1):
15589 case COND_FLOAT_MOV(MOVF, 2):
15590 case COND_FLOAT_MOV(MOVF, 3):
15591 case COND_FLOAT_MOV(MOVF, 4):
15592 case COND_FLOAT_MOV(MOVF, 5):
15593 case COND_FLOAT_MOV(MOVF, 6):
15594 case COND_FLOAT_MOV(MOVF, 7):
15595 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15596 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15599 MIPS_INVAL("pool32fxf");
15600 generate_exception_end(ctx, EXCP_RI);
15605 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15609 int rt, rs, rd, rr;
15611 uint32_t op, minor, minor2, mips32_op;
15612 uint32_t cond, fmt, cc;
15614 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15615 ctx->opcode = (ctx->opcode << 16) | insn;
15617 rt = (ctx->opcode >> 21) & 0x1f;
15618 rs = (ctx->opcode >> 16) & 0x1f;
15619 rd = (ctx->opcode >> 11) & 0x1f;
15620 rr = (ctx->opcode >> 6) & 0x1f;
15621 imm = (int16_t) ctx->opcode;
15623 op = (ctx->opcode >> 26) & 0x3f;
15626 minor = ctx->opcode & 0x3f;
15629 minor = (ctx->opcode >> 6) & 0xf;
15632 mips32_op = OPC_SLL;
15635 mips32_op = OPC_SRA;
15638 mips32_op = OPC_SRL;
15641 mips32_op = OPC_ROTR;
15643 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15646 check_insn(ctx, ISA_MIPS32R6);
15647 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15650 check_insn(ctx, ISA_MIPS32R6);
15651 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15654 check_insn(ctx, ISA_MIPS32R6);
15655 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15658 goto pool32a_invalid;
15662 minor = (ctx->opcode >> 6) & 0xf;
15666 mips32_op = OPC_ADD;
15669 mips32_op = OPC_ADDU;
15672 mips32_op = OPC_SUB;
15675 mips32_op = OPC_SUBU;
15678 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15679 mips32_op = OPC_MUL;
15681 gen_arith(ctx, mips32_op, rd, rs, rt);
15685 mips32_op = OPC_SLLV;
15688 mips32_op = OPC_SRLV;
15691 mips32_op = OPC_SRAV;
15694 mips32_op = OPC_ROTRV;
15696 gen_shift(ctx, mips32_op, rd, rs, rt);
15698 /* Logical operations */
15700 mips32_op = OPC_AND;
15703 mips32_op = OPC_OR;
15706 mips32_op = OPC_NOR;
15709 mips32_op = OPC_XOR;
15711 gen_logic(ctx, mips32_op, rd, rs, rt);
15713 /* Set less than */
15715 mips32_op = OPC_SLT;
15718 mips32_op = OPC_SLTU;
15720 gen_slt(ctx, mips32_op, rd, rs, rt);
15723 goto pool32a_invalid;
15727 minor = (ctx->opcode >> 6) & 0xf;
15729 /* Conditional moves */
15730 case MOVN: /* MUL */
15731 if (ctx->insn_flags & ISA_MIPS32R6) {
15733 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15736 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15739 case MOVZ: /* MUH */
15740 if (ctx->insn_flags & ISA_MIPS32R6) {
15742 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15745 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15749 check_insn(ctx, ISA_MIPS32R6);
15750 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15753 check_insn(ctx, ISA_MIPS32R6);
15754 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15756 case LWXS: /* DIV */
15757 if (ctx->insn_flags & ISA_MIPS32R6) {
15759 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15762 gen_ldxs(ctx, rs, rt, rd);
15766 check_insn(ctx, ISA_MIPS32R6);
15767 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15770 check_insn(ctx, ISA_MIPS32R6);
15771 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15774 check_insn(ctx, ISA_MIPS32R6);
15775 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15778 goto pool32a_invalid;
15782 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15785 check_insn(ctx, ISA_MIPS32R6);
15786 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15787 extract32(ctx->opcode, 9, 2));
15790 check_insn(ctx, ISA_MIPS32R6);
15791 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15794 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15797 gen_pool32axf(env, ctx, rt, rs);
15800 generate_exception_end(ctx, EXCP_BREAK);
15803 check_insn(ctx, ISA_MIPS32R6);
15804 generate_exception_end(ctx, EXCP_RI);
15808 MIPS_INVAL("pool32a");
15809 generate_exception_end(ctx, EXCP_RI);
15814 minor = (ctx->opcode >> 12) & 0xf;
15817 check_cp0_enabled(ctx);
15818 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15819 gen_cache_operation(ctx, rt, rs, imm);
15824 /* COP2: Not implemented. */
15825 generate_exception_err(ctx, EXCP_CpU, 2);
15827 #ifdef TARGET_MIPS64
15830 check_insn(ctx, ISA_MIPS3);
15831 check_mips_64(ctx);
15836 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15838 #ifdef TARGET_MIPS64
15841 check_insn(ctx, ISA_MIPS3);
15842 check_mips_64(ctx);
15847 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15850 MIPS_INVAL("pool32b");
15851 generate_exception_end(ctx, EXCP_RI);
15856 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15857 minor = ctx->opcode & 0x3f;
15858 check_cp1_enabled(ctx);
15861 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15862 mips32_op = OPC_ALNV_PS;
15865 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15866 mips32_op = OPC_MADD_S;
15869 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15870 mips32_op = OPC_MADD_D;
15873 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15874 mips32_op = OPC_MADD_PS;
15877 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15878 mips32_op = OPC_MSUB_S;
15881 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15882 mips32_op = OPC_MSUB_D;
15885 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15886 mips32_op = OPC_MSUB_PS;
15889 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15890 mips32_op = OPC_NMADD_S;
15893 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15894 mips32_op = OPC_NMADD_D;
15897 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15898 mips32_op = OPC_NMADD_PS;
15901 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15902 mips32_op = OPC_NMSUB_S;
15905 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15906 mips32_op = OPC_NMSUB_D;
15909 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15910 mips32_op = OPC_NMSUB_PS;
15912 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15914 case CABS_COND_FMT:
15915 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15916 cond = (ctx->opcode >> 6) & 0xf;
15917 cc = (ctx->opcode >> 13) & 0x7;
15918 fmt = (ctx->opcode >> 10) & 0x3;
15921 gen_cmpabs_s(ctx, cond, rt, rs, cc);
15924 gen_cmpabs_d(ctx, cond, rt, rs, cc);
15927 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15930 goto pool32f_invalid;
15934 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15935 cond = (ctx->opcode >> 6) & 0xf;
15936 cc = (ctx->opcode >> 13) & 0x7;
15937 fmt = (ctx->opcode >> 10) & 0x3;
15940 gen_cmp_s(ctx, cond, rt, rs, cc);
15943 gen_cmp_d(ctx, cond, rt, rs, cc);
15946 gen_cmp_ps(ctx, cond, rt, rs, cc);
15949 goto pool32f_invalid;
15953 check_insn(ctx, ISA_MIPS32R6);
15954 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15957 check_insn(ctx, ISA_MIPS32R6);
15958 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15961 gen_pool32fxf(ctx, rt, rs);
15965 switch ((ctx->opcode >> 6) & 0x7) {
15967 mips32_op = OPC_PLL_PS;
15970 mips32_op = OPC_PLU_PS;
15973 mips32_op = OPC_PUL_PS;
15976 mips32_op = OPC_PUU_PS;
15979 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15980 mips32_op = OPC_CVT_PS_S;
15982 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15985 goto pool32f_invalid;
15989 check_insn(ctx, ISA_MIPS32R6);
15990 switch ((ctx->opcode >> 9) & 0x3) {
15992 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15995 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15998 goto pool32f_invalid;
16003 switch ((ctx->opcode >> 6) & 0x7) {
16005 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16006 mips32_op = OPC_LWXC1;
16009 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16010 mips32_op = OPC_SWXC1;
16013 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16014 mips32_op = OPC_LDXC1;
16017 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16018 mips32_op = OPC_SDXC1;
16021 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16022 mips32_op = OPC_LUXC1;
16025 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16026 mips32_op = OPC_SUXC1;
16028 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16031 goto pool32f_invalid;
16035 check_insn(ctx, ISA_MIPS32R6);
16036 switch ((ctx->opcode >> 9) & 0x3) {
16038 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16041 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16044 goto pool32f_invalid;
16049 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16050 fmt = (ctx->opcode >> 9) & 0x3;
16051 switch ((ctx->opcode >> 6) & 0x7) {
16055 mips32_op = OPC_RSQRT2_S;
16058 mips32_op = OPC_RSQRT2_D;
16061 mips32_op = OPC_RSQRT2_PS;
16064 goto pool32f_invalid;
16070 mips32_op = OPC_RECIP2_S;
16073 mips32_op = OPC_RECIP2_D;
16076 mips32_op = OPC_RECIP2_PS;
16079 goto pool32f_invalid;
16083 mips32_op = OPC_ADDR_PS;
16086 mips32_op = OPC_MULR_PS;
16088 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16091 goto pool32f_invalid;
16095 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16096 cc = (ctx->opcode >> 13) & 0x7;
16097 fmt = (ctx->opcode >> 9) & 0x3;
16098 switch ((ctx->opcode >> 6) & 0x7) {
16099 case MOVF_FMT: /* RINT_FMT */
16100 if (ctx->insn_flags & ISA_MIPS32R6) {
16104 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16107 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16110 goto pool32f_invalid;
16116 gen_movcf_s(ctx, rs, rt, cc, 0);
16119 gen_movcf_d(ctx, rs, rt, cc, 0);
16123 gen_movcf_ps(ctx, rs, rt, cc, 0);
16126 goto pool32f_invalid;
16130 case MOVT_FMT: /* CLASS_FMT */
16131 if (ctx->insn_flags & ISA_MIPS32R6) {
16135 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16138 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16141 goto pool32f_invalid;
16147 gen_movcf_s(ctx, rs, rt, cc, 1);
16150 gen_movcf_d(ctx, rs, rt, cc, 1);
16154 gen_movcf_ps(ctx, rs, rt, cc, 1);
16157 goto pool32f_invalid;
16162 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16165 goto pool32f_invalid;
16168 #define FINSN_3ARG_SDPS(prfx) \
16169 switch ((ctx->opcode >> 8) & 0x3) { \
16171 mips32_op = OPC_##prfx##_S; \
16174 mips32_op = OPC_##prfx##_D; \
16176 case FMT_SDPS_PS: \
16178 mips32_op = OPC_##prfx##_PS; \
16181 goto pool32f_invalid; \
16184 check_insn(ctx, ISA_MIPS32R6);
16185 switch ((ctx->opcode >> 9) & 0x3) {
16187 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16190 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16193 goto pool32f_invalid;
16197 check_insn(ctx, ISA_MIPS32R6);
16198 switch ((ctx->opcode >> 9) & 0x3) {
16200 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16203 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16206 goto pool32f_invalid;
16210 /* regular FP ops */
16211 switch ((ctx->opcode >> 6) & 0x3) {
16213 FINSN_3ARG_SDPS(ADD);
16216 FINSN_3ARG_SDPS(SUB);
16219 FINSN_3ARG_SDPS(MUL);
16222 fmt = (ctx->opcode >> 8) & 0x3;
16224 mips32_op = OPC_DIV_D;
16225 } else if (fmt == 0) {
16226 mips32_op = OPC_DIV_S;
16228 goto pool32f_invalid;
16232 goto pool32f_invalid;
16237 switch ((ctx->opcode >> 6) & 0x7) {
16238 case MOVN_FMT: /* SELEQZ_FMT */
16239 if (ctx->insn_flags & ISA_MIPS32R6) {
16241 switch ((ctx->opcode >> 9) & 0x3) {
16243 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16246 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16249 goto pool32f_invalid;
16253 FINSN_3ARG_SDPS(MOVN);
16257 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16258 FINSN_3ARG_SDPS(MOVN);
16260 case MOVZ_FMT: /* SELNEZ_FMT */
16261 if (ctx->insn_flags & ISA_MIPS32R6) {
16263 switch ((ctx->opcode >> 9) & 0x3) {
16265 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16268 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16271 goto pool32f_invalid;
16275 FINSN_3ARG_SDPS(MOVZ);
16279 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16280 FINSN_3ARG_SDPS(MOVZ);
16283 check_insn(ctx, ISA_MIPS32R6);
16284 switch ((ctx->opcode >> 9) & 0x3) {
16286 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16289 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16292 goto pool32f_invalid;
16296 check_insn(ctx, ISA_MIPS32R6);
16297 switch ((ctx->opcode >> 9) & 0x3) {
16299 mips32_op = OPC_MADDF_S;
16302 mips32_op = OPC_MADDF_D;
16305 goto pool32f_invalid;
16309 check_insn(ctx, ISA_MIPS32R6);
16310 switch ((ctx->opcode >> 9) & 0x3) {
16312 mips32_op = OPC_MSUBF_S;
16315 mips32_op = OPC_MSUBF_D;
16318 goto pool32f_invalid;
16322 goto pool32f_invalid;
16326 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16330 MIPS_INVAL("pool32f");
16331 generate_exception_end(ctx, EXCP_RI);
16335 generate_exception_err(ctx, EXCP_CpU, 1);
16339 minor = (ctx->opcode >> 21) & 0x1f;
16342 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16343 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16346 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16347 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16348 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16351 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16352 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16353 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16356 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16357 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16360 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16361 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16362 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16365 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16366 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16367 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16370 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16371 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16374 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16375 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16379 case TLTI: /* BC1EQZC */
16380 if (ctx->insn_flags & ISA_MIPS32R6) {
16382 check_cp1_enabled(ctx);
16383 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16386 mips32_op = OPC_TLTI;
16390 case TGEI: /* BC1NEZC */
16391 if (ctx->insn_flags & ISA_MIPS32R6) {
16393 check_cp1_enabled(ctx);
16394 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16397 mips32_op = OPC_TGEI;
16402 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16403 mips32_op = OPC_TLTIU;
16406 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16407 mips32_op = OPC_TGEIU;
16409 case TNEI: /* SYNCI */
16410 if (ctx->insn_flags & ISA_MIPS32R6) {
16412 /* Break the TB to be able to sync copied instructions
16414 ctx->base.is_jmp = DISAS_STOP;
16417 mips32_op = OPC_TNEI;
16422 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16423 mips32_op = OPC_TEQI;
16425 gen_trap(ctx, mips32_op, rs, -1, imm);
16430 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16431 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16432 4, rs, 0, imm << 1, 0);
16433 /* Compact branches don't have a delay slot, so just let
16434 the normal delay slot handling take us to the branch
16438 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16439 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16442 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16443 /* Break the TB to be able to sync copied instructions
16445 ctx->base.is_jmp = DISAS_STOP;
16449 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16450 /* COP2: Not implemented. */
16451 generate_exception_err(ctx, EXCP_CpU, 2);
16454 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16455 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16458 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16459 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16462 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16463 mips32_op = OPC_BC1FANY4;
16466 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16467 mips32_op = OPC_BC1TANY4;
16470 check_insn(ctx, ASE_MIPS3D);
16473 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16474 check_cp1_enabled(ctx);
16475 gen_compute_branch1(ctx, mips32_op,
16476 (ctx->opcode >> 18) & 0x7, imm << 1);
16478 generate_exception_err(ctx, EXCP_CpU, 1);
16483 /* MIPS DSP: not implemented */
16486 MIPS_INVAL("pool32i");
16487 generate_exception_end(ctx, EXCP_RI);
16492 minor = (ctx->opcode >> 12) & 0xf;
16493 offset = sextract32(ctx->opcode, 0,
16494 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16497 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16498 mips32_op = OPC_LWL;
16501 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16502 mips32_op = OPC_SWL;
16505 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16506 mips32_op = OPC_LWR;
16509 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16510 mips32_op = OPC_SWR;
16512 #if defined(TARGET_MIPS64)
16514 check_insn(ctx, ISA_MIPS3);
16515 check_mips_64(ctx);
16516 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16517 mips32_op = OPC_LDL;
16520 check_insn(ctx, ISA_MIPS3);
16521 check_mips_64(ctx);
16522 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16523 mips32_op = OPC_SDL;
16526 check_insn(ctx, ISA_MIPS3);
16527 check_mips_64(ctx);
16528 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16529 mips32_op = OPC_LDR;
16532 check_insn(ctx, ISA_MIPS3);
16533 check_mips_64(ctx);
16534 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16535 mips32_op = OPC_SDR;
16538 check_insn(ctx, ISA_MIPS3);
16539 check_mips_64(ctx);
16540 mips32_op = OPC_LWU;
16543 check_insn(ctx, ISA_MIPS3);
16544 check_mips_64(ctx);
16545 mips32_op = OPC_LLD;
16549 mips32_op = OPC_LL;
16552 gen_ld(ctx, mips32_op, rt, rs, offset);
16555 gen_st(ctx, mips32_op, rt, rs, offset);
16558 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
16560 #if defined(TARGET_MIPS64)
16562 check_insn(ctx, ISA_MIPS3);
16563 check_mips_64(ctx);
16564 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
16569 MIPS_INVAL("pool32c ld-eva");
16570 generate_exception_end(ctx, EXCP_RI);
16573 check_cp0_enabled(ctx);
16575 minor2 = (ctx->opcode >> 9) & 0x7;
16576 offset = sextract32(ctx->opcode, 0, 9);
16579 mips32_op = OPC_LBUE;
16582 mips32_op = OPC_LHUE;
16585 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16586 mips32_op = OPC_LWLE;
16589 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16590 mips32_op = OPC_LWRE;
16593 mips32_op = OPC_LBE;
16596 mips32_op = OPC_LHE;
16599 mips32_op = OPC_LLE;
16602 mips32_op = OPC_LWE;
16608 MIPS_INVAL("pool32c st-eva");
16609 generate_exception_end(ctx, EXCP_RI);
16612 check_cp0_enabled(ctx);
16614 minor2 = (ctx->opcode >> 9) & 0x7;
16615 offset = sextract32(ctx->opcode, 0, 9);
16618 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16619 mips32_op = OPC_SWLE;
16622 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16623 mips32_op = OPC_SWRE;
16626 /* Treat as no-op */
16627 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16628 /* hint codes 24-31 are reserved and signal RI */
16629 generate_exception(ctx, EXCP_RI);
16633 /* Treat as no-op */
16634 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16635 gen_cache_operation(ctx, rt, rs, offset);
16639 mips32_op = OPC_SBE;
16642 mips32_op = OPC_SHE;
16645 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16648 mips32_op = OPC_SWE;
16653 /* Treat as no-op */
16654 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16655 /* hint codes 24-31 are reserved and signal RI */
16656 generate_exception(ctx, EXCP_RI);
16660 MIPS_INVAL("pool32c");
16661 generate_exception_end(ctx, EXCP_RI);
16665 case ADDI32: /* AUI, LUI */
16666 if (ctx->insn_flags & ISA_MIPS32R6) {
16668 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16671 mips32_op = OPC_ADDI;
16676 mips32_op = OPC_ADDIU;
16678 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16681 /* Logical operations */
16683 mips32_op = OPC_ORI;
16686 mips32_op = OPC_XORI;
16689 mips32_op = OPC_ANDI;
16691 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16694 /* Set less than immediate */
16696 mips32_op = OPC_SLTI;
16699 mips32_op = OPC_SLTIU;
16701 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16704 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16705 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16706 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16707 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16709 case JALS32: /* BOVC, BEQC, BEQZALC */
16710 if (ctx->insn_flags & ISA_MIPS32R6) {
16713 mips32_op = OPC_BOVC;
16714 } else if (rs < rt && rs == 0) {
16716 mips32_op = OPC_BEQZALC;
16719 mips32_op = OPC_BEQC;
16721 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16724 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16725 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16726 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16729 case BEQ32: /* BC */
16730 if (ctx->insn_flags & ISA_MIPS32R6) {
16732 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16733 sextract32(ctx->opcode << 1, 0, 27));
16736 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16739 case BNE32: /* BALC */
16740 if (ctx->insn_flags & ISA_MIPS32R6) {
16742 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16743 sextract32(ctx->opcode << 1, 0, 27));
16746 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16749 case J32: /* BGTZC, BLTZC, BLTC */
16750 if (ctx->insn_flags & ISA_MIPS32R6) {
16751 if (rs == 0 && rt != 0) {
16753 mips32_op = OPC_BGTZC;
16754 } else if (rs != 0 && rt != 0 && rs == rt) {
16756 mips32_op = OPC_BLTZC;
16759 mips32_op = OPC_BLTC;
16761 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16764 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16765 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16768 case JAL32: /* BLEZC, BGEZC, BGEC */
16769 if (ctx->insn_flags & ISA_MIPS32R6) {
16770 if (rs == 0 && rt != 0) {
16772 mips32_op = OPC_BLEZC;
16773 } else if (rs != 0 && rt != 0 && rs == rt) {
16775 mips32_op = OPC_BGEZC;
16778 mips32_op = OPC_BGEC;
16780 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16783 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16784 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16785 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16788 /* Floating point (COP1) */
16790 mips32_op = OPC_LWC1;
16793 mips32_op = OPC_LDC1;
16796 mips32_op = OPC_SWC1;
16799 mips32_op = OPC_SDC1;
16801 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16803 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16804 if (ctx->insn_flags & ISA_MIPS32R6) {
16805 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16806 switch ((ctx->opcode >> 16) & 0x1f) {
16815 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16818 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16821 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16831 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16834 generate_exception(ctx, EXCP_RI);
16839 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16840 offset = SIMM(ctx->opcode, 0, 23) << 2;
16842 gen_addiupc(ctx, reg, offset, 0, 0);
16845 case BNVC: /* BNEC, BNEZALC */
16846 check_insn(ctx, ISA_MIPS32R6);
16849 mips32_op = OPC_BNVC;
16850 } else if (rs < rt && rs == 0) {
16852 mips32_op = OPC_BNEZALC;
16855 mips32_op = OPC_BNEC;
16857 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16859 case R6_BNEZC: /* JIALC */
16860 check_insn(ctx, ISA_MIPS32R6);
16863 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16864 sextract32(ctx->opcode << 1, 0, 22));
16867 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16870 case R6_BEQZC: /* JIC */
16871 check_insn(ctx, ISA_MIPS32R6);
16874 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16875 sextract32(ctx->opcode << 1, 0, 22));
16878 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16881 case BLEZALC: /* BGEZALC, BGEUC */
16882 check_insn(ctx, ISA_MIPS32R6);
16883 if (rs == 0 && rt != 0) {
16885 mips32_op = OPC_BLEZALC;
16886 } else if (rs != 0 && rt != 0 && rs == rt) {
16888 mips32_op = OPC_BGEZALC;
16891 mips32_op = OPC_BGEUC;
16893 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16895 case BGTZALC: /* BLTZALC, BLTUC */
16896 check_insn(ctx, ISA_MIPS32R6);
16897 if (rs == 0 && rt != 0) {
16899 mips32_op = OPC_BGTZALC;
16900 } else if (rs != 0 && rt != 0 && rs == rt) {
16902 mips32_op = OPC_BLTZALC;
16905 mips32_op = OPC_BLTUC;
16907 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16909 /* Loads and stores */
16911 mips32_op = OPC_LB;
16914 mips32_op = OPC_LBU;
16917 mips32_op = OPC_LH;
16920 mips32_op = OPC_LHU;
16923 mips32_op = OPC_LW;
16925 #ifdef TARGET_MIPS64
16927 check_insn(ctx, ISA_MIPS3);
16928 check_mips_64(ctx);
16929 mips32_op = OPC_LD;
16932 check_insn(ctx, ISA_MIPS3);
16933 check_mips_64(ctx);
16934 mips32_op = OPC_SD;
16938 mips32_op = OPC_SB;
16941 mips32_op = OPC_SH;
16944 mips32_op = OPC_SW;
16947 gen_ld(ctx, mips32_op, rt, rs, imm);
16950 gen_st(ctx, mips32_op, rt, rs, imm);
16953 generate_exception_end(ctx, EXCP_RI);
16958 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
16962 /* make sure instructions are on a halfword boundary */
16963 if (ctx->base.pc_next & 0x1) {
16964 env->CP0_BadVAddr = ctx->base.pc_next;
16965 generate_exception_end(ctx, EXCP_AdEL);
16969 op = (ctx->opcode >> 10) & 0x3f;
16970 /* Enforce properly-sized instructions in a delay slot */
16971 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16972 switch (op & 0x7) { /* MSB-3..MSB-5 */
16974 /* POOL32A, POOL32B, POOL32I, POOL32C */
16976 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16978 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16980 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16982 /* LB32, LH32, LWC132, LDC132, LW32 */
16983 if (ctx->hflags & MIPS_HFLAG_BDS16) {
16984 generate_exception_end(ctx, EXCP_RI);
16989 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16991 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16993 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16994 if (ctx->hflags & MIPS_HFLAG_BDS32) {
16995 generate_exception_end(ctx, EXCP_RI);
17005 int rd = mmreg(uMIPS_RD(ctx->opcode));
17006 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17007 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17010 switch (ctx->opcode & 0x1) {
17018 if (ctx->insn_flags & ISA_MIPS32R6) {
17019 /* In the Release 6 the register number location in
17020 * the instruction encoding has changed.
17022 gen_arith(ctx, opc, rs1, rd, rs2);
17024 gen_arith(ctx, opc, rd, rs1, rs2);
17030 int rd = mmreg(uMIPS_RD(ctx->opcode));
17031 int rs = mmreg(uMIPS_RS(ctx->opcode));
17032 int amount = (ctx->opcode >> 1) & 0x7;
17034 amount = amount == 0 ? 8 : amount;
17036 switch (ctx->opcode & 0x1) {
17045 gen_shift_imm(ctx, opc, rd, rs, amount);
17049 if (ctx->insn_flags & ISA_MIPS32R6) {
17050 gen_pool16c_r6_insn(ctx);
17052 gen_pool16c_insn(ctx);
17057 int rd = mmreg(uMIPS_RD(ctx->opcode));
17058 int rb = 28; /* GP */
17059 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17061 gen_ld(ctx, OPC_LW, rd, rb, offset);
17065 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17066 if (ctx->opcode & 1) {
17067 generate_exception_end(ctx, EXCP_RI);
17070 int enc_dest = uMIPS_RD(ctx->opcode);
17071 int enc_rt = uMIPS_RS2(ctx->opcode);
17072 int enc_rs = uMIPS_RS1(ctx->opcode);
17073 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17078 int rd = mmreg(uMIPS_RD(ctx->opcode));
17079 int rb = mmreg(uMIPS_RS(ctx->opcode));
17080 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17081 offset = (offset == 0xf ? -1 : offset);
17083 gen_ld(ctx, OPC_LBU, rd, rb, offset);
17088 int rd = mmreg(uMIPS_RD(ctx->opcode));
17089 int rb = mmreg(uMIPS_RS(ctx->opcode));
17090 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17092 gen_ld(ctx, OPC_LHU, rd, rb, offset);
17097 int rd = (ctx->opcode >> 5) & 0x1f;
17098 int rb = 29; /* SP */
17099 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17101 gen_ld(ctx, OPC_LW, rd, rb, offset);
17106 int rd = mmreg(uMIPS_RD(ctx->opcode));
17107 int rb = mmreg(uMIPS_RS(ctx->opcode));
17108 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17110 gen_ld(ctx, OPC_LW, rd, rb, offset);
17115 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17116 int rb = mmreg(uMIPS_RS(ctx->opcode));
17117 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17119 gen_st(ctx, OPC_SB, rd, rb, offset);
17124 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17125 int rb = mmreg(uMIPS_RS(ctx->opcode));
17126 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17128 gen_st(ctx, OPC_SH, rd, rb, offset);
17133 int rd = (ctx->opcode >> 5) & 0x1f;
17134 int rb = 29; /* SP */
17135 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17137 gen_st(ctx, OPC_SW, rd, rb, offset);
17142 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17143 int rb = mmreg(uMIPS_RS(ctx->opcode));
17144 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17146 gen_st(ctx, OPC_SW, rd, rb, offset);
17151 int rd = uMIPS_RD5(ctx->opcode);
17152 int rs = uMIPS_RS5(ctx->opcode);
17154 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17161 switch (ctx->opcode & 0x1) {
17171 switch (ctx->opcode & 0x1) {
17176 gen_addiur1sp(ctx);
17180 case B16: /* BC16 */
17181 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17182 sextract32(ctx->opcode, 0, 10) << 1,
17183 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17185 case BNEZ16: /* BNEZC16 */
17186 case BEQZ16: /* BEQZC16 */
17187 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17188 mmreg(uMIPS_RD(ctx->opcode)),
17189 0, sextract32(ctx->opcode, 0, 7) << 1,
17190 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17195 int reg = mmreg(uMIPS_RD(ctx->opcode));
17196 int imm = ZIMM(ctx->opcode, 0, 7);
17198 imm = (imm == 0x7f ? -1 : imm);
17199 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17205 generate_exception_end(ctx, EXCP_RI);
17208 decode_micromips32_opc(env, ctx);
17221 /* MAJOR, P16, and P32 pools opcodes */
17225 NM_MOVE_BALC = 0x02,
17233 NM_P16_SHIFT = 0x0c,
17251 NM_P_LS_U12 = 0x21,
17261 NM_P16_ADDU = 0x2c,
17275 NM_MOVEPREV = 0x3f,
17278 /* POOL32A instruction pool */
17280 NM_POOL32A0 = 0x00,
17281 NM_SPECIAL2 = 0x01,
17284 NM_POOL32A5 = 0x05,
17285 NM_POOL32A7 = 0x07,
17288 /* P.GP.W instruction pool */
17290 NM_ADDIUGP_W = 0x00,
17295 /* P48I instruction pool */
17299 NM_ADDIUGP48 = 0x02,
17300 NM_ADDIUPC48 = 0x03,
17305 /* P.U12 instruction pool */
17314 NM_ADDIUNEG = 0x08,
17321 /* POOL32F instruction pool */
17323 NM_POOL32F_0 = 0x00,
17324 NM_POOL32F_3 = 0x03,
17325 NM_POOL32F_5 = 0x05,
17328 /* POOL32S instruction pool */
17330 NM_POOL32S_0 = 0x00,
17331 NM_POOL32S_4 = 0x04,
17334 /* P.LUI instruction pool */
17340 /* P.GP.BH instruction pool */
17345 NM_ADDIUGP_B = 0x03,
17348 NM_P_GP_CP1 = 0x06,
17351 /* P.LS.U12 instruction pool */
17356 NM_P_PREFU12 = 0x03,
17369 /* P.LS.S9 instruction pool */
17375 NM_P_LS_UAWM = 0x05,
17378 /* P.BAL instruction pool */
17384 /* P.J instruction pool */
17387 NM_JALRC_HB = 0x01,
17388 NM_P_BALRSC = 0x08,
17391 /* P.BR1 instruction pool */
17399 /* P.BR2 instruction pool */
17406 /* P.BRI instruction pool */
17418 /* P16.SHIFT instruction pool */
17424 /* POOL16C instruction pool */
17426 NM_POOL16C_0 = 0x00,
17430 /* P16.A1 instruction pool */
17432 NM_ADDIUR1SP = 0x01,
17435 /* P16.A2 instruction pool */
17438 NM_P_ADDIURS5 = 0x01,
17441 /* P16.ADDU instruction pool */
17447 /* P16.SR instruction pool */
17450 NM_RESTORE_JRC16 = 0x01,
17453 /* P16.4X4 instruction pool */
17459 /* P16.LB instruction pool */
17466 /* P16.LH instruction pool */
17473 /* P.RI instruction pool */
17476 NM_P_SYSCALL = 0x01,
17481 /* POOL32A0 instruction pool */
17516 NM_D_E_MT_VPE = 0x56,
17524 /* CRC32 instruction pool */
17534 /* POOL32A5 instruction pool */
17536 NM_CMP_EQ_PH = 0x00,
17537 NM_CMP_LT_PH = 0x08,
17538 NM_CMP_LE_PH = 0x10,
17539 NM_CMPGU_EQ_QB = 0x18,
17540 NM_CMPGU_LT_QB = 0x20,
17541 NM_CMPGU_LE_QB = 0x28,
17542 NM_CMPGDU_EQ_QB = 0x30,
17543 NM_CMPGDU_LT_QB = 0x38,
17544 NM_CMPGDU_LE_QB = 0x40,
17545 NM_CMPU_EQ_QB = 0x48,
17546 NM_CMPU_LT_QB = 0x50,
17547 NM_CMPU_LE_QB = 0x58,
17548 NM_ADDQ_S_W = 0x60,
17549 NM_SUBQ_S_W = 0x68,
17553 NM_ADDQ_S_PH = 0x01,
17554 NM_ADDQH_R_PH = 0x09,
17555 NM_ADDQH_R_W = 0x11,
17556 NM_ADDU_S_QB = 0x19,
17557 NM_ADDU_S_PH = 0x21,
17558 NM_ADDUH_R_QB = 0x29,
17559 NM_SHRAV_R_PH = 0x31,
17560 NM_SHRAV_R_QB = 0x39,
17561 NM_SUBQ_S_PH = 0x41,
17562 NM_SUBQH_R_PH = 0x49,
17563 NM_SUBQH_R_W = 0x51,
17564 NM_SUBU_S_QB = 0x59,
17565 NM_SUBU_S_PH = 0x61,
17566 NM_SUBUH_R_QB = 0x69,
17567 NM_SHLLV_S_PH = 0x71,
17568 NM_PRECR_SRA_R_PH_W = 0x79,
17570 NM_MULEU_S_PH_QBL = 0x12,
17571 NM_MULEU_S_PH_QBR = 0x1a,
17572 NM_MULQ_RS_PH = 0x22,
17573 NM_MULQ_S_PH = 0x2a,
17574 NM_MULQ_RS_W = 0x32,
17575 NM_MULQ_S_W = 0x3a,
17578 NM_SHRAV_R_W = 0x5a,
17579 NM_SHRLV_PH = 0x62,
17580 NM_SHRLV_QB = 0x6a,
17581 NM_SHLLV_QB = 0x72,
17582 NM_SHLLV_S_W = 0x7a,
17586 NM_MULEQ_S_W_PHL = 0x04,
17587 NM_MULEQ_S_W_PHR = 0x0c,
17589 NM_MUL_S_PH = 0x05,
17590 NM_PRECR_QB_PH = 0x0d,
17591 NM_PRECRQ_QB_PH = 0x15,
17592 NM_PRECRQ_PH_W = 0x1d,
17593 NM_PRECRQ_RS_PH_W = 0x25,
17594 NM_PRECRQU_S_QB_PH = 0x2d,
17595 NM_PACKRL_PH = 0x35,
17599 NM_SHRA_R_W = 0x5e,
17600 NM_SHRA_R_PH = 0x66,
17601 NM_SHLL_S_PH = 0x76,
17602 NM_SHLL_S_W = 0x7e,
17607 /* POOL32A7 instruction pool */
17612 NM_POOL32AXF = 0x07,
17615 /* P.SR instruction pool */
17621 /* P.SHIFT instruction pool */
17629 /* P.ROTX instruction pool */
17634 /* P.INS instruction pool */
17639 /* P.EXT instruction pool */
17644 /* POOL32F_0 (fmt) instruction pool */
17649 NM_SELEQZ_S = 0x07,
17650 NM_SELEQZ_D = 0x47,
17654 NM_SELNEZ_S = 0x0f,
17655 NM_SELNEZ_D = 0x4f,
17670 /* POOL32F_3 instruction pool */
17674 NM_MINA_FMT = 0x04,
17675 NM_MAXA_FMT = 0x05,
17676 NM_POOL32FXF = 0x07,
17679 /* POOL32F_5 instruction pool */
17681 NM_CMP_CONDN_S = 0x00,
17682 NM_CMP_CONDN_D = 0x02,
17685 /* P.GP.LH instruction pool */
17691 /* P.GP.SH instruction pool */
17696 /* P.GP.CP1 instruction pool */
17704 /* P.LS.S0 instruction pool */
17721 NM_P_PREFS9 = 0x03,
17727 /* P.LS.S1 instruction pool */
17729 NM_ASET_ACLR = 0x02,
17737 /* P.LS.E0 instruction pool */
17753 /* P.PREFE instruction pool */
17759 /* P.LLE instruction pool */
17765 /* P.SCE instruction pool */
17771 /* P.LS.WM instruction pool */
17777 /* P.LS.UAWM instruction pool */
17783 /* P.BR3A instruction pool */
17789 NM_BPOSGE32C = 0x04,
17792 /* P16.RI instruction pool */
17794 NM_P16_SYSCALL = 0x01,
17799 /* POOL16C_0 instruction pool */
17801 NM_POOL16C_00 = 0x00,
17804 /* P16.JRC instruction pool */
17810 /* P.SYSCALL instruction pool */
17816 /* P.TRAP instruction pool */
17822 /* P.CMOVE instruction pool */
17828 /* POOL32Axf instruction pool */
17830 NM_POOL32AXF_1 = 0x01,
17831 NM_POOL32AXF_2 = 0x02,
17832 NM_POOL32AXF_4 = 0x04,
17833 NM_POOL32AXF_5 = 0x05,
17834 NM_POOL32AXF_7 = 0x07,
17837 /* POOL32Axf_1 instruction pool */
17839 NM_POOL32AXF_1_0 = 0x00,
17840 NM_POOL32AXF_1_1 = 0x01,
17841 NM_POOL32AXF_1_3 = 0x03,
17842 NM_POOL32AXF_1_4 = 0x04,
17843 NM_POOL32AXF_1_5 = 0x05,
17844 NM_POOL32AXF_1_7 = 0x07,
17847 /* POOL32Axf_2 instruction pool */
17849 NM_POOL32AXF_2_0_7 = 0x00,
17850 NM_POOL32AXF_2_8_15 = 0x01,
17851 NM_POOL32AXF_2_16_23 = 0x02,
17852 NM_POOL32AXF_2_24_31 = 0x03,
17855 /* POOL32Axf_7 instruction pool */
17857 NM_SHRA_R_QB = 0x0,
17862 /* POOL32Axf_1_0 instruction pool */
17870 /* POOL32Axf_1_1 instruction pool */
17876 /* POOL32Axf_1_3 instruction pool */
17884 /* POOL32Axf_1_4 instruction pool */
17890 /* POOL32Axf_1_5 instruction pool */
17892 NM_MAQ_S_W_PHR = 0x0,
17893 NM_MAQ_S_W_PHL = 0x1,
17894 NM_MAQ_SA_W_PHR = 0x2,
17895 NM_MAQ_SA_W_PHL = 0x3,
17898 /* POOL32Axf_1_7 instruction pool */
17902 NM_EXTR_RS_W = 0x2,
17906 /* POOL32Axf_2_0_7 instruction pool */
17909 NM_DPAQ_S_W_PH = 0x1,
17911 NM_DPSQ_S_W_PH = 0x3,
17918 /* POOL32Axf_2_8_15 instruction pool */
17920 NM_DPAX_W_PH = 0x0,
17921 NM_DPAQ_SA_L_W = 0x1,
17922 NM_DPSX_W_PH = 0x2,
17923 NM_DPSQ_SA_L_W = 0x3,
17926 NM_EXTRV_R_W = 0x7,
17929 /* POOL32Axf_2_16_23 instruction pool */
17931 NM_DPAU_H_QBL = 0x0,
17932 NM_DPAQX_S_W_PH = 0x1,
17933 NM_DPSU_H_QBL = 0x2,
17934 NM_DPSQX_S_W_PH = 0x3,
17937 NM_MULSA_W_PH = 0x6,
17938 NM_EXTRV_RS_W = 0x7,
17941 /* POOL32Axf_2_24_31 instruction pool */
17943 NM_DPAU_H_QBR = 0x0,
17944 NM_DPAQX_SA_W_PH = 0x1,
17945 NM_DPSU_H_QBR = 0x2,
17946 NM_DPSQX_SA_W_PH = 0x3,
17949 NM_MULSAQ_S_W_PH = 0x6,
17950 NM_EXTRV_S_H = 0x7,
17953 /* POOL32Axf_{4, 5} instruction pool */
17972 /* nanoMIPS DSP instructions */
17973 NM_ABSQ_S_QB = 0x00,
17974 NM_ABSQ_S_PH = 0x08,
17975 NM_ABSQ_S_W = 0x10,
17976 NM_PRECEQ_W_PHL = 0x28,
17977 NM_PRECEQ_W_PHR = 0x30,
17978 NM_PRECEQU_PH_QBL = 0x38,
17979 NM_PRECEQU_PH_QBR = 0x48,
17980 NM_PRECEU_PH_QBL = 0x58,
17981 NM_PRECEU_PH_QBR = 0x68,
17982 NM_PRECEQU_PH_QBLA = 0x39,
17983 NM_PRECEQU_PH_QBRA = 0x49,
17984 NM_PRECEU_PH_QBLA = 0x59,
17985 NM_PRECEU_PH_QBRA = 0x69,
17986 NM_REPLV_PH = 0x01,
17987 NM_REPLV_QB = 0x09,
17990 NM_RADDU_W_QB = 0x78,
17996 /* PP.SR instruction pool */
18000 NM_RESTORE_JRC = 0x03,
18003 /* P.SR.F instruction pool */
18006 NM_RESTOREF = 0x01,
18009 /* P16.SYSCALL instruction pool */
18011 NM_SYSCALL16 = 0x00,
18012 NM_HYPCALL16 = 0x01,
18015 /* POOL16C_00 instruction pool */
18023 /* PP.LSX and PP.LSXS instruction pool */
18061 /* ERETx instruction pool */
18067 /* POOL32FxF_{0, 1} insturction pool */
18076 NM_CVT_S_PL = 0x84,
18077 NM_CVT_S_PU = 0xa4,
18079 NM_CVT_L_S = 0x004,
18080 NM_CVT_L_D = 0x104,
18081 NM_CVT_W_S = 0x024,
18082 NM_CVT_W_D = 0x124,
18084 NM_RSQRT_S = 0x008,
18085 NM_RSQRT_D = 0x108,
18090 NM_RECIP_S = 0x048,
18091 NM_RECIP_D = 0x148,
18093 NM_FLOOR_L_S = 0x00c,
18094 NM_FLOOR_L_D = 0x10c,
18096 NM_FLOOR_W_S = 0x02c,
18097 NM_FLOOR_W_D = 0x12c,
18099 NM_CEIL_L_S = 0x04c,
18100 NM_CEIL_L_D = 0x14c,
18101 NM_CEIL_W_S = 0x06c,
18102 NM_CEIL_W_D = 0x16c,
18103 NM_TRUNC_L_S = 0x08c,
18104 NM_TRUNC_L_D = 0x18c,
18105 NM_TRUNC_W_S = 0x0ac,
18106 NM_TRUNC_W_D = 0x1ac,
18107 NM_ROUND_L_S = 0x0cc,
18108 NM_ROUND_L_D = 0x1cc,
18109 NM_ROUND_W_S = 0x0ec,
18110 NM_ROUND_W_D = 0x1ec,
18118 NM_CVT_D_S = 0x04d,
18119 NM_CVT_D_W = 0x0cd,
18120 NM_CVT_D_L = 0x14d,
18121 NM_CVT_S_D = 0x06d,
18122 NM_CVT_S_W = 0x0ed,
18123 NM_CVT_S_L = 0x16d,
18126 /* P.LL instruction pool */
18132 /* P.SC instruction pool */
18138 /* P.DVP instruction pool */
18147 * nanoMIPS decoding engine
18152 /* extraction utilities */
18154 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18155 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18156 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18157 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18158 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18159 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18161 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18162 static inline int decode_gpr_gpr3(int r)
18164 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18166 return map[r & 0x7];
18169 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18170 static inline int decode_gpr_gpr3_src_store(int r)
18172 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18174 return map[r & 0x7];
18177 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18178 static inline int decode_gpr_gpr4(int r)
18180 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18181 16, 17, 18, 19, 20, 21, 22, 23 };
18183 return map[r & 0xf];
18186 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18187 static inline int decode_gpr_gpr4_zero(int r)
18189 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18190 16, 17, 18, 19, 20, 21, 22, 23 };
18192 return map[r & 0xf];
18196 /* extraction utilities */
18198 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18199 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18200 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18201 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18202 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18203 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18206 static void gen_adjust_sp(DisasContext *ctx, int u)
18208 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18211 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18212 uint8_t gp, uint16_t u)
18215 TCGv va = tcg_temp_new();
18216 TCGv t0 = tcg_temp_new();
18218 while (counter != count) {
18219 bool use_gp = gp && (counter == count - 1);
18220 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18221 int this_offset = -((counter + 1) << 2);
18222 gen_base_offset_addr(ctx, va, 29, this_offset);
18223 gen_load_gpr(t0, this_rt);
18224 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18225 (MO_TEUL | ctx->default_tcg_memop_mask));
18229 /* adjust stack pointer */
18230 gen_adjust_sp(ctx, -u);
18236 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18237 uint8_t gp, uint16_t u)
18240 TCGv va = tcg_temp_new();
18241 TCGv t0 = tcg_temp_new();
18243 while (counter != count) {
18244 bool use_gp = gp && (counter == count - 1);
18245 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18246 int this_offset = u - ((counter + 1) << 2);
18247 gen_base_offset_addr(ctx, va, 29, this_offset);
18248 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18249 ctx->default_tcg_memop_mask);
18250 tcg_gen_ext32s_tl(t0, t0);
18251 gen_store_gpr(t0, this_rt);
18255 /* adjust stack pointer */
18256 gen_adjust_sp(ctx, u);
18262 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18264 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18265 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18267 switch (extract32(ctx->opcode, 2, 2)) {
18269 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18272 gen_logic(ctx, OPC_AND, rt, rt, rs);
18275 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18278 gen_logic(ctx, OPC_OR, rt, rt, rs);
18283 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18285 int rt = extract32(ctx->opcode, 21, 5);
18286 int rs = extract32(ctx->opcode, 16, 5);
18287 int rd = extract32(ctx->opcode, 11, 5);
18289 switch (extract32(ctx->opcode, 3, 7)) {
18291 switch (extract32(ctx->opcode, 10, 1)) {
18294 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18298 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18304 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18308 gen_bshfl(ctx, OPC_SEB, rs, rt);
18311 gen_bshfl(ctx, OPC_SEH, rs, rt);
18314 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18317 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18320 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18323 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18326 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18329 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18333 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18336 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18339 switch (extract32(ctx->opcode, 10, 1)) {
18341 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18344 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18349 gen_logic(ctx, OPC_AND, rd, rs, rt);
18352 gen_logic(ctx, OPC_OR, rd, rs, rt);
18355 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18358 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18361 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18366 #ifndef CONFIG_USER_ONLY
18367 TCGv t0 = tcg_temp_new();
18368 switch (extract32(ctx->opcode, 10, 1)) {
18371 check_cp0_enabled(ctx);
18372 gen_helper_dvp(t0, cpu_env);
18373 gen_store_gpr(t0, rt);
18378 check_cp0_enabled(ctx);
18379 gen_helper_evp(t0, cpu_env);
18380 gen_store_gpr(t0, rt);
18387 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18392 TCGv t0 = tcg_temp_new();
18393 TCGv t1 = tcg_temp_new();
18394 TCGv t2 = tcg_temp_new();
18396 gen_load_gpr(t1, rs);
18397 gen_load_gpr(t2, rt);
18398 tcg_gen_add_tl(t0, t1, t2);
18399 tcg_gen_ext32s_tl(t0, t0);
18400 tcg_gen_xor_tl(t1, t1, t2);
18401 tcg_gen_xor_tl(t2, t0, t2);
18402 tcg_gen_andc_tl(t1, t2, t1);
18404 /* operands of same sign, result different sign */
18405 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18406 gen_store_gpr(t0, rd);
18414 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18417 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18420 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18423 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18426 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18429 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18432 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18435 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18437 #ifndef CONFIG_USER_ONLY
18439 check_cp0_enabled(ctx);
18441 /* Treat as NOP. */
18444 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18447 check_cp0_enabled(ctx);
18449 TCGv t0 = tcg_temp_new();
18451 gen_load_gpr(t0, rt);
18452 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18456 case NM_D_E_MT_VPE:
18458 uint8_t sc = extract32(ctx->opcode, 10, 1);
18459 TCGv t0 = tcg_temp_new();
18466 gen_helper_dmt(t0);
18467 gen_store_gpr(t0, rt);
18468 } else if (rs == 0) {
18471 gen_helper_dvpe(t0, cpu_env);
18472 gen_store_gpr(t0, rt);
18474 generate_exception_end(ctx, EXCP_RI);
18481 gen_helper_emt(t0);
18482 gen_store_gpr(t0, rt);
18483 } else if (rs == 0) {
18486 gen_helper_evpe(t0, cpu_env);
18487 gen_store_gpr(t0, rt);
18489 generate_exception_end(ctx, EXCP_RI);
18500 TCGv t0 = tcg_temp_new();
18501 TCGv t1 = tcg_temp_new();
18503 gen_load_gpr(t0, rt);
18504 gen_load_gpr(t1, rs);
18505 gen_helper_fork(t0, t1);
18512 check_cp0_enabled(ctx);
18514 /* Treat as NOP. */
18517 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18518 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18522 check_cp0_enabled(ctx);
18523 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18524 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18529 TCGv t0 = tcg_temp_new();
18531 gen_load_gpr(t0, rs);
18532 gen_helper_yield(t0, cpu_env, t0);
18533 gen_store_gpr(t0, rt);
18539 generate_exception_end(ctx, EXCP_RI);
18545 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18546 int ret, int v1, int v2)
18552 t0 = tcg_temp_new_i32();
18554 v0_t = tcg_temp_new();
18555 v1_t = tcg_temp_new();
18557 tcg_gen_movi_i32(t0, v2 >> 3);
18559 gen_load_gpr(v0_t, ret);
18560 gen_load_gpr(v1_t, v1);
18563 case NM_MAQ_S_W_PHR:
18565 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18567 case NM_MAQ_S_W_PHL:
18569 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18571 case NM_MAQ_SA_W_PHR:
18573 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18575 case NM_MAQ_SA_W_PHL:
18577 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18580 generate_exception_end(ctx, EXCP_RI);
18584 tcg_temp_free_i32(t0);
18586 tcg_temp_free(v0_t);
18587 tcg_temp_free(v1_t);
18591 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18592 int ret, int v1, int v2)
18595 TCGv t0 = tcg_temp_new();
18596 TCGv t1 = tcg_temp_new();
18597 TCGv v0_t = tcg_temp_new();
18599 gen_load_gpr(v0_t, v1);
18602 case NM_POOL32AXF_1_0:
18604 switch (extract32(ctx->opcode, 12, 2)) {
18606 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18609 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18612 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18615 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18619 case NM_POOL32AXF_1_1:
18621 switch (extract32(ctx->opcode, 12, 2)) {
18623 tcg_gen_movi_tl(t0, v2);
18624 gen_helper_mthlip(t0, v0_t, cpu_env);
18627 tcg_gen_movi_tl(t0, v2 >> 3);
18628 gen_helper_shilo(t0, v0_t, cpu_env);
18631 generate_exception_end(ctx, EXCP_RI);
18635 case NM_POOL32AXF_1_3:
18637 imm = extract32(ctx->opcode, 14, 7);
18638 switch (extract32(ctx->opcode, 12, 2)) {
18640 tcg_gen_movi_tl(t0, imm);
18641 gen_helper_rddsp(t0, t0, cpu_env);
18642 gen_store_gpr(t0, ret);
18645 gen_load_gpr(t0, ret);
18646 tcg_gen_movi_tl(t1, imm);
18647 gen_helper_wrdsp(t0, t1, cpu_env);
18650 tcg_gen_movi_tl(t0, v2 >> 3);
18651 tcg_gen_movi_tl(t1, v1);
18652 gen_helper_extp(t0, t0, t1, cpu_env);
18653 gen_store_gpr(t0, ret);
18656 tcg_gen_movi_tl(t0, v2 >> 3);
18657 tcg_gen_movi_tl(t1, v1);
18658 gen_helper_extpdp(t0, t0, t1, cpu_env);
18659 gen_store_gpr(t0, ret);
18663 case NM_POOL32AXF_1_4:
18665 tcg_gen_movi_tl(t0, v2 >> 2);
18666 switch (extract32(ctx->opcode, 12, 1)) {
18668 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18669 gen_store_gpr(t0, ret);
18672 gen_helper_shrl_qb(t0, t0, v0_t);
18673 gen_store_gpr(t0, ret);
18677 case NM_POOL32AXF_1_5:
18678 opc = extract32(ctx->opcode, 12, 2);
18679 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18681 case NM_POOL32AXF_1_7:
18683 tcg_gen_movi_tl(t0, v2 >> 3);
18684 tcg_gen_movi_tl(t1, v1);
18685 switch (extract32(ctx->opcode, 12, 2)) {
18687 gen_helper_extr_w(t0, t0, t1, cpu_env);
18688 gen_store_gpr(t0, ret);
18691 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18692 gen_store_gpr(t0, ret);
18695 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18696 gen_store_gpr(t0, ret);
18699 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18700 gen_store_gpr(t0, ret);
18705 generate_exception_end(ctx, EXCP_RI);
18711 tcg_temp_free(v0_t);
18714 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18715 TCGv v0, TCGv v1, int rd)
18719 t0 = tcg_temp_new_i32();
18721 tcg_gen_movi_i32(t0, rd >> 3);
18724 case NM_POOL32AXF_2_0_7:
18725 switch (extract32(ctx->opcode, 9, 3)) {
18728 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18730 case NM_DPAQ_S_W_PH:
18732 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18736 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18738 case NM_DPSQ_S_W_PH:
18740 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18743 generate_exception_end(ctx, EXCP_RI);
18747 case NM_POOL32AXF_2_8_15:
18748 switch (extract32(ctx->opcode, 9, 3)) {
18751 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18753 case NM_DPAQ_SA_L_W:
18755 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18759 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18761 case NM_DPSQ_SA_L_W:
18763 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18766 generate_exception_end(ctx, EXCP_RI);
18770 case NM_POOL32AXF_2_16_23:
18771 switch (extract32(ctx->opcode, 9, 3)) {
18772 case NM_DPAU_H_QBL:
18774 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18776 case NM_DPAQX_S_W_PH:
18778 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18780 case NM_DPSU_H_QBL:
18782 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18784 case NM_DPSQX_S_W_PH:
18786 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18788 case NM_MULSA_W_PH:
18790 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18793 generate_exception_end(ctx, EXCP_RI);
18797 case NM_POOL32AXF_2_24_31:
18798 switch (extract32(ctx->opcode, 9, 3)) {
18799 case NM_DPAU_H_QBR:
18801 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18803 case NM_DPAQX_SA_W_PH:
18805 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18807 case NM_DPSU_H_QBR:
18809 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18811 case NM_DPSQX_SA_W_PH:
18813 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18815 case NM_MULSAQ_S_W_PH:
18817 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18820 generate_exception_end(ctx, EXCP_RI);
18825 generate_exception_end(ctx, EXCP_RI);
18829 tcg_temp_free_i32(t0);
18832 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18833 int rt, int rs, int rd)
18836 TCGv t0 = tcg_temp_new();
18837 TCGv t1 = tcg_temp_new();
18838 TCGv v0_t = tcg_temp_new();
18839 TCGv v1_t = tcg_temp_new();
18841 gen_load_gpr(v0_t, rt);
18842 gen_load_gpr(v1_t, rs);
18845 case NM_POOL32AXF_2_0_7:
18846 switch (extract32(ctx->opcode, 9, 3)) {
18848 case NM_DPAQ_S_W_PH:
18850 case NM_DPSQ_S_W_PH:
18851 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18856 gen_load_gpr(t0, rs);
18858 if (rd != 0 && rd != 2) {
18859 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18860 tcg_gen_ext32u_tl(t0, t0);
18861 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18862 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18864 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18870 int acc = extract32(ctx->opcode, 14, 2);
18871 TCGv_i64 t2 = tcg_temp_new_i64();
18872 TCGv_i64 t3 = tcg_temp_new_i64();
18874 gen_load_gpr(t0, rt);
18875 gen_load_gpr(t1, rs);
18876 tcg_gen_ext_tl_i64(t2, t0);
18877 tcg_gen_ext_tl_i64(t3, t1);
18878 tcg_gen_mul_i64(t2, t2, t3);
18879 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18880 tcg_gen_add_i64(t2, t2, t3);
18881 tcg_temp_free_i64(t3);
18882 gen_move_low32(cpu_LO[acc], t2);
18883 gen_move_high32(cpu_HI[acc], t2);
18884 tcg_temp_free_i64(t2);
18890 int acc = extract32(ctx->opcode, 14, 2);
18891 TCGv_i32 t2 = tcg_temp_new_i32();
18892 TCGv_i32 t3 = tcg_temp_new_i32();
18894 gen_load_gpr(t0, rs);
18895 gen_load_gpr(t1, rt);
18896 tcg_gen_trunc_tl_i32(t2, t0);
18897 tcg_gen_trunc_tl_i32(t3, t1);
18898 tcg_gen_muls2_i32(t2, t3, t2, t3);
18899 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18900 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18901 tcg_temp_free_i32(t2);
18902 tcg_temp_free_i32(t3);
18907 gen_load_gpr(v1_t, rs);
18908 tcg_gen_movi_tl(t0, rd >> 3);
18909 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18910 gen_store_gpr(t0, ret);
18914 case NM_POOL32AXF_2_8_15:
18915 switch (extract32(ctx->opcode, 9, 3)) {
18917 case NM_DPAQ_SA_L_W:
18919 case NM_DPSQ_SA_L_W:
18920 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18925 int acc = extract32(ctx->opcode, 14, 2);
18926 TCGv_i64 t2 = tcg_temp_new_i64();
18927 TCGv_i64 t3 = tcg_temp_new_i64();
18929 gen_load_gpr(t0, rs);
18930 gen_load_gpr(t1, rt);
18931 tcg_gen_ext32u_tl(t0, t0);
18932 tcg_gen_ext32u_tl(t1, t1);
18933 tcg_gen_extu_tl_i64(t2, t0);
18934 tcg_gen_extu_tl_i64(t3, t1);
18935 tcg_gen_mul_i64(t2, t2, t3);
18936 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18937 tcg_gen_add_i64(t2, t2, t3);
18938 tcg_temp_free_i64(t3);
18939 gen_move_low32(cpu_LO[acc], t2);
18940 gen_move_high32(cpu_HI[acc], t2);
18941 tcg_temp_free_i64(t2);
18947 int acc = extract32(ctx->opcode, 14, 2);
18948 TCGv_i32 t2 = tcg_temp_new_i32();
18949 TCGv_i32 t3 = tcg_temp_new_i32();
18951 gen_load_gpr(t0, rs);
18952 gen_load_gpr(t1, rt);
18953 tcg_gen_trunc_tl_i32(t2, t0);
18954 tcg_gen_trunc_tl_i32(t3, t1);
18955 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18956 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18957 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18958 tcg_temp_free_i32(t2);
18959 tcg_temp_free_i32(t3);
18964 tcg_gen_movi_tl(t0, rd >> 3);
18965 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18966 gen_store_gpr(t0, ret);
18969 generate_exception_end(ctx, EXCP_RI);
18973 case NM_POOL32AXF_2_16_23:
18974 switch (extract32(ctx->opcode, 9, 3)) {
18975 case NM_DPAU_H_QBL:
18976 case NM_DPAQX_S_W_PH:
18977 case NM_DPSU_H_QBL:
18978 case NM_DPSQX_S_W_PH:
18979 case NM_MULSA_W_PH:
18980 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18984 tcg_gen_movi_tl(t0, rd >> 3);
18985 gen_helper_extp(t0, t0, v1_t, cpu_env);
18986 gen_store_gpr(t0, ret);
18991 int acc = extract32(ctx->opcode, 14, 2);
18992 TCGv_i64 t2 = tcg_temp_new_i64();
18993 TCGv_i64 t3 = tcg_temp_new_i64();
18995 gen_load_gpr(t0, rs);
18996 gen_load_gpr(t1, rt);
18997 tcg_gen_ext_tl_i64(t2, t0);
18998 tcg_gen_ext_tl_i64(t3, t1);
18999 tcg_gen_mul_i64(t2, t2, t3);
19000 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19001 tcg_gen_sub_i64(t2, t3, t2);
19002 tcg_temp_free_i64(t3);
19003 gen_move_low32(cpu_LO[acc], t2);
19004 gen_move_high32(cpu_HI[acc], t2);
19005 tcg_temp_free_i64(t2);
19008 case NM_EXTRV_RS_W:
19010 tcg_gen_movi_tl(t0, rd >> 3);
19011 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19012 gen_store_gpr(t0, ret);
19016 case NM_POOL32AXF_2_24_31:
19017 switch (extract32(ctx->opcode, 9, 3)) {
19018 case NM_DPAU_H_QBR:
19019 case NM_DPAQX_SA_W_PH:
19020 case NM_DPSU_H_QBR:
19021 case NM_DPSQX_SA_W_PH:
19022 case NM_MULSAQ_S_W_PH:
19023 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19027 tcg_gen_movi_tl(t0, rd >> 3);
19028 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19029 gen_store_gpr(t0, ret);
19034 int acc = extract32(ctx->opcode, 14, 2);
19035 TCGv_i64 t2 = tcg_temp_new_i64();
19036 TCGv_i64 t3 = tcg_temp_new_i64();
19038 gen_load_gpr(t0, rs);
19039 gen_load_gpr(t1, rt);
19040 tcg_gen_ext32u_tl(t0, t0);
19041 tcg_gen_ext32u_tl(t1, t1);
19042 tcg_gen_extu_tl_i64(t2, t0);
19043 tcg_gen_extu_tl_i64(t3, t1);
19044 tcg_gen_mul_i64(t2, t2, t3);
19045 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19046 tcg_gen_sub_i64(t2, t3, t2);
19047 tcg_temp_free_i64(t3);
19048 gen_move_low32(cpu_LO[acc], t2);
19049 gen_move_high32(cpu_HI[acc], t2);
19050 tcg_temp_free_i64(t2);
19055 tcg_gen_movi_tl(t0, rd >> 3);
19056 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19057 gen_store_gpr(t0, ret);
19062 generate_exception_end(ctx, EXCP_RI);
19069 tcg_temp_free(v0_t);
19070 tcg_temp_free(v1_t);
19073 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19077 TCGv t0 = tcg_temp_new();
19078 TCGv v0_t = tcg_temp_new();
19080 gen_load_gpr(v0_t, rs);
19085 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19086 gen_store_gpr(v0_t, ret);
19090 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19091 gen_store_gpr(v0_t, ret);
19095 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19096 gen_store_gpr(v0_t, ret);
19098 case NM_PRECEQ_W_PHL:
19100 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19101 tcg_gen_ext32s_tl(v0_t, v0_t);
19102 gen_store_gpr(v0_t, ret);
19104 case NM_PRECEQ_W_PHR:
19106 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19107 tcg_gen_shli_tl(v0_t, v0_t, 16);
19108 tcg_gen_ext32s_tl(v0_t, v0_t);
19109 gen_store_gpr(v0_t, ret);
19111 case NM_PRECEQU_PH_QBL:
19113 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19114 gen_store_gpr(v0_t, ret);
19116 case NM_PRECEQU_PH_QBR:
19118 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19119 gen_store_gpr(v0_t, ret);
19121 case NM_PRECEQU_PH_QBLA:
19123 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19124 gen_store_gpr(v0_t, ret);
19126 case NM_PRECEQU_PH_QBRA:
19128 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19129 gen_store_gpr(v0_t, ret);
19131 case NM_PRECEU_PH_QBL:
19133 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19134 gen_store_gpr(v0_t, ret);
19136 case NM_PRECEU_PH_QBR:
19138 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19139 gen_store_gpr(v0_t, ret);
19141 case NM_PRECEU_PH_QBLA:
19143 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19144 gen_store_gpr(v0_t, ret);
19146 case NM_PRECEU_PH_QBRA:
19148 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19149 gen_store_gpr(v0_t, ret);
19153 tcg_gen_ext16u_tl(v0_t, v0_t);
19154 tcg_gen_shli_tl(t0, v0_t, 16);
19155 tcg_gen_or_tl(v0_t, v0_t, t0);
19156 tcg_gen_ext32s_tl(v0_t, v0_t);
19157 gen_store_gpr(v0_t, ret);
19161 tcg_gen_ext8u_tl(v0_t, v0_t);
19162 tcg_gen_shli_tl(t0, v0_t, 8);
19163 tcg_gen_or_tl(v0_t, v0_t, t0);
19164 tcg_gen_shli_tl(t0, v0_t, 16);
19165 tcg_gen_or_tl(v0_t, v0_t, t0);
19166 tcg_gen_ext32s_tl(v0_t, v0_t);
19167 gen_store_gpr(v0_t, ret);
19171 gen_helper_bitrev(v0_t, v0_t);
19172 gen_store_gpr(v0_t, ret);
19177 TCGv tv0 = tcg_temp_new();
19179 gen_load_gpr(tv0, rt);
19180 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19181 gen_store_gpr(v0_t, ret);
19182 tcg_temp_free(tv0);
19185 case NM_RADDU_W_QB:
19187 gen_helper_raddu_w_qb(v0_t, v0_t);
19188 gen_store_gpr(v0_t, ret);
19191 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19195 gen_cl(ctx, OPC_CLO, ret, rs);
19199 gen_cl(ctx, OPC_CLZ, ret, rs);
19202 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19205 generate_exception_end(ctx, EXCP_RI);
19209 tcg_temp_free(v0_t);
19213 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19214 int rt, int rs, int rd)
19216 TCGv t0 = tcg_temp_new();
19217 TCGv rs_t = tcg_temp_new();
19219 gen_load_gpr(rs_t, rs);
19224 tcg_gen_movi_tl(t0, rd >> 2);
19225 switch (extract32(ctx->opcode, 12, 1)) {
19228 gen_helper_shra_qb(t0, t0, rs_t);
19229 gen_store_gpr(t0, rt);
19233 gen_helper_shra_r_qb(t0, t0, rs_t);
19234 gen_store_gpr(t0, rt);
19240 tcg_gen_movi_tl(t0, rd >> 1);
19241 gen_helper_shrl_ph(t0, t0, rs_t);
19242 gen_store_gpr(t0, rt);
19248 target_long result;
19249 imm = extract32(ctx->opcode, 13, 8);
19250 result = (uint32_t)imm << 24 |
19251 (uint32_t)imm << 16 |
19252 (uint32_t)imm << 8 |
19254 result = (int32_t)result;
19255 tcg_gen_movi_tl(t0, result);
19256 gen_store_gpr(t0, rt);
19260 generate_exception_end(ctx, EXCP_RI);
19264 tcg_temp_free(rs_t);
19268 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19270 int rt = extract32(ctx->opcode, 21, 5);
19271 int rs = extract32(ctx->opcode, 16, 5);
19272 int rd = extract32(ctx->opcode, 11, 5);
19274 switch (extract32(ctx->opcode, 6, 3)) {
19275 case NM_POOL32AXF_1:
19277 int32_t op1 = extract32(ctx->opcode, 9, 3);
19278 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19281 case NM_POOL32AXF_2:
19283 int32_t op1 = extract32(ctx->opcode, 12, 2);
19284 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19287 case NM_POOL32AXF_4:
19289 int32_t op1 = extract32(ctx->opcode, 9, 7);
19290 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19293 case NM_POOL32AXF_5:
19294 switch (extract32(ctx->opcode, 9, 7)) {
19295 #ifndef CONFIG_USER_ONLY
19297 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19300 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19303 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19306 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19309 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19312 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19315 check_cp0_enabled(ctx);
19317 TCGv t0 = tcg_temp_new();
19319 save_cpu_state(ctx, 1);
19320 gen_helper_di(t0, cpu_env);
19321 gen_store_gpr(t0, rt);
19322 /* Stop translation as we may have switched the execution mode */
19323 ctx->base.is_jmp = DISAS_STOP;
19328 check_cp0_enabled(ctx);
19330 TCGv t0 = tcg_temp_new();
19332 save_cpu_state(ctx, 1);
19333 gen_helper_ei(t0, cpu_env);
19334 gen_store_gpr(t0, rt);
19335 /* Stop translation as we may have switched the execution mode */
19336 ctx->base.is_jmp = DISAS_STOP;
19341 gen_load_srsgpr(rs, rt);
19344 gen_store_srsgpr(rs, rt);
19347 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19350 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19353 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19357 generate_exception_end(ctx, EXCP_RI);
19361 case NM_POOL32AXF_7:
19363 int32_t op1 = extract32(ctx->opcode, 9, 3);
19364 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19368 generate_exception_end(ctx, EXCP_RI);
19373 /* Immediate Value Compact Branches */
19374 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19375 int rt, int32_t imm, int32_t offset)
19378 int bcond_compute = 0;
19379 TCGv t0 = tcg_temp_new();
19380 TCGv t1 = tcg_temp_new();
19382 gen_load_gpr(t0, rt);
19383 tcg_gen_movi_tl(t1, imm);
19384 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19386 /* Load needed operands and calculate btarget */
19389 if (rt == 0 && imm == 0) {
19390 /* Unconditional branch */
19391 } else if (rt == 0 && imm != 0) {
19396 cond = TCG_COND_EQ;
19402 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19403 generate_exception_end(ctx, EXCP_RI);
19405 } else if (rt == 0 && opc == NM_BBEQZC) {
19406 /* Unconditional branch */
19407 } else if (rt == 0 && opc == NM_BBNEZC) {
19411 tcg_gen_shri_tl(t0, t0, imm);
19412 tcg_gen_andi_tl(t0, t0, 1);
19413 tcg_gen_movi_tl(t1, 0);
19415 if (opc == NM_BBEQZC) {
19416 cond = TCG_COND_EQ;
19418 cond = TCG_COND_NE;
19423 if (rt == 0 && imm == 0) {
19426 } else if (rt == 0 && imm != 0) {
19427 /* Unconditional branch */
19430 cond = TCG_COND_NE;
19434 if (rt == 0 && imm == 0) {
19435 /* Unconditional branch */
19438 cond = TCG_COND_GE;
19443 cond = TCG_COND_LT;
19446 if (rt == 0 && imm == 0) {
19447 /* Unconditional branch */
19450 cond = TCG_COND_GEU;
19455 cond = TCG_COND_LTU;
19458 MIPS_INVAL("Immediate Value Compact branch");
19459 generate_exception_end(ctx, EXCP_RI);
19463 if (bcond_compute == 0) {
19464 /* Uncoditional compact branch */
19465 gen_goto_tb(ctx, 0, ctx->btarget);
19467 /* Conditional compact branch */
19468 TCGLabel *fs = gen_new_label();
19470 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19472 gen_goto_tb(ctx, 1, ctx->btarget);
19475 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19483 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19484 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19487 TCGv t0 = tcg_temp_new();
19488 TCGv t1 = tcg_temp_new();
19491 gen_load_gpr(t0, rs);
19495 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19498 /* calculate btarget */
19499 tcg_gen_shli_tl(t0, t0, 1);
19500 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19501 gen_op_addr_add(ctx, btarget, t1, t0);
19503 /* unconditional branch to register */
19504 tcg_gen_mov_tl(cpu_PC, btarget);
19505 tcg_gen_lookup_and_goto_ptr();
19511 /* nanoMIPS Branches */
19512 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19513 int rs, int rt, int32_t offset)
19515 int bcond_compute = 0;
19516 TCGv t0 = tcg_temp_new();
19517 TCGv t1 = tcg_temp_new();
19519 /* Load needed operands and calculate btarget */
19521 /* compact branch */
19524 gen_load_gpr(t0, rs);
19525 gen_load_gpr(t1, rt);
19527 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19531 if (rs == 0 || rs == rt) {
19532 /* OPC_BLEZALC, OPC_BGEZALC */
19533 /* OPC_BGTZALC, OPC_BLTZALC */
19534 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19536 gen_load_gpr(t0, rs);
19537 gen_load_gpr(t1, rt);
19539 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19542 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19546 /* OPC_BEQZC, OPC_BNEZC */
19547 gen_load_gpr(t0, rs);
19549 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19551 /* OPC_JIC, OPC_JIALC */
19552 TCGv tbase = tcg_temp_new();
19553 TCGv toffset = tcg_temp_new();
19555 gen_load_gpr(tbase, rt);
19556 tcg_gen_movi_tl(toffset, offset);
19557 gen_op_addr_add(ctx, btarget, tbase, toffset);
19558 tcg_temp_free(tbase);
19559 tcg_temp_free(toffset);
19563 MIPS_INVAL("Compact branch/jump");
19564 generate_exception_end(ctx, EXCP_RI);
19568 if (bcond_compute == 0) {
19569 /* Uncoditional compact branch */
19572 gen_goto_tb(ctx, 0, ctx->btarget);
19575 MIPS_INVAL("Compact branch/jump");
19576 generate_exception_end(ctx, EXCP_RI);
19580 /* Conditional compact branch */
19581 TCGLabel *fs = gen_new_label();
19585 if (rs == 0 && rt != 0) {
19587 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19588 } else if (rs != 0 && rt != 0 && rs == rt) {
19590 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19593 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19597 if (rs == 0 && rt != 0) {
19599 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19600 } else if (rs != 0 && rt != 0 && rs == rt) {
19602 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19605 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19609 if (rs == 0 && rt != 0) {
19611 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19612 } else if (rs != 0 && rt != 0 && rs == rt) {
19614 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19617 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19621 if (rs == 0 && rt != 0) {
19623 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19624 } else if (rs != 0 && rt != 0 && rs == rt) {
19626 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19629 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19633 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19636 MIPS_INVAL("Compact conditional branch/jump");
19637 generate_exception_end(ctx, EXCP_RI);
19641 /* Generating branch here as compact branches don't have delay slot */
19642 gen_goto_tb(ctx, 1, ctx->btarget);
19645 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19654 /* nanoMIPS CP1 Branches */
19655 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19656 int32_t ft, int32_t offset)
19658 target_ulong btarget;
19659 TCGv_i64 t0 = tcg_temp_new_i64();
19661 gen_load_fpr64(ctx, t0, ft);
19662 tcg_gen_andi_i64(t0, t0, 1);
19664 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19668 tcg_gen_xori_i64(t0, t0, 1);
19669 ctx->hflags |= MIPS_HFLAG_BC;
19672 /* t0 already set */
19673 ctx->hflags |= MIPS_HFLAG_BC;
19676 MIPS_INVAL("cp1 cond branch");
19677 generate_exception_end(ctx, EXCP_RI);
19681 tcg_gen_trunc_i64_tl(bcond, t0);
19683 ctx->btarget = btarget;
19686 tcg_temp_free_i64(t0);
19690 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19693 t0 = tcg_temp_new();
19694 t1 = tcg_temp_new();
19696 gen_load_gpr(t0, rs);
19697 gen_load_gpr(t1, rt);
19699 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19700 /* PP.LSXS instructions require shifting */
19701 switch (extract32(ctx->opcode, 7, 4)) {
19706 tcg_gen_shli_tl(t0, t0, 1);
19713 tcg_gen_shli_tl(t0, t0, 2);
19717 tcg_gen_shli_tl(t0, t0, 3);
19721 gen_op_addr_add(ctx, t0, t0, t1);
19723 switch (extract32(ctx->opcode, 7, 4)) {
19725 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19727 gen_store_gpr(t0, rd);
19731 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19733 gen_store_gpr(t0, rd);
19737 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19739 gen_store_gpr(t0, rd);
19742 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19744 gen_store_gpr(t0, rd);
19748 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19750 gen_store_gpr(t0, rd);
19754 gen_load_gpr(t1, rd);
19755 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19761 gen_load_gpr(t1, rd);
19762 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19768 gen_load_gpr(t1, rd);
19769 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19773 /*case NM_LWC1XS:*/
19775 /*case NM_LDC1XS:*/
19777 /*case NM_SWC1XS:*/
19779 /*case NM_SDC1XS:*/
19780 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19781 check_cp1_enabled(ctx);
19782 switch (extract32(ctx->opcode, 7, 4)) {
19784 /*case NM_LWC1XS:*/
19785 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19788 /*case NM_LDC1XS:*/
19789 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19792 /*case NM_SWC1XS:*/
19793 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19796 /*case NM_SDC1XS:*/
19797 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19801 generate_exception_err(ctx, EXCP_CpU, 1);
19805 generate_exception_end(ctx, EXCP_RI);
19813 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19817 rt = extract32(ctx->opcode, 21, 5);
19818 rs = extract32(ctx->opcode, 16, 5);
19819 rd = extract32(ctx->opcode, 11, 5);
19821 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19822 generate_exception_end(ctx, EXCP_RI);
19825 check_cp1_enabled(ctx);
19826 switch (extract32(ctx->opcode, 0, 3)) {
19828 switch (extract32(ctx->opcode, 3, 7)) {
19830 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19833 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19836 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19839 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19842 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19845 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19848 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19851 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19854 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19857 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19860 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19863 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19866 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19869 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19872 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19875 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19878 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19881 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19884 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19887 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19890 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19893 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19896 generate_exception_end(ctx, EXCP_RI);
19901 switch (extract32(ctx->opcode, 3, 3)) {
19903 switch (extract32(ctx->opcode, 9, 1)) {
19905 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19908 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19913 switch (extract32(ctx->opcode, 9, 1)) {
19915 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19918 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19923 switch (extract32(ctx->opcode, 9, 1)) {
19925 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19928 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19933 switch (extract32(ctx->opcode, 9, 1)) {
19935 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19938 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19943 switch (extract32(ctx->opcode, 6, 8)) {
19945 gen_cp1(ctx, OPC_CFC1, rt, rs);
19948 gen_cp1(ctx, OPC_CTC1, rt, rs);
19951 gen_cp1(ctx, OPC_MFC1, rt, rs);
19954 gen_cp1(ctx, OPC_MTC1, rt, rs);
19957 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19960 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19963 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19966 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19969 switch (extract32(ctx->opcode, 6, 9)) {
19971 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19974 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19977 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19980 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19983 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19986 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19989 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19992 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19995 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19998 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20001 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20004 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20007 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20010 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20013 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20016 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20019 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20022 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20025 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20028 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20031 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20034 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20037 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20040 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20043 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20046 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20049 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20052 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20055 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20058 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20061 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20064 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20067 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20070 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20073 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20076 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20079 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20082 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20085 generate_exception_end(ctx, EXCP_RI);
20094 switch (extract32(ctx->opcode, 3, 3)) {
20095 case NM_CMP_CONDN_S:
20096 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20098 case NM_CMP_CONDN_D:
20099 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20102 generate_exception_end(ctx, EXCP_RI);
20107 generate_exception_end(ctx, EXCP_RI);
20112 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20113 int rd, int rs, int rt)
20116 TCGv t0 = tcg_temp_new();
20117 TCGv v1_t = tcg_temp_new();
20118 TCGv v2_t = tcg_temp_new();
20120 gen_load_gpr(v1_t, rs);
20121 gen_load_gpr(v2_t, rt);
20126 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20130 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20134 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20136 case NM_CMPU_EQ_QB:
20138 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20140 case NM_CMPU_LT_QB:
20142 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20144 case NM_CMPU_LE_QB:
20146 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20148 case NM_CMPGU_EQ_QB:
20150 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20151 gen_store_gpr(v1_t, ret);
20153 case NM_CMPGU_LT_QB:
20155 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20156 gen_store_gpr(v1_t, ret);
20158 case NM_CMPGU_LE_QB:
20160 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20161 gen_store_gpr(v1_t, ret);
20163 case NM_CMPGDU_EQ_QB:
20165 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20166 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20167 gen_store_gpr(v1_t, ret);
20169 case NM_CMPGDU_LT_QB:
20171 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20172 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20173 gen_store_gpr(v1_t, ret);
20175 case NM_CMPGDU_LE_QB:
20177 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20178 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20179 gen_store_gpr(v1_t, ret);
20183 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20184 gen_store_gpr(v1_t, ret);
20188 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20189 gen_store_gpr(v1_t, ret);
20193 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20194 gen_store_gpr(v1_t, ret);
20198 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20199 gen_store_gpr(v1_t, ret);
20203 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20204 gen_store_gpr(v1_t, ret);
20208 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20209 gen_store_gpr(v1_t, ret);
20213 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20214 gen_store_gpr(v1_t, ret);
20218 switch (extract32(ctx->opcode, 10, 1)) {
20221 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20222 gen_store_gpr(v1_t, ret);
20226 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20227 gen_store_gpr(v1_t, ret);
20231 case NM_ADDQH_R_PH:
20233 switch (extract32(ctx->opcode, 10, 1)) {
20236 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20237 gen_store_gpr(v1_t, ret);
20241 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20242 gen_store_gpr(v1_t, ret);
20248 switch (extract32(ctx->opcode, 10, 1)) {
20251 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20252 gen_store_gpr(v1_t, ret);
20256 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20257 gen_store_gpr(v1_t, ret);
20263 switch (extract32(ctx->opcode, 10, 1)) {
20266 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20267 gen_store_gpr(v1_t, ret);
20271 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20272 gen_store_gpr(v1_t, ret);
20278 switch (extract32(ctx->opcode, 10, 1)) {
20281 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20282 gen_store_gpr(v1_t, ret);
20286 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20287 gen_store_gpr(v1_t, ret);
20291 case NM_ADDUH_R_QB:
20293 switch (extract32(ctx->opcode, 10, 1)) {
20296 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20297 gen_store_gpr(v1_t, ret);
20301 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20302 gen_store_gpr(v1_t, ret);
20306 case NM_SHRAV_R_PH:
20308 switch (extract32(ctx->opcode, 10, 1)) {
20311 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20312 gen_store_gpr(v1_t, ret);
20316 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20317 gen_store_gpr(v1_t, ret);
20321 case NM_SHRAV_R_QB:
20323 switch (extract32(ctx->opcode, 10, 1)) {
20326 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20327 gen_store_gpr(v1_t, ret);
20331 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20332 gen_store_gpr(v1_t, ret);
20338 switch (extract32(ctx->opcode, 10, 1)) {
20341 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20342 gen_store_gpr(v1_t, ret);
20346 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20347 gen_store_gpr(v1_t, ret);
20351 case NM_SUBQH_R_PH:
20353 switch (extract32(ctx->opcode, 10, 1)) {
20356 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20357 gen_store_gpr(v1_t, ret);
20361 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20362 gen_store_gpr(v1_t, ret);
20368 switch (extract32(ctx->opcode, 10, 1)) {
20371 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20372 gen_store_gpr(v1_t, ret);
20376 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20377 gen_store_gpr(v1_t, ret);
20383 switch (extract32(ctx->opcode, 10, 1)) {
20386 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20387 gen_store_gpr(v1_t, ret);
20391 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20392 gen_store_gpr(v1_t, ret);
20398 switch (extract32(ctx->opcode, 10, 1)) {
20401 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20402 gen_store_gpr(v1_t, ret);
20406 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20407 gen_store_gpr(v1_t, ret);
20411 case NM_SUBUH_R_QB:
20413 switch (extract32(ctx->opcode, 10, 1)) {
20416 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20417 gen_store_gpr(v1_t, ret);
20421 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20422 gen_store_gpr(v1_t, ret);
20426 case NM_SHLLV_S_PH:
20428 switch (extract32(ctx->opcode, 10, 1)) {
20431 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20432 gen_store_gpr(v1_t, ret);
20436 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20437 gen_store_gpr(v1_t, ret);
20441 case NM_PRECR_SRA_R_PH_W:
20443 switch (extract32(ctx->opcode, 10, 1)) {
20445 /* PRECR_SRA_PH_W */
20447 TCGv_i32 sa_t = tcg_const_i32(rd);
20448 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20450 gen_store_gpr(v1_t, rt);
20451 tcg_temp_free_i32(sa_t);
20455 /* PRECR_SRA_R_PH_W */
20457 TCGv_i32 sa_t = tcg_const_i32(rd);
20458 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20460 gen_store_gpr(v1_t, rt);
20461 tcg_temp_free_i32(sa_t);
20466 case NM_MULEU_S_PH_QBL:
20468 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20469 gen_store_gpr(v1_t, ret);
20471 case NM_MULEU_S_PH_QBR:
20473 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20474 gen_store_gpr(v1_t, ret);
20476 case NM_MULQ_RS_PH:
20478 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20479 gen_store_gpr(v1_t, ret);
20483 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20484 gen_store_gpr(v1_t, ret);
20488 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20489 gen_store_gpr(v1_t, ret);
20493 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20494 gen_store_gpr(v1_t, ret);
20498 gen_load_gpr(t0, rs);
20500 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20502 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20506 gen_helper_modsub(v1_t, v1_t, v2_t);
20507 gen_store_gpr(v1_t, ret);
20511 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20512 gen_store_gpr(v1_t, ret);
20516 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20517 gen_store_gpr(v1_t, ret);
20521 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20522 gen_store_gpr(v1_t, ret);
20526 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20527 gen_store_gpr(v1_t, ret);
20531 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20532 gen_store_gpr(v1_t, ret);
20537 TCGv tv0 = tcg_temp_new();
20538 TCGv tv1 = tcg_temp_new();
20539 int16_t imm = extract32(ctx->opcode, 16, 7);
20541 tcg_gen_movi_tl(tv0, rd >> 3);
20542 tcg_gen_movi_tl(tv1, imm);
20543 gen_helper_shilo(tv0, tv1, cpu_env);
20546 case NM_MULEQ_S_W_PHL:
20548 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20549 gen_store_gpr(v1_t, ret);
20551 case NM_MULEQ_S_W_PHR:
20553 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20554 gen_store_gpr(v1_t, ret);
20558 switch (extract32(ctx->opcode, 10, 1)) {
20561 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20562 gen_store_gpr(v1_t, ret);
20566 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20567 gen_store_gpr(v1_t, ret);
20571 case NM_PRECR_QB_PH:
20573 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20574 gen_store_gpr(v1_t, ret);
20576 case NM_PRECRQ_QB_PH:
20578 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20579 gen_store_gpr(v1_t, ret);
20581 case NM_PRECRQ_PH_W:
20583 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20584 gen_store_gpr(v1_t, ret);
20586 case NM_PRECRQ_RS_PH_W:
20588 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20589 gen_store_gpr(v1_t, ret);
20591 case NM_PRECRQU_S_QB_PH:
20593 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20594 gen_store_gpr(v1_t, ret);
20598 tcg_gen_movi_tl(t0, rd);
20599 gen_helper_shra_r_w(v1_t, t0, v1_t);
20600 gen_store_gpr(v1_t, rt);
20604 tcg_gen_movi_tl(t0, rd >> 1);
20605 switch (extract32(ctx->opcode, 10, 1)) {
20608 gen_helper_shra_ph(v1_t, t0, v1_t);
20609 gen_store_gpr(v1_t, rt);
20613 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20614 gen_store_gpr(v1_t, rt);
20620 tcg_gen_movi_tl(t0, rd >> 1);
20621 switch (extract32(ctx->opcode, 10, 2)) {
20624 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20625 gen_store_gpr(v1_t, rt);
20629 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20630 gen_store_gpr(v1_t, rt);
20633 generate_exception_end(ctx, EXCP_RI);
20639 tcg_gen_movi_tl(t0, rd);
20640 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20641 gen_store_gpr(v1_t, rt);
20647 imm = sextract32(ctx->opcode, 11, 11);
20648 imm = (int16_t)(imm << 6) >> 6;
20650 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20655 generate_exception_end(ctx, EXCP_RI);
20660 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20668 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20669 ctx->opcode = (ctx->opcode << 16) | insn;
20671 rt = extract32(ctx->opcode, 21, 5);
20672 rs = extract32(ctx->opcode, 16, 5);
20673 rd = extract32(ctx->opcode, 11, 5);
20675 op = extract32(ctx->opcode, 26, 6);
20680 switch (extract32(ctx->opcode, 19, 2)) {
20683 generate_exception_end(ctx, EXCP_RI);
20686 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20687 generate_exception_end(ctx, EXCP_SYSCALL);
20689 generate_exception_end(ctx, EXCP_RI);
20693 generate_exception_end(ctx, EXCP_BREAK);
20696 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20697 gen_helper_do_semihosting(cpu_env);
20699 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20700 generate_exception_end(ctx, EXCP_RI);
20702 generate_exception_end(ctx, EXCP_DBp);
20709 imm = extract32(ctx->opcode, 0, 16);
20711 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20713 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20715 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20720 offset = sextract32(ctx->opcode, 0, 1) << 21 |
20721 extract32(ctx->opcode, 1, 20) << 1;
20722 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20723 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20727 switch (ctx->opcode & 0x07) {
20729 gen_pool32a0_nanomips_insn(env, ctx);
20733 int32_t op1 = extract32(ctx->opcode, 3, 7);
20734 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20738 switch (extract32(ctx->opcode, 3, 3)) {
20740 gen_p_lsx(ctx, rd, rs, rt);
20743 /* In nanoMIPS, the shift field directly encodes the shift
20744 * amount, meaning that the supported shift values are in
20745 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20746 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20747 extract32(ctx->opcode, 9, 2) - 1);
20750 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20753 gen_pool32axf_nanomips_insn(env, ctx);
20756 generate_exception_end(ctx, EXCP_RI);
20761 generate_exception_end(ctx, EXCP_RI);
20766 switch (ctx->opcode & 0x03) {
20769 offset = extract32(ctx->opcode, 0, 21);
20770 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20774 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20777 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20780 generate_exception_end(ctx, EXCP_RI);
20786 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20787 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20788 switch (extract32(ctx->opcode, 16, 5)) {
20792 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20798 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20799 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20805 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20811 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20814 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20821 t0 = tcg_temp_new();
20823 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20826 tcg_gen_movi_tl(t0, addr);
20827 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20835 t0 = tcg_temp_new();
20836 t1 = tcg_temp_new();
20838 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20841 tcg_gen_movi_tl(t0, addr);
20842 gen_load_gpr(t1, rt);
20844 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20851 generate_exception_end(ctx, EXCP_RI);
20857 switch (extract32(ctx->opcode, 12, 4)) {
20859 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20862 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20865 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20868 switch (extract32(ctx->opcode, 20, 1)) {
20870 switch (ctx->opcode & 3) {
20872 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20873 extract32(ctx->opcode, 2, 1),
20874 extract32(ctx->opcode, 3, 9) << 3);
20877 case NM_RESTORE_JRC:
20878 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20879 extract32(ctx->opcode, 2, 1),
20880 extract32(ctx->opcode, 3, 9) << 3);
20881 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20882 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20886 generate_exception_end(ctx, EXCP_RI);
20891 generate_exception_end(ctx, EXCP_RI);
20896 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20899 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20903 TCGv t0 = tcg_temp_new();
20905 imm = extract32(ctx->opcode, 0, 12);
20906 gen_load_gpr(t0, rs);
20907 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20908 gen_store_gpr(t0, rt);
20914 imm = (int16_t) extract32(ctx->opcode, 0, 12);
20915 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20919 int shift = extract32(ctx->opcode, 0, 5);
20920 switch (extract32(ctx->opcode, 5, 4)) {
20922 if (rt == 0 && shift == 0) {
20924 } else if (rt == 0 && shift == 3) {
20925 /* EHB - treat as NOP */
20926 } else if (rt == 0 && shift == 5) {
20927 /* PAUSE - treat as NOP */
20928 } else if (rt == 0 && shift == 6) {
20930 gen_sync(extract32(ctx->opcode, 16, 5));
20933 gen_shift_imm(ctx, OPC_SLL, rt, rs,
20934 extract32(ctx->opcode, 0, 5));
20938 gen_shift_imm(ctx, OPC_SRL, rt, rs,
20939 extract32(ctx->opcode, 0, 5));
20942 gen_shift_imm(ctx, OPC_SRA, rt, rs,
20943 extract32(ctx->opcode, 0, 5));
20946 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20947 extract32(ctx->opcode, 0, 5));
20955 TCGv t0 = tcg_temp_new();
20956 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20957 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20959 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20961 gen_load_gpr(t0, rs);
20962 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20965 tcg_temp_free_i32(shift);
20966 tcg_temp_free_i32(shiftx);
20967 tcg_temp_free_i32(stripe);
20971 switch (((ctx->opcode >> 10) & 2) |
20972 (extract32(ctx->opcode, 5, 1))) {
20975 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20976 extract32(ctx->opcode, 6, 5));
20979 generate_exception_end(ctx, EXCP_RI);
20984 switch (((ctx->opcode >> 10) & 2) |
20985 (extract32(ctx->opcode, 5, 1))) {
20988 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20989 extract32(ctx->opcode, 6, 5));
20992 generate_exception_end(ctx, EXCP_RI);
20997 generate_exception_end(ctx, EXCP_RI);
21002 gen_pool32f_nanomips_insn(ctx);
21007 switch (extract32(ctx->opcode, 1, 1)) {
21010 tcg_gen_movi_tl(cpu_gpr[rt],
21011 sextract32(ctx->opcode, 0, 1) << 31 |
21012 extract32(ctx->opcode, 2, 10) << 21 |
21013 extract32(ctx->opcode, 12, 9) << 12);
21018 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21019 extract32(ctx->opcode, 2, 10) << 21 |
21020 extract32(ctx->opcode, 12, 9) << 12;
21022 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21023 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21030 uint32_t u = extract32(ctx->opcode, 0, 18);
21032 switch (extract32(ctx->opcode, 18, 3)) {
21034 gen_ld(ctx, OPC_LB, rt, 28, u);
21037 gen_st(ctx, OPC_SB, rt, 28, u);
21040 gen_ld(ctx, OPC_LBU, rt, 28, u);
21044 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21049 switch (ctx->opcode & 1) {
21051 gen_ld(ctx, OPC_LH, rt, 28, u);
21054 gen_ld(ctx, OPC_LHU, rt, 28, u);
21060 switch (ctx->opcode & 1) {
21062 gen_st(ctx, OPC_SH, rt, 28, u);
21065 generate_exception_end(ctx, EXCP_RI);
21071 switch (ctx->opcode & 0x3) {
21073 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21076 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21079 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21082 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21087 generate_exception_end(ctx, EXCP_RI);
21094 uint32_t u = extract32(ctx->opcode, 0, 12);
21096 switch (extract32(ctx->opcode, 12, 4)) {
21100 /* Break the TB to be able to sync copied instructions
21102 ctx->base.is_jmp = DISAS_STOP;
21105 /* Treat as NOP. */
21109 gen_ld(ctx, OPC_LB, rt, rs, u);
21112 gen_ld(ctx, OPC_LH, rt, rs, u);
21115 gen_ld(ctx, OPC_LW, rt, rs, u);
21118 gen_ld(ctx, OPC_LBU, rt, rs, u);
21121 gen_ld(ctx, OPC_LHU, rt, rs, u);
21124 gen_st(ctx, OPC_SB, rt, rs, u);
21127 gen_st(ctx, OPC_SH, rt, rs, u);
21130 gen_st(ctx, OPC_SW, rt, rs, u);
21133 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21136 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21139 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21142 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21145 generate_exception_end(ctx, EXCP_RI);
21152 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21153 extract32(ctx->opcode, 0, 8);
21155 switch (extract32(ctx->opcode, 8, 3)) {
21157 switch (extract32(ctx->opcode, 11, 4)) {
21159 gen_ld(ctx, OPC_LB, rt, rs, s);
21162 gen_ld(ctx, OPC_LH, rt, rs, s);
21165 gen_ld(ctx, OPC_LW, rt, rs, s);
21168 gen_ld(ctx, OPC_LBU, rt, rs, s);
21171 gen_ld(ctx, OPC_LHU, rt, rs, s);
21174 gen_st(ctx, OPC_SB, rt, rs, s);
21177 gen_st(ctx, OPC_SH, rt, rs, s);
21180 gen_st(ctx, OPC_SW, rt, rs, s);
21183 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21186 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21189 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21192 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21197 /* Break the TB to be able to sync copied instructions
21199 ctx->base.is_jmp = DISAS_STOP;
21202 /* Treat as NOP. */
21206 generate_exception_end(ctx, EXCP_RI);
21211 switch (extract32(ctx->opcode, 11, 4)) {
21216 TCGv t0 = tcg_temp_new();
21217 TCGv t1 = tcg_temp_new();
21219 gen_base_offset_addr(ctx, t0, rs, s);
21221 switch (extract32(ctx->opcode, 11, 4)) {
21223 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21225 gen_store_gpr(t0, rt);
21228 gen_load_gpr(t1, rt);
21229 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21238 switch (ctx->opcode & 0x03) {
21240 gen_ld(ctx, OPC_LL, rt, rs, s);
21244 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21249 switch (ctx->opcode & 0x03) {
21251 gen_st_cond(ctx, OPC_SC, rt, rs, s);
21255 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21260 check_cp0_enabled(ctx);
21261 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21262 gen_cache_operation(ctx, rt, rs, s);
21268 switch (extract32(ctx->opcode, 11, 4)) {
21271 check_cp0_enabled(ctx);
21272 gen_ld(ctx, OPC_LBE, rt, rs, s);
21276 check_cp0_enabled(ctx);
21277 gen_st(ctx, OPC_SBE, rt, rs, s);
21281 check_cp0_enabled(ctx);
21282 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21286 /* case NM_SYNCIE */
21288 check_cp0_enabled(ctx);
21289 /* Break the TB to be able to sync copied instructions
21291 ctx->base.is_jmp = DISAS_STOP;
21293 /* case NM_PREFE */
21295 check_cp0_enabled(ctx);
21296 /* Treat as NOP. */
21301 check_cp0_enabled(ctx);
21302 gen_ld(ctx, OPC_LHE, rt, rs, s);
21306 check_cp0_enabled(ctx);
21307 gen_st(ctx, OPC_SHE, rt, rs, s);
21311 check_cp0_enabled(ctx);
21312 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21315 check_nms_dl_il_sl_tl_l2c(ctx);
21316 gen_cache_operation(ctx, rt, rs, s);
21320 check_cp0_enabled(ctx);
21321 gen_ld(ctx, OPC_LWE, rt, rs, s);
21325 check_cp0_enabled(ctx);
21326 gen_st(ctx, OPC_SWE, rt, rs, s);
21329 switch (extract32(ctx->opcode, 2, 2)) {
21333 check_cp0_enabled(ctx);
21334 gen_ld(ctx, OPC_LLE, rt, rs, s);
21339 check_cp0_enabled(ctx);
21340 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21343 generate_exception_end(ctx, EXCP_RI);
21348 switch (extract32(ctx->opcode, 2, 2)) {
21352 check_cp0_enabled(ctx);
21353 gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21358 check_cp0_enabled(ctx);
21359 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21362 generate_exception_end(ctx, EXCP_RI);
21372 int count = extract32(ctx->opcode, 12, 3);
21375 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21376 extract32(ctx->opcode, 0, 8);
21377 TCGv va = tcg_temp_new();
21378 TCGv t1 = tcg_temp_new();
21379 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21380 NM_P_LS_UAWM ? MO_UNALN : 0;
21382 count = (count == 0) ? 8 : count;
21383 while (counter != count) {
21384 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21385 int this_offset = offset + (counter << 2);
21387 gen_base_offset_addr(ctx, va, rs, this_offset);
21389 switch (extract32(ctx->opcode, 11, 1)) {
21391 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21393 gen_store_gpr(t1, this_rt);
21394 if ((this_rt == rs) &&
21395 (counter != (count - 1))) {
21396 /* UNPREDICTABLE */
21400 this_rt = (rt == 0) ? 0 : this_rt;
21401 gen_load_gpr(t1, this_rt);
21402 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21413 generate_exception_end(ctx, EXCP_RI);
21421 TCGv t0 = tcg_temp_new();
21422 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21423 extract32(ctx->opcode, 1, 20) << 1;
21424 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21425 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21426 extract32(ctx->opcode, 21, 3));
21427 gen_load_gpr(t0, rt);
21428 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21429 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21435 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21436 extract32(ctx->opcode, 1, 24) << 1;
21438 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21440 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21443 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21448 switch (extract32(ctx->opcode, 12, 4)) {
21451 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21454 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21457 generate_exception_end(ctx, EXCP_RI);
21463 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21464 extract32(ctx->opcode, 1, 13) << 1;
21465 switch (extract32(ctx->opcode, 14, 2)) {
21468 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21471 s = sextract32(ctx->opcode, 0, 1) << 14 |
21472 extract32(ctx->opcode, 1, 13) << 1;
21473 check_cp1_enabled(ctx);
21474 switch (extract32(ctx->opcode, 16, 5)) {
21476 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21479 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21484 int32_t imm = extract32(ctx->opcode, 1, 13) |
21485 extract32(ctx->opcode, 0, 1) << 13;
21487 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21492 generate_exception_end(ctx, EXCP_RI);
21498 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21500 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21504 if (rs == rt || rt == 0) {
21505 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21506 } else if (rs == 0) {
21507 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21509 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21517 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21518 extract32(ctx->opcode, 1, 13) << 1;
21519 switch (extract32(ctx->opcode, 14, 2)) {
21522 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21525 if (rs != 0 && rt != 0 && rs == rt) {
21527 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21529 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21533 if (rs == 0 || rs == rt) {
21535 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21537 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21541 generate_exception_end(ctx, EXCP_RI);
21548 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21549 extract32(ctx->opcode, 1, 10) << 1;
21550 uint32_t u = extract32(ctx->opcode, 11, 7);
21552 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21557 generate_exception_end(ctx, EXCP_RI);
21563 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21566 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21567 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21568 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
21572 /* make sure instructions are on a halfword boundary */
21573 if (ctx->base.pc_next & 0x1) {
21574 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21575 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21576 tcg_temp_free(tmp);
21577 generate_exception_end(ctx, EXCP_AdEL);
21581 op = extract32(ctx->opcode, 10, 6);
21584 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21587 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21588 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21591 switch (extract32(ctx->opcode, 3, 2)) {
21592 case NM_P16_SYSCALL:
21593 if (extract32(ctx->opcode, 2, 1) == 0) {
21594 generate_exception_end(ctx, EXCP_SYSCALL);
21596 generate_exception_end(ctx, EXCP_RI);
21600 generate_exception_end(ctx, EXCP_BREAK);
21603 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21604 gen_helper_do_semihosting(cpu_env);
21606 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21607 generate_exception_end(ctx, EXCP_RI);
21609 generate_exception_end(ctx, EXCP_DBp);
21614 generate_exception_end(ctx, EXCP_RI);
21621 int shift = extract32(ctx->opcode, 0, 3);
21623 shift = (shift == 0) ? 8 : shift;
21625 switch (extract32(ctx->opcode, 3, 1)) {
21633 gen_shift_imm(ctx, opc, rt, rs, shift);
21637 switch (ctx->opcode & 1) {
21639 gen_pool16c_nanomips_insn(ctx);
21642 gen_ldxs(ctx, rt, rs, rd);
21647 switch (extract32(ctx->opcode, 6, 1)) {
21649 imm = extract32(ctx->opcode, 0, 6) << 2;
21650 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21653 generate_exception_end(ctx, EXCP_RI);
21658 switch (extract32(ctx->opcode, 3, 1)) {
21660 imm = extract32(ctx->opcode, 0, 3) << 2;
21661 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21663 case NM_P_ADDIURS5:
21664 rt = extract32(ctx->opcode, 5, 5);
21666 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21667 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21668 (extract32(ctx->opcode, 0, 3));
21669 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21675 switch (ctx->opcode & 0x1) {
21677 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21680 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21685 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21686 extract32(ctx->opcode, 5, 3);
21687 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21688 extract32(ctx->opcode, 0, 3);
21689 rt = decode_gpr_gpr4(rt);
21690 rs = decode_gpr_gpr4(rs);
21691 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21692 (extract32(ctx->opcode, 3, 1))) {
21695 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21699 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21702 generate_exception_end(ctx, EXCP_RI);
21708 int imm = extract32(ctx->opcode, 0, 7);
21709 imm = (imm == 0x7f ? -1 : imm);
21711 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21717 uint32_t u = extract32(ctx->opcode, 0, 4);
21718 u = (u == 12) ? 0xff :
21719 (u == 13) ? 0xffff : u;
21720 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21724 offset = extract32(ctx->opcode, 0, 2);
21725 switch (extract32(ctx->opcode, 2, 2)) {
21727 gen_ld(ctx, OPC_LB, rt, rs, offset);
21730 rt = decode_gpr_gpr3_src_store(
21731 NANOMIPS_EXTRACT_RD(ctx->opcode));
21732 gen_st(ctx, OPC_SB, rt, rs, offset);
21735 gen_ld(ctx, OPC_LBU, rt, rs, offset);
21738 generate_exception_end(ctx, EXCP_RI);
21743 offset = extract32(ctx->opcode, 1, 2) << 1;
21744 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21746 gen_ld(ctx, OPC_LH, rt, rs, offset);
21749 rt = decode_gpr_gpr3_src_store(
21750 NANOMIPS_EXTRACT_RD(ctx->opcode));
21751 gen_st(ctx, OPC_SH, rt, rs, offset);
21754 gen_ld(ctx, OPC_LHU, rt, rs, offset);
21757 generate_exception_end(ctx, EXCP_RI);
21762 offset = extract32(ctx->opcode, 0, 4) << 2;
21763 gen_ld(ctx, OPC_LW, rt, rs, offset);
21766 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21767 offset = extract32(ctx->opcode, 0, 5) << 2;
21768 gen_ld(ctx, OPC_LW, rt, 29, offset);
21772 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21773 extract32(ctx->opcode, 5, 3);
21774 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21775 extract32(ctx->opcode, 0, 3);
21776 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21777 (extract32(ctx->opcode, 8, 1) << 2);
21778 rt = decode_gpr_gpr4(rt);
21779 rs = decode_gpr_gpr4(rs);
21780 gen_ld(ctx, OPC_LW, rt, rs, offset);
21784 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21785 extract32(ctx->opcode, 5, 3);
21786 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21787 extract32(ctx->opcode, 0, 3);
21788 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21789 (extract32(ctx->opcode, 8, 1) << 2);
21790 rt = decode_gpr_gpr4_zero(rt);
21791 rs = decode_gpr_gpr4(rs);
21792 gen_st(ctx, OPC_SW, rt, rs, offset);
21795 offset = extract32(ctx->opcode, 0, 7) << 2;
21796 gen_ld(ctx, OPC_LW, rt, 28, offset);
21799 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21800 offset = extract32(ctx->opcode, 0, 5) << 2;
21801 gen_st(ctx, OPC_SW, rt, 29, offset);
21804 rt = decode_gpr_gpr3_src_store(
21805 NANOMIPS_EXTRACT_RD(ctx->opcode));
21806 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21807 offset = extract32(ctx->opcode, 0, 4) << 2;
21808 gen_st(ctx, OPC_SW, rt, rs, offset);
21811 rt = decode_gpr_gpr3_src_store(
21812 NANOMIPS_EXTRACT_RD(ctx->opcode));
21813 offset = extract32(ctx->opcode, 0, 7) << 2;
21814 gen_st(ctx, OPC_SW, rt, 28, offset);
21817 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21818 (sextract32(ctx->opcode, 0, 1) << 10) |
21819 (extract32(ctx->opcode, 1, 9) << 1));
21822 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21823 (sextract32(ctx->opcode, 0, 1) << 10) |
21824 (extract32(ctx->opcode, 1, 9) << 1));
21827 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21828 (sextract32(ctx->opcode, 0, 1) << 7) |
21829 (extract32(ctx->opcode, 1, 6) << 1));
21832 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21833 (sextract32(ctx->opcode, 0, 1) << 7) |
21834 (extract32(ctx->opcode, 1, 6) << 1));
21837 switch (ctx->opcode & 0xf) {
21840 switch (extract32(ctx->opcode, 4, 1)) {
21842 gen_compute_branch_nm(ctx, OPC_JR, 2,
21843 extract32(ctx->opcode, 5, 5), 0, 0);
21846 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21847 extract32(ctx->opcode, 5, 5), 31, 0);
21854 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21855 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21856 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21857 extract32(ctx->opcode, 0, 4) << 1);
21864 int count = extract32(ctx->opcode, 0, 4);
21865 int u = extract32(ctx->opcode, 4, 4) << 4;
21867 rt = 30 + extract32(ctx->opcode, 9, 1);
21868 switch (extract32(ctx->opcode, 8, 1)) {
21870 gen_save(ctx, rt, count, 0, u);
21872 case NM_RESTORE_JRC16:
21873 gen_restore(ctx, rt, count, 0, u);
21874 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21883 static const int gpr2reg1[] = {4, 5, 6, 7};
21884 static const int gpr2reg2[] = {5, 6, 7, 8};
21886 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21887 extract32(ctx->opcode, 8, 1);
21888 int r1 = gpr2reg1[rd2];
21889 int r2 = gpr2reg2[rd2];
21890 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21891 extract32(ctx->opcode, 0, 3);
21892 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21893 extract32(ctx->opcode, 5, 3);
21894 TCGv t0 = tcg_temp_new();
21895 TCGv t1 = tcg_temp_new();
21896 if (op == NM_MOVEP) {
21899 rs = decode_gpr_gpr4_zero(r3);
21900 rt = decode_gpr_gpr4_zero(r4);
21902 rd = decode_gpr_gpr4(r3);
21903 re = decode_gpr_gpr4(r4);
21907 gen_load_gpr(t0, rs);
21908 gen_load_gpr(t1, rt);
21909 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21910 tcg_gen_mov_tl(cpu_gpr[re], t1);
21916 return decode_nanomips_32_48_opc(env, ctx);
21923 /* SmartMIPS extension to MIPS32 */
21925 #if defined(TARGET_MIPS64)
21927 /* MDMX extension to MIPS64 */
21931 /* MIPSDSP functions. */
21932 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
21933 int rd, int base, int offset)
21938 t0 = tcg_temp_new();
21941 gen_load_gpr(t0, offset);
21942 } else if (offset == 0) {
21943 gen_load_gpr(t0, base);
21945 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21950 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
21951 gen_store_gpr(t0, rd);
21954 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
21955 gen_store_gpr(t0, rd);
21958 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
21959 gen_store_gpr(t0, rd);
21961 #if defined(TARGET_MIPS64)
21963 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
21964 gen_store_gpr(t0, rd);
21971 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21972 int ret, int v1, int v2)
21978 /* Treat as NOP. */
21982 v1_t = tcg_temp_new();
21983 v2_t = tcg_temp_new();
21985 gen_load_gpr(v1_t, v1);
21986 gen_load_gpr(v2_t, v2);
21989 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21990 case OPC_MULT_G_2E:
21994 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21996 case OPC_ADDUH_R_QB:
21997 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22000 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22002 case OPC_ADDQH_R_PH:
22003 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22006 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22008 case OPC_ADDQH_R_W:
22009 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22012 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22014 case OPC_SUBUH_R_QB:
22015 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22018 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22020 case OPC_SUBQH_R_PH:
22021 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22024 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22026 case OPC_SUBQH_R_W:
22027 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22031 case OPC_ABSQ_S_PH_DSP:
22033 case OPC_ABSQ_S_QB:
22035 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22037 case OPC_ABSQ_S_PH:
22039 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22043 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22045 case OPC_PRECEQ_W_PHL:
22047 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22048 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22050 case OPC_PRECEQ_W_PHR:
22052 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22053 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22054 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22056 case OPC_PRECEQU_PH_QBL:
22058 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22060 case OPC_PRECEQU_PH_QBR:
22062 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22064 case OPC_PRECEQU_PH_QBLA:
22066 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22068 case OPC_PRECEQU_PH_QBRA:
22070 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22072 case OPC_PRECEU_PH_QBL:
22074 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22076 case OPC_PRECEU_PH_QBR:
22078 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22080 case OPC_PRECEU_PH_QBLA:
22082 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22084 case OPC_PRECEU_PH_QBRA:
22086 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22090 case OPC_ADDU_QB_DSP:
22094 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22096 case OPC_ADDQ_S_PH:
22098 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22102 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22106 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22108 case OPC_ADDU_S_QB:
22110 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22114 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22116 case OPC_ADDU_S_PH:
22118 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22122 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22124 case OPC_SUBQ_S_PH:
22126 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22130 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22134 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22136 case OPC_SUBU_S_QB:
22138 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22142 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22144 case OPC_SUBU_S_PH:
22146 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22150 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22154 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22158 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22160 case OPC_RADDU_W_QB:
22162 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22166 case OPC_CMPU_EQ_QB_DSP:
22168 case OPC_PRECR_QB_PH:
22170 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22172 case OPC_PRECRQ_QB_PH:
22174 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22176 case OPC_PRECR_SRA_PH_W:
22179 TCGv_i32 sa_t = tcg_const_i32(v2);
22180 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22182 tcg_temp_free_i32(sa_t);
22185 case OPC_PRECR_SRA_R_PH_W:
22188 TCGv_i32 sa_t = tcg_const_i32(v2);
22189 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22191 tcg_temp_free_i32(sa_t);
22194 case OPC_PRECRQ_PH_W:
22196 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22198 case OPC_PRECRQ_RS_PH_W:
22200 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22202 case OPC_PRECRQU_S_QB_PH:
22204 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22208 #ifdef TARGET_MIPS64
22209 case OPC_ABSQ_S_QH_DSP:
22211 case OPC_PRECEQ_L_PWL:
22213 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22215 case OPC_PRECEQ_L_PWR:
22217 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22219 case OPC_PRECEQ_PW_QHL:
22221 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22223 case OPC_PRECEQ_PW_QHR:
22225 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22227 case OPC_PRECEQ_PW_QHLA:
22229 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22231 case OPC_PRECEQ_PW_QHRA:
22233 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22235 case OPC_PRECEQU_QH_OBL:
22237 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22239 case OPC_PRECEQU_QH_OBR:
22241 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22243 case OPC_PRECEQU_QH_OBLA:
22245 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22247 case OPC_PRECEQU_QH_OBRA:
22249 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22251 case OPC_PRECEU_QH_OBL:
22253 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22255 case OPC_PRECEU_QH_OBR:
22257 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22259 case OPC_PRECEU_QH_OBLA:
22261 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22263 case OPC_PRECEU_QH_OBRA:
22265 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22267 case OPC_ABSQ_S_OB:
22269 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22271 case OPC_ABSQ_S_PW:
22273 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22275 case OPC_ABSQ_S_QH:
22277 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22281 case OPC_ADDU_OB_DSP:
22283 case OPC_RADDU_L_OB:
22285 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22289 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22291 case OPC_SUBQ_S_PW:
22293 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22297 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22299 case OPC_SUBQ_S_QH:
22301 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22305 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22307 case OPC_SUBU_S_OB:
22309 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22313 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22315 case OPC_SUBU_S_QH:
22317 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22321 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22323 case OPC_SUBUH_R_OB:
22325 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22329 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22331 case OPC_ADDQ_S_PW:
22333 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22337 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22339 case OPC_ADDQ_S_QH:
22341 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22345 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22347 case OPC_ADDU_S_OB:
22349 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22353 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22355 case OPC_ADDU_S_QH:
22357 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22361 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22363 case OPC_ADDUH_R_OB:
22365 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22369 case OPC_CMPU_EQ_OB_DSP:
22371 case OPC_PRECR_OB_QH:
22373 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22375 case OPC_PRECR_SRA_QH_PW:
22378 TCGv_i32 ret_t = tcg_const_i32(ret);
22379 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22380 tcg_temp_free_i32(ret_t);
22383 case OPC_PRECR_SRA_R_QH_PW:
22386 TCGv_i32 sa_v = tcg_const_i32(ret);
22387 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22388 tcg_temp_free_i32(sa_v);
22391 case OPC_PRECRQ_OB_QH:
22393 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22395 case OPC_PRECRQ_PW_L:
22397 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22399 case OPC_PRECRQ_QH_PW:
22401 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22403 case OPC_PRECRQ_RS_QH_PW:
22405 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22407 case OPC_PRECRQU_S_OB_QH:
22409 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22416 tcg_temp_free(v1_t);
22417 tcg_temp_free(v2_t);
22420 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22421 int ret, int v1, int v2)
22429 /* Treat as NOP. */
22433 t0 = tcg_temp_new();
22434 v1_t = tcg_temp_new();
22435 v2_t = tcg_temp_new();
22437 tcg_gen_movi_tl(t0, v1);
22438 gen_load_gpr(v1_t, v1);
22439 gen_load_gpr(v2_t, v2);
22442 case OPC_SHLL_QB_DSP:
22444 op2 = MASK_SHLL_QB(ctx->opcode);
22448 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22452 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22456 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22460 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22462 case OPC_SHLL_S_PH:
22464 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22466 case OPC_SHLLV_S_PH:
22468 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22472 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22474 case OPC_SHLLV_S_W:
22476 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22480 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22484 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22488 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22492 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22496 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22498 case OPC_SHRA_R_QB:
22500 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22504 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22506 case OPC_SHRAV_R_QB:
22508 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22512 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22514 case OPC_SHRA_R_PH:
22516 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22520 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22522 case OPC_SHRAV_R_PH:
22524 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22528 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22530 case OPC_SHRAV_R_W:
22532 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22534 default: /* Invalid */
22535 MIPS_INVAL("MASK SHLL.QB");
22536 generate_exception_end(ctx, EXCP_RI);
22541 #ifdef TARGET_MIPS64
22542 case OPC_SHLL_OB_DSP:
22543 op2 = MASK_SHLL_OB(ctx->opcode);
22547 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22551 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22553 case OPC_SHLL_S_PW:
22555 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22557 case OPC_SHLLV_S_PW:
22559 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22563 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22567 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22571 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22575 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22577 case OPC_SHLL_S_QH:
22579 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22581 case OPC_SHLLV_S_QH:
22583 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22587 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22591 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22593 case OPC_SHRA_R_OB:
22595 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22597 case OPC_SHRAV_R_OB:
22599 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22603 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22607 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22609 case OPC_SHRA_R_PW:
22611 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22613 case OPC_SHRAV_R_PW:
22615 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22619 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22623 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22625 case OPC_SHRA_R_QH:
22627 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22629 case OPC_SHRAV_R_QH:
22631 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22635 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22639 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22643 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22647 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22649 default: /* Invalid */
22650 MIPS_INVAL("MASK SHLL.OB");
22651 generate_exception_end(ctx, EXCP_RI);
22659 tcg_temp_free(v1_t);
22660 tcg_temp_free(v2_t);
22663 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22664 int ret, int v1, int v2, int check_ret)
22670 if ((ret == 0) && (check_ret == 1)) {
22671 /* Treat as NOP. */
22675 t0 = tcg_temp_new_i32();
22676 v1_t = tcg_temp_new();
22677 v2_t = tcg_temp_new();
22679 tcg_gen_movi_i32(t0, ret);
22680 gen_load_gpr(v1_t, v1);
22681 gen_load_gpr(v2_t, v2);
22684 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22685 * the same mask and op1. */
22686 case OPC_MULT_G_2E:
22690 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22693 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22696 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22698 case OPC_MULQ_RS_W:
22699 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22703 case OPC_DPA_W_PH_DSP:
22705 case OPC_DPAU_H_QBL:
22707 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22709 case OPC_DPAU_H_QBR:
22711 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22713 case OPC_DPSU_H_QBL:
22715 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22717 case OPC_DPSU_H_QBR:
22719 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22723 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22725 case OPC_DPAX_W_PH:
22727 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22729 case OPC_DPAQ_S_W_PH:
22731 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22733 case OPC_DPAQX_S_W_PH:
22735 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22737 case OPC_DPAQX_SA_W_PH:
22739 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22743 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22745 case OPC_DPSX_W_PH:
22747 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22749 case OPC_DPSQ_S_W_PH:
22751 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22753 case OPC_DPSQX_S_W_PH:
22755 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22757 case OPC_DPSQX_SA_W_PH:
22759 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22761 case OPC_MULSAQ_S_W_PH:
22763 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22765 case OPC_DPAQ_SA_L_W:
22767 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22769 case OPC_DPSQ_SA_L_W:
22771 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22773 case OPC_MAQ_S_W_PHL:
22775 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22777 case OPC_MAQ_S_W_PHR:
22779 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22781 case OPC_MAQ_SA_W_PHL:
22783 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22785 case OPC_MAQ_SA_W_PHR:
22787 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22789 case OPC_MULSA_W_PH:
22791 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22795 #ifdef TARGET_MIPS64
22796 case OPC_DPAQ_W_QH_DSP:
22798 int ac = ret & 0x03;
22799 tcg_gen_movi_i32(t0, ac);
22804 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22808 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22812 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22816 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22820 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22822 case OPC_DPAQ_S_W_QH:
22824 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22826 case OPC_DPAQ_SA_L_PW:
22828 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22830 case OPC_DPAU_H_OBL:
22832 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22834 case OPC_DPAU_H_OBR:
22836 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22840 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22842 case OPC_DPSQ_S_W_QH:
22844 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22846 case OPC_DPSQ_SA_L_PW:
22848 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22850 case OPC_DPSU_H_OBL:
22852 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22854 case OPC_DPSU_H_OBR:
22856 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22858 case OPC_MAQ_S_L_PWL:
22860 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22862 case OPC_MAQ_S_L_PWR:
22864 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22866 case OPC_MAQ_S_W_QHLL:
22868 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22870 case OPC_MAQ_SA_W_QHLL:
22872 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22874 case OPC_MAQ_S_W_QHLR:
22876 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22878 case OPC_MAQ_SA_W_QHLR:
22880 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22882 case OPC_MAQ_S_W_QHRL:
22884 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22886 case OPC_MAQ_SA_W_QHRL:
22888 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22890 case OPC_MAQ_S_W_QHRR:
22892 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22894 case OPC_MAQ_SA_W_QHRR:
22896 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22898 case OPC_MULSAQ_S_L_PW:
22900 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22902 case OPC_MULSAQ_S_W_QH:
22904 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22910 case OPC_ADDU_QB_DSP:
22912 case OPC_MULEU_S_PH_QBL:
22914 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22916 case OPC_MULEU_S_PH_QBR:
22918 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22920 case OPC_MULQ_RS_PH:
22922 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22924 case OPC_MULEQ_S_W_PHL:
22926 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22928 case OPC_MULEQ_S_W_PHR:
22930 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22932 case OPC_MULQ_S_PH:
22934 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22938 #ifdef TARGET_MIPS64
22939 case OPC_ADDU_OB_DSP:
22941 case OPC_MULEQ_S_PW_QHL:
22943 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22945 case OPC_MULEQ_S_PW_QHR:
22947 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22949 case OPC_MULEU_S_QH_OBL:
22951 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22953 case OPC_MULEU_S_QH_OBR:
22955 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22957 case OPC_MULQ_RS_QH:
22959 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22966 tcg_temp_free_i32(t0);
22967 tcg_temp_free(v1_t);
22968 tcg_temp_free(v2_t);
22971 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22979 /* Treat as NOP. */
22983 t0 = tcg_temp_new();
22984 val_t = tcg_temp_new();
22985 gen_load_gpr(val_t, val);
22988 case OPC_ABSQ_S_PH_DSP:
22992 gen_helper_bitrev(cpu_gpr[ret], val_t);
22997 target_long result;
22998 imm = (ctx->opcode >> 16) & 0xFF;
22999 result = (uint32_t)imm << 24 |
23000 (uint32_t)imm << 16 |
23001 (uint32_t)imm << 8 |
23003 result = (int32_t)result;
23004 tcg_gen_movi_tl(cpu_gpr[ret], result);
23009 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23010 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23011 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23012 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23013 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23014 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23019 imm = (ctx->opcode >> 16) & 0x03FF;
23020 imm = (int16_t)(imm << 6) >> 6;
23021 tcg_gen_movi_tl(cpu_gpr[ret], \
23022 (target_long)((int32_t)imm << 16 | \
23028 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23029 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23030 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23031 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23035 #ifdef TARGET_MIPS64
23036 case OPC_ABSQ_S_QH_DSP:
23043 imm = (ctx->opcode >> 16) & 0xFF;
23044 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23045 temp = (temp << 16) | temp;
23046 temp = (temp << 32) | temp;
23047 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23055 imm = (ctx->opcode >> 16) & 0x03FF;
23056 imm = (int16_t)(imm << 6) >> 6;
23057 temp = ((target_long)imm << 32) \
23058 | ((target_long)imm & 0xFFFFFFFF);
23059 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23067 imm = (ctx->opcode >> 16) & 0x03FF;
23068 imm = (int16_t)(imm << 6) >> 6;
23070 temp = ((uint64_t)(uint16_t)imm << 48) |
23071 ((uint64_t)(uint16_t)imm << 32) |
23072 ((uint64_t)(uint16_t)imm << 16) |
23073 (uint64_t)(uint16_t)imm;
23074 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23079 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23080 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23081 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23082 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23083 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23084 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23085 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23089 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23090 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23091 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23095 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23096 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23097 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23098 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23099 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23106 tcg_temp_free(val_t);
23109 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23110 uint32_t op1, uint32_t op2,
23111 int ret, int v1, int v2, int check_ret)
23117 if ((ret == 0) && (check_ret == 1)) {
23118 /* Treat as NOP. */
23122 t1 = tcg_temp_new();
23123 v1_t = tcg_temp_new();
23124 v2_t = tcg_temp_new();
23126 gen_load_gpr(v1_t, v1);
23127 gen_load_gpr(v2_t, v2);
23130 case OPC_CMPU_EQ_QB_DSP:
23132 case OPC_CMPU_EQ_QB:
23134 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23136 case OPC_CMPU_LT_QB:
23138 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23140 case OPC_CMPU_LE_QB:
23142 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23144 case OPC_CMPGU_EQ_QB:
23146 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23148 case OPC_CMPGU_LT_QB:
23150 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23152 case OPC_CMPGU_LE_QB:
23154 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23156 case OPC_CMPGDU_EQ_QB:
23158 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23159 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23160 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23161 tcg_gen_shli_tl(t1, t1, 24);
23162 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23164 case OPC_CMPGDU_LT_QB:
23166 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23167 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23168 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23169 tcg_gen_shli_tl(t1, t1, 24);
23170 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23172 case OPC_CMPGDU_LE_QB:
23174 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23175 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23176 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23177 tcg_gen_shli_tl(t1, t1, 24);
23178 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23180 case OPC_CMP_EQ_PH:
23182 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23184 case OPC_CMP_LT_PH:
23186 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23188 case OPC_CMP_LE_PH:
23190 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23194 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23198 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23200 case OPC_PACKRL_PH:
23202 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23206 #ifdef TARGET_MIPS64
23207 case OPC_CMPU_EQ_OB_DSP:
23209 case OPC_CMP_EQ_PW:
23211 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23213 case OPC_CMP_LT_PW:
23215 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23217 case OPC_CMP_LE_PW:
23219 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23221 case OPC_CMP_EQ_QH:
23223 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23225 case OPC_CMP_LT_QH:
23227 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23229 case OPC_CMP_LE_QH:
23231 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23233 case OPC_CMPGDU_EQ_OB:
23235 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23237 case OPC_CMPGDU_LT_OB:
23239 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23241 case OPC_CMPGDU_LE_OB:
23243 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23245 case OPC_CMPGU_EQ_OB:
23247 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23249 case OPC_CMPGU_LT_OB:
23251 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23253 case OPC_CMPGU_LE_OB:
23255 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23257 case OPC_CMPU_EQ_OB:
23259 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23261 case OPC_CMPU_LT_OB:
23263 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23265 case OPC_CMPU_LE_OB:
23267 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23269 case OPC_PACKRL_PW:
23271 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23275 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23279 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23283 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23291 tcg_temp_free(v1_t);
23292 tcg_temp_free(v2_t);
23295 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23296 uint32_t op1, int rt, int rs, int sa)
23303 /* Treat as NOP. */
23307 t0 = tcg_temp_new();
23308 gen_load_gpr(t0, rs);
23311 case OPC_APPEND_DSP:
23312 switch (MASK_APPEND(ctx->opcode)) {
23315 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23317 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23321 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23322 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23323 tcg_gen_shli_tl(t0, t0, 32 - sa);
23324 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23326 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23330 if (sa != 0 && sa != 2) {
23331 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23332 tcg_gen_ext32u_tl(t0, t0);
23333 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23334 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23336 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23338 default: /* Invalid */
23339 MIPS_INVAL("MASK APPEND");
23340 generate_exception_end(ctx, EXCP_RI);
23344 #ifdef TARGET_MIPS64
23345 case OPC_DAPPEND_DSP:
23346 switch (MASK_DAPPEND(ctx->opcode)) {
23349 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23353 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23354 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23355 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23359 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23360 tcg_gen_shli_tl(t0, t0, 64 - sa);
23361 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23366 if (sa != 0 && sa != 2 && sa != 4) {
23367 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23368 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23369 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23372 default: /* Invalid */
23373 MIPS_INVAL("MASK DAPPEND");
23374 generate_exception_end(ctx, EXCP_RI);
23383 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23384 int ret, int v1, int v2, int check_ret)
23393 if ((ret == 0) && (check_ret == 1)) {
23394 /* Treat as NOP. */
23398 t0 = tcg_temp_new();
23399 t1 = tcg_temp_new();
23400 v1_t = tcg_temp_new();
23401 v2_t = tcg_temp_new();
23403 gen_load_gpr(v1_t, v1);
23404 gen_load_gpr(v2_t, v2);
23407 case OPC_EXTR_W_DSP:
23411 tcg_gen_movi_tl(t0, v2);
23412 tcg_gen_movi_tl(t1, v1);
23413 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23416 tcg_gen_movi_tl(t0, v2);
23417 tcg_gen_movi_tl(t1, v1);
23418 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23420 case OPC_EXTR_RS_W:
23421 tcg_gen_movi_tl(t0, v2);
23422 tcg_gen_movi_tl(t1, v1);
23423 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23426 tcg_gen_movi_tl(t0, v2);
23427 tcg_gen_movi_tl(t1, v1);
23428 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23430 case OPC_EXTRV_S_H:
23431 tcg_gen_movi_tl(t0, v2);
23432 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23435 tcg_gen_movi_tl(t0, v2);
23436 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23438 case OPC_EXTRV_R_W:
23439 tcg_gen_movi_tl(t0, v2);
23440 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23442 case OPC_EXTRV_RS_W:
23443 tcg_gen_movi_tl(t0, v2);
23444 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23447 tcg_gen_movi_tl(t0, v2);
23448 tcg_gen_movi_tl(t1, v1);
23449 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23452 tcg_gen_movi_tl(t0, v2);
23453 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23456 tcg_gen_movi_tl(t0, v2);
23457 tcg_gen_movi_tl(t1, v1);
23458 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23461 tcg_gen_movi_tl(t0, v2);
23462 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23465 imm = (ctx->opcode >> 20) & 0x3F;
23466 tcg_gen_movi_tl(t0, ret);
23467 tcg_gen_movi_tl(t1, imm);
23468 gen_helper_shilo(t0, t1, cpu_env);
23471 tcg_gen_movi_tl(t0, ret);
23472 gen_helper_shilo(t0, v1_t, cpu_env);
23475 tcg_gen_movi_tl(t0, ret);
23476 gen_helper_mthlip(t0, v1_t, cpu_env);
23479 imm = (ctx->opcode >> 11) & 0x3FF;
23480 tcg_gen_movi_tl(t0, imm);
23481 gen_helper_wrdsp(v1_t, t0, cpu_env);
23484 imm = (ctx->opcode >> 16) & 0x03FF;
23485 tcg_gen_movi_tl(t0, imm);
23486 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23490 #ifdef TARGET_MIPS64
23491 case OPC_DEXTR_W_DSP:
23495 tcg_gen_movi_tl(t0, ret);
23496 gen_helper_dmthlip(v1_t, t0, cpu_env);
23500 int shift = (ctx->opcode >> 19) & 0x7F;
23501 int ac = (ctx->opcode >> 11) & 0x03;
23502 tcg_gen_movi_tl(t0, shift);
23503 tcg_gen_movi_tl(t1, ac);
23504 gen_helper_dshilo(t0, t1, cpu_env);
23509 int ac = (ctx->opcode >> 11) & 0x03;
23510 tcg_gen_movi_tl(t0, ac);
23511 gen_helper_dshilo(v1_t, t0, cpu_env);
23515 tcg_gen_movi_tl(t0, v2);
23516 tcg_gen_movi_tl(t1, v1);
23518 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23521 tcg_gen_movi_tl(t0, v2);
23522 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23525 tcg_gen_movi_tl(t0, v2);
23526 tcg_gen_movi_tl(t1, v1);
23527 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23530 tcg_gen_movi_tl(t0, v2);
23531 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23534 tcg_gen_movi_tl(t0, v2);
23535 tcg_gen_movi_tl(t1, v1);
23536 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23538 case OPC_DEXTR_R_L:
23539 tcg_gen_movi_tl(t0, v2);
23540 tcg_gen_movi_tl(t1, v1);
23541 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23543 case OPC_DEXTR_RS_L:
23544 tcg_gen_movi_tl(t0, v2);
23545 tcg_gen_movi_tl(t1, v1);
23546 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23549 tcg_gen_movi_tl(t0, v2);
23550 tcg_gen_movi_tl(t1, v1);
23551 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23553 case OPC_DEXTR_R_W:
23554 tcg_gen_movi_tl(t0, v2);
23555 tcg_gen_movi_tl(t1, v1);
23556 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23558 case OPC_DEXTR_RS_W:
23559 tcg_gen_movi_tl(t0, v2);
23560 tcg_gen_movi_tl(t1, v1);
23561 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23563 case OPC_DEXTR_S_H:
23564 tcg_gen_movi_tl(t0, v2);
23565 tcg_gen_movi_tl(t1, v1);
23566 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23568 case OPC_DEXTRV_S_H:
23569 tcg_gen_movi_tl(t0, v2);
23570 tcg_gen_movi_tl(t1, v1);
23571 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23574 tcg_gen_movi_tl(t0, v2);
23575 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23577 case OPC_DEXTRV_R_L:
23578 tcg_gen_movi_tl(t0, v2);
23579 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23581 case OPC_DEXTRV_RS_L:
23582 tcg_gen_movi_tl(t0, v2);
23583 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23586 tcg_gen_movi_tl(t0, v2);
23587 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23589 case OPC_DEXTRV_R_W:
23590 tcg_gen_movi_tl(t0, v2);
23591 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23593 case OPC_DEXTRV_RS_W:
23594 tcg_gen_movi_tl(t0, v2);
23595 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23604 tcg_temp_free(v1_t);
23605 tcg_temp_free(v2_t);
23608 /* End MIPSDSP functions. */
23610 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23612 int rs, rt, rd, sa;
23615 rs = (ctx->opcode >> 21) & 0x1f;
23616 rt = (ctx->opcode >> 16) & 0x1f;
23617 rd = (ctx->opcode >> 11) & 0x1f;
23618 sa = (ctx->opcode >> 6) & 0x1f;
23620 op1 = MASK_SPECIAL(ctx->opcode);
23623 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23629 op2 = MASK_R6_MULDIV(ctx->opcode);
23639 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23642 MIPS_INVAL("special_r6 muldiv");
23643 generate_exception_end(ctx, EXCP_RI);
23649 gen_cond_move(ctx, op1, rd, rs, rt);
23653 if (rt == 0 && sa == 1) {
23654 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23655 We need additionally to check other fields */
23656 gen_cl(ctx, op1, rd, rs);
23658 generate_exception_end(ctx, EXCP_RI);
23662 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23663 gen_helper_do_semihosting(cpu_env);
23665 if (ctx->hflags & MIPS_HFLAG_SBRI) {
23666 generate_exception_end(ctx, EXCP_RI);
23668 generate_exception_end(ctx, EXCP_DBp);
23672 #if defined(TARGET_MIPS64)
23674 check_mips_64(ctx);
23675 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23679 if (rt == 0 && sa == 1) {
23680 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23681 We need additionally to check other fields */
23682 check_mips_64(ctx);
23683 gen_cl(ctx, op1, rd, rs);
23685 generate_exception_end(ctx, EXCP_RI);
23693 op2 = MASK_R6_MULDIV(ctx->opcode);
23703 check_mips_64(ctx);
23704 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23707 MIPS_INVAL("special_r6 muldiv");
23708 generate_exception_end(ctx, EXCP_RI);
23713 default: /* Invalid */
23714 MIPS_INVAL("special_r6");
23715 generate_exception_end(ctx, EXCP_RI);
23720 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23722 int rs, rt, rd, sa;
23725 rs = (ctx->opcode >> 21) & 0x1f;
23726 rt = (ctx->opcode >> 16) & 0x1f;
23727 rd = (ctx->opcode >> 11) & 0x1f;
23728 sa = (ctx->opcode >> 6) & 0x1f;
23730 op1 = MASK_SPECIAL(ctx->opcode);
23732 case OPC_MOVN: /* Conditional move */
23734 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
23735 INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900);
23736 gen_cond_move(ctx, op1, rd, rs, rt);
23738 case OPC_MFHI: /* Move from HI/LO */
23740 gen_HILO(ctx, op1, rs & 3, rd);
23743 case OPC_MTLO: /* Move to HI/LO */
23744 gen_HILO(ctx, op1, rd & 3, rs);
23747 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23748 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23749 check_cp1_enabled(ctx);
23750 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23751 (ctx->opcode >> 16) & 1);
23753 generate_exception_err(ctx, EXCP_CpU, 1);
23759 check_insn(ctx, INSN_VR54XX);
23760 op1 = MASK_MUL_VR54XX(ctx->opcode);
23761 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23762 } else if (ctx->insn_flags & INSN_R5900) {
23763 gen_mul_txx9(ctx, op1, rd, rs, rt);
23765 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23770 gen_muldiv(ctx, op1, 0, rs, rt);
23772 #if defined(TARGET_MIPS64)
23777 check_insn(ctx, ISA_MIPS3);
23778 check_insn_opc_user_only(ctx, INSN_R5900);
23779 check_mips_64(ctx);
23780 gen_muldiv(ctx, op1, 0, rs, rt);
23784 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23787 #ifdef MIPS_STRICT_STANDARD
23788 MIPS_INVAL("SPIM");
23789 generate_exception_end(ctx, EXCP_RI);
23791 /* Implemented as RI exception for now. */
23792 MIPS_INVAL("spim (unofficial)");
23793 generate_exception_end(ctx, EXCP_RI);
23796 default: /* Invalid */
23797 MIPS_INVAL("special_legacy");
23798 generate_exception_end(ctx, EXCP_RI);
23803 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
23805 int rs, rt, rd, sa;
23808 rs = (ctx->opcode >> 21) & 0x1f;
23809 rt = (ctx->opcode >> 16) & 0x1f;
23810 rd = (ctx->opcode >> 11) & 0x1f;
23811 sa = (ctx->opcode >> 6) & 0x1f;
23813 op1 = MASK_SPECIAL(ctx->opcode);
23815 case OPC_SLL: /* Shift with immediate */
23816 if (sa == 5 && rd == 0 &&
23817 rs == 0 && rt == 0) { /* PAUSE */
23818 if ((ctx->insn_flags & ISA_MIPS32R6) &&
23819 (ctx->hflags & MIPS_HFLAG_BMASK)) {
23820 generate_exception_end(ctx, EXCP_RI);
23826 gen_shift_imm(ctx, op1, rd, rt, sa);
23829 switch ((ctx->opcode >> 21) & 0x1f) {
23831 /* rotr is decoded as srl on non-R2 CPUs */
23832 if (ctx->insn_flags & ISA_MIPS32R2) {
23837 gen_shift_imm(ctx, op1, rd, rt, sa);
23840 generate_exception_end(ctx, EXCP_RI);
23848 gen_arith(ctx, op1, rd, rs, rt);
23850 case OPC_SLLV: /* Shifts */
23852 gen_shift(ctx, op1, rd, rs, rt);
23855 switch ((ctx->opcode >> 6) & 0x1f) {
23857 /* rotrv is decoded as srlv on non-R2 CPUs */
23858 if (ctx->insn_flags & ISA_MIPS32R2) {
23863 gen_shift(ctx, op1, rd, rs, rt);
23866 generate_exception_end(ctx, EXCP_RI);
23870 case OPC_SLT: /* Set on less than */
23872 gen_slt(ctx, op1, rd, rs, rt);
23874 case OPC_AND: /* Logic*/
23878 gen_logic(ctx, op1, rd, rs, rt);
23881 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23883 case OPC_TGE: /* Traps */
23889 check_insn(ctx, ISA_MIPS2);
23890 gen_trap(ctx, op1, rs, rt, -1);
23892 case OPC_LSA: /* OPC_PMON */
23893 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23894 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23895 decode_opc_special_r6(env, ctx);
23897 /* Pmon entry point, also R4010 selsl */
23898 #ifdef MIPS_STRICT_STANDARD
23899 MIPS_INVAL("PMON / selsl");
23900 generate_exception_end(ctx, EXCP_RI);
23902 gen_helper_0e0i(pmon, sa);
23907 generate_exception_end(ctx, EXCP_SYSCALL);
23910 generate_exception_end(ctx, EXCP_BREAK);
23913 check_insn(ctx, ISA_MIPS2);
23914 gen_sync(extract32(ctx->opcode, 6, 5));
23917 #if defined(TARGET_MIPS64)
23918 /* MIPS64 specific opcodes */
23923 check_insn(ctx, ISA_MIPS3);
23924 check_mips_64(ctx);
23925 gen_shift_imm(ctx, op1, rd, rt, sa);
23928 switch ((ctx->opcode >> 21) & 0x1f) {
23930 /* drotr is decoded as dsrl on non-R2 CPUs */
23931 if (ctx->insn_flags & ISA_MIPS32R2) {
23936 check_insn(ctx, ISA_MIPS3);
23937 check_mips_64(ctx);
23938 gen_shift_imm(ctx, op1, rd, rt, sa);
23941 generate_exception_end(ctx, EXCP_RI);
23946 switch ((ctx->opcode >> 21) & 0x1f) {
23948 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23949 if (ctx->insn_flags & ISA_MIPS32R2) {
23954 check_insn(ctx, ISA_MIPS3);
23955 check_mips_64(ctx);
23956 gen_shift_imm(ctx, op1, rd, rt, sa);
23959 generate_exception_end(ctx, EXCP_RI);
23967 check_insn(ctx, ISA_MIPS3);
23968 check_mips_64(ctx);
23969 gen_arith(ctx, op1, rd, rs, rt);
23973 check_insn(ctx, ISA_MIPS3);
23974 check_mips_64(ctx);
23975 gen_shift(ctx, op1, rd, rs, rt);
23978 switch ((ctx->opcode >> 6) & 0x1f) {
23980 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23981 if (ctx->insn_flags & ISA_MIPS32R2) {
23986 check_insn(ctx, ISA_MIPS3);
23987 check_mips_64(ctx);
23988 gen_shift(ctx, op1, rd, rs, rt);
23991 generate_exception_end(ctx, EXCP_RI);
23996 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23997 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23998 decode_opc_special_r6(env, ctx);
24003 if (ctx->insn_flags & ISA_MIPS32R6) {
24004 decode_opc_special_r6(env, ctx);
24006 decode_opc_special_legacy(env, ctx);
24012 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24013 #define MXU_APTN1_A 0
24014 #define MXU_APTN1_S 1
24016 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24017 #define MXU_APTN2_AA 0
24018 #define MXU_APTN2_AS 1
24019 #define MXU_APTN2_SA 2
24020 #define MXU_APTN2_SS 3
24022 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24023 #define MXU_EPTN2_AA 0
24024 #define MXU_EPTN2_AS 1
24025 #define MXU_EPTN2_SA 2
24026 #define MXU_EPTN2_SS 3
24028 /* MXU operand getting pattern 'optn2' */
24029 #define MXU_OPTN2_WW 0
24030 #define MXU_OPTN2_LW 1
24031 #define MXU_OPTN2_HW 2
24032 #define MXU_OPTN2_XW 3
24034 /* MXU operand getting pattern 'optn3' */
24035 #define MXU_OPTN3_PTN0 0
24036 #define MXU_OPTN3_PTN1 1
24037 #define MXU_OPTN3_PTN2 2
24038 #define MXU_OPTN3_PTN3 3
24039 #define MXU_OPTN3_PTN4 4
24040 #define MXU_OPTN3_PTN5 5
24041 #define MXU_OPTN3_PTN6 6
24042 #define MXU_OPTN3_PTN7 7
24046 * S32I2M XRa, rb - Register move from GRF to XRF
24048 static void gen_mxu_s32i2m(DisasContext *ctx)
24053 t0 = tcg_temp_new();
24055 XRa = extract32(ctx->opcode, 6, 5);
24056 Rb = extract32(ctx->opcode, 16, 5);
24058 gen_load_gpr(t0, Rb);
24060 gen_store_mxu_gpr(t0, XRa);
24061 } else if (XRa == 16) {
24062 gen_store_mxu_cr(t0);
24069 * S32M2I XRa, rb - Register move from XRF to GRF
24071 static void gen_mxu_s32m2i(DisasContext *ctx)
24076 t0 = tcg_temp_new();
24078 XRa = extract32(ctx->opcode, 6, 5);
24079 Rb = extract32(ctx->opcode, 16, 5);
24082 gen_load_mxu_gpr(t0, XRa);
24083 } else if (XRa == 16) {
24084 gen_load_mxu_cr(t0);
24087 gen_store_gpr(t0, Rb);
24094 * Decoding engine for MXU
24095 * =======================
24100 * Decode MXU pool00
24102 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24103 * +-----------+---------+-----+-------+-------+-------+-----------+
24104 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
24105 * +-----------+---------+-----+-------+-------+-------+-----------+
24108 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
24110 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24113 case OPC_MXU_S32MAX:
24114 /* TODO: Implement emulation of S32MAX instruction. */
24115 MIPS_INVAL("OPC_MXU_S32MAX");
24116 generate_exception_end(ctx, EXCP_RI);
24118 case OPC_MXU_S32MIN:
24119 /* TODO: Implement emulation of S32MIN instruction. */
24120 MIPS_INVAL("OPC_MXU_S32MIN");
24121 generate_exception_end(ctx, EXCP_RI);
24123 case OPC_MXU_D16MAX:
24124 /* TODO: Implement emulation of D16MAX instruction. */
24125 MIPS_INVAL("OPC_MXU_D16MAX");
24126 generate_exception_end(ctx, EXCP_RI);
24128 case OPC_MXU_D16MIN:
24129 /* TODO: Implement emulation of D16MIN instruction. */
24130 MIPS_INVAL("OPC_MXU_D16MIN");
24131 generate_exception_end(ctx, EXCP_RI);
24133 case OPC_MXU_Q8MAX:
24134 /* TODO: Implement emulation of Q8MAX instruction. */
24135 MIPS_INVAL("OPC_MXU_Q8MAX");
24136 generate_exception_end(ctx, EXCP_RI);
24138 case OPC_MXU_Q8MIN:
24139 /* TODO: Implement emulation of Q8MIN instruction. */
24140 MIPS_INVAL("OPC_MXU_Q8MIN");
24141 generate_exception_end(ctx, EXCP_RI);
24143 case OPC_MXU_Q8SLT:
24144 /* TODO: Implement emulation of Q8SLT instruction. */
24145 MIPS_INVAL("OPC_MXU_Q8SLT");
24146 generate_exception_end(ctx, EXCP_RI);
24148 case OPC_MXU_Q8SLTU:
24149 /* TODO: Implement emulation of Q8SLTU instruction. */
24150 MIPS_INVAL("OPC_MXU_Q8SLTU");
24151 generate_exception_end(ctx, EXCP_RI);
24154 MIPS_INVAL("decode_opc_mxu");
24155 generate_exception_end(ctx, EXCP_RI);
24162 * Decode MXU pool01
24164 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
24165 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24166 * +-----------+---------+-----+-------+-------+-------+-----------+
24167 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
24168 * +-----------+---------+-----+-------+-------+-------+-----------+
24171 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24172 * +-----------+---+-----+-----+-------+-------+-------+-----------+
24173 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
24174 * +-----------+---+-----+-----+-------+-------+-------+-----------+
24177 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
24179 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24182 case OPC_MXU_S32SLT:
24183 /* TODO: Implement emulation of S32SLT instruction. */
24184 MIPS_INVAL("OPC_MXU_S32SLT");
24185 generate_exception_end(ctx, EXCP_RI);
24187 case OPC_MXU_D16SLT:
24188 /* TODO: Implement emulation of D16SLT instruction. */
24189 MIPS_INVAL("OPC_MXU_D16SLT");
24190 generate_exception_end(ctx, EXCP_RI);
24192 case OPC_MXU_D16AVG:
24193 /* TODO: Implement emulation of D16AVG instruction. */
24194 MIPS_INVAL("OPC_MXU_D16AVG");
24195 generate_exception_end(ctx, EXCP_RI);
24197 case OPC_MXU_D16AVGR:
24198 /* TODO: Implement emulation of D16AVGR instruction. */
24199 MIPS_INVAL("OPC_MXU_D16AVGR");
24200 generate_exception_end(ctx, EXCP_RI);
24202 case OPC_MXU_Q8AVG:
24203 /* TODO: Implement emulation of Q8AVG instruction. */
24204 MIPS_INVAL("OPC_MXU_Q8AVG");
24205 generate_exception_end(ctx, EXCP_RI);
24207 case OPC_MXU_Q8AVGR:
24208 /* TODO: Implement emulation of Q8AVGR instruction. */
24209 MIPS_INVAL("OPC_MXU_Q8AVGR");
24210 generate_exception_end(ctx, EXCP_RI);
24212 case OPC_MXU_Q8ADD:
24213 /* TODO: Implement emulation of Q8ADD instruction. */
24214 MIPS_INVAL("OPC_MXU_Q8ADD");
24215 generate_exception_end(ctx, EXCP_RI);
24218 MIPS_INVAL("decode_opc_mxu");
24219 generate_exception_end(ctx, EXCP_RI);
24226 * Decode MXU pool02
24228 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24229 * +-----------+---------+-----+-------+-------+-------+-----------+
24230 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
24231 * +-----------+---------+-----+-------+-------+-------+-----------+
24234 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
24236 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24239 case OPC_MXU_S32CPS:
24240 /* TODO: Implement emulation of S32CPS instruction. */
24241 MIPS_INVAL("OPC_MXU_S32CPS");
24242 generate_exception_end(ctx, EXCP_RI);
24244 case OPC_MXU_D16CPS:
24245 /* TODO: Implement emulation of D16CPS instruction. */
24246 MIPS_INVAL("OPC_MXU_D16CPS");
24247 generate_exception_end(ctx, EXCP_RI);
24249 case OPC_MXU_Q8ABD:
24250 /* TODO: Implement emulation of Q8ABD instruction. */
24251 MIPS_INVAL("OPC_MXU_Q8ABD");
24252 generate_exception_end(ctx, EXCP_RI);
24254 case OPC_MXU_Q16SAT:
24255 /* TODO: Implement emulation of Q16SAT instruction. */
24256 MIPS_INVAL("OPC_MXU_Q16SAT");
24257 generate_exception_end(ctx, EXCP_RI);
24260 MIPS_INVAL("decode_opc_mxu");
24261 generate_exception_end(ctx, EXCP_RI);
24268 * Decode MXU pool03
24271 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24272 * +-----------+---+---+-------+-------+-------+-------+-----------+
24273 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
24274 * +-----------+---+---+-------+-------+-------+-------+-----------+
24277 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24278 * +-----------+---+---+-------+-------+-------+-------+-----------+
24279 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
24280 * +-----------+---+---+-------+-------+-------+-------+-----------+
24283 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
24285 uint32_t opcode = extract32(ctx->opcode, 24, 2);
24288 case OPC_MXU_D16MULF:
24289 /* TODO: Implement emulation of D16MULF instruction. */
24290 MIPS_INVAL("OPC_MXU_D16MULF");
24291 generate_exception_end(ctx, EXCP_RI);
24293 case OPC_MXU_D16MULE:
24294 /* TODO: Implement emulation of D16MULE instruction. */
24295 MIPS_INVAL("OPC_MXU_D16MULE");
24296 generate_exception_end(ctx, EXCP_RI);
24299 MIPS_INVAL("decode_opc_mxu");
24300 generate_exception_end(ctx, EXCP_RI);
24307 * Decode MXU pool04
24309 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24310 * +-----------+---------+-+-------------------+-------+-----------+
24311 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
24312 * +-----------+---------+-+-------------------+-------+-----------+
24315 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
24317 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24320 case OPC_MXU_S32LDD:
24321 /* TODO: Implement emulation of S32LDD instruction. */
24322 MIPS_INVAL("OPC_MXU_S32LDD");
24323 generate_exception_end(ctx, EXCP_RI);
24325 case OPC_MXU_S32LDDR:
24326 /* TODO: Implement emulation of S32LDDR instruction. */
24327 MIPS_INVAL("OPC_MXU_S32LDDR");
24328 generate_exception_end(ctx, EXCP_RI);
24331 MIPS_INVAL("decode_opc_mxu");
24332 generate_exception_end(ctx, EXCP_RI);
24339 * Decode MXU pool05
24341 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24342 * +-----------+---------+-+-------------------+-------+-----------+
24343 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
24344 * +-----------+---------+-+-------------------+-------+-----------+
24347 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
24349 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24352 case OPC_MXU_S32STD:
24353 /* TODO: Implement emulation of S32STD instruction. */
24354 MIPS_INVAL("OPC_MXU_S32STD");
24355 generate_exception_end(ctx, EXCP_RI);
24357 case OPC_MXU_S32STDR:
24358 /* TODO: Implement emulation of S32STDR instruction. */
24359 MIPS_INVAL("OPC_MXU_S32STDR");
24360 generate_exception_end(ctx, EXCP_RI);
24363 MIPS_INVAL("decode_opc_mxu");
24364 generate_exception_end(ctx, EXCP_RI);
24371 * Decode MXU pool06
24373 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24374 * +-----------+---------+---------+---+-------+-------+-----------+
24375 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
24376 * +-----------+---------+---------+---+-------+-------+-----------+
24379 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
24381 uint32_t opcode = extract32(ctx->opcode, 10, 4);
24384 case OPC_MXU_S32LDDV:
24385 /* TODO: Implement emulation of S32LDDV instruction. */
24386 MIPS_INVAL("OPC_MXU_S32LDDV");
24387 generate_exception_end(ctx, EXCP_RI);
24389 case OPC_MXU_S32LDDVR:
24390 /* TODO: Implement emulation of S32LDDVR instruction. */
24391 MIPS_INVAL("OPC_MXU_S32LDDVR");
24392 generate_exception_end(ctx, EXCP_RI);
24395 MIPS_INVAL("decode_opc_mxu");
24396 generate_exception_end(ctx, EXCP_RI);
24403 * Decode MXU pool07
24405 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24406 * +-----------+---------+---------+---+-------+-------+-----------+
24407 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
24408 * +-----------+---------+---------+---+-------+-------+-----------+
24411 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
24413 uint32_t opcode = extract32(ctx->opcode, 10, 4);
24416 case OPC_MXU_S32STDV:
24417 /* TODO: Implement emulation of S32TDV instruction. */
24418 MIPS_INVAL("OPC_MXU_S32TDV");
24419 generate_exception_end(ctx, EXCP_RI);
24421 case OPC_MXU_S32STDVR:
24422 /* TODO: Implement emulation of S32TDVR instruction. */
24423 MIPS_INVAL("OPC_MXU_S32TDVR");
24424 generate_exception_end(ctx, EXCP_RI);
24427 MIPS_INVAL("decode_opc_mxu");
24428 generate_exception_end(ctx, EXCP_RI);
24435 * Decode MXU pool08
24437 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24438 * +-----------+---------+-+-------------------+-------+-----------+
24439 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
24440 * +-----------+---------+-+-------------------+-------+-----------+
24443 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
24445 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24448 case OPC_MXU_S32LDI:
24449 /* TODO: Implement emulation of S32LDI instruction. */
24450 MIPS_INVAL("OPC_MXU_S32LDI");
24451 generate_exception_end(ctx, EXCP_RI);
24453 case OPC_MXU_S32LDIR:
24454 /* TODO: Implement emulation of S32LDIR instruction. */
24455 MIPS_INVAL("OPC_MXU_S32LDIR");
24456 generate_exception_end(ctx, EXCP_RI);
24459 MIPS_INVAL("decode_opc_mxu");
24460 generate_exception_end(ctx, EXCP_RI);
24467 * Decode MXU pool09
24469 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24470 * +-----------+---------+-+-------------------+-------+-----------+
24471 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
24472 * +-----------+---------+-+-------------------+-------+-----------+
24475 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
24477 uint32_t opcode = extract32(ctx->opcode, 5, 0);
24480 case OPC_MXU_S32SDI:
24481 /* TODO: Implement emulation of S32SDI instruction. */
24482 MIPS_INVAL("OPC_MXU_S32SDI");
24483 generate_exception_end(ctx, EXCP_RI);
24485 case OPC_MXU_S32SDIR:
24486 /* TODO: Implement emulation of S32SDIR instruction. */
24487 MIPS_INVAL("OPC_MXU_S32SDIR");
24488 generate_exception_end(ctx, EXCP_RI);
24491 MIPS_INVAL("decode_opc_mxu");
24492 generate_exception_end(ctx, EXCP_RI);
24499 * Decode MXU pool10
24501 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24502 * +-----------+---------+---------+---+-------+-------+-----------+
24503 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
24504 * +-----------+---------+---------+---+-------+-------+-----------+
24507 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
24509 uint32_t opcode = extract32(ctx->opcode, 5, 0);
24512 case OPC_MXU_S32LDIV:
24513 /* TODO: Implement emulation of S32LDIV instruction. */
24514 MIPS_INVAL("OPC_MXU_S32LDIV");
24515 generate_exception_end(ctx, EXCP_RI);
24517 case OPC_MXU_S32LDIVR:
24518 /* TODO: Implement emulation of S32LDIVR instruction. */
24519 MIPS_INVAL("OPC_MXU_S32LDIVR");
24520 generate_exception_end(ctx, EXCP_RI);
24523 MIPS_INVAL("decode_opc_mxu");
24524 generate_exception_end(ctx, EXCP_RI);
24531 * Decode MXU pool11
24533 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24534 * +-----------+---------+---------+---+-------+-------+-----------+
24535 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
24536 * +-----------+---------+---------+---+-------+-------+-----------+
24539 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
24541 uint32_t opcode = extract32(ctx->opcode, 10, 4);
24544 case OPC_MXU_S32SDIV:
24545 /* TODO: Implement emulation of S32SDIV instruction. */
24546 MIPS_INVAL("OPC_MXU_S32SDIV");
24547 generate_exception_end(ctx, EXCP_RI);
24549 case OPC_MXU_S32SDIVR:
24550 /* TODO: Implement emulation of S32SDIVR instruction. */
24551 MIPS_INVAL("OPC_MXU_S32SDIVR");
24552 generate_exception_end(ctx, EXCP_RI);
24555 MIPS_INVAL("decode_opc_mxu");
24556 generate_exception_end(ctx, EXCP_RI);
24563 * Decode MXU pool12
24565 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24566 * +-----------+---+---+-------+-------+-------+-------+-----------+
24567 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
24568 * +-----------+---+---+-------+-------+-------+-------+-----------+
24571 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
24573 uint32_t opcode = extract32(ctx->opcode, 22, 2);
24576 case OPC_MXU_D32ACC:
24577 /* TODO: Implement emulation of D32ACC instruction. */
24578 MIPS_INVAL("OPC_MXU_D32ACC");
24579 generate_exception_end(ctx, EXCP_RI);
24581 case OPC_MXU_D32ACCM:
24582 /* TODO: Implement emulation of D32ACCM instruction. */
24583 MIPS_INVAL("OPC_MXU_D32ACCM");
24584 generate_exception_end(ctx, EXCP_RI);
24586 case OPC_MXU_D32ASUM:
24587 /* TODO: Implement emulation of D32ASUM instruction. */
24588 MIPS_INVAL("OPC_MXU_D32ASUM");
24589 generate_exception_end(ctx, EXCP_RI);
24592 MIPS_INVAL("decode_opc_mxu");
24593 generate_exception_end(ctx, EXCP_RI);
24600 * Decode MXU pool13
24602 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24603 * +-----------+---+---+-------+-------+-------+-------+-----------+
24604 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
24605 * +-----------+---+---+-------+-------+-------+-------+-----------+
24608 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
24610 uint32_t opcode = extract32(ctx->opcode, 22, 2);
24613 case OPC_MXU_Q16ACC:
24614 /* TODO: Implement emulation of Q16ACC instruction. */
24615 MIPS_INVAL("OPC_MXU_Q16ACC");
24616 generate_exception_end(ctx, EXCP_RI);
24618 case OPC_MXU_Q16ACCM:
24619 /* TODO: Implement emulation of Q16ACCM instruction. */
24620 MIPS_INVAL("OPC_MXU_Q16ACCM");
24621 generate_exception_end(ctx, EXCP_RI);
24623 case OPC_MXU_Q16ASUM:
24624 /* TODO: Implement emulation of Q16ASUM instruction. */
24625 MIPS_INVAL("OPC_MXU_Q16ASUM");
24626 generate_exception_end(ctx, EXCP_RI);
24629 MIPS_INVAL("decode_opc_mxu");
24630 generate_exception_end(ctx, EXCP_RI);
24637 * Decode MXU pool14
24640 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24641 * +-----------+---+---+-------+-------+-------+-------+-----------+
24642 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
24643 * +-----------+---+---+-------+-------+-------+-------+-----------+
24646 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24647 * +-----------+---+---+-------+-------+-------+-------+-----------+
24648 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
24649 * +-----------+---+---+-------+-------+-------+-------+-----------+
24652 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
24654 uint32_t opcode = extract32(ctx->opcode, 22, 2);
24657 case OPC_MXU_Q8ADDE:
24658 /* TODO: Implement emulation of Q8ADDE instruction. */
24659 MIPS_INVAL("OPC_MXU_Q8ADDE");
24660 generate_exception_end(ctx, EXCP_RI);
24662 case OPC_MXU_D8SUM:
24663 /* TODO: Implement emulation of D8SUM instruction. */
24664 MIPS_INVAL("OPC_MXU_D8SUM");
24665 generate_exception_end(ctx, EXCP_RI);
24667 case OPC_MXU_D8SUMC:
24668 /* TODO: Implement emulation of D8SUMC instruction. */
24669 MIPS_INVAL("OPC_MXU_D8SUMC");
24670 generate_exception_end(ctx, EXCP_RI);
24673 MIPS_INVAL("decode_opc_mxu");
24674 generate_exception_end(ctx, EXCP_RI);
24681 * Decode MXU pool15
24683 * S32MUL, S32MULU, S32EXTRV:
24684 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24685 * +-----------+---------+---------+---+-------+-------+-----------+
24686 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
24687 * +-----------+---------+---------+---+-------+-------+-----------+
24690 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24691 * +-----------+---------+---------+---+-------+-------+-----------+
24692 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
24693 * +-----------+---------+---------+---+-------+-------+-----------+
24696 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
24698 uint32_t opcode = extract32(ctx->opcode, 14, 2);
24701 case OPC_MXU_S32MUL:
24702 /* TODO: Implement emulation of S32MUL instruction. */
24703 MIPS_INVAL("OPC_MXU_S32MUL");
24704 generate_exception_end(ctx, EXCP_RI);
24706 case OPC_MXU_S32MULU:
24707 /* TODO: Implement emulation of S32MULU instruction. */
24708 MIPS_INVAL("OPC_MXU_S32MULU");
24709 generate_exception_end(ctx, EXCP_RI);
24711 case OPC_MXU_S32EXTR:
24712 /* TODO: Implement emulation of S32EXTR instruction. */
24713 MIPS_INVAL("OPC_MXU_S32EXTR");
24714 generate_exception_end(ctx, EXCP_RI);
24716 case OPC_MXU_S32EXTRV:
24717 /* TODO: Implement emulation of S32EXTRV instruction. */
24718 MIPS_INVAL("OPC_MXU_S32EXTRV");
24719 generate_exception_end(ctx, EXCP_RI);
24722 MIPS_INVAL("decode_opc_mxu");
24723 generate_exception_end(ctx, EXCP_RI);
24730 * Decode MXU pool16
24733 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24734 * +-----------+---------+-----+-------+-------+-------+-----------+
24735 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
24736 * +-----------+---------+-----+-------+-------+-------+-----------+
24739 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24740 * +-----------+---------+-----+-------+-------+-------+-----------+
24741 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
24742 * +-----------+---------+-----+-------+-------+-------+-----------+
24745 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24746 * +-----------+-----+---+-----+-------+-------+-------+-----------+
24747 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
24748 * +-----------+-----+---+-----+-------+-------+-------+-----------+
24750 * S32NOR, S32AND, S32OR, S32XOR:
24751 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24752 * +-----------+---------+-----+-------+-------+-------+-----------+
24753 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
24754 * +-----------+---------+-----+-------+-------+-------+-----------+
24757 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24758 * +-----------+-----+---+-----+-------+---------------+-----------+
24759 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
24760 * +-----------+-----+---+-----+-------+---------------+-----------+
24763 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
24765 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24768 case OPC_MXU_D32SARW:
24769 /* TODO: Implement emulation of D32SARW instruction. */
24770 MIPS_INVAL("OPC_MXU_D32SARW");
24771 generate_exception_end(ctx, EXCP_RI);
24773 case OPC_MXU_S32ALN:
24774 /* TODO: Implement emulation of S32ALN instruction. */
24775 MIPS_INVAL("OPC_MXU_S32ALN");
24776 generate_exception_end(ctx, EXCP_RI);
24778 case OPC_MXU_S32ALNI:
24779 /* TODO: Implement emulation of S32ALNI instruction. */
24780 MIPS_INVAL("OPC_MXU_S32ALNI");
24781 generate_exception_end(ctx, EXCP_RI);
24783 case OPC_MXU_S32NOR:
24784 /* TODO: Implement emulation of S32NOR instruction. */
24785 MIPS_INVAL("OPC_MXU_S32NOR");
24786 generate_exception_end(ctx, EXCP_RI);
24788 case OPC_MXU_S32AND:
24789 /* TODO: Implement emulation of S32AND instruction. */
24790 MIPS_INVAL("OPC_MXU_S32AND");
24791 generate_exception_end(ctx, EXCP_RI);
24793 case OPC_MXU_S32OR:
24794 /* TODO: Implement emulation of S32OR instruction. */
24795 MIPS_INVAL("OPC_MXU_S32OR");
24796 generate_exception_end(ctx, EXCP_RI);
24798 case OPC_MXU_S32XOR:
24799 /* TODO: Implement emulation of S32XOR instruction. */
24800 MIPS_INVAL("OPC_MXU_S32XOR");
24801 generate_exception_end(ctx, EXCP_RI);
24803 case OPC_MXU_S32LUI:
24804 /* TODO: Implement emulation of S32LUI instruction. */
24805 MIPS_INVAL("OPC_MXU_S32LUI");
24806 generate_exception_end(ctx, EXCP_RI);
24809 MIPS_INVAL("decode_opc_mxu");
24810 generate_exception_end(ctx, EXCP_RI);
24817 * Decode MXU pool17
24819 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24820 * +-----------+---------+-----+-------+-------+-------+-----------+
24821 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL17|
24822 * +-----------+---------+-----+-------+-------+-------+-----------+
24825 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
24827 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24830 case OPC_MXU_D32SLLV:
24831 /* TODO: Implement emulation of D32SLLV instruction. */
24832 MIPS_INVAL("OPC_MXU_D32SLLV");
24833 generate_exception_end(ctx, EXCP_RI);
24835 case OPC_MXU_D32SLRV:
24836 /* TODO: Implement emulation of D32SLRV instruction. */
24837 MIPS_INVAL("OPC_MXU_D32SLRV");
24838 generate_exception_end(ctx, EXCP_RI);
24840 case OPC_MXU_D32SARV:
24841 /* TODO: Implement emulation of D32SARV instruction. */
24842 MIPS_INVAL("OPC_MXU_D32SARV");
24843 generate_exception_end(ctx, EXCP_RI);
24845 case OPC_MXU_Q16SLLV:
24846 /* TODO: Implement emulation of Q16SLLV instruction. */
24847 MIPS_INVAL("OPC_MXU_Q16SLLV");
24848 generate_exception_end(ctx, EXCP_RI);
24850 case OPC_MXU_Q16SLRV:
24851 /* TODO: Implement emulation of Q16SLRV instruction. */
24852 MIPS_INVAL("OPC_MXU_Q16SLRV");
24853 generate_exception_end(ctx, EXCP_RI);
24855 case OPC_MXU_Q16SARV:
24856 /* TODO: Implement emulation of Q16SARV instruction. */
24857 MIPS_INVAL("OPC_MXU_Q16SARV");
24858 generate_exception_end(ctx, EXCP_RI);
24861 MIPS_INVAL("decode_opc_mxu");
24862 generate_exception_end(ctx, EXCP_RI);
24869 * Decode MXU pool18
24871 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24872 * +-----------+---+---+-------+-------+-------+-------+-----------+
24873 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL18|
24874 * +-----------+---+---+-------+-------+-------+-------+-----------+
24877 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
24879 uint32_t opcode = extract32(ctx->opcode, 22, 2);
24882 case OPC_MXU_Q8MUL:
24883 /* TODO: Implement emulation of Q8MUL instruction. */
24884 MIPS_INVAL("OPC_MXU_Q8MUL");
24885 generate_exception_end(ctx, EXCP_RI);
24887 case OPC_MXU_Q8MULSU:
24888 /* TODO: Implement emulation of Q8MULSU instruction. */
24889 MIPS_INVAL("OPC_MXU_Q8MULSU");
24890 generate_exception_end(ctx, EXCP_RI);
24893 MIPS_INVAL("decode_opc_mxu");
24894 generate_exception_end(ctx, EXCP_RI);
24901 * Decode MXU pool19
24903 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24904 * +-----------+---------+-----+-------+-------+-------+-----------+
24905 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL19|
24906 * +-----------+---------+-----+-------+-------+-------+-----------+
24909 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
24911 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24914 case OPC_MXU_Q8MOVZ:
24915 /* TODO: Implement emulation of Q8MOVZ instruction. */
24916 MIPS_INVAL("OPC_MXU_Q8MOVZ");
24917 generate_exception_end(ctx, EXCP_RI);
24919 case OPC_MXU_Q8MOVN:
24920 /* TODO: Implement emulation of Q8MOVN instruction. */
24921 MIPS_INVAL("OPC_MXU_Q8MOVN");
24922 generate_exception_end(ctx, EXCP_RI);
24924 case OPC_MXU_D16MOVZ:
24925 /* TODO: Implement emulation of D16MOVZ instruction. */
24926 MIPS_INVAL("OPC_MXU_D16MOVZ");
24927 generate_exception_end(ctx, EXCP_RI);
24929 case OPC_MXU_D16MOVN:
24930 /* TODO: Implement emulation of D16MOVN instruction. */
24931 MIPS_INVAL("OPC_MXU_D16MOVN");
24932 generate_exception_end(ctx, EXCP_RI);
24934 case OPC_MXU_S32MOVZ:
24935 /* TODO: Implement emulation of S32MOVZ instruction. */
24936 MIPS_INVAL("OPC_MXU_S32MOVZ");
24937 generate_exception_end(ctx, EXCP_RI);
24939 case OPC_MXU_S32MOVN:
24940 /* TODO: Implement emulation of S32MOVN instruction. */
24941 MIPS_INVAL("OPC_MXU_S32MOVN");
24942 generate_exception_end(ctx, EXCP_RI);
24945 MIPS_INVAL("decode_opc_mxu");
24946 generate_exception_end(ctx, EXCP_RI);
24953 * Decode MXU pool20
24955 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24956 * +-----------+---+---+-------+-------+-------+-------+-----------+
24957 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL20|
24958 * +-----------+---+---+-------+-------+-------+-------+-----------+
24961 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
24963 uint32_t opcode = extract32(ctx->opcode, 22, 2);
24966 case OPC_MXU_Q8MAC:
24967 /* TODO: Implement emulation of Q8MAC instruction. */
24968 MIPS_INVAL("OPC_MXU_Q8MAC");
24969 generate_exception_end(ctx, EXCP_RI);
24971 case OPC_MXU_Q8MACSU:
24972 /* TODO: Implement emulation of Q8MACSU instruction. */
24973 MIPS_INVAL("OPC_MXU_Q8MACSU");
24974 generate_exception_end(ctx, EXCP_RI);
24977 MIPS_INVAL("decode_opc_mxu");
24978 generate_exception_end(ctx, EXCP_RI);
24985 * Main MXU decoding function
24987 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24988 * +-----------+---------------------------------------+-----------+
24989 * | SPECIAL2 | |x x x x x x|
24990 * +-----------+---------------------------------------+-----------+
24993 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
24996 * TODO: Investigate necessity of including handling of
24997 * CLZ, CLO, SDBB in this function, as they belong to
24998 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
25000 uint32_t opcode = extract32(ctx->opcode, 0, 6);
25003 case OPC_MXU_S32MADD:
25004 /* TODO: Implement emulation of S32MADD instruction. */
25005 MIPS_INVAL("OPC_MXU_S32MADD");
25006 generate_exception_end(ctx, EXCP_RI);
25008 case OPC_MXU_S32MADDU:
25009 /* TODO: Implement emulation of S32MADDU instruction. */
25010 MIPS_INVAL("OPC_MXU_S32MADDU");
25011 generate_exception_end(ctx, EXCP_RI);
25013 case OPC__MXU_MUL: /* 0x2 - unused in MXU specs */
25015 uint32_t rs, rt, rd, op1;
25017 rs = extract32(ctx->opcode, 21, 5);
25018 rt = extract32(ctx->opcode, 16, 5);
25019 rd = extract32(ctx->opcode, 11, 5);
25020 op1 = MASK_SPECIAL2(ctx->opcode);
25022 gen_arith(ctx, op1, rd, rs, rt);
25025 case OPC_MXU__POOL00:
25026 decode_opc_mxu__pool00(env, ctx);
25028 case OPC_MXU_S32MSUB:
25029 /* TODO: Implement emulation of S32MSUB instruction. */
25030 MIPS_INVAL("OPC_MXU_S32MSUB");
25031 generate_exception_end(ctx, EXCP_RI);
25033 case OPC_MXU_S32MSUBU:
25034 /* TODO: Implement emulation of S32MSUBU instruction. */
25035 MIPS_INVAL("OPC_MXU_S32MSUBU");
25036 generate_exception_end(ctx, EXCP_RI);
25038 case OPC_MXU__POOL01:
25039 decode_opc_mxu__pool01(env, ctx);
25041 case OPC_MXU__POOL02:
25042 decode_opc_mxu__pool02(env, ctx);
25044 case OPC_MXU_D16MUL:
25045 /* TODO: Implement emulation of D16MUL instruction. */
25046 MIPS_INVAL("OPC_MXU_D16MUL");
25047 generate_exception_end(ctx, EXCP_RI);
25049 case OPC_MXU__POOL03:
25050 decode_opc_mxu__pool03(env, ctx);
25052 case OPC_MXU_D16MAC:
25053 /* TODO: Implement emulation of D16MAC instruction. */
25054 MIPS_INVAL("OPC_MXU_D16MAC");
25055 generate_exception_end(ctx, EXCP_RI);
25057 case OPC_MXU_D16MACF:
25058 /* TODO: Implement emulation of D16MACF instruction. */
25059 MIPS_INVAL("OPC_MXU_D16MACF");
25060 generate_exception_end(ctx, EXCP_RI);
25062 case OPC_MXU_D16MADL:
25063 /* TODO: Implement emulation of D16MADL instruction. */
25064 MIPS_INVAL("OPC_MXU_D16MADL");
25065 generate_exception_end(ctx, EXCP_RI);
25067 case OPC_MXU_S16MAD:
25068 /* TODO: Implement emulation of S16MAD instruction. */
25069 MIPS_INVAL("OPC_MXU_S16MAD");
25070 generate_exception_end(ctx, EXCP_RI);
25072 case OPC_MXU_Q16ADD:
25073 /* TODO: Implement emulation of Q16ADD instruction. */
25074 MIPS_INVAL("OPC_MXU_Q16ADD");
25075 generate_exception_end(ctx, EXCP_RI);
25077 case OPC_MXU_D16MACE:
25078 /* TODO: Implement emulation of D16MACE instruction. */
25079 MIPS_INVAL("OPC_MXU_D16MACE");
25080 generate_exception_end(ctx, EXCP_RI);
25082 case OPC_MXU__POOL04:
25083 decode_opc_mxu__pool04(env, ctx);
25085 case OPC_MXU__POOL05:
25086 decode_opc_mxu__pool05(env, ctx);
25088 case OPC_MXU__POOL06:
25089 decode_opc_mxu__pool06(env, ctx);
25091 case OPC_MXU__POOL07:
25092 decode_opc_mxu__pool07(env, ctx);
25094 case OPC_MXU__POOL08:
25095 decode_opc_mxu__pool08(env, ctx);
25097 case OPC_MXU__POOL09:
25098 decode_opc_mxu__pool09(env, ctx);
25100 case OPC_MXU__POOL10:
25101 decode_opc_mxu__pool10(env, ctx);
25103 case OPC_MXU__POOL11:
25104 decode_opc_mxu__pool11(env, ctx);
25106 case OPC_MXU_D32ADD:
25107 /* TODO: Implement emulation of D32ADD instruction. */
25108 MIPS_INVAL("OPC_MXU_D32ADD");
25109 generate_exception_end(ctx, EXCP_RI);
25111 case OPC_MXU__POOL12:
25112 decode_opc_mxu__pool12(env, ctx);
25114 case OPC_MXU__POOL13:
25115 decode_opc_mxu__pool13(env, ctx);
25117 case OPC_MXU__POOL14:
25118 decode_opc_mxu__pool14(env, ctx);
25120 case OPC_MXU_Q8ACCE:
25121 /* TODO: Implement emulation of Q8ACCE instruction. */
25122 MIPS_INVAL("OPC_MXU_Q8ACCE");
25123 generate_exception_end(ctx, EXCP_RI);
25125 case OPC_MXU_S8LDD:
25126 /* TODO: Implement emulation of S8LDD instruction. */
25127 MIPS_INVAL("OPC_MXU_S8LDD");
25128 generate_exception_end(ctx, EXCP_RI);
25130 case OPC_MXU_S8STD:
25131 /* TODO: Implement emulation of S8STD instruction. */
25132 MIPS_INVAL("OPC_MXU_S8STD");
25133 generate_exception_end(ctx, EXCP_RI);
25135 case OPC_MXU_S8LDI:
25136 /* TODO: Implement emulation of S8LDI instruction. */
25137 MIPS_INVAL("OPC_MXU_S8LDI");
25138 generate_exception_end(ctx, EXCP_RI);
25140 case OPC_MXU_S8SDI:
25141 /* TODO: Implement emulation of S8SDI instruction. */
25142 MIPS_INVAL("OPC_MXU_S8SDI");
25143 generate_exception_end(ctx, EXCP_RI);
25145 case OPC_MXU__POOL15:
25146 decode_opc_mxu__pool15(env, ctx);
25148 case OPC_MXU__POOL16:
25149 decode_opc_mxu__pool16(env, ctx);
25152 /* TODO: Implement emulation of LXB instruction. */
25153 MIPS_INVAL("OPC_MXU_LXB");
25154 generate_exception_end(ctx, EXCP_RI);
25156 case OPC_MXU_S16LDD:
25157 /* TODO: Implement emulation of S16LDD instruction. */
25158 MIPS_INVAL("OPC_MXU_S16LDD");
25159 generate_exception_end(ctx, EXCP_RI);
25161 case OPC_MXU_S16STD:
25162 /* TODO: Implement emulation of S16STD instruction. */
25163 MIPS_INVAL("OPC_MXU_S16STD");
25164 generate_exception_end(ctx, EXCP_RI);
25166 case OPC_MXU_S16LDI:
25167 /* TODO: Implement emulation of S16LDI instruction. */
25168 MIPS_INVAL("OPC_MXU_S16LDI");
25169 generate_exception_end(ctx, EXCP_RI);
25171 case OPC_MXU_S16SDI:
25172 /* TODO: Implement emulation of S16SDI instruction. */
25173 MIPS_INVAL("OPC_MXU_S16SDI");
25174 generate_exception_end(ctx, EXCP_RI);
25176 case OPC_MXU_S32M2I:
25177 gen_mxu_s32m2i(ctx);
25179 case OPC_MXU_S32I2M:
25180 gen_mxu_s32i2m(ctx);
25182 case OPC_MXU_D32SLL:
25183 /* TODO: Implement emulation of D32SLL instruction. */
25184 MIPS_INVAL("OPC_MXU_D32SLL");
25185 generate_exception_end(ctx, EXCP_RI);
25187 case OPC_MXU_D32SLR:
25188 /* TODO: Implement emulation of D32SLR instruction. */
25189 MIPS_INVAL("OPC_MXU_D32SLR");
25190 generate_exception_end(ctx, EXCP_RI);
25192 case OPC_MXU_D32SARL:
25193 /* TODO: Implement emulation of D32SARL instruction. */
25194 MIPS_INVAL("OPC_MXU_D32SARL");
25195 generate_exception_end(ctx, EXCP_RI);
25197 case OPC_MXU_D32SAR:
25198 /* TODO: Implement emulation of D32SAR instruction. */
25199 MIPS_INVAL("OPC_MXU_D32SAR");
25200 generate_exception_end(ctx, EXCP_RI);
25202 case OPC_MXU_Q16SLL:
25203 /* TODO: Implement emulation of Q16SLL instruction. */
25204 MIPS_INVAL("OPC_MXU_Q16SLL");
25205 generate_exception_end(ctx, EXCP_RI);
25207 case OPC_MXU_Q16SLR:
25208 /* TODO: Implement emulation of Q16SLR instruction. */
25209 MIPS_INVAL("OPC_MXU_Q16SLR");
25210 generate_exception_end(ctx, EXCP_RI);
25212 case OPC_MXU__POOL17:
25213 decode_opc_mxu__pool17(env, ctx);
25215 case OPC_MXU_Q16SAR:
25216 /* TODO: Implement emulation of Q16SAR instruction. */
25217 MIPS_INVAL("OPC_MXU_Q16SAR");
25218 generate_exception_end(ctx, EXCP_RI);
25220 case OPC_MXU__POOL18:
25221 decode_opc_mxu__pool18(env, ctx);
25223 case OPC_MXU__POOL19:
25224 decode_opc_mxu__pool19(env, ctx);
25226 case OPC_MXU__POOL20:
25227 decode_opc_mxu__pool20(env, ctx);
25229 case OPC_MXU_Q16SCOP:
25230 /* TODO: Implement emulation of Q16SCOP instruction. */
25231 MIPS_INVAL("OPC_MXU_Q16SCOP");
25232 generate_exception_end(ctx, EXCP_RI);
25234 case OPC_MXU_Q8MADL:
25235 /* TODO: Implement emulation of Q8MADL instruction. */
25236 MIPS_INVAL("OPC_MXU_Q8MADL");
25237 generate_exception_end(ctx, EXCP_RI);
25239 case OPC_MXU_S32SFL:
25240 /* TODO: Implement emulation of S32SFL instruction. */
25241 MIPS_INVAL("OPC_MXU_S32SFL");
25242 generate_exception_end(ctx, EXCP_RI);
25244 case OPC_MXU_Q8SAD:
25245 /* TODO: Implement emulation of Q8SAD instruction. */
25246 MIPS_INVAL("OPC_MXU_Q8SAD");
25247 generate_exception_end(ctx, EXCP_RI);
25250 MIPS_INVAL("decode_opc_mxu");
25251 generate_exception_end(ctx, EXCP_RI);
25256 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
25261 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25263 rs = (ctx->opcode >> 21) & 0x1f;
25264 rt = (ctx->opcode >> 16) & 0x1f;
25265 rd = (ctx->opcode >> 11) & 0x1f;
25267 op1 = MASK_SPECIAL2(ctx->opcode);
25269 case OPC_MADD: /* Multiply and add/sub */
25273 check_insn(ctx, ISA_MIPS32);
25274 gen_muldiv(ctx, op1, rd & 3, rs, rt);
25277 gen_arith(ctx, op1, rd, rs, rt);
25280 case OPC_DIVU_G_2F:
25281 case OPC_MULT_G_2F:
25282 case OPC_MULTU_G_2F:
25284 case OPC_MODU_G_2F:
25285 check_insn(ctx, INSN_LOONGSON2F);
25286 gen_loongson_integer(ctx, op1, rd, rs, rt);
25290 check_insn(ctx, ISA_MIPS32);
25291 gen_cl(ctx, op1, rd, rs);
25294 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
25295 gen_helper_do_semihosting(cpu_env);
25297 /* XXX: not clear which exception should be raised
25298 * when in debug mode...
25300 check_insn(ctx, ISA_MIPS32);
25301 generate_exception_end(ctx, EXCP_DBp);
25304 #if defined(TARGET_MIPS64)
25307 check_insn(ctx, ISA_MIPS64);
25308 check_mips_64(ctx);
25309 gen_cl(ctx, op1, rd, rs);
25311 case OPC_DMULT_G_2F:
25312 case OPC_DMULTU_G_2F:
25313 case OPC_DDIV_G_2F:
25314 case OPC_DDIVU_G_2F:
25315 case OPC_DMOD_G_2F:
25316 case OPC_DMODU_G_2F:
25317 check_insn(ctx, INSN_LOONGSON2F);
25318 gen_loongson_integer(ctx, op1, rd, rs, rt);
25321 default: /* Invalid */
25322 MIPS_INVAL("special2_legacy");
25323 generate_exception_end(ctx, EXCP_RI);
25328 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
25330 int rs, rt, rd, sa;
25334 rs = (ctx->opcode >> 21) & 0x1f;
25335 rt = (ctx->opcode >> 16) & 0x1f;
25336 rd = (ctx->opcode >> 11) & 0x1f;
25337 sa = (ctx->opcode >> 6) & 0x1f;
25338 imm = (int16_t)ctx->opcode >> 7;
25340 op1 = MASK_SPECIAL3(ctx->opcode);
25344 /* hint codes 24-31 are reserved and signal RI */
25345 generate_exception_end(ctx, EXCP_RI);
25347 /* Treat as NOP. */
25350 check_cp0_enabled(ctx);
25351 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25352 gen_cache_operation(ctx, rt, rs, imm);
25356 gen_st_cond(ctx, op1, rt, rs, imm);
25359 gen_ld(ctx, op1, rt, rs, imm);
25364 /* Treat as NOP. */
25367 op2 = MASK_BSHFL(ctx->opcode);
25373 gen_align(ctx, 32, rd, rs, rt, sa & 3);
25376 gen_bitswap(ctx, op2, rd, rt);
25381 #if defined(TARGET_MIPS64)
25383 gen_st_cond(ctx, op1, rt, rs, imm);
25386 gen_ld(ctx, op1, rt, rs, imm);
25389 check_mips_64(ctx);
25392 /* Treat as NOP. */
25395 op2 = MASK_DBSHFL(ctx->opcode);
25405 gen_align(ctx, 64, rd, rs, rt, sa & 7);
25408 gen_bitswap(ctx, op2, rd, rt);
25415 default: /* Invalid */
25416 MIPS_INVAL("special3_r6");
25417 generate_exception_end(ctx, EXCP_RI);
25422 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
25427 rs = (ctx->opcode >> 21) & 0x1f;
25428 rt = (ctx->opcode >> 16) & 0x1f;
25429 rd = (ctx->opcode >> 11) & 0x1f;
25431 op1 = MASK_SPECIAL3(ctx->opcode);
25434 case OPC_DIVU_G_2E:
25436 case OPC_MODU_G_2E:
25437 case OPC_MULT_G_2E:
25438 case OPC_MULTU_G_2E:
25439 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
25440 * the same mask and op1. */
25441 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
25442 op2 = MASK_ADDUH_QB(ctx->opcode);
25445 case OPC_ADDUH_R_QB:
25447 case OPC_ADDQH_R_PH:
25449 case OPC_ADDQH_R_W:
25451 case OPC_SUBUH_R_QB:
25453 case OPC_SUBQH_R_PH:
25455 case OPC_SUBQH_R_W:
25456 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25461 case OPC_MULQ_RS_W:
25462 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
25465 MIPS_INVAL("MASK ADDUH.QB");
25466 generate_exception_end(ctx, EXCP_RI);
25469 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
25470 gen_loongson_integer(ctx, op1, rd, rs, rt);
25472 generate_exception_end(ctx, EXCP_RI);
25476 op2 = MASK_LX(ctx->opcode);
25478 #if defined(TARGET_MIPS64)
25484 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
25486 default: /* Invalid */
25487 MIPS_INVAL("MASK LX");
25488 generate_exception_end(ctx, EXCP_RI);
25492 case OPC_ABSQ_S_PH_DSP:
25493 op2 = MASK_ABSQ_S_PH(ctx->opcode);
25495 case OPC_ABSQ_S_QB:
25496 case OPC_ABSQ_S_PH:
25498 case OPC_PRECEQ_W_PHL:
25499 case OPC_PRECEQ_W_PHR:
25500 case OPC_PRECEQU_PH_QBL:
25501 case OPC_PRECEQU_PH_QBR:
25502 case OPC_PRECEQU_PH_QBLA:
25503 case OPC_PRECEQU_PH_QBRA:
25504 case OPC_PRECEU_PH_QBL:
25505 case OPC_PRECEU_PH_QBR:
25506 case OPC_PRECEU_PH_QBLA:
25507 case OPC_PRECEU_PH_QBRA:
25508 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25515 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
25518 MIPS_INVAL("MASK ABSQ_S.PH");
25519 generate_exception_end(ctx, EXCP_RI);
25523 case OPC_ADDU_QB_DSP:
25524 op2 = MASK_ADDU_QB(ctx->opcode);
25527 case OPC_ADDQ_S_PH:
25530 case OPC_ADDU_S_QB:
25532 case OPC_ADDU_S_PH:
25534 case OPC_SUBQ_S_PH:
25537 case OPC_SUBU_S_QB:
25539 case OPC_SUBU_S_PH:
25543 case OPC_RADDU_W_QB:
25544 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25546 case OPC_MULEU_S_PH_QBL:
25547 case OPC_MULEU_S_PH_QBR:
25548 case OPC_MULQ_RS_PH:
25549 case OPC_MULEQ_S_W_PHL:
25550 case OPC_MULEQ_S_W_PHR:
25551 case OPC_MULQ_S_PH:
25552 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
25554 default: /* Invalid */
25555 MIPS_INVAL("MASK ADDU.QB");
25556 generate_exception_end(ctx, EXCP_RI);
25561 case OPC_CMPU_EQ_QB_DSP:
25562 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
25564 case OPC_PRECR_SRA_PH_W:
25565 case OPC_PRECR_SRA_R_PH_W:
25566 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
25568 case OPC_PRECR_QB_PH:
25569 case OPC_PRECRQ_QB_PH:
25570 case OPC_PRECRQ_PH_W:
25571 case OPC_PRECRQ_RS_PH_W:
25572 case OPC_PRECRQU_S_QB_PH:
25573 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25575 case OPC_CMPU_EQ_QB:
25576 case OPC_CMPU_LT_QB:
25577 case OPC_CMPU_LE_QB:
25578 case OPC_CMP_EQ_PH:
25579 case OPC_CMP_LT_PH:
25580 case OPC_CMP_LE_PH:
25581 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
25583 case OPC_CMPGU_EQ_QB:
25584 case OPC_CMPGU_LT_QB:
25585 case OPC_CMPGU_LE_QB:
25586 case OPC_CMPGDU_EQ_QB:
25587 case OPC_CMPGDU_LT_QB:
25588 case OPC_CMPGDU_LE_QB:
25591 case OPC_PACKRL_PH:
25592 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
25594 default: /* Invalid */
25595 MIPS_INVAL("MASK CMPU.EQ.QB");
25596 generate_exception_end(ctx, EXCP_RI);
25600 case OPC_SHLL_QB_DSP:
25601 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
25603 case OPC_DPA_W_PH_DSP:
25604 op2 = MASK_DPA_W_PH(ctx->opcode);
25606 case OPC_DPAU_H_QBL:
25607 case OPC_DPAU_H_QBR:
25608 case OPC_DPSU_H_QBL:
25609 case OPC_DPSU_H_QBR:
25611 case OPC_DPAX_W_PH:
25612 case OPC_DPAQ_S_W_PH:
25613 case OPC_DPAQX_S_W_PH:
25614 case OPC_DPAQX_SA_W_PH:
25616 case OPC_DPSX_W_PH:
25617 case OPC_DPSQ_S_W_PH:
25618 case OPC_DPSQX_S_W_PH:
25619 case OPC_DPSQX_SA_W_PH:
25620 case OPC_MULSAQ_S_W_PH:
25621 case OPC_DPAQ_SA_L_W:
25622 case OPC_DPSQ_SA_L_W:
25623 case OPC_MAQ_S_W_PHL:
25624 case OPC_MAQ_S_W_PHR:
25625 case OPC_MAQ_SA_W_PHL:
25626 case OPC_MAQ_SA_W_PHR:
25627 case OPC_MULSA_W_PH:
25628 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
25630 default: /* Invalid */
25631 MIPS_INVAL("MASK DPAW.PH");
25632 generate_exception_end(ctx, EXCP_RI);
25637 op2 = MASK_INSV(ctx->opcode);
25648 t0 = tcg_temp_new();
25649 t1 = tcg_temp_new();
25651 gen_load_gpr(t0, rt);
25652 gen_load_gpr(t1, rs);
25654 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
25660 default: /* Invalid */
25661 MIPS_INVAL("MASK INSV");
25662 generate_exception_end(ctx, EXCP_RI);
25666 case OPC_APPEND_DSP:
25667 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
25669 case OPC_EXTR_W_DSP:
25670 op2 = MASK_EXTR_W(ctx->opcode);
25674 case OPC_EXTR_RS_W:
25676 case OPC_EXTRV_S_H:
25678 case OPC_EXTRV_R_W:
25679 case OPC_EXTRV_RS_W:
25684 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
25687 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
25693 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
25695 default: /* Invalid */
25696 MIPS_INVAL("MASK EXTR.W");
25697 generate_exception_end(ctx, EXCP_RI);
25701 #if defined(TARGET_MIPS64)
25702 case OPC_DDIV_G_2E:
25703 case OPC_DDIVU_G_2E:
25704 case OPC_DMULT_G_2E:
25705 case OPC_DMULTU_G_2E:
25706 case OPC_DMOD_G_2E:
25707 case OPC_DMODU_G_2E:
25708 check_insn(ctx, INSN_LOONGSON2E);
25709 gen_loongson_integer(ctx, op1, rd, rs, rt);
25711 case OPC_ABSQ_S_QH_DSP:
25712 op2 = MASK_ABSQ_S_QH(ctx->opcode);
25714 case OPC_PRECEQ_L_PWL:
25715 case OPC_PRECEQ_L_PWR:
25716 case OPC_PRECEQ_PW_QHL:
25717 case OPC_PRECEQ_PW_QHR:
25718 case OPC_PRECEQ_PW_QHLA:
25719 case OPC_PRECEQ_PW_QHRA:
25720 case OPC_PRECEQU_QH_OBL:
25721 case OPC_PRECEQU_QH_OBR:
25722 case OPC_PRECEQU_QH_OBLA:
25723 case OPC_PRECEQU_QH_OBRA:
25724 case OPC_PRECEU_QH_OBL:
25725 case OPC_PRECEU_QH_OBR:
25726 case OPC_PRECEU_QH_OBLA:
25727 case OPC_PRECEU_QH_OBRA:
25728 case OPC_ABSQ_S_OB:
25729 case OPC_ABSQ_S_PW:
25730 case OPC_ABSQ_S_QH:
25731 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25739 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
25741 default: /* Invalid */
25742 MIPS_INVAL("MASK ABSQ_S.QH");
25743 generate_exception_end(ctx, EXCP_RI);
25747 case OPC_ADDU_OB_DSP:
25748 op2 = MASK_ADDU_OB(ctx->opcode);
25750 case OPC_RADDU_L_OB:
25752 case OPC_SUBQ_S_PW:
25754 case OPC_SUBQ_S_QH:
25756 case OPC_SUBU_S_OB:
25758 case OPC_SUBU_S_QH:
25760 case OPC_SUBUH_R_OB:
25762 case OPC_ADDQ_S_PW:
25764 case OPC_ADDQ_S_QH:
25766 case OPC_ADDU_S_OB:
25768 case OPC_ADDU_S_QH:
25770 case OPC_ADDUH_R_OB:
25771 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25773 case OPC_MULEQ_S_PW_QHL:
25774 case OPC_MULEQ_S_PW_QHR:
25775 case OPC_MULEU_S_QH_OBL:
25776 case OPC_MULEU_S_QH_OBR:
25777 case OPC_MULQ_RS_QH:
25778 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
25780 default: /* Invalid */
25781 MIPS_INVAL("MASK ADDU.OB");
25782 generate_exception_end(ctx, EXCP_RI);
25786 case OPC_CMPU_EQ_OB_DSP:
25787 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
25789 case OPC_PRECR_SRA_QH_PW:
25790 case OPC_PRECR_SRA_R_QH_PW:
25791 /* Return value is rt. */
25792 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
25794 case OPC_PRECR_OB_QH:
25795 case OPC_PRECRQ_OB_QH:
25796 case OPC_PRECRQ_PW_L:
25797 case OPC_PRECRQ_QH_PW:
25798 case OPC_PRECRQ_RS_QH_PW:
25799 case OPC_PRECRQU_S_OB_QH:
25800 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25802 case OPC_CMPU_EQ_OB:
25803 case OPC_CMPU_LT_OB:
25804 case OPC_CMPU_LE_OB:
25805 case OPC_CMP_EQ_QH:
25806 case OPC_CMP_LT_QH:
25807 case OPC_CMP_LE_QH:
25808 case OPC_CMP_EQ_PW:
25809 case OPC_CMP_LT_PW:
25810 case OPC_CMP_LE_PW:
25811 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
25813 case OPC_CMPGDU_EQ_OB:
25814 case OPC_CMPGDU_LT_OB:
25815 case OPC_CMPGDU_LE_OB:
25816 case OPC_CMPGU_EQ_OB:
25817 case OPC_CMPGU_LT_OB:
25818 case OPC_CMPGU_LE_OB:
25819 case OPC_PACKRL_PW:
25823 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
25825 default: /* Invalid */
25826 MIPS_INVAL("MASK CMPU_EQ.OB");
25827 generate_exception_end(ctx, EXCP_RI);
25831 case OPC_DAPPEND_DSP:
25832 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
25834 case OPC_DEXTR_W_DSP:
25835 op2 = MASK_DEXTR_W(ctx->opcode);
25842 case OPC_DEXTR_R_L:
25843 case OPC_DEXTR_RS_L:
25845 case OPC_DEXTR_R_W:
25846 case OPC_DEXTR_RS_W:
25847 case OPC_DEXTR_S_H:
25849 case OPC_DEXTRV_R_L:
25850 case OPC_DEXTRV_RS_L:
25851 case OPC_DEXTRV_S_H:
25853 case OPC_DEXTRV_R_W:
25854 case OPC_DEXTRV_RS_W:
25855 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
25860 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
25862 default: /* Invalid */
25863 MIPS_INVAL("MASK EXTR.W");
25864 generate_exception_end(ctx, EXCP_RI);
25868 case OPC_DPAQ_W_QH_DSP:
25869 op2 = MASK_DPAQ_W_QH(ctx->opcode);
25871 case OPC_DPAU_H_OBL:
25872 case OPC_DPAU_H_OBR:
25873 case OPC_DPSU_H_OBL:
25874 case OPC_DPSU_H_OBR:
25876 case OPC_DPAQ_S_W_QH:
25878 case OPC_DPSQ_S_W_QH:
25879 case OPC_MULSAQ_S_W_QH:
25880 case OPC_DPAQ_SA_L_PW:
25881 case OPC_DPSQ_SA_L_PW:
25882 case OPC_MULSAQ_S_L_PW:
25883 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
25885 case OPC_MAQ_S_W_QHLL:
25886 case OPC_MAQ_S_W_QHLR:
25887 case OPC_MAQ_S_W_QHRL:
25888 case OPC_MAQ_S_W_QHRR:
25889 case OPC_MAQ_SA_W_QHLL:
25890 case OPC_MAQ_SA_W_QHLR:
25891 case OPC_MAQ_SA_W_QHRL:
25892 case OPC_MAQ_SA_W_QHRR:
25893 case OPC_MAQ_S_L_PWL:
25894 case OPC_MAQ_S_L_PWR:
25899 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
25901 default: /* Invalid */
25902 MIPS_INVAL("MASK DPAQ.W.QH");
25903 generate_exception_end(ctx, EXCP_RI);
25907 case OPC_DINSV_DSP:
25908 op2 = MASK_INSV(ctx->opcode);
25919 t0 = tcg_temp_new();
25920 t1 = tcg_temp_new();
25922 gen_load_gpr(t0, rt);
25923 gen_load_gpr(t1, rs);
25925 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
25931 default: /* Invalid */
25932 MIPS_INVAL("MASK DINSV");
25933 generate_exception_end(ctx, EXCP_RI);
25937 case OPC_SHLL_OB_DSP:
25938 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
25941 default: /* Invalid */
25942 MIPS_INVAL("special3_legacy");
25943 generate_exception_end(ctx, EXCP_RI);
25948 static void decode_tx79_mmi0(CPUMIPSState *env, DisasContext *ctx)
25950 uint32_t opc = MASK_TX79_MMI0(ctx->opcode);
25953 case TX79_MMI0_PADDW: /* TODO: TX79_MMI0_PADDW */
25954 case TX79_MMI0_PSUBW: /* TODO: TX79_MMI0_PSUBW */
25955 case TX79_MMI0_PCGTW: /* TODO: TX79_MMI0_PCGTW */
25956 case TX79_MMI0_PMAXW: /* TODO: TX79_MMI0_PMAXW */
25957 case TX79_MMI0_PADDH: /* TODO: TX79_MMI0_PADDH */
25958 case TX79_MMI0_PSUBH: /* TODO: TX79_MMI0_PSUBH */
25959 case TX79_MMI0_PCGTH: /* TODO: TX79_MMI0_PCGTH */
25960 case TX79_MMI0_PMAXH: /* TODO: TX79_MMI0_PMAXH */
25961 case TX79_MMI0_PADDB: /* TODO: TX79_MMI0_PADDB */
25962 case TX79_MMI0_PSUBB: /* TODO: TX79_MMI0_PSUBB */
25963 case TX79_MMI0_PCGTB: /* TODO: TX79_MMI0_PCGTB */
25964 case TX79_MMI0_PADDSW: /* TODO: TX79_MMI0_PADDSW */
25965 case TX79_MMI0_PSUBSW: /* TODO: TX79_MMI0_PSUBSW */
25966 case TX79_MMI0_PEXTLW: /* TODO: TX79_MMI0_PEXTLW */
25967 case TX79_MMI0_PPACW: /* TODO: TX79_MMI0_PPACW */
25968 case TX79_MMI0_PADDSH: /* TODO: TX79_MMI0_PADDSH */
25969 case TX79_MMI0_PSUBSH: /* TODO: TX79_MMI0_PSUBSH */
25970 case TX79_MMI0_PEXTLH: /* TODO: TX79_MMI0_PEXTLH */
25971 case TX79_MMI0_PPACH: /* TODO: TX79_MMI0_PPACH */
25972 case TX79_MMI0_PADDSB: /* TODO: TX79_MMI0_PADDSB */
25973 case TX79_MMI0_PSUBSB: /* TODO: TX79_MMI0_PSUBSB */
25974 case TX79_MMI0_PEXTLB: /* TODO: TX79_MMI0_PEXTLB */
25975 case TX79_MMI0_PPACB: /* TODO: TX79_MMI0_PPACB */
25976 case TX79_MMI0_PEXT5: /* TODO: TX79_MMI0_PEXT5 */
25977 case TX79_MMI0_PPAC5: /* TODO: TX79_MMI0_PPAC5 */
25978 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI0 */
25981 MIPS_INVAL("TX79 MMI class MMI0");
25982 generate_exception_end(ctx, EXCP_RI);
25987 static void decode_tx79_mmi1(CPUMIPSState *env, DisasContext *ctx)
25989 uint32_t opc = MASK_TX79_MMI1(ctx->opcode);
25992 case TX79_MMI1_PABSW: /* TODO: TX79_MMI1_PABSW */
25993 case TX79_MMI1_PCEQW: /* TODO: TX79_MMI1_PCEQW */
25994 case TX79_MMI1_PMINW: /* TODO: TX79_MMI1_PMINW */
25995 case TX79_MMI1_PADSBH: /* TODO: TX79_MMI1_PADSBH */
25996 case TX79_MMI1_PABSH: /* TODO: TX79_MMI1_PABSH */
25997 case TX79_MMI1_PCEQH: /* TODO: TX79_MMI1_PCEQH */
25998 case TX79_MMI1_PMINH: /* TODO: TX79_MMI1_PMINH */
25999 case TX79_MMI1_PCEQB: /* TODO: TX79_MMI1_PCEQB */
26000 case TX79_MMI1_PADDUW: /* TODO: TX79_MMI1_PADDUW */
26001 case TX79_MMI1_PSUBUW: /* TODO: TX79_MMI1_PSUBUW */
26002 case TX79_MMI1_PEXTUW: /* TODO: TX79_MMI1_PEXTUW */
26003 case TX79_MMI1_PADDUH: /* TODO: TX79_MMI1_PADDUH */
26004 case TX79_MMI1_PSUBUH: /* TODO: TX79_MMI1_PSUBUH */
26005 case TX79_MMI1_PEXTUH: /* TODO: TX79_MMI1_PEXTUH */
26006 case TX79_MMI1_PADDUB: /* TODO: TX79_MMI1_PADDUB */
26007 case TX79_MMI1_PSUBUB: /* TODO: TX79_MMI1_PSUBUB */
26008 case TX79_MMI1_PEXTUB: /* TODO: TX79_MMI1_PEXTUB */
26009 case TX79_MMI1_QFSRV: /* TODO: TX79_MMI1_QFSRV */
26010 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI1 */
26013 MIPS_INVAL("TX79 MMI class MMI1");
26014 generate_exception_end(ctx, EXCP_RI);
26019 static void decode_tx79_mmi2(CPUMIPSState *env, DisasContext *ctx)
26021 uint32_t opc = MASK_TX79_MMI2(ctx->opcode);
26024 case TX79_MMI2_PMADDW: /* TODO: TX79_MMI2_PMADDW */
26025 case TX79_MMI2_PSLLVW: /* TODO: TX79_MMI2_PSLLVW */
26026 case TX79_MMI2_PSRLVW: /* TODO: TX79_MMI2_PSRLVW */
26027 case TX79_MMI2_PMSUBW: /* TODO: TX79_MMI2_PMSUBW */
26028 case TX79_MMI2_PMFHI: /* TODO: TX79_MMI2_PMFHI */
26029 case TX79_MMI2_PMFLO: /* TODO: TX79_MMI2_PMFLO */
26030 case TX79_MMI2_PINTH: /* TODO: TX79_MMI2_PINTH */
26031 case TX79_MMI2_PMULTW: /* TODO: TX79_MMI2_PMULTW */
26032 case TX79_MMI2_PDIVW: /* TODO: TX79_MMI2_PDIVW */
26033 case TX79_MMI2_PCPYLD: /* TODO: TX79_MMI2_PCPYLD */
26034 case TX79_MMI2_PMADDH: /* TODO: TX79_MMI2_PMADDH */
26035 case TX79_MMI2_PHMADH: /* TODO: TX79_MMI2_PHMADH */
26036 case TX79_MMI2_PAND: /* TODO: TX79_MMI2_PAND */
26037 case TX79_MMI2_PXOR: /* TODO: TX79_MMI2_PXOR */
26038 case TX79_MMI2_PMSUBH: /* TODO: TX79_MMI2_PMSUBH */
26039 case TX79_MMI2_PHMSBH: /* TODO: TX79_MMI2_PHMSBH */
26040 case TX79_MMI2_PEXEH: /* TODO: TX79_MMI2_PEXEH */
26041 case TX79_MMI2_PREVH: /* TODO: TX79_MMI2_PREVH */
26042 case TX79_MMI2_PMULTH: /* TODO: TX79_MMI2_PMULTH */
26043 case TX79_MMI2_PDIVBW: /* TODO: TX79_MMI2_PDIVBW */
26044 case TX79_MMI2_PEXEW: /* TODO: TX79_MMI2_PEXEW */
26045 case TX79_MMI2_PROT3W: /* TODO: TX79_MMI2_PROT3W */
26046 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI2 */
26049 MIPS_INVAL("TX79 MMI class MMI2");
26050 generate_exception_end(ctx, EXCP_RI);
26055 static void decode_tx79_mmi3(CPUMIPSState *env, DisasContext *ctx)
26057 uint32_t opc = MASK_TX79_MMI3(ctx->opcode);
26060 case TX79_MMI3_PMADDUW: /* TODO: TX79_MMI3_PMADDUW */
26061 case TX79_MMI3_PSRAVW: /* TODO: TX79_MMI3_PSRAVW */
26062 case TX79_MMI3_PMTHI: /* TODO: TX79_MMI3_PMTHI */
26063 case TX79_MMI3_PMTLO: /* TODO: TX79_MMI3_PMTLO */
26064 case TX79_MMI3_PINTEH: /* TODO: TX79_MMI3_PINTEH */
26065 case TX79_MMI3_PMULTUW: /* TODO: TX79_MMI3_PMULTUW */
26066 case TX79_MMI3_PDIVUW: /* TODO: TX79_MMI3_PDIVUW */
26067 case TX79_MMI3_PCPYUD: /* TODO: TX79_MMI3_PCPYUD */
26068 case TX79_MMI3_POR: /* TODO: TX79_MMI3_POR */
26069 case TX79_MMI3_PNOR: /* TODO: TX79_MMI3_PNOR */
26070 case TX79_MMI3_PEXCH: /* TODO: TX79_MMI3_PEXCH */
26071 case TX79_MMI3_PCPYH: /* TODO: TX79_MMI3_PCPYH */
26072 case TX79_MMI3_PEXCW: /* TODO: TX79_MMI3_PEXCW */
26073 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI3 */
26076 MIPS_INVAL("TX79 MMI class MMI3");
26077 generate_exception_end(ctx, EXCP_RI);
26082 static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
26084 uint32_t opc = MASK_TX79_MMI(ctx->opcode);
26085 int rs = extract32(ctx->opcode, 21, 5);
26086 int rt = extract32(ctx->opcode, 16, 5);
26087 int rd = extract32(ctx->opcode, 11, 5);
26090 case TX79_MMI_CLASS_MMI0:
26091 decode_tx79_mmi0(env, ctx);
26093 case TX79_MMI_CLASS_MMI1:
26094 decode_tx79_mmi1(env, ctx);
26096 case TX79_MMI_CLASS_MMI2:
26097 decode_tx79_mmi2(env, ctx);
26099 case TX79_MMI_CLASS_MMI3:
26100 decode_tx79_mmi3(env, ctx);
26102 case TX79_MMI_MULT1:
26103 case TX79_MMI_MULTU1:
26104 gen_mul_txx9(ctx, opc, rd, rs, rt);
26106 case TX79_MMI_DIV1:
26107 case TX79_MMI_DIVU1:
26108 gen_muldiv(ctx, opc, 1, rs, rt);
26110 case TX79_MMI_MTLO1:
26111 case TX79_MMI_MTHI1:
26112 gen_HILO(ctx, opc, 1, rs);
26114 case TX79_MMI_MFLO1:
26115 case TX79_MMI_MFHI1:
26116 gen_HILO(ctx, opc, 1, rd);
26118 case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */
26119 case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */
26120 case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */
26121 case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */
26122 case TX79_MMI_MADDU1: /* TODO: TX79_MMI_MADDU1 */
26123 case TX79_MMI_PMFHL: /* TODO: TX79_MMI_PMFHL */
26124 case TX79_MMI_PMTHL: /* TODO: TX79_MMI_PMTHL */
26125 case TX79_MMI_PSLLH: /* TODO: TX79_MMI_PSLLH */
26126 case TX79_MMI_PSRLH: /* TODO: TX79_MMI_PSRLH */
26127 case TX79_MMI_PSRAH: /* TODO: TX79_MMI_PSRAH */
26128 case TX79_MMI_PSLLW: /* TODO: TX79_MMI_PSLLW */
26129 case TX79_MMI_PSRLW: /* TODO: TX79_MMI_PSRLW */
26130 case TX79_MMI_PSRAW: /* TODO: TX79_MMI_PSRAW */
26131 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_CLASS_MMI */
26134 MIPS_INVAL("TX79 MMI class");
26135 generate_exception_end(ctx, EXCP_RI);
26140 static void decode_tx79_lq(CPUMIPSState *env, DisasContext *ctx)
26142 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_LQ */
26145 static void gen_tx79_sq(DisasContext *ctx, int base, int rt, int offset)
26147 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_SQ */
26151 * The TX79-specific instruction Store Quadword
26153 * +--------+-------+-------+------------------------+
26154 * | 011111 | base | rt | offset | SQ
26155 * +--------+-------+-------+------------------------+
26158 * has the same opcode as the Read Hardware Register instruction
26160 * +--------+-------+-------+-------+-------+--------+
26161 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
26162 * +--------+-------+-------+-------+-------+--------+
26165 * that is required, trapped and emulated by the Linux kernel. However, all
26166 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
26167 * offset is odd. Therefore all valid SQ instructions can execute normally.
26168 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
26169 * between SQ and RDHWR, as the Linux kernel does.
26171 static void decode_tx79_sq(CPUMIPSState *env, DisasContext *ctx)
26173 int base = extract32(ctx->opcode, 21, 5);
26174 int rt = extract32(ctx->opcode, 16, 5);
26175 int offset = extract32(ctx->opcode, 0, 16);
26177 #ifdef CONFIG_USER_ONLY
26178 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
26179 uint32_t op2 = extract32(ctx->opcode, 6, 5);
26181 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
26182 int rd = extract32(ctx->opcode, 11, 5);
26184 gen_rdhwr(ctx, rt, rd, 0);
26189 gen_tx79_sq(ctx, base, rt, offset);
26192 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
26194 int rs, rt, rd, sa;
26198 rs = (ctx->opcode >> 21) & 0x1f;
26199 rt = (ctx->opcode >> 16) & 0x1f;
26200 rd = (ctx->opcode >> 11) & 0x1f;
26201 sa = (ctx->opcode >> 6) & 0x1f;
26202 imm = sextract32(ctx->opcode, 7, 9);
26204 op1 = MASK_SPECIAL3(ctx->opcode);
26207 * EVA loads and stores overlap Loongson 2E instructions decoded by
26208 * decode_opc_special3_legacy(), so be careful to allow their decoding when
26215 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26223 check_cp0_enabled(ctx);
26224 gen_ld(ctx, op1, rt, rs, imm);
26228 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26233 check_cp0_enabled(ctx);
26234 gen_st(ctx, op1, rt, rs, imm);
26237 check_cp0_enabled(ctx);
26238 gen_st_cond(ctx, op1, rt, rs, imm);
26241 check_cp0_enabled(ctx);
26242 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26243 gen_cache_operation(ctx, rt, rs, imm);
26245 /* Treat as NOP. */
26248 check_cp0_enabled(ctx);
26249 /* Treat as NOP. */
26257 check_insn(ctx, ISA_MIPS32R2);
26258 gen_bitops(ctx, op1, rt, rs, sa, rd);
26261 op2 = MASK_BSHFL(ctx->opcode);
26268 check_insn(ctx, ISA_MIPS32R6);
26269 decode_opc_special3_r6(env, ctx);
26272 check_insn(ctx, ISA_MIPS32R2);
26273 gen_bshfl(ctx, op2, rt, rd);
26277 #if defined(TARGET_MIPS64)
26284 check_insn(ctx, ISA_MIPS64R2);
26285 check_mips_64(ctx);
26286 gen_bitops(ctx, op1, rt, rs, sa, rd);
26289 op2 = MASK_DBSHFL(ctx->opcode);
26300 check_insn(ctx, ISA_MIPS32R6);
26301 decode_opc_special3_r6(env, ctx);
26304 check_insn(ctx, ISA_MIPS64R2);
26305 check_mips_64(ctx);
26306 op2 = MASK_DBSHFL(ctx->opcode);
26307 gen_bshfl(ctx, op2, rt, rd);
26313 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
26318 TCGv t0 = tcg_temp_new();
26319 TCGv t1 = tcg_temp_new();
26321 gen_load_gpr(t0, rt);
26322 gen_load_gpr(t1, rs);
26323 gen_helper_fork(t0, t1);
26331 TCGv t0 = tcg_temp_new();
26333 gen_load_gpr(t0, rs);
26334 gen_helper_yield(t0, cpu_env, t0);
26335 gen_store_gpr(t0, rd);
26340 if (ctx->insn_flags & ISA_MIPS32R6) {
26341 decode_opc_special3_r6(env, ctx);
26343 decode_opc_special3_legacy(env, ctx);
26348 /* MIPS SIMD Architecture (MSA) */
26349 static inline int check_msa_access(DisasContext *ctx)
26351 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
26352 !(ctx->hflags & MIPS_HFLAG_F64))) {
26353 generate_exception_end(ctx, EXCP_RI);
26357 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
26358 if (ctx->insn_flags & ASE_MSA) {
26359 generate_exception_end(ctx, EXCP_MSADIS);
26362 generate_exception_end(ctx, EXCP_RI);
26369 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
26371 /* generates tcg ops to check if any element is 0 */
26372 /* Note this function only works with MSA_WRLEN = 128 */
26373 uint64_t eval_zero_or_big = 0;
26374 uint64_t eval_big = 0;
26375 TCGv_i64 t0 = tcg_temp_new_i64();
26376 TCGv_i64 t1 = tcg_temp_new_i64();
26379 eval_zero_or_big = 0x0101010101010101ULL;
26380 eval_big = 0x8080808080808080ULL;
26383 eval_zero_or_big = 0x0001000100010001ULL;
26384 eval_big = 0x8000800080008000ULL;
26387 eval_zero_or_big = 0x0000000100000001ULL;
26388 eval_big = 0x8000000080000000ULL;
26391 eval_zero_or_big = 0x0000000000000001ULL;
26392 eval_big = 0x8000000000000000ULL;
26395 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
26396 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
26397 tcg_gen_andi_i64(t0, t0, eval_big);
26398 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
26399 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
26400 tcg_gen_andi_i64(t1, t1, eval_big);
26401 tcg_gen_or_i64(t0, t0, t1);
26402 /* if all bits are zero then all elements are not zero */
26403 /* if some bit is non-zero then some element is zero */
26404 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
26405 tcg_gen_trunc_i64_tl(tresult, t0);
26406 tcg_temp_free_i64(t0);
26407 tcg_temp_free_i64(t1);
26410 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
26412 uint8_t df = (ctx->opcode >> 21) & 0x3;
26413 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26414 int64_t s16 = (int16_t)ctx->opcode;
26416 check_msa_access(ctx);
26418 if (ctx->hflags & MIPS_HFLAG_BMASK) {
26419 generate_exception_end(ctx, EXCP_RI);
26426 TCGv_i64 t0 = tcg_temp_new_i64();
26427 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
26428 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
26429 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
26430 tcg_gen_trunc_i64_tl(bcond, t0);
26431 tcg_temp_free_i64(t0);
26438 gen_check_zero_element(bcond, df, wt);
26444 gen_check_zero_element(bcond, df, wt);
26445 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
26449 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
26451 ctx->hflags |= MIPS_HFLAG_BC;
26452 ctx->hflags |= MIPS_HFLAG_BDS32;
26455 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
26457 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
26458 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
26459 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26460 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26462 TCGv_i32 twd = tcg_const_i32(wd);
26463 TCGv_i32 tws = tcg_const_i32(ws);
26464 TCGv_i32 ti8 = tcg_const_i32(i8);
26466 switch (MASK_MSA_I8(ctx->opcode)) {
26468 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
26471 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
26474 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
26477 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
26480 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
26483 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
26486 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
26492 uint8_t df = (ctx->opcode >> 24) & 0x3;
26493 if (df == DF_DOUBLE) {
26494 generate_exception_end(ctx, EXCP_RI);
26496 TCGv_i32 tdf = tcg_const_i32(df);
26497 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
26498 tcg_temp_free_i32(tdf);
26503 MIPS_INVAL("MSA instruction");
26504 generate_exception_end(ctx, EXCP_RI);
26508 tcg_temp_free_i32(twd);
26509 tcg_temp_free_i32(tws);
26510 tcg_temp_free_i32(ti8);
26513 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
26515 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
26516 uint8_t df = (ctx->opcode >> 21) & 0x3;
26517 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
26518 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
26519 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26520 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26522 TCGv_i32 tdf = tcg_const_i32(df);
26523 TCGv_i32 twd = tcg_const_i32(wd);
26524 TCGv_i32 tws = tcg_const_i32(ws);
26525 TCGv_i32 timm = tcg_temp_new_i32();
26526 tcg_gen_movi_i32(timm, u5);
26528 switch (MASK_MSA_I5(ctx->opcode)) {
26530 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
26533 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
26535 case OPC_MAXI_S_df:
26536 tcg_gen_movi_i32(timm, s5);
26537 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
26539 case OPC_MAXI_U_df:
26540 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
26542 case OPC_MINI_S_df:
26543 tcg_gen_movi_i32(timm, s5);
26544 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
26546 case OPC_MINI_U_df:
26547 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
26550 tcg_gen_movi_i32(timm, s5);
26551 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
26553 case OPC_CLTI_S_df:
26554 tcg_gen_movi_i32(timm, s5);
26555 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
26557 case OPC_CLTI_U_df:
26558 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
26560 case OPC_CLEI_S_df:
26561 tcg_gen_movi_i32(timm, s5);
26562 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
26564 case OPC_CLEI_U_df:
26565 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
26569 int32_t s10 = sextract32(ctx->opcode, 11, 10);
26570 tcg_gen_movi_i32(timm, s10);
26571 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
26575 MIPS_INVAL("MSA instruction");
26576 generate_exception_end(ctx, EXCP_RI);
26580 tcg_temp_free_i32(tdf);
26581 tcg_temp_free_i32(twd);
26582 tcg_temp_free_i32(tws);
26583 tcg_temp_free_i32(timm);
26586 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
26588 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
26589 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
26590 uint32_t df = 0, m = 0;
26591 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26592 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26599 if ((dfm & 0x40) == 0x00) {
26602 } else if ((dfm & 0x60) == 0x40) {
26605 } else if ((dfm & 0x70) == 0x60) {
26608 } else if ((dfm & 0x78) == 0x70) {
26612 generate_exception_end(ctx, EXCP_RI);
26616 tdf = tcg_const_i32(df);
26617 tm = tcg_const_i32(m);
26618 twd = tcg_const_i32(wd);
26619 tws = tcg_const_i32(ws);
26621 switch (MASK_MSA_BIT(ctx->opcode)) {
26623 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
26626 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
26629 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
26632 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
26635 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
26638 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
26640 case OPC_BINSLI_df:
26641 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
26643 case OPC_BINSRI_df:
26644 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
26647 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
26650 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
26653 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
26656 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
26659 MIPS_INVAL("MSA instruction");
26660 generate_exception_end(ctx, EXCP_RI);
26664 tcg_temp_free_i32(tdf);
26665 tcg_temp_free_i32(tm);
26666 tcg_temp_free_i32(twd);
26667 tcg_temp_free_i32(tws);
26670 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
26672 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
26673 uint8_t df = (ctx->opcode >> 21) & 0x3;
26674 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26675 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26676 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26678 TCGv_i32 tdf = tcg_const_i32(df);
26679 TCGv_i32 twd = tcg_const_i32(wd);
26680 TCGv_i32 tws = tcg_const_i32(ws);
26681 TCGv_i32 twt = tcg_const_i32(wt);
26683 switch (MASK_MSA_3R(ctx->opcode)) {
26685 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
26688 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
26691 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
26694 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
26696 case OPC_SUBS_S_df:
26697 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
26700 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
26703 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
26706 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
26709 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
26712 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
26714 case OPC_ADDS_A_df:
26715 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
26717 case OPC_SUBS_U_df:
26718 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
26721 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
26724 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
26727 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
26730 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
26733 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
26736 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
26738 case OPC_ADDS_S_df:
26739 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
26741 case OPC_SUBSUS_U_df:
26742 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
26745 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
26748 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
26751 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
26754 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
26757 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
26760 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
26762 case OPC_ADDS_U_df:
26763 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
26765 case OPC_SUBSUU_S_df:
26766 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
26769 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
26772 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
26775 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
26778 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
26781 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
26783 case OPC_ASUB_S_df:
26784 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
26787 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
26790 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
26793 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
26796 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
26799 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
26802 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
26804 case OPC_ASUB_U_df:
26805 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
26808 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
26811 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
26814 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
26817 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
26819 case OPC_AVER_S_df:
26820 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
26823 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
26826 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
26829 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
26832 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
26834 case OPC_AVER_U_df:
26835 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
26838 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
26841 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
26844 case OPC_DOTP_S_df:
26845 case OPC_DOTP_U_df:
26846 case OPC_DPADD_S_df:
26847 case OPC_DPADD_U_df:
26848 case OPC_DPSUB_S_df:
26849 case OPC_HADD_S_df:
26850 case OPC_DPSUB_U_df:
26851 case OPC_HADD_U_df:
26852 case OPC_HSUB_S_df:
26853 case OPC_HSUB_U_df:
26854 if (df == DF_BYTE) {
26855 generate_exception_end(ctx, EXCP_RI);
26858 switch (MASK_MSA_3R(ctx->opcode)) {
26859 case OPC_DOTP_S_df:
26860 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
26862 case OPC_DOTP_U_df:
26863 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
26865 case OPC_DPADD_S_df:
26866 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
26868 case OPC_DPADD_U_df:
26869 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
26871 case OPC_DPSUB_S_df:
26872 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
26874 case OPC_HADD_S_df:
26875 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
26877 case OPC_DPSUB_U_df:
26878 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
26880 case OPC_HADD_U_df:
26881 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
26883 case OPC_HSUB_S_df:
26884 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
26886 case OPC_HSUB_U_df:
26887 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
26892 MIPS_INVAL("MSA instruction");
26893 generate_exception_end(ctx, EXCP_RI);
26896 tcg_temp_free_i32(twd);
26897 tcg_temp_free_i32(tws);
26898 tcg_temp_free_i32(twt);
26899 tcg_temp_free_i32(tdf);
26902 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
26904 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
26905 uint8_t source = (ctx->opcode >> 11) & 0x1f;
26906 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
26907 TCGv telm = tcg_temp_new();
26908 TCGv_i32 tsr = tcg_const_i32(source);
26909 TCGv_i32 tdt = tcg_const_i32(dest);
26911 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
26913 gen_load_gpr(telm, source);
26914 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
26917 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
26918 gen_store_gpr(telm, dest);
26921 gen_helper_msa_move_v(cpu_env, tdt, tsr);
26924 MIPS_INVAL("MSA instruction");
26925 generate_exception_end(ctx, EXCP_RI);
26929 tcg_temp_free(telm);
26930 tcg_temp_free_i32(tdt);
26931 tcg_temp_free_i32(tsr);
26934 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
26937 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
26938 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26939 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26941 TCGv_i32 tws = tcg_const_i32(ws);
26942 TCGv_i32 twd = tcg_const_i32(wd);
26943 TCGv_i32 tn = tcg_const_i32(n);
26944 TCGv_i32 tdf = tcg_const_i32(df);
26946 switch (MASK_MSA_ELM(ctx->opcode)) {
26948 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
26950 case OPC_SPLATI_df:
26951 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
26954 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
26956 case OPC_COPY_S_df:
26957 case OPC_COPY_U_df:
26958 case OPC_INSERT_df:
26959 #if !defined(TARGET_MIPS64)
26960 /* Double format valid only for MIPS64 */
26961 if (df == DF_DOUBLE) {
26962 generate_exception_end(ctx, EXCP_RI);
26966 switch (MASK_MSA_ELM(ctx->opcode)) {
26967 case OPC_COPY_S_df:
26968 if (likely(wd != 0)) {
26969 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
26972 case OPC_COPY_U_df:
26973 if (likely(wd != 0)) {
26974 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
26977 case OPC_INSERT_df:
26978 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
26983 MIPS_INVAL("MSA instruction");
26984 generate_exception_end(ctx, EXCP_RI);
26986 tcg_temp_free_i32(twd);
26987 tcg_temp_free_i32(tws);
26988 tcg_temp_free_i32(tn);
26989 tcg_temp_free_i32(tdf);
26992 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
26994 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
26995 uint32_t df = 0, n = 0;
26997 if ((dfn & 0x30) == 0x00) {
27000 } else if ((dfn & 0x38) == 0x20) {
27003 } else if ((dfn & 0x3c) == 0x30) {
27006 } else if ((dfn & 0x3e) == 0x38) {
27009 } else if (dfn == 0x3E) {
27010 /* CTCMSA, CFCMSA, MOVE.V */
27011 gen_msa_elm_3e(env, ctx);
27014 generate_exception_end(ctx, EXCP_RI);
27018 gen_msa_elm_df(env, ctx, df, n);
27021 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
27023 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
27024 uint8_t df = (ctx->opcode >> 21) & 0x1;
27025 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27026 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27027 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27029 TCGv_i32 twd = tcg_const_i32(wd);
27030 TCGv_i32 tws = tcg_const_i32(ws);
27031 TCGv_i32 twt = tcg_const_i32(wt);
27032 TCGv_i32 tdf = tcg_temp_new_i32();
27034 /* adjust df value for floating-point instruction */
27035 tcg_gen_movi_i32(tdf, df + 2);
27037 switch (MASK_MSA_3RF(ctx->opcode)) {
27039 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
27042 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
27045 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
27048 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
27051 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
27054 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
27057 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
27060 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
27063 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
27066 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
27069 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
27072 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
27075 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
27078 tcg_gen_movi_i32(tdf, df + 1);
27079 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
27082 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
27085 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
27087 case OPC_MADD_Q_df:
27088 tcg_gen_movi_i32(tdf, df + 1);
27089 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
27092 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
27094 case OPC_MSUB_Q_df:
27095 tcg_gen_movi_i32(tdf, df + 1);
27096 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
27099 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
27102 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
27105 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
27108 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
27111 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
27114 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
27117 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
27120 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
27123 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
27126 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
27129 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
27132 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
27135 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
27137 case OPC_MULR_Q_df:
27138 tcg_gen_movi_i32(tdf, df + 1);
27139 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
27142 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
27144 case OPC_FMIN_A_df:
27145 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
27147 case OPC_MADDR_Q_df:
27148 tcg_gen_movi_i32(tdf, df + 1);
27149 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
27152 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
27155 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
27157 case OPC_MSUBR_Q_df:
27158 tcg_gen_movi_i32(tdf, df + 1);
27159 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
27162 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
27164 case OPC_FMAX_A_df:
27165 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
27168 MIPS_INVAL("MSA instruction");
27169 generate_exception_end(ctx, EXCP_RI);
27173 tcg_temp_free_i32(twd);
27174 tcg_temp_free_i32(tws);
27175 tcg_temp_free_i32(twt);
27176 tcg_temp_free_i32(tdf);
27179 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
27181 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27182 (op & (0x7 << 18)))
27183 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27184 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27185 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27186 uint8_t df = (ctx->opcode >> 16) & 0x3;
27187 TCGv_i32 twd = tcg_const_i32(wd);
27188 TCGv_i32 tws = tcg_const_i32(ws);
27189 TCGv_i32 twt = tcg_const_i32(wt);
27190 TCGv_i32 tdf = tcg_const_i32(df);
27192 switch (MASK_MSA_2R(ctx->opcode)) {
27194 #if !defined(TARGET_MIPS64)
27195 /* Double format valid only for MIPS64 */
27196 if (df == DF_DOUBLE) {
27197 generate_exception_end(ctx, EXCP_RI);
27201 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
27204 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
27207 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
27210 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
27213 MIPS_INVAL("MSA instruction");
27214 generate_exception_end(ctx, EXCP_RI);
27218 tcg_temp_free_i32(twd);
27219 tcg_temp_free_i32(tws);
27220 tcg_temp_free_i32(twt);
27221 tcg_temp_free_i32(tdf);
27224 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
27226 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27227 (op & (0xf << 17)))
27228 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27229 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27230 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27231 uint8_t df = (ctx->opcode >> 16) & 0x1;
27232 TCGv_i32 twd = tcg_const_i32(wd);
27233 TCGv_i32 tws = tcg_const_i32(ws);
27234 TCGv_i32 twt = tcg_const_i32(wt);
27235 /* adjust df value for floating-point instruction */
27236 TCGv_i32 tdf = tcg_const_i32(df + 2);
27238 switch (MASK_MSA_2RF(ctx->opcode)) {
27239 case OPC_FCLASS_df:
27240 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
27242 case OPC_FTRUNC_S_df:
27243 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
27245 case OPC_FTRUNC_U_df:
27246 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
27249 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
27251 case OPC_FRSQRT_df:
27252 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
27255 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
27258 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
27261 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
27263 case OPC_FEXUPL_df:
27264 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
27266 case OPC_FEXUPR_df:
27267 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
27270 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
27273 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
27275 case OPC_FTINT_S_df:
27276 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
27278 case OPC_FTINT_U_df:
27279 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
27281 case OPC_FFINT_S_df:
27282 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
27284 case OPC_FFINT_U_df:
27285 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
27289 tcg_temp_free_i32(twd);
27290 tcg_temp_free_i32(tws);
27291 tcg_temp_free_i32(twt);
27292 tcg_temp_free_i32(tdf);
27295 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
27297 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
27298 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27299 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27300 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27301 TCGv_i32 twd = tcg_const_i32(wd);
27302 TCGv_i32 tws = tcg_const_i32(ws);
27303 TCGv_i32 twt = tcg_const_i32(wt);
27305 switch (MASK_MSA_VEC(ctx->opcode)) {
27307 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
27310 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
27313 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
27316 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
27319 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
27322 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
27325 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
27328 MIPS_INVAL("MSA instruction");
27329 generate_exception_end(ctx, EXCP_RI);
27333 tcg_temp_free_i32(twd);
27334 tcg_temp_free_i32(tws);
27335 tcg_temp_free_i32(twt);
27338 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
27340 switch (MASK_MSA_VEC(ctx->opcode)) {
27348 gen_msa_vec_v(env, ctx);
27351 gen_msa_2r(env, ctx);
27354 gen_msa_2rf(env, ctx);
27357 MIPS_INVAL("MSA instruction");
27358 generate_exception_end(ctx, EXCP_RI);
27363 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
27365 uint32_t opcode = ctx->opcode;
27366 check_insn(ctx, ASE_MSA);
27367 check_msa_access(ctx);
27369 switch (MASK_MSA_MINOR(opcode)) {
27370 case OPC_MSA_I8_00:
27371 case OPC_MSA_I8_01:
27372 case OPC_MSA_I8_02:
27373 gen_msa_i8(env, ctx);
27375 case OPC_MSA_I5_06:
27376 case OPC_MSA_I5_07:
27377 gen_msa_i5(env, ctx);
27379 case OPC_MSA_BIT_09:
27380 case OPC_MSA_BIT_0A:
27381 gen_msa_bit(env, ctx);
27383 case OPC_MSA_3R_0D:
27384 case OPC_MSA_3R_0E:
27385 case OPC_MSA_3R_0F:
27386 case OPC_MSA_3R_10:
27387 case OPC_MSA_3R_11:
27388 case OPC_MSA_3R_12:
27389 case OPC_MSA_3R_13:
27390 case OPC_MSA_3R_14:
27391 case OPC_MSA_3R_15:
27392 gen_msa_3r(env, ctx);
27395 gen_msa_elm(env, ctx);
27397 case OPC_MSA_3RF_1A:
27398 case OPC_MSA_3RF_1B:
27399 case OPC_MSA_3RF_1C:
27400 gen_msa_3rf(env, ctx);
27403 gen_msa_vec(env, ctx);
27414 int32_t s10 = sextract32(ctx->opcode, 16, 10);
27415 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
27416 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27417 uint8_t df = (ctx->opcode >> 0) & 0x3;
27419 TCGv_i32 twd = tcg_const_i32(wd);
27420 TCGv taddr = tcg_temp_new();
27421 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
27423 switch (MASK_MSA_MINOR(opcode)) {
27425 gen_helper_msa_ld_b(cpu_env, twd, taddr);
27428 gen_helper_msa_ld_h(cpu_env, twd, taddr);
27431 gen_helper_msa_ld_w(cpu_env, twd, taddr);
27434 gen_helper_msa_ld_d(cpu_env, twd, taddr);
27437 gen_helper_msa_st_b(cpu_env, twd, taddr);
27440 gen_helper_msa_st_h(cpu_env, twd, taddr);
27443 gen_helper_msa_st_w(cpu_env, twd, taddr);
27446 gen_helper_msa_st_d(cpu_env, twd, taddr);
27450 tcg_temp_free_i32(twd);
27451 tcg_temp_free(taddr);
27455 MIPS_INVAL("MSA instruction");
27456 generate_exception_end(ctx, EXCP_RI);
27462 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
27465 int rs, rt, rd, sa;
27469 /* make sure instructions are on a word boundary */
27470 if (ctx->base.pc_next & 0x3) {
27471 env->CP0_BadVAddr = ctx->base.pc_next;
27472 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
27476 /* Handle blikely not taken case */
27477 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
27478 TCGLabel *l1 = gen_new_label();
27480 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
27481 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
27482 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
27486 op = MASK_OP_MAJOR(ctx->opcode);
27487 rs = (ctx->opcode >> 21) & 0x1f;
27488 rt = (ctx->opcode >> 16) & 0x1f;
27489 rd = (ctx->opcode >> 11) & 0x1f;
27490 sa = (ctx->opcode >> 6) & 0x1f;
27491 imm = (int16_t)ctx->opcode;
27494 decode_opc_special(env, ctx);
27497 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
27498 decode_tx79_mmi(env, ctx);
27499 } else if (ctx->insn_flags & ASE_MXU) {
27500 decode_opc_mxu(env, ctx);
27502 decode_opc_special2_legacy(env, ctx);
27506 if (ctx->insn_flags & INSN_R5900) {
27507 decode_tx79_sq(env, ctx); /* TX79_SQ */
27509 decode_opc_special3(env, ctx);
27513 op1 = MASK_REGIMM(ctx->opcode);
27515 case OPC_BLTZL: /* REGIMM branches */
27519 check_insn(ctx, ISA_MIPS2);
27520 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27524 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
27528 if (ctx->insn_flags & ISA_MIPS32R6) {
27530 /* OPC_NAL, OPC_BAL */
27531 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
27533 generate_exception_end(ctx, EXCP_RI);
27536 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
27539 case OPC_TGEI: /* REGIMM traps */
27546 check_insn(ctx, ISA_MIPS2);
27547 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27548 gen_trap(ctx, op1, rs, -1, imm);
27551 check_insn(ctx, ISA_MIPS32R6);
27552 generate_exception_end(ctx, EXCP_RI);
27555 check_insn(ctx, ISA_MIPS32R2);
27556 /* Break the TB to be able to sync copied instructions
27558 ctx->base.is_jmp = DISAS_STOP;
27560 case OPC_BPOSGE32: /* MIPS DSP branch */
27561 #if defined(TARGET_MIPS64)
27565 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
27567 #if defined(TARGET_MIPS64)
27569 check_insn(ctx, ISA_MIPS32R6);
27570 check_mips_64(ctx);
27572 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
27576 check_insn(ctx, ISA_MIPS32R6);
27577 check_mips_64(ctx);
27579 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
27583 default: /* Invalid */
27584 MIPS_INVAL("regimm");
27585 generate_exception_end(ctx, EXCP_RI);
27590 check_cp0_enabled(ctx);
27591 op1 = MASK_CP0(ctx->opcode);
27599 #if defined(TARGET_MIPS64)
27603 #ifndef CONFIG_USER_ONLY
27604 gen_cp0(env, ctx, op1, rt, rd);
27605 #endif /* !CONFIG_USER_ONLY */
27623 #ifndef CONFIG_USER_ONLY
27624 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
27625 #endif /* !CONFIG_USER_ONLY */
27628 #ifndef CONFIG_USER_ONLY
27631 TCGv t0 = tcg_temp_new();
27633 op2 = MASK_MFMC0(ctx->opcode);
27637 gen_helper_dmt(t0);
27638 gen_store_gpr(t0, rt);
27642 gen_helper_emt(t0);
27643 gen_store_gpr(t0, rt);
27647 gen_helper_dvpe(t0, cpu_env);
27648 gen_store_gpr(t0, rt);
27652 gen_helper_evpe(t0, cpu_env);
27653 gen_store_gpr(t0, rt);
27656 check_insn(ctx, ISA_MIPS32R6);
27658 gen_helper_dvp(t0, cpu_env);
27659 gen_store_gpr(t0, rt);
27663 check_insn(ctx, ISA_MIPS32R6);
27665 gen_helper_evp(t0, cpu_env);
27666 gen_store_gpr(t0, rt);
27670 check_insn(ctx, ISA_MIPS32R2);
27671 save_cpu_state(ctx, 1);
27672 gen_helper_di(t0, cpu_env);
27673 gen_store_gpr(t0, rt);
27674 /* Stop translation as we may have switched
27675 the execution mode. */
27676 ctx->base.is_jmp = DISAS_STOP;
27679 check_insn(ctx, ISA_MIPS32R2);
27680 save_cpu_state(ctx, 1);
27681 gen_helper_ei(t0, cpu_env);
27682 gen_store_gpr(t0, rt);
27683 /* DISAS_STOP isn't sufficient, we need to ensure we break
27684 out of translated code to check for pending interrupts */
27685 gen_save_pc(ctx->base.pc_next + 4);
27686 ctx->base.is_jmp = DISAS_EXIT;
27688 default: /* Invalid */
27689 MIPS_INVAL("mfmc0");
27690 generate_exception_end(ctx, EXCP_RI);
27695 #endif /* !CONFIG_USER_ONLY */
27698 check_insn(ctx, ISA_MIPS32R2);
27699 gen_load_srsgpr(rt, rd);
27702 check_insn(ctx, ISA_MIPS32R2);
27703 gen_store_srsgpr(rt, rd);
27707 generate_exception_end(ctx, EXCP_RI);
27711 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
27712 if (ctx->insn_flags & ISA_MIPS32R6) {
27713 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
27714 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27717 /* Arithmetic with immediate opcode */
27718 gen_arith_imm(ctx, op, rt, rs, imm);
27722 gen_arith_imm(ctx, op, rt, rs, imm);
27724 case OPC_SLTI: /* Set on less than with immediate opcode */
27726 gen_slt_imm(ctx, op, rt, rs, imm);
27728 case OPC_ANDI: /* Arithmetic with immediate opcode */
27729 case OPC_LUI: /* OPC_AUI */
27732 gen_logic_imm(ctx, op, rt, rs, imm);
27734 case OPC_J: /* Jump */
27736 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
27737 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
27740 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
27741 if (ctx->insn_flags & ISA_MIPS32R6) {
27743 generate_exception_end(ctx, EXCP_RI);
27746 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
27747 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27750 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
27753 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
27754 if (ctx->insn_flags & ISA_MIPS32R6) {
27756 generate_exception_end(ctx, EXCP_RI);
27759 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
27760 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27763 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
27766 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
27769 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
27771 check_insn(ctx, ISA_MIPS32R6);
27772 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
27773 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27776 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
27779 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
27781 check_insn(ctx, ISA_MIPS32R6);
27782 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
27783 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27788 check_insn(ctx, ISA_MIPS2);
27789 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27793 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
27795 case OPC_LL: /* Load and stores */
27796 check_insn(ctx, ISA_MIPS2);
27797 check_insn_opc_user_only(ctx, INSN_R5900);
27801 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27809 gen_ld(ctx, op, rt, rs, imm);
27813 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27818 gen_st(ctx, op, rt, rs, imm);
27821 check_insn(ctx, ISA_MIPS2);
27822 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27823 check_insn_opc_user_only(ctx, INSN_R5900);
27824 gen_st_cond(ctx, op, rt, rs, imm);
27827 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27828 check_cp0_enabled(ctx);
27829 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
27830 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27831 gen_cache_operation(ctx, rt, rs, imm);
27833 /* Treat as NOP. */
27836 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27837 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
27839 /* Treat as NOP. */
27842 /* Floating point (COP1). */
27847 gen_cop1_ldst(ctx, op, rt, rs, imm);
27851 op1 = MASK_CP1(ctx->opcode);
27856 check_cp1_enabled(ctx);
27857 check_insn(ctx, ISA_MIPS32R2);
27863 check_cp1_enabled(ctx);
27864 gen_cp1(ctx, op1, rt, rd);
27866 #if defined(TARGET_MIPS64)
27869 check_cp1_enabled(ctx);
27870 check_insn(ctx, ISA_MIPS3);
27871 check_mips_64(ctx);
27872 gen_cp1(ctx, op1, rt, rd);
27875 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
27876 check_cp1_enabled(ctx);
27877 if (ctx->insn_flags & ISA_MIPS32R6) {
27879 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
27884 check_insn(ctx, ASE_MIPS3D);
27885 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
27886 (rt >> 2) & 0x7, imm << 2);
27890 check_cp1_enabled(ctx);
27891 check_insn(ctx, ISA_MIPS32R6);
27892 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
27896 check_cp1_enabled(ctx);
27897 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27899 check_insn(ctx, ASE_MIPS3D);
27902 check_cp1_enabled(ctx);
27903 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27904 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
27905 (rt >> 2) & 0x7, imm << 2);
27912 check_cp1_enabled(ctx);
27913 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
27919 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
27920 check_cp1_enabled(ctx);
27921 if (ctx->insn_flags & ISA_MIPS32R6) {
27923 case R6_OPC_CMP_AF_S:
27924 case R6_OPC_CMP_UN_S:
27925 case R6_OPC_CMP_EQ_S:
27926 case R6_OPC_CMP_UEQ_S:
27927 case R6_OPC_CMP_LT_S:
27928 case R6_OPC_CMP_ULT_S:
27929 case R6_OPC_CMP_LE_S:
27930 case R6_OPC_CMP_ULE_S:
27931 case R6_OPC_CMP_SAF_S:
27932 case R6_OPC_CMP_SUN_S:
27933 case R6_OPC_CMP_SEQ_S:
27934 case R6_OPC_CMP_SEUQ_S:
27935 case R6_OPC_CMP_SLT_S:
27936 case R6_OPC_CMP_SULT_S:
27937 case R6_OPC_CMP_SLE_S:
27938 case R6_OPC_CMP_SULE_S:
27939 case R6_OPC_CMP_OR_S:
27940 case R6_OPC_CMP_UNE_S:
27941 case R6_OPC_CMP_NE_S:
27942 case R6_OPC_CMP_SOR_S:
27943 case R6_OPC_CMP_SUNE_S:
27944 case R6_OPC_CMP_SNE_S:
27945 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
27947 case R6_OPC_CMP_AF_D:
27948 case R6_OPC_CMP_UN_D:
27949 case R6_OPC_CMP_EQ_D:
27950 case R6_OPC_CMP_UEQ_D:
27951 case R6_OPC_CMP_LT_D:
27952 case R6_OPC_CMP_ULT_D:
27953 case R6_OPC_CMP_LE_D:
27954 case R6_OPC_CMP_ULE_D:
27955 case R6_OPC_CMP_SAF_D:
27956 case R6_OPC_CMP_SUN_D:
27957 case R6_OPC_CMP_SEQ_D:
27958 case R6_OPC_CMP_SEUQ_D:
27959 case R6_OPC_CMP_SLT_D:
27960 case R6_OPC_CMP_SULT_D:
27961 case R6_OPC_CMP_SLE_D:
27962 case R6_OPC_CMP_SULE_D:
27963 case R6_OPC_CMP_OR_D:
27964 case R6_OPC_CMP_UNE_D:
27965 case R6_OPC_CMP_NE_D:
27966 case R6_OPC_CMP_SOR_D:
27967 case R6_OPC_CMP_SUNE_D:
27968 case R6_OPC_CMP_SNE_D:
27969 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
27972 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
27973 rt, rd, sa, (imm >> 8) & 0x7);
27978 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
27993 check_insn(ctx, ASE_MSA);
27994 gen_msa_branch(env, ctx, op1);
27998 generate_exception_end(ctx, EXCP_RI);
28003 /* Compact branches [R6] and COP2 [non-R6] */
28004 case OPC_BC: /* OPC_LWC2 */
28005 case OPC_BALC: /* OPC_SWC2 */
28006 if (ctx->insn_flags & ISA_MIPS32R6) {
28007 /* OPC_BC, OPC_BALC */
28008 gen_compute_compact_branch(ctx, op, 0, 0,
28009 sextract32(ctx->opcode << 2, 0, 28));
28011 /* OPC_LWC2, OPC_SWC2 */
28012 /* COP2: Not implemented. */
28013 generate_exception_err(ctx, EXCP_CpU, 2);
28016 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
28017 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
28018 if (ctx->insn_flags & ISA_MIPS32R6) {
28020 /* OPC_BEQZC, OPC_BNEZC */
28021 gen_compute_compact_branch(ctx, op, rs, 0,
28022 sextract32(ctx->opcode << 2, 0, 23));
28024 /* OPC_JIC, OPC_JIALC */
28025 gen_compute_compact_branch(ctx, op, 0, rt, imm);
28028 /* OPC_LWC2, OPC_SWC2 */
28029 /* COP2: Not implemented. */
28030 generate_exception_err(ctx, EXCP_CpU, 2);
28034 check_insn(ctx, INSN_LOONGSON2F);
28035 /* Note that these instructions use different fields. */
28036 gen_loongson_multimedia(ctx, sa, rd, rt);
28040 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28041 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
28042 check_cp1_enabled(ctx);
28043 op1 = MASK_CP3(ctx->opcode);
28047 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
28053 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28054 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
28057 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28058 /* Treat as NOP. */
28061 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
28075 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28076 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
28080 generate_exception_end(ctx, EXCP_RI);
28084 generate_exception_err(ctx, EXCP_CpU, 1);
28088 #if defined(TARGET_MIPS64)
28089 /* MIPS64 opcodes */
28091 check_insn_opc_user_only(ctx, INSN_R5900);
28095 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28099 check_insn(ctx, ISA_MIPS3);
28100 check_mips_64(ctx);
28101 gen_ld(ctx, op, rt, rs, imm);
28105 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28108 check_insn(ctx, ISA_MIPS3);
28109 check_mips_64(ctx);
28110 gen_st(ctx, op, rt, rs, imm);
28113 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28114 check_insn(ctx, ISA_MIPS3);
28115 check_insn_opc_user_only(ctx, INSN_R5900);
28116 check_mips_64(ctx);
28117 gen_st_cond(ctx, op, rt, rs, imm);
28119 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
28120 if (ctx->insn_flags & ISA_MIPS32R6) {
28121 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
28122 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28125 check_insn(ctx, ISA_MIPS3);
28126 check_mips_64(ctx);
28127 gen_arith_imm(ctx, op, rt, rs, imm);
28131 check_insn(ctx, ISA_MIPS3);
28132 check_mips_64(ctx);
28133 gen_arith_imm(ctx, op, rt, rs, imm);
28136 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
28137 if (ctx->insn_flags & ISA_MIPS32R6) {
28138 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28140 MIPS_INVAL("major opcode");
28141 generate_exception_end(ctx, EXCP_RI);
28145 case OPC_DAUI: /* OPC_JALX */
28146 if (ctx->insn_flags & ISA_MIPS32R6) {
28147 #if defined(TARGET_MIPS64)
28149 check_mips_64(ctx);
28151 generate_exception(ctx, EXCP_RI);
28152 } else if (rt != 0) {
28153 TCGv t0 = tcg_temp_new();
28154 gen_load_gpr(t0, rs);
28155 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
28159 generate_exception_end(ctx, EXCP_RI);
28160 MIPS_INVAL("major opcode");
28164 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
28165 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
28166 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
28169 case OPC_MSA: /* OPC_MDMX */
28170 if (ctx->insn_flags & INSN_R5900) {
28171 decode_tx79_lq(env, ctx); /* TX79_LQ */
28173 /* MDMX: Not implemented. */
28178 check_insn(ctx, ISA_MIPS32R6);
28179 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
28181 default: /* Invalid */
28182 MIPS_INVAL("major opcode");
28183 generate_exception_end(ctx, EXCP_RI);
28188 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
28190 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28191 CPUMIPSState *env = cs->env_ptr;
28193 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
28194 ctx->saved_pc = -1;
28195 ctx->insn_flags = env->insn_flags;
28196 ctx->CP0_Config1 = env->CP0_Config1;
28197 ctx->CP0_Config2 = env->CP0_Config2;
28198 ctx->CP0_Config3 = env->CP0_Config3;
28199 ctx->CP0_Config5 = env->CP0_Config5;
28201 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
28202 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
28203 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
28204 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
28205 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
28206 ctx->PAMask = env->PAMask;
28207 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
28208 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
28209 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
28210 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
28211 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
28212 /* Restore delay slot state from the tb context. */
28213 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
28214 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
28215 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
28216 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
28217 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
28218 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
28219 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
28220 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
28221 restore_cpu_state(env, ctx);
28222 #ifdef CONFIG_USER_ONLY
28223 ctx->mem_idx = MIPS_HFLAG_UM;
28225 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
28227 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
28228 MO_UNALN : MO_ALIGN;
28230 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
28234 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
28238 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
28240 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28242 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
28246 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
28247 const CPUBreakpoint *bp)
28249 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28251 save_cpu_state(ctx, 1);
28252 ctx->base.is_jmp = DISAS_NORETURN;
28253 gen_helper_raise_exception_debug(cpu_env);
28254 /* The address covered by the breakpoint must be included in
28255 [tb->pc, tb->pc + tb->size) in order to for it to be
28256 properly cleared -- thus we increment the PC here so that
28257 the logic setting tb->size below does the right thing. */
28258 ctx->base.pc_next += 4;
28262 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
28264 CPUMIPSState *env = cs->env_ptr;
28265 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28269 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
28270 if (ctx->insn_flags & ISA_NANOMIPS32) {
28271 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28272 insn_bytes = decode_nanomips_opc(env, ctx);
28273 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
28274 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
28276 decode_opc(env, ctx);
28277 } else if (ctx->insn_flags & ASE_MICROMIPS) {
28278 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28279 insn_bytes = decode_micromips_opc(env, ctx);
28280 } else if (ctx->insn_flags & ASE_MIPS16) {
28281 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28282 insn_bytes = decode_mips16_opc(env, ctx);
28284 generate_exception_end(ctx, EXCP_RI);
28285 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
28289 if (ctx->hflags & MIPS_HFLAG_BMASK) {
28290 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
28291 MIPS_HFLAG_FBNSLOT))) {
28292 /* force to generate branch as there is neither delay nor
28296 if ((ctx->hflags & MIPS_HFLAG_M16) &&
28297 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
28298 /* Force to generate branch as microMIPS R6 doesn't restrict
28299 branches in the forbidden slot. */
28304 gen_branch(ctx, insn_bytes);
28306 ctx->base.pc_next += insn_bytes;
28308 if (ctx->base.is_jmp != DISAS_NEXT) {
28311 /* Execute a branch and its delay slot as a single instruction.
28312 This is what GDB expects and is consistent with what the
28313 hardware does (e.g. if a delay slot instruction faults, the
28314 reported PC is the PC of the branch). */
28315 if (ctx->base.singlestep_enabled &&
28316 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
28317 ctx->base.is_jmp = DISAS_TOO_MANY;
28319 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
28320 ctx->base.is_jmp = DISAS_TOO_MANY;
28324 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
28326 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28328 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
28329 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
28330 gen_helper_raise_exception_debug(cpu_env);
28332 switch (ctx->base.is_jmp) {
28334 gen_save_pc(ctx->base.pc_next);
28335 tcg_gen_lookup_and_goto_ptr();
28338 case DISAS_TOO_MANY:
28339 save_cpu_state(ctx, 0);
28340 gen_goto_tb(ctx, 0, ctx->base.pc_next);
28343 tcg_gen_exit_tb(NULL, 0);
28345 case DISAS_NORETURN:
28348 g_assert_not_reached();
28353 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
28355 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
28356 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
28359 static const TranslatorOps mips_tr_ops = {
28360 .init_disas_context = mips_tr_init_disas_context,
28361 .tb_start = mips_tr_tb_start,
28362 .insn_start = mips_tr_insn_start,
28363 .breakpoint_check = mips_tr_breakpoint_check,
28364 .translate_insn = mips_tr_translate_insn,
28365 .tb_stop = mips_tr_tb_stop,
28366 .disas_log = mips_tr_disas_log,
28369 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
28373 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
28376 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
28380 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
28382 #define printfpr(fp) \
28385 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
28386 " fd:%13g fs:%13g psu: %13g\n", \
28387 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
28388 (double)(fp)->fd, \
28389 (double)(fp)->fs[FP_ENDIAN_IDX], \
28390 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
28393 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
28394 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
28395 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
28396 " fd:%13g fs:%13g psu:%13g\n", \
28397 tmp.w[FP_ENDIAN_IDX], tmp.d, \
28399 (double)tmp.fs[FP_ENDIAN_IDX], \
28400 (double)tmp.fs[!FP_ENDIAN_IDX]); \
28405 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
28406 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
28407 get_float_exception_flags(&env->active_fpu.fp_status));
28408 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
28409 fpu_fprintf(f, "%3s: ", fregnames[i]);
28410 printfpr(&env->active_fpu.fpr[i]);
28416 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
28419 MIPSCPU *cpu = MIPS_CPU(cs);
28420 CPUMIPSState *env = &cpu->env;
28423 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
28424 " LO=0x" TARGET_FMT_lx " ds %04x "
28425 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
28426 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
28427 env->hflags, env->btarget, env->bcond);
28428 for (i = 0; i < 32; i++) {
28430 cpu_fprintf(f, "GPR%02d:", i);
28431 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
28433 cpu_fprintf(f, "\n");
28436 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
28437 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
28438 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
28440 env->CP0_Config0, env->CP0_Config1, env->lladdr);
28441 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
28442 env->CP0_Config2, env->CP0_Config3);
28443 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
28444 env->CP0_Config4, env->CP0_Config5);
28445 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
28446 fpu_dump_state(env, f, cpu_fprintf, flags);
28450 void mips_tcg_init(void)
28455 for (i = 1; i < 32; i++)
28456 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
28457 offsetof(CPUMIPSState, active_tc.gpr[i]),
28460 for (i = 0; i < 32; i++) {
28461 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
28463 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
28464 /* The scalar floating-point unit (FPU) registers are mapped on
28465 * the MSA vector registers. */
28466 fpu_f64[i] = msa_wr_d[i * 2];
28467 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
28468 msa_wr_d[i * 2 + 1] =
28469 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
28472 cpu_PC = tcg_global_mem_new(cpu_env,
28473 offsetof(CPUMIPSState, active_tc.PC), "PC");
28474 for (i = 0; i < MIPS_DSP_ACC; i++) {
28475 cpu_HI[i] = tcg_global_mem_new(cpu_env,
28476 offsetof(CPUMIPSState, active_tc.HI[i]),
28478 cpu_LO[i] = tcg_global_mem_new(cpu_env,
28479 offsetof(CPUMIPSState, active_tc.LO[i]),
28482 cpu_dspctrl = tcg_global_mem_new(cpu_env,
28483 offsetof(CPUMIPSState, active_tc.DSPControl),
28485 bcond = tcg_global_mem_new(cpu_env,
28486 offsetof(CPUMIPSState, bcond), "bcond");
28487 btarget = tcg_global_mem_new(cpu_env,
28488 offsetof(CPUMIPSState, btarget), "btarget");
28489 hflags = tcg_global_mem_new_i32(cpu_env,
28490 offsetof(CPUMIPSState, hflags), "hflags");
28492 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
28493 offsetof(CPUMIPSState, active_fpu.fcr0),
28495 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
28496 offsetof(CPUMIPSState, active_fpu.fcr31),
28499 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
28500 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
28501 offsetof(CPUMIPSState,
28502 active_tc.mxu_gpr[i]),
28506 mxu_CR = tcg_global_mem_new(cpu_env,
28507 offsetof(CPUMIPSState, active_tc.mxu_cr),
28508 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
28511 #include "translate_init.inc.c"
28513 void cpu_mips_realize_env(CPUMIPSState *env)
28515 env->exception_base = (int32_t)0xBFC00000;
28517 #ifndef CONFIG_USER_ONLY
28518 mmu_init(env, env->cpu_model);
28520 fpu_init(env, env->cpu_model);
28521 mvp_init(env, env->cpu_model);
28524 bool cpu_supports_cps_smp(const char *cpu_type)
28526 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
28527 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
28530 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
28532 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
28533 return (mcc->cpu_def->insn_flags & isa) != 0;
28536 void cpu_set_exception_base(int vp_index, target_ulong address)
28538 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
28539 vp->env.exception_base = address;
28542 void cpu_state_reset(CPUMIPSState *env)
28544 MIPSCPU *cpu = mips_env_get_cpu(env);
28545 CPUState *cs = CPU(cpu);
28547 /* Reset registers to their default values */
28548 env->CP0_PRid = env->cpu_model->CP0_PRid;
28549 env->CP0_Config0 = env->cpu_model->CP0_Config0;
28550 #ifdef TARGET_WORDS_BIGENDIAN
28551 env->CP0_Config0 |= (1 << CP0C0_BE);
28553 env->CP0_Config1 = env->cpu_model->CP0_Config1;
28554 env->CP0_Config2 = env->cpu_model->CP0_Config2;
28555 env->CP0_Config3 = env->cpu_model->CP0_Config3;
28556 env->CP0_Config4 = env->cpu_model->CP0_Config4;
28557 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
28558 env->CP0_Config5 = env->cpu_model->CP0_Config5;
28559 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
28560 env->CP0_Config6 = env->cpu_model->CP0_Config6;
28561 env->CP0_Config7 = env->cpu_model->CP0_Config7;
28562 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
28563 << env->cpu_model->CP0_LLAddr_shift;
28564 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
28565 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
28566 env->CCRes = env->cpu_model->CCRes;
28567 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
28568 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
28569 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
28570 env->current_tc = 0;
28571 env->SEGBITS = env->cpu_model->SEGBITS;
28572 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
28573 #if defined(TARGET_MIPS64)
28574 if (env->cpu_model->insn_flags & ISA_MIPS3) {
28575 env->SEGMask |= 3ULL << 62;
28578 env->PABITS = env->cpu_model->PABITS;
28579 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
28580 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
28581 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
28582 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
28583 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
28584 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
28585 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
28586 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
28587 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
28588 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
28589 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
28590 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
28591 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
28592 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
28593 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
28594 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
28595 env->msair = env->cpu_model->MSAIR;
28596 env->insn_flags = env->cpu_model->insn_flags;
28598 #if defined(CONFIG_USER_ONLY)
28599 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
28600 # ifdef TARGET_MIPS64
28601 /* Enable 64-bit register mode. */
28602 env->CP0_Status |= (1 << CP0St_PX);
28604 # ifdef TARGET_ABI_MIPSN64
28605 /* Enable 64-bit address mode. */
28606 env->CP0_Status |= (1 << CP0St_UX);
28608 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
28609 hardware registers. */
28610 env->CP0_HWREna |= 0x0000000F;
28611 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
28612 env->CP0_Status |= (1 << CP0St_CU1);
28614 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
28615 env->CP0_Status |= (1 << CP0St_MX);
28617 # if defined(TARGET_MIPS64)
28618 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
28619 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
28620 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
28621 env->CP0_Status |= (1 << CP0St_FR);
28625 if (env->hflags & MIPS_HFLAG_BMASK) {
28626 /* If the exception was raised from a delay slot,
28627 come back to the jump. */
28628 env->CP0_ErrorEPC = (env->active_tc.PC
28629 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
28631 env->CP0_ErrorEPC = env->active_tc.PC;
28633 env->active_tc.PC = env->exception_base;
28634 env->CP0_Random = env->tlb->nb_tlb - 1;
28635 env->tlb->tlb_in_use = env->tlb->nb_tlb;
28636 env->CP0_Wired = 0;
28637 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
28638 env->CP0_EBase = (cs->cpu_index & 0x3FF);
28639 if (mips_um_ksegs_enabled()) {
28640 env->CP0_EBase |= 0x40000000;
28642 env->CP0_EBase |= (int32_t)0x80000000;
28644 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
28645 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
28647 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
28649 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
28650 /* vectored interrupts not implemented, timer on int 7,
28651 no performance counters. */
28652 env->CP0_IntCtl = 0xe0000000;
28656 for (i = 0; i < 7; i++) {
28657 env->CP0_WatchLo[i] = 0;
28658 env->CP0_WatchHi[i] = 0x80000000;
28660 env->CP0_WatchLo[7] = 0;
28661 env->CP0_WatchHi[7] = 0;
28663 /* Count register increments in debug mode, EJTAG version 1 */
28664 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
28666 cpu_mips_store_count(env, 1);
28668 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
28671 /* Only TC0 on VPE 0 starts as active. */
28672 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
28673 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
28674 env->tcs[i].CP0_TCHalt = 1;
28676 env->active_tc.CP0_TCHalt = 1;
28679 if (cs->cpu_index == 0) {
28680 /* VPE0 starts up enabled. */
28681 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
28682 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
28684 /* TC0 starts up unhalted. */
28686 env->active_tc.CP0_TCHalt = 0;
28687 env->tcs[0].CP0_TCHalt = 0;
28688 /* With thread 0 active. */
28689 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
28690 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
28695 * Configure default legacy segmentation control. We use this regardless of
28696 * whether segmentation control is presented to the guest.
28698 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
28699 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
28700 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
28701 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
28702 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
28703 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
28705 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
28706 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
28707 (3 << CP0SC_C)) << 16;
28708 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
28709 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
28710 (1 << CP0SC_EU) | (2 << CP0SC_C);
28711 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
28712 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
28713 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
28714 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
28715 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
28717 if ((env->insn_flags & ISA_MIPS32R6) &&
28718 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
28719 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
28720 env->CP0_Status |= (1 << CP0St_FR);
28723 if (env->insn_flags & ISA_MIPS32R6) {
28725 env->CP0_PWSize = 0x40;
28731 env->CP0_PWField = 0x0C30C302;
28738 env->CP0_PWField = 0x02;
28741 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
28742 /* microMIPS on reset when Config3.ISA is 3 */
28743 env->hflags |= MIPS_HFLAG_M16;
28747 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
28751 compute_hflags(env);
28752 restore_fp_status(env);
28753 restore_pamask(env);
28754 cs->exception_index = EXCP_NONE;
28756 if (semihosting_get_argc()) {
28757 /* UHI interface can be used to obtain argc and argv */
28758 env->active_tc.gpr[4] = -1;
28762 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
28763 target_ulong *data)
28765 env->active_tc.PC = data[0];
28766 env->hflags &= ~MIPS_HFLAG_BMASK;
28767 env->hflags |= data[1];
28768 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
28769 case MIPS_HFLAG_BR:
28771 case MIPS_HFLAG_BC:
28772 case MIPS_HFLAG_BL:
28774 env->btarget = data[2];