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
1414 * --------------------------------------------
1418 * XRa, XRb, XRc, XRd - MXU registers
1419 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1423 * aptn1 - 1-bit accumulate add/subtract pattern
1424 * aptn2 - 2-bit accumulate add/subtract pattern
1425 * eptn2 - 2-bit execute add/subtract pattern
1426 * optn2 - 2-bit operand pattern
1427 * optn3 - 3-bit operand pattern
1428 * sft4 - 4-bit shift amount
1429 * strd2 - 2-bit stride amount
1433 * <Operation parallel level><Operand size>
1440 * E - Expand results
1441 * F - Fixed point multiplication
1442 * L - Low part result
1443 * R - Doing rounding
1444 * V - Variable instead of immediate
1445 * W - Combine above L and V
1449 * ADD - Add or subtract
1450 * ADDC - Add with carry-in
1452 * ASUM - Sum together then accumulate (add or subtract)
1453 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1454 * AVG - Average between 2 operands
1455 * ABD - Absolute difference
1457 * AND - Logical bitwise 'and' operation
1459 * EXTR - Extract bits
1460 * I2M - Move from GPR register to MXU register
1461 * LDD - Load data from memory to XRF
1462 * LDI - Load data from memory to XRF (and increase the address base)
1463 * LUI - Load unsigned immediate
1465 * MULU - Unsigned multiply
1466 * MADD - 64-bit operand add 32x32 product
1467 * MSUB - 64-bit operand subtract 32x32 product
1468 * MAC - Multiply and accumulate (add or subtract)
1469 * MAD - Multiply and add or subtract
1470 * MAX - Maximum between 2 operands
1471 * MIN - Minimum between 2 operands
1472 * M2I - Move from MXU register to GPR register
1473 * MOVZ - Move if zero
1474 * MOVN - Move if non-zero
1475 * NOR - Logical bitwise 'nor' operation
1476 * OR - Logical bitwise 'or' operation
1477 * STD - Store data from XRF to memory
1478 * SDI - Store data from XRF to memory (and increase the address base)
1479 * SLT - Set of less than comparison
1480 * SAD - Sum of absolute differences
1481 * SLL - Logical shift left
1482 * SLR - Logical shift right
1483 * SAR - Arithmetic shift right
1486 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1487 * XOR - Logical bitwise 'exclusive or' operation
1489 * Load/Store instructions Multiplication instructions
1490 * ----------------------- ---------------------------
1492 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1493 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1494 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1495 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1496 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1497 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1498 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1499 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1500 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1501 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1502 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1503 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1504 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1505 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1506 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1507 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1508 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1509 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1510 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1511 * S16SDI XRa, Rb, s10, eptn2
1512 * S8LDD XRa, Rb, s8, eptn3
1513 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1514 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1515 * S8SDI XRa, Rb, s8, eptn3
1516 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1517 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1518 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1519 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1520 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1521 * S32CPS XRa, XRb, XRc
1522 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1523 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1524 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1525 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1526 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1527 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1528 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1529 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1530 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1531 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1532 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1533 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1534 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1535 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1536 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1537 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1538 * Q8SLT XRa, XRb, XRc
1539 * Q8SLTU XRa, XRb, XRc
1540 * Q8MOVZ XRa, XRb, XRc Shift instructions
1541 * Q8MOVN XRa, XRb, XRc ------------------
1543 * D32SLL XRa, XRb, XRc, XRd, sft4
1544 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1545 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1546 * D32SARL XRa, XRb, XRc, sft4
1547 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1548 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1549 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1550 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1551 * Q16SLL XRa, XRb, XRc, XRd, sft4
1552 * Q16SLR XRa, XRb, XRc, XRd, sft4
1553 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1554 * ------------------------- Q16SLLV XRa, XRb, Rb
1555 * Q16SLRV XRa, XRb, Rb
1556 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1557 * S32ALN XRa, XRb, XRc, Rb
1558 * S32ALNI XRa, XRb, XRc, s3
1559 * S32LUI XRa, s8, optn3 Move instructions
1560 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1561 * S32EXTRV XRa, XRb, Rs, Rt
1562 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1563 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1569 * ┌─ 000000 ─ OPC_MXU_S32MADD
1570 * ├─ 000001 ─ OPC_MXU_S32MADDU
1571 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1574 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1575 * │ ├─ 001 ─ OPC_MXU_S32MIN
1576 * │ ├─ 010 ─ OPC_MXU_D16MAX
1577 * │ ├─ 011 ─ OPC_MXU_D16MIN
1578 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1579 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1580 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1581 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1582 * ├─ 000100 ─ OPC_MXU_S32MSUB
1583 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1584 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1585 * │ ├─ 001 ─ OPC_MXU_D16SLT
1586 * │ ├─ 010 ─ OPC_MXU_D16AVG
1587 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1588 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1589 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1590 * │ └─ 111 ─ OPC_MXU_Q8ADD
1593 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1594 * │ ├─ 010 ─ OPC_MXU_D16CPS
1595 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1596 * │ └─ 110 ─ OPC_MXU_Q16SAT
1597 * ├─ 001000 ─ OPC_MXU_D16MUL
1599 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1600 * │ └─ 01 ─ OPC_MXU_D16MULE
1601 * ├─ 001010 ─ OPC_MXU_D16MAC
1602 * ├─ 001011 ─ OPC_MXU_D16MACF
1603 * ├─ 001100 ─ OPC_MXU_D16MADL
1604 * ├─ 001101 ─ OPC_MXU_S16MAD
1605 * ├─ 001110 ─ OPC_MXU_Q16ADD
1606 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1607 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1608 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1611 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1612 * │ └─ 1 ─ OPC_MXU_S32STDR
1615 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1616 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1619 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1620 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1623 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1624 * │ └─ 1 ─ OPC_MXU_S32LDIR
1627 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1628 * │ └─ 1 ─ OPC_MXU_S32SDIR
1631 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1632 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1635 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1636 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1637 * ├─ 011000 ─ OPC_MXU_D32ADD
1639 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1640 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1641 * │ └─ 10 ─ OPC_MXU_D32ASUM
1642 * ├─ 011010 ─ <not assigned>
1644 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1645 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1646 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1649 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1650 * │ ├─ 01 ─ OPC_MXU_D8SUM
1651 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1652 * ├─ 011110 ─ <not assigned>
1653 * ├─ 011111 ─ <not assigned>
1654 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1655 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1656 * ├─ 100010 ─ OPC_MXU_S8LDD
1657 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1658 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1659 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1660 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1661 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1664 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1665 * │ ├─ 001 ─ OPC_MXU_S32ALN
1666 * ├─ 101000 ─ OPC_MXU_LXB ├─ 010 ─ OPC_MXU_S32ALNI
1667 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_S32NOR
1668 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_S32AND
1669 * ├─ 101011 ─ OPC_MXU_S16STD ├─ 101 ─ OPC_MXU_S32OR
1670 * ├─ 101100 ─ OPC_MXU_S16LDI ├─ 110 ─ OPC_MXU_S32XOR
1671 * ├─ 101101 ─ OPC_MXU_S16SDI └─ 111 ─ OPC_MXU_S32LUI
1672 * ├─ 101110 ─ OPC_MXU_S32M2I
1673 * ├─ 101111 ─ OPC_MXU_S32I2M
1674 * ├─ 110000 ─ OPC_MXU_D32SLL
1675 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1676 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1677 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1678 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1679 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1680 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1681 * ├─ 110110 ─ OPC_MXU__POOL17 ─┴─ 101 ─ OPC_MXU_Q16SARV
1683 * ├─ 110111 ─ OPC_MXU_Q16SAR
1685 * ├─ 111000 ─ OPC_MXU__POOL18 ─┬─ 00 ─ OPC_MXU_Q8MUL
1686 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1689 * ├─ 111001 ─ OPC_MXU__POOL19 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1690 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1691 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1692 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1693 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1694 * │ └─ 101 ─ OPC_MXU_S32MOV
1697 * ├─ 111010 ─ OPC_MXU__POOL20 ─┬─ 00 ─ OPC_MXU_Q8MAC
1698 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1699 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1700 * ├─ 111100 ─ OPC_MXU_Q8MADL
1701 * ├─ 111101 ─ OPC_MXU_S32SFL
1702 * ├─ 111110 ─ OPC_MXU_Q8SAD
1703 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1708 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1709 * Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1713 OPC_MXU_S32MADD = 0x00,
1714 OPC_MXU_S32MADDU = 0x01,
1715 OPC__MXU_MUL = 0x02,
1716 OPC_MXU__POOL00 = 0x03,
1717 OPC_MXU_S32MSUB = 0x04,
1718 OPC_MXU_S32MSUBU = 0x05,
1719 OPC_MXU__POOL01 = 0x06,
1720 OPC_MXU__POOL02 = 0x07,
1721 OPC_MXU_D16MUL = 0x08,
1722 OPC_MXU__POOL03 = 0x09,
1723 OPC_MXU_D16MAC = 0x0A,
1724 OPC_MXU_D16MACF = 0x0B,
1725 OPC_MXU_D16MADL = 0x0C,
1726 OPC_MXU_S16MAD = 0x0D,
1727 OPC_MXU_Q16ADD = 0x0E,
1728 OPC_MXU_D16MACE = 0x0F,
1729 OPC_MXU__POOL04 = 0x10,
1730 OPC_MXU__POOL05 = 0x11,
1731 OPC_MXU__POOL06 = 0x12,
1732 OPC_MXU__POOL07 = 0x13,
1733 OPC_MXU__POOL08 = 0x14,
1734 OPC_MXU__POOL09 = 0x15,
1735 OPC_MXU__POOL10 = 0x16,
1736 OPC_MXU__POOL11 = 0x17,
1737 OPC_MXU_D32ADD = 0x18,
1738 OPC_MXU__POOL12 = 0x19,
1739 /* not assigned 0x1A */
1740 OPC_MXU__POOL13 = 0x1B,
1741 OPC_MXU__POOL14 = 0x1C,
1742 OPC_MXU_Q8ACCE = 0x1D,
1743 /* not assigned 0x1E */
1744 /* not assigned 0x1F */
1745 /* not assigned 0x20 */
1746 /* not assigned 0x21 */
1747 OPC_MXU_S8LDD = 0x22,
1748 OPC_MXU_S8STD = 0x23,
1749 OPC_MXU_S8LDI = 0x24,
1750 OPC_MXU_S8SDI = 0x25,
1751 OPC_MXU__POOL15 = 0x26,
1752 OPC_MXU__POOL16 = 0x27,
1754 /* not assigned 0x29 */
1755 OPC_MXU_S16LDD = 0x2A,
1756 OPC_MXU_S16STD = 0x2B,
1757 OPC_MXU_S16LDI = 0x2C,
1758 OPC_MXU_S16SDI = 0x2D,
1759 OPC_MXU_S32M2I = 0x2E,
1760 OPC_MXU_S32I2M = 0x2F,
1761 OPC_MXU_D32SLL = 0x30,
1762 OPC_MXU_D32SLR = 0x31,
1763 OPC_MXU_D32SARL = 0x32,
1764 OPC_MXU_D32SAR = 0x33,
1765 OPC_MXU_Q16SLL = 0x34,
1766 OPC_MXU_Q16SLR = 0x35,
1767 OPC_MXU__POOL17 = 0x36,
1768 OPC_MXU_Q16SAR = 0x37,
1769 OPC_MXU__POOL18 = 0x38,
1770 OPC_MXU__POOL19 = 0x39,
1771 OPC_MXU__POOL20 = 0x3A,
1772 OPC_MXU_Q16SCOP = 0x3B,
1773 OPC_MXU_Q8MADL = 0x3C,
1774 OPC_MXU_S32SFL = 0x3D,
1775 OPC_MXU_Q8SAD = 0x3E,
1776 /* not assigned 0x3F */
1784 OPC_MXU_S32MAX = 0x00,
1785 OPC_MXU_S32MIN = 0x01,
1786 OPC_MXU_D16MAX = 0x02,
1787 OPC_MXU_D16MIN = 0x03,
1788 OPC_MXU_Q8MAX = 0x04,
1789 OPC_MXU_Q8MIN = 0x05,
1790 OPC_MXU_Q8SLT = 0x06,
1791 OPC_MXU_Q8SLTU = 0x07,
1798 OPC_MXU_S32SLT = 0x00,
1799 OPC_MXU_D16SLT = 0x01,
1800 OPC_MXU_D16AVG = 0x02,
1801 OPC_MXU_D16AVGR = 0x03,
1802 OPC_MXU_Q8AVG = 0x04,
1803 OPC_MXU_Q8AVGR = 0x05,
1804 OPC_MXU_Q8ADD = 0x07,
1811 OPC_MXU_S32CPS = 0x00,
1812 OPC_MXU_D16CPS = 0x02,
1813 OPC_MXU_Q8ABD = 0x04,
1814 OPC_MXU_Q16SAT = 0x06,
1821 OPC_MXU_D16MULF = 0x00,
1822 OPC_MXU_D16MULE = 0x01,
1829 OPC_MXU_S32LDD = 0x00,
1830 OPC_MXU_S32LDDR = 0x01,
1837 OPC_MXU_S32STD = 0x00,
1838 OPC_MXU_S32STDR = 0x01,
1845 OPC_MXU_S32LDDV = 0x00,
1846 OPC_MXU_S32LDDVR = 0x01,
1853 OPC_MXU_S32STDV = 0x00,
1854 OPC_MXU_S32STDVR = 0x01,
1861 OPC_MXU_S32LDI = 0x00,
1862 OPC_MXU_S32LDIR = 0x01,
1869 OPC_MXU_S32SDI = 0x00,
1870 OPC_MXU_S32SDIR = 0x01,
1877 OPC_MXU_S32LDIV = 0x00,
1878 OPC_MXU_S32LDIVR = 0x01,
1885 OPC_MXU_S32SDIV = 0x00,
1886 OPC_MXU_S32SDIVR = 0x01,
1893 OPC_MXU_D32ACC = 0x00,
1894 OPC_MXU_D32ACCM = 0x01,
1895 OPC_MXU_D32ASUM = 0x02,
1902 OPC_MXU_Q16ACC = 0x00,
1903 OPC_MXU_Q16ACCM = 0x01,
1904 OPC_MXU_Q16ASUM = 0x02,
1911 OPC_MXU_Q8ADDE = 0x00,
1912 OPC_MXU_D8SUM = 0x01,
1913 OPC_MXU_D8SUMC = 0x02,
1920 OPC_MXU_S32MUL = 0x00,
1921 OPC_MXU_S32MULU = 0x01,
1922 OPC_MXU_S32EXTR = 0x02,
1923 OPC_MXU_S32EXTRV = 0x03,
1930 OPC_MXU_D32SARW = 0x00,
1931 OPC_MXU_S32ALN = 0x01,
1932 OPC_MXU_S32ALNI = 0x02,
1933 OPC_MXU_S32NOR = 0x03,
1934 OPC_MXU_S32AND = 0x04,
1935 OPC_MXU_S32OR = 0x05,
1936 OPC_MXU_S32XOR = 0x06,
1937 OPC_MXU_S32LUI = 0x07,
1944 OPC_MXU_D32SLLV = 0x00,
1945 OPC_MXU_D32SLRV = 0x01,
1946 OPC_MXU_D32SARV = 0x03,
1947 OPC_MXU_Q16SLLV = 0x04,
1948 OPC_MXU_Q16SLRV = 0x05,
1949 OPC_MXU_Q16SARV = 0x07,
1956 OPC_MXU_Q8MUL = 0x00,
1957 OPC_MXU_Q8MULSU = 0x01,
1964 OPC_MXU_Q8MOVZ = 0x00,
1965 OPC_MXU_Q8MOVN = 0x01,
1966 OPC_MXU_D16MOVZ = 0x02,
1967 OPC_MXU_D16MOVN = 0x03,
1968 OPC_MXU_S32MOVZ = 0x04,
1969 OPC_MXU_S32MOVN = 0x05,
1976 OPC_MXU_Q8MAC = 0x00,
1977 OPC_MXU_Q8MACSU = 0x01,
1981 * Overview of the TX79-specific instruction set
1982 * =============================================
1984 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1985 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1986 * instructions and certain multimedia instructions (MMIs). These MMIs
1987 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1988 * or sixteen 8-bit paths.
1992 * The Toshiba TX System RISC TX79 Core Architecture manual,
1993 * https://wiki.qemu.org/File:C790.pdf
1995 * Three-Operand Multiply and Multiply-Add (4 instructions)
1996 * --------------------------------------------------------
1997 * MADD [rd,] rs, rt Multiply/Add
1998 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1999 * MULT [rd,] rs, rt Multiply (3-operand)
2000 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2002 * Multiply Instructions for Pipeline 1 (10 instructions)
2003 * ------------------------------------------------------
2004 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2005 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2006 * DIV1 rs, rt Divide Pipeline 1
2007 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2008 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2009 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2010 * MFHI1 rd Move From HI1 Register
2011 * MFLO1 rd Move From LO1 Register
2012 * MTHI1 rs Move To HI1 Register
2013 * MTLO1 rs Move To LO1 Register
2015 * Arithmetic (19 instructions)
2016 * ----------------------------
2017 * PADDB rd, rs, rt Parallel Add Byte
2018 * PSUBB rd, rs, rt Parallel Subtract Byte
2019 * PADDH rd, rs, rt Parallel Add Halfword
2020 * PSUBH rd, rs, rt Parallel Subtract Halfword
2021 * PADDW rd, rs, rt Parallel Add Word
2022 * PSUBW rd, rs, rt Parallel Subtract Word
2023 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2024 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2025 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2026 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2027 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2028 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2029 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2030 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2031 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2032 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2033 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2034 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2035 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2037 * Min/Max (4 instructions)
2038 * ------------------------
2039 * PMAXH rd, rs, rt Parallel Maximum Halfword
2040 * PMINH rd, rs, rt Parallel Minimum Halfword
2041 * PMAXW rd, rs, rt Parallel Maximum Word
2042 * PMINW rd, rs, rt Parallel Minimum Word
2044 * Absolute (2 instructions)
2045 * -------------------------
2046 * PABSH rd, rt Parallel Absolute Halfword
2047 * PABSW rd, rt Parallel Absolute Word
2049 * Logical (4 instructions)
2050 * ------------------------
2051 * PAND rd, rs, rt Parallel AND
2052 * POR rd, rs, rt Parallel OR
2053 * PXOR rd, rs, rt Parallel XOR
2054 * PNOR rd, rs, rt Parallel NOR
2056 * Shift (9 instructions)
2057 * ----------------------
2058 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2059 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2060 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2061 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2062 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2063 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2064 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2065 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2066 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2068 * Compare (6 instructions)
2069 * ------------------------
2070 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2071 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2072 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2073 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2074 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2075 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2077 * LZC (1 instruction)
2078 * -------------------
2079 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2081 * Quadword Load and Store (2 instructions)
2082 * ----------------------------------------
2083 * LQ rt, offset(base) Load Quadword
2084 * SQ rt, offset(base) Store Quadword
2086 * Multiply and Divide (19 instructions)
2087 * -------------------------------------
2088 * PMULTW rd, rs, rt Parallel Multiply Word
2089 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2090 * PDIVW rs, rt Parallel Divide Word
2091 * PDIVUW rs, rt Parallel Divide Unsigned Word
2092 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2093 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2094 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2095 * PMULTH rd, rs, rt Parallel Multiply Halfword
2096 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2097 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2098 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2099 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2100 * PDIVBW rs, rt Parallel Divide Broadcast Word
2101 * PMFHI rd Parallel Move From HI Register
2102 * PMFLO rd Parallel Move From LO Register
2103 * PMTHI rs Parallel Move To HI Register
2104 * PMTLO rs Parallel Move To LO Register
2105 * PMFHL rd Parallel Move From HI/LO Register
2106 * PMTHL rs Parallel Move To HI/LO Register
2108 * Pack/Extend (11 instructions)
2109 * -----------------------------
2110 * PPAC5 rd, rt Parallel Pack to 5 bits
2111 * PPACB rd, rs, rt Parallel Pack to Byte
2112 * PPACH rd, rs, rt Parallel Pack to Halfword
2113 * PPACW rd, rs, rt Parallel Pack to Word
2114 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2115 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2116 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2117 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2118 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2119 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2120 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2122 * Others (16 instructions)
2123 * ------------------------
2124 * PCPYH rd, rt Parallel Copy Halfword
2125 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2126 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2127 * PREVH rd, rt Parallel Reverse Halfword
2128 * PINTH rd, rs, rt Parallel Interleave Halfword
2129 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2130 * PEXEH rd, rt Parallel Exchange Even Halfword
2131 * PEXCH rd, rt Parallel Exchange Center Halfword
2132 * PEXEW rd, rt Parallel Exchange Even Word
2133 * PEXCW rd, rt Parallel Exchange Center Word
2134 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2135 * MFSA rd Move from Shift Amount Register
2136 * MTSA rs Move to Shift Amount Register
2137 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2138 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2139 * PROT3W rd, rt Parallel Rotate 3 Words
2141 * MMI (MultiMedia Instruction) encodings
2142 * ======================================
2144 * MMI instructions encoding table keys:
2146 * * This code is reserved for future use. An attempt to execute it
2147 * causes a Reserved Instruction exception.
2148 * % This code indicates an instruction class. The instruction word
2149 * must be further decoded by examining additional tables that show
2150 * the values for other instruction fields.
2151 * # This code is reserved for the unsupported instructions DMULT,
2152 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2153 * to execute it causes a Reserved Instruction exception.
2155 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2158 * +--------+----------------------------------------+
2160 * +--------+----------------------------------------+
2162 * opcode bits 28..26
2163 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2164 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2165 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2166 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2167 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2168 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2169 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2170 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2171 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2172 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2173 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2177 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2178 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */
2179 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
2183 * MMI instructions with opcode field = MMI:
2186 * +--------+-------------------------------+--------+
2187 * | MMI | |function|
2188 * +--------+-------------------------------+--------+
2190 * function bits 2..0
2191 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2192 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2193 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2194 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2195 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2196 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2197 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2198 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2199 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2200 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2201 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2204 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2206 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2207 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2208 MMI_OPC_PLZCW = 0x04 | MMI_OPC_CLASS_MMI,
2209 MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2210 MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2211 MMI_OPC_MFHI1 = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2212 MMI_OPC_MTHI1 = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2213 MMI_OPC_MFLO1 = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2214 MMI_OPC_MTLO1 = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2215 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2216 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2217 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
2218 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2219 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
2220 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
2221 MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2222 MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2223 MMI_OPC_PMFHL = 0x30 | MMI_OPC_CLASS_MMI,
2224 MMI_OPC_PMTHL = 0x31 | MMI_OPC_CLASS_MMI,
2225 MMI_OPC_PSLLH = 0x34 | MMI_OPC_CLASS_MMI,
2226 MMI_OPC_PSRLH = 0x36 | MMI_OPC_CLASS_MMI,
2227 MMI_OPC_PSRAH = 0x37 | MMI_OPC_CLASS_MMI,
2228 MMI_OPC_PSLLW = 0x3C | MMI_OPC_CLASS_MMI,
2229 MMI_OPC_PSRLW = 0x3E | MMI_OPC_CLASS_MMI,
2230 MMI_OPC_PSRAW = 0x3F | MMI_OPC_CLASS_MMI,
2234 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2237 * +--------+----------------------+--------+--------+
2238 * | MMI | |function| MMI0 |
2239 * +--------+----------------------+--------+--------+
2241 * function bits 7..6
2242 * bits | 0 | 1 | 2 | 3
2243 * 10..8 | 00 | 01 | 10 | 11
2244 * -------+-------+-------+-------+-------
2245 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2246 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2247 * 2 010 | PADDB | PSUBB | PCGTB | *
2248 * 3 011 | * | * | * | *
2249 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2250 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2251 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2252 * 7 111 | * | * | PEXT5 | PPAC5
2255 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2257 MMI_OPC_0_PADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2258 MMI_OPC_0_PSUBW = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2259 MMI_OPC_0_PCGTW = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2260 MMI_OPC_0_PMAXW = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2261 MMI_OPC_0_PADDH = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2262 MMI_OPC_0_PSUBH = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2263 MMI_OPC_0_PCGTH = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2264 MMI_OPC_0_PMAXH = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2265 MMI_OPC_0_PADDB = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2266 MMI_OPC_0_PSUBB = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2267 MMI_OPC_0_PCGTB = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2268 MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2269 MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2270 MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2271 MMI_OPC_0_PPACW = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2272 MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2273 MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2274 MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2275 MMI_OPC_0_PPACH = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2276 MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2277 MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2278 MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2279 MMI_OPC_0_PPACB = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2280 MMI_OPC_0_PEXT5 = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2281 MMI_OPC_0_PPAC5 = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2285 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2288 * +--------+----------------------+--------+--------+
2289 * | MMI | |function| MMI1 |
2290 * +--------+----------------------+--------+--------+
2292 * function bits 7..6
2293 * bits | 0 | 1 | 2 | 3
2294 * 10..8 | 00 | 01 | 10 | 11
2295 * -------+-------+-------+-------+-------
2296 * 0 000 | * | PABSW | PCEQW | PMINW
2297 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2298 * 2 010 | * | * | PCEQB | *
2299 * 3 011 | * | * | * | *
2300 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2301 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2302 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2303 * 7 111 | * | * | * | *
2306 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2308 MMI_OPC_1_PABSW = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2309 MMI_OPC_1_PCEQW = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2310 MMI_OPC_1_PMINW = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2311 MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2312 MMI_OPC_1_PABSH = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2313 MMI_OPC_1_PCEQH = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2314 MMI_OPC_1_PMINH = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2315 MMI_OPC_1_PCEQB = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2316 MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2317 MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2318 MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2319 MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2320 MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2321 MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2322 MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2323 MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2324 MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2325 MMI_OPC_1_QFSRV = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2329 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2332 * +--------+----------------------+--------+--------+
2333 * | MMI | |function| MMI2 |
2334 * +--------+----------------------+--------+--------+
2336 * function bits 7..6
2337 * bits | 0 | 1 | 2 | 3
2338 * 10..8 | 00 | 01 | 10 | 11
2339 * -------+-------+-------+-------+-------
2340 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2341 * 1 001 | PMSUBW| * | * | *
2342 * 2 010 | PMFHI | PMFLO | PINTH | *
2343 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2344 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2345 * 5 101 | PMSUBH| PHMSBH| * | *
2346 * 6 110 | * | * | PEXEH | PREVH
2347 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2350 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2352 MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2353 MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2354 MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2355 MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2356 MMI_OPC_2_PMFHI = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2357 MMI_OPC_2_PMFLO = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2358 MMI_OPC_2_PINTH = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2359 MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2360 MMI_OPC_2_PDIVW = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2361 MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2362 MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2363 MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2364 MMI_OPC_2_PAND = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2365 MMI_OPC_2_PXOR = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2366 MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2367 MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2368 MMI_OPC_2_PEXEH = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2369 MMI_OPC_2_PREVH = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2370 MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2371 MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2372 MMI_OPC_2_PEXEW = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2373 MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2377 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2380 * +--------+----------------------+--------+--------+
2381 * | MMI | |function| MMI3 |
2382 * +--------+----------------------+--------+--------+
2384 * function bits 7..6
2385 * bits | 0 | 1 | 2 | 3
2386 * 10..8 | 00 | 01 | 10 | 11
2387 * -------+-------+-------+-------+-------
2388 * 0 000 |PMADDUW| * | * | PSRAVW
2389 * 1 001 | * | * | * | *
2390 * 2 010 | PMTHI | PMTLO | PINTEH| *
2391 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2392 * 4 100 | * | * | POR | PNOR
2393 * 5 101 | * | * | * | *
2394 * 6 110 | * | * | PEXCH | PCPYH
2395 * 7 111 | * | * | PEXCW | *
2398 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2400 MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2401 MMI_OPC_3_PSRAVW = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2402 MMI_OPC_3_PMTHI = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2403 MMI_OPC_3_PMTLO = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2404 MMI_OPC_3_PINTEH = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2405 MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2406 MMI_OPC_3_PDIVUW = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2407 MMI_OPC_3_PCPYUD = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2408 MMI_OPC_3_POR = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2409 MMI_OPC_3_PNOR = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2410 MMI_OPC_3_PEXCH = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2411 MMI_OPC_3_PCPYH = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2412 MMI_OPC_3_PEXCW = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2415 /* global register indices */
2416 static TCGv cpu_gpr[32], cpu_PC;
2417 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2418 static TCGv cpu_dspctrl, btarget, bcond;
2419 static TCGv_i32 hflags;
2420 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2421 static TCGv_i64 fpu_f64[32];
2422 static TCGv_i64 msa_wr_d[64];
2425 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2428 #include "exec/gen-icount.h"
2430 #define gen_helper_0e0i(name, arg) do { \
2431 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2432 gen_helper_##name(cpu_env, helper_tmp); \
2433 tcg_temp_free_i32(helper_tmp); \
2436 #define gen_helper_0e1i(name, arg1, arg2) do { \
2437 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2438 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2439 tcg_temp_free_i32(helper_tmp); \
2442 #define gen_helper_1e0i(name, ret, arg1) do { \
2443 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2444 gen_helper_##name(ret, cpu_env, helper_tmp); \
2445 tcg_temp_free_i32(helper_tmp); \
2448 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2449 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2450 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2451 tcg_temp_free_i32(helper_tmp); \
2454 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2455 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2456 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2457 tcg_temp_free_i32(helper_tmp); \
2460 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2461 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2462 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2463 tcg_temp_free_i32(helper_tmp); \
2466 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2467 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2468 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2469 tcg_temp_free_i32(helper_tmp); \
2472 typedef struct DisasContext {
2473 DisasContextBase base;
2474 target_ulong saved_pc;
2475 target_ulong page_start;
2477 uint64_t insn_flags;
2478 int32_t CP0_Config1;
2479 int32_t CP0_Config2;
2480 int32_t CP0_Config3;
2481 int32_t CP0_Config5;
2482 /* Routine used to access memory */
2484 TCGMemOp default_tcg_memop_mask;
2485 uint32_t hflags, saved_hflags;
2486 target_ulong btarget;
2497 int CP0_LLAddr_shift;
2506 #define DISAS_STOP DISAS_TARGET_0
2507 #define DISAS_EXIT DISAS_TARGET_1
2509 static const char * const regnames[] = {
2510 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2511 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2512 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2513 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2516 static const char * const regnames_HI[] = {
2517 "HI0", "HI1", "HI2", "HI3",
2520 static const char * const regnames_LO[] = {
2521 "LO0", "LO1", "LO2", "LO3",
2524 static const char * const fregnames[] = {
2525 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2526 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2527 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2528 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2531 static const char * const msaregnames[] = {
2532 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2533 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2534 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2535 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2536 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2537 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2538 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2539 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2540 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2541 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2542 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2543 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2544 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2545 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2546 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2547 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2550 static const char * const mxuregnames[] = {
2551 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2552 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2555 #define LOG_DISAS(...) \
2557 if (MIPS_DEBUG_DISAS) { \
2558 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2562 #define MIPS_INVAL(op) \
2564 if (MIPS_DEBUG_DISAS) { \
2565 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2566 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2567 ctx->base.pc_next, ctx->opcode, op, \
2568 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2569 ((ctx->opcode >> 16) & 0x1F)); \
2573 /* General purpose registers moves. */
2574 static inline void gen_load_gpr (TCGv t, int reg)
2577 tcg_gen_movi_tl(t, 0);
2579 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2582 static inline void gen_store_gpr (TCGv t, int reg)
2585 tcg_gen_mov_tl(cpu_gpr[reg], t);
2588 /* Moves to/from shadow registers. */
2589 static inline void gen_load_srsgpr (int from, int to)
2591 TCGv t0 = tcg_temp_new();
2594 tcg_gen_movi_tl(t0, 0);
2596 TCGv_i32 t2 = tcg_temp_new_i32();
2597 TCGv_ptr addr = tcg_temp_new_ptr();
2599 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2600 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2601 tcg_gen_andi_i32(t2, t2, 0xf);
2602 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2603 tcg_gen_ext_i32_ptr(addr, t2);
2604 tcg_gen_add_ptr(addr, cpu_env, addr);
2606 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2607 tcg_temp_free_ptr(addr);
2608 tcg_temp_free_i32(t2);
2610 gen_store_gpr(t0, to);
2614 static inline void gen_store_srsgpr (int from, int to)
2617 TCGv t0 = tcg_temp_new();
2618 TCGv_i32 t2 = tcg_temp_new_i32();
2619 TCGv_ptr addr = tcg_temp_new_ptr();
2621 gen_load_gpr(t0, from);
2622 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2623 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2624 tcg_gen_andi_i32(t2, t2, 0xf);
2625 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2626 tcg_gen_ext_i32_ptr(addr, t2);
2627 tcg_gen_add_ptr(addr, cpu_env, addr);
2629 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2630 tcg_temp_free_ptr(addr);
2631 tcg_temp_free_i32(t2);
2636 /* MXU General purpose registers moves. */
2637 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2640 tcg_gen_movi_tl(t, 0);
2641 } else if (reg <= 15) {
2642 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2646 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2648 if (reg > 0 && reg <= 15) {
2649 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2653 /* MXU control register moves. */
2654 static inline void gen_load_mxu_cr(TCGv t)
2656 tcg_gen_mov_tl(t, mxu_CR);
2659 static inline void gen_store_mxu_cr(TCGv t)
2661 /* TODO: Add handling of RW rules for MXU_CR. */
2662 tcg_gen_mov_tl(mxu_CR, t);
2667 static inline void gen_save_pc(target_ulong pc)
2669 tcg_gen_movi_tl(cpu_PC, pc);
2672 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2674 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2675 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2676 gen_save_pc(ctx->base.pc_next);
2677 ctx->saved_pc = ctx->base.pc_next;
2679 if (ctx->hflags != ctx->saved_hflags) {
2680 tcg_gen_movi_i32(hflags, ctx->hflags);
2681 ctx->saved_hflags = ctx->hflags;
2682 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2688 tcg_gen_movi_tl(btarget, ctx->btarget);
2694 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2696 ctx->saved_hflags = ctx->hflags;
2697 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2703 ctx->btarget = env->btarget;
2708 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2710 TCGv_i32 texcp = tcg_const_i32(excp);
2711 TCGv_i32 terr = tcg_const_i32(err);
2712 save_cpu_state(ctx, 1);
2713 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2714 tcg_temp_free_i32(terr);
2715 tcg_temp_free_i32(texcp);
2716 ctx->base.is_jmp = DISAS_NORETURN;
2719 static inline void generate_exception(DisasContext *ctx, int excp)
2721 gen_helper_0e0i(raise_exception, excp);
2724 static inline void generate_exception_end(DisasContext *ctx, int excp)
2726 generate_exception_err(ctx, excp, 0);
2729 /* Floating point register moves. */
2730 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2732 if (ctx->hflags & MIPS_HFLAG_FRE) {
2733 generate_exception(ctx, EXCP_RI);
2735 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2738 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2741 if (ctx->hflags & MIPS_HFLAG_FRE) {
2742 generate_exception(ctx, EXCP_RI);
2744 t64 = tcg_temp_new_i64();
2745 tcg_gen_extu_i32_i64(t64, t);
2746 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2747 tcg_temp_free_i64(t64);
2750 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2752 if (ctx->hflags & MIPS_HFLAG_F64) {
2753 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2755 gen_load_fpr32(ctx, t, reg | 1);
2759 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2761 if (ctx->hflags & MIPS_HFLAG_F64) {
2762 TCGv_i64 t64 = tcg_temp_new_i64();
2763 tcg_gen_extu_i32_i64(t64, t);
2764 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2765 tcg_temp_free_i64(t64);
2767 gen_store_fpr32(ctx, t, reg | 1);
2771 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2773 if (ctx->hflags & MIPS_HFLAG_F64) {
2774 tcg_gen_mov_i64(t, fpu_f64[reg]);
2776 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2780 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2782 if (ctx->hflags & MIPS_HFLAG_F64) {
2783 tcg_gen_mov_i64(fpu_f64[reg], t);
2786 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2787 t0 = tcg_temp_new_i64();
2788 tcg_gen_shri_i64(t0, t, 32);
2789 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2790 tcg_temp_free_i64(t0);
2794 static inline int get_fp_bit (int cc)
2802 /* Addresses computation */
2803 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2805 tcg_gen_add_tl(ret, arg0, arg1);
2807 #if defined(TARGET_MIPS64)
2808 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2809 tcg_gen_ext32s_i64(ret, ret);
2814 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2817 tcg_gen_addi_tl(ret, base, ofs);
2819 #if defined(TARGET_MIPS64)
2820 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2821 tcg_gen_ext32s_i64(ret, ret);
2826 /* Addresses computation (translation time) */
2827 static target_long addr_add(DisasContext *ctx, target_long base,
2830 target_long sum = base + offset;
2832 #if defined(TARGET_MIPS64)
2833 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2840 /* Sign-extract the low 32-bits to a target_long. */
2841 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2843 #if defined(TARGET_MIPS64)
2844 tcg_gen_ext32s_i64(ret, arg);
2846 tcg_gen_extrl_i64_i32(ret, arg);
2850 /* Sign-extract the high 32-bits to a target_long. */
2851 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2853 #if defined(TARGET_MIPS64)
2854 tcg_gen_sari_i64(ret, arg, 32);
2856 tcg_gen_extrh_i64_i32(ret, arg);
2860 static inline void check_cp0_enabled(DisasContext *ctx)
2862 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2863 generate_exception_err(ctx, EXCP_CpU, 0);
2866 static inline void check_cp1_enabled(DisasContext *ctx)
2868 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2869 generate_exception_err(ctx, EXCP_CpU, 1);
2872 /* Verify that the processor is running with COP1X instructions enabled.
2873 This is associated with the nabla symbol in the MIPS32 and MIPS64
2876 static inline void check_cop1x(DisasContext *ctx)
2878 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2879 generate_exception_end(ctx, EXCP_RI);
2882 /* Verify that the processor is running with 64-bit floating-point
2883 operations enabled. */
2885 static inline void check_cp1_64bitmode(DisasContext *ctx)
2887 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2888 generate_exception_end(ctx, EXCP_RI);
2892 * Verify if floating point register is valid; an operation is not defined
2893 * if bit 0 of any register specification is set and the FR bit in the
2894 * Status register equals zero, since the register numbers specify an
2895 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2896 * in the Status register equals one, both even and odd register numbers
2897 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2899 * Multiple 64 bit wide registers can be checked by calling
2900 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2902 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2904 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2905 generate_exception_end(ctx, EXCP_RI);
2908 /* Verify that the processor is running with DSP instructions enabled.
2909 This is enabled by CP0 Status register MX(24) bit.
2912 static inline void check_dsp(DisasContext *ctx)
2914 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2915 if (ctx->insn_flags & ASE_DSP) {
2916 generate_exception_end(ctx, EXCP_DSPDIS);
2918 generate_exception_end(ctx, EXCP_RI);
2923 static inline void check_dsp_r2(DisasContext *ctx)
2925 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2926 if (ctx->insn_flags & ASE_DSP) {
2927 generate_exception_end(ctx, EXCP_DSPDIS);
2929 generate_exception_end(ctx, EXCP_RI);
2934 static inline void check_dsp_r3(DisasContext *ctx)
2936 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2937 if (ctx->insn_flags & ASE_DSP) {
2938 generate_exception_end(ctx, EXCP_DSPDIS);
2940 generate_exception_end(ctx, EXCP_RI);
2945 /* This code generates a "reserved instruction" exception if the
2946 CPU does not support the instruction set corresponding to flags. */
2947 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2949 if (unlikely(!(ctx->insn_flags & flags))) {
2950 generate_exception_end(ctx, EXCP_RI);
2954 /* This code generates a "reserved instruction" exception if the
2955 CPU has corresponding flag set which indicates that the instruction
2956 has been removed. */
2957 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2959 if (unlikely(ctx->insn_flags & flags)) {
2960 generate_exception_end(ctx, EXCP_RI);
2965 * The Linux kernel traps certain reserved instruction exceptions to
2966 * emulate the corresponding instructions. QEMU is the kernel in user
2967 * mode, so those traps are emulated by accepting the instructions.
2969 * A reserved instruction exception is generated for flagged CPUs if
2970 * QEMU runs in system mode.
2972 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
2974 #ifndef CONFIG_USER_ONLY
2975 check_insn_opc_removed(ctx, flags);
2979 /* This code generates a "reserved instruction" exception if the
2980 CPU does not support 64-bit paired-single (PS) floating point data type */
2981 static inline void check_ps(DisasContext *ctx)
2983 if (unlikely(!ctx->ps)) {
2984 generate_exception(ctx, EXCP_RI);
2986 check_cp1_64bitmode(ctx);
2989 #ifdef TARGET_MIPS64
2990 /* This code generates a "reserved instruction" exception if 64-bit
2991 instructions are not enabled. */
2992 static inline void check_mips_64(DisasContext *ctx)
2994 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
2995 generate_exception_end(ctx, EXCP_RI);
2999 #ifndef CONFIG_USER_ONLY
3000 static inline void check_mvh(DisasContext *ctx)
3002 if (unlikely(!ctx->mvh)) {
3003 generate_exception(ctx, EXCP_RI);
3009 * This code generates a "reserved instruction" exception if the
3010 * Config5 XNP bit is set.
3012 static inline void check_xnp(DisasContext *ctx)
3014 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3015 generate_exception_end(ctx, EXCP_RI);
3019 #ifndef CONFIG_USER_ONLY
3021 * This code generates a "reserved instruction" exception if the
3022 * Config3 PW bit is NOT set.
3024 static inline void check_pw(DisasContext *ctx)
3026 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3027 generate_exception_end(ctx, EXCP_RI);
3033 * This code generates a "reserved instruction" exception if the
3034 * Config3 MT bit is NOT set.
3036 static inline void check_mt(DisasContext *ctx)
3038 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3039 generate_exception_end(ctx, EXCP_RI);
3043 #ifndef CONFIG_USER_ONLY
3045 * This code generates a "coprocessor unusable" exception if CP0 is not
3046 * available, and, if that is not the case, generates a "reserved instruction"
3047 * exception if the Config5 MT bit is NOT set. This is needed for availability
3048 * control of some of MT ASE instructions.
3050 static inline void check_cp0_mt(DisasContext *ctx)
3052 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3053 generate_exception_err(ctx, EXCP_CpU, 0);
3055 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3056 generate_exception_err(ctx, EXCP_RI, 0);
3063 * This code generates a "reserved instruction" exception if the
3064 * Config5 NMS bit is set.
3066 static inline void check_nms(DisasContext *ctx)
3068 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3069 generate_exception_end(ctx, EXCP_RI);
3074 * This code generates a "reserved instruction" exception if the
3075 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3076 * Config2 TL, and Config5 L2C are unset.
3078 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3080 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3081 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3082 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3083 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3084 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3085 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3087 generate_exception_end(ctx, EXCP_RI);
3092 * This code generates a "reserved instruction" exception if the
3093 * Config5 EVA bit is NOT set.
3095 static inline void check_eva(DisasContext *ctx)
3097 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3098 generate_exception_end(ctx, EXCP_RI);
3103 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3104 calling interface for 32 and 64-bit FPRs. No sense in changing
3105 all callers for gen_load_fpr32 when we need the CTX parameter for
3107 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3108 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3109 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3110 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3111 int ft, int fs, int cc) \
3113 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3114 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3123 check_cp1_registers(ctx, fs | ft); \
3131 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3132 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3134 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3135 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3136 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3137 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3138 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3139 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3140 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3141 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3142 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3143 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3144 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3145 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3146 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3147 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3148 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3149 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
3152 tcg_temp_free_i##bits (fp0); \
3153 tcg_temp_free_i##bits (fp1); \
3156 FOP_CONDS(, 0, d, FMT_D, 64)
3157 FOP_CONDS(abs, 1, d, FMT_D, 64)
3158 FOP_CONDS(, 0, s, FMT_S, 32)
3159 FOP_CONDS(abs, 1, s, FMT_S, 32)
3160 FOP_CONDS(, 0, ps, FMT_PS, 64)
3161 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3164 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3165 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3166 int ft, int fs, int fd) \
3168 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3169 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3170 if (ifmt == FMT_D) { \
3171 check_cp1_registers(ctx, fs | ft | fd); \
3173 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3174 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3177 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3180 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3183 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3186 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3189 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3192 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3195 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3198 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3201 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3204 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3207 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3210 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3213 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3216 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3219 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3222 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3225 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3228 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3231 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3234 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3237 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3240 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3246 tcg_temp_free_i ## bits (fp0); \
3247 tcg_temp_free_i ## bits (fp1); \
3250 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3251 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3253 #undef gen_ldcmp_fpr32
3254 #undef gen_ldcmp_fpr64
3256 /* load/store instructions. */
3257 #ifdef CONFIG_USER_ONLY
3258 #define OP_LD_ATOMIC(insn,fname) \
3259 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3260 DisasContext *ctx) \
3262 TCGv t0 = tcg_temp_new(); \
3263 tcg_gen_mov_tl(t0, arg1); \
3264 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3265 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3266 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3267 tcg_temp_free(t0); \
3270 #define OP_LD_ATOMIC(insn,fname) \
3271 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3272 DisasContext *ctx) \
3274 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3277 OP_LD_ATOMIC(ll,ld32s);
3278 #if defined(TARGET_MIPS64)
3279 OP_LD_ATOMIC(lld,ld64);
3283 #ifdef CONFIG_USER_ONLY
3284 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
3285 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3286 DisasContext *ctx) \
3288 TCGv t0 = tcg_temp_new(); \
3289 TCGLabel *l1 = gen_new_label(); \
3290 TCGLabel *l2 = gen_new_label(); \
3292 tcg_gen_andi_tl(t0, arg2, almask); \
3293 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
3294 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
3295 generate_exception(ctx, EXCP_AdES); \
3296 gen_set_label(l1); \
3297 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3298 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
3299 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
3300 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
3301 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
3302 generate_exception_end(ctx, EXCP_SC); \
3303 gen_set_label(l2); \
3304 tcg_gen_movi_tl(t0, 0); \
3305 gen_store_gpr(t0, rt); \
3306 tcg_temp_free(t0); \
3309 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
3310 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3311 DisasContext *ctx) \
3313 TCGv t0 = tcg_temp_new(); \
3314 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
3315 gen_store_gpr(t0, rt); \
3316 tcg_temp_free(t0); \
3319 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
3320 #if defined(TARGET_MIPS64)
3321 OP_ST_ATOMIC(scd,st64,ld64,0x7);
3325 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3326 int base, int offset)
3329 tcg_gen_movi_tl(addr, offset);
3330 } else if (offset == 0) {
3331 gen_load_gpr(addr, base);
3333 tcg_gen_movi_tl(addr, offset);
3334 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3338 static target_ulong pc_relative_pc (DisasContext *ctx)
3340 target_ulong pc = ctx->base.pc_next;
3342 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3343 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3348 pc &= ~(target_ulong)3;
3353 static void gen_ld(DisasContext *ctx, uint32_t opc,
3354 int rt, int base, int offset)
3357 int mem_idx = ctx->mem_idx;
3359 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3360 /* Loongson CPU uses a load to zero register for prefetch.
3361 We emulate it as a NOP. On other CPU we must perform the
3362 actual memory access. */
3366 t0 = tcg_temp_new();
3367 gen_base_offset_addr(ctx, t0, base, offset);
3370 #if defined(TARGET_MIPS64)
3372 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3373 ctx->default_tcg_memop_mask);
3374 gen_store_gpr(t0, rt);
3377 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3378 ctx->default_tcg_memop_mask);
3379 gen_store_gpr(t0, rt);
3383 op_ld_lld(t0, t0, mem_idx, ctx);
3384 gen_store_gpr(t0, rt);
3387 t1 = tcg_temp_new();
3388 /* Do a byte access to possibly trigger a page
3389 fault with the unaligned address. */
3390 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3391 tcg_gen_andi_tl(t1, t0, 7);
3392 #ifndef TARGET_WORDS_BIGENDIAN
3393 tcg_gen_xori_tl(t1, t1, 7);
3395 tcg_gen_shli_tl(t1, t1, 3);
3396 tcg_gen_andi_tl(t0, t0, ~7);
3397 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3398 tcg_gen_shl_tl(t0, t0, t1);
3399 t2 = tcg_const_tl(-1);
3400 tcg_gen_shl_tl(t2, t2, t1);
3401 gen_load_gpr(t1, rt);
3402 tcg_gen_andc_tl(t1, t1, t2);
3404 tcg_gen_or_tl(t0, t0, t1);
3406 gen_store_gpr(t0, rt);
3409 t1 = tcg_temp_new();
3410 /* Do a byte access to possibly trigger a page
3411 fault with the unaligned address. */
3412 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3413 tcg_gen_andi_tl(t1, t0, 7);
3414 #ifdef TARGET_WORDS_BIGENDIAN
3415 tcg_gen_xori_tl(t1, t1, 7);
3417 tcg_gen_shli_tl(t1, t1, 3);
3418 tcg_gen_andi_tl(t0, t0, ~7);
3419 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3420 tcg_gen_shr_tl(t0, t0, t1);
3421 tcg_gen_xori_tl(t1, t1, 63);
3422 t2 = tcg_const_tl(0xfffffffffffffffeull);
3423 tcg_gen_shl_tl(t2, t2, t1);
3424 gen_load_gpr(t1, rt);
3425 tcg_gen_and_tl(t1, t1, t2);
3427 tcg_gen_or_tl(t0, t0, t1);
3429 gen_store_gpr(t0, rt);
3432 t1 = tcg_const_tl(pc_relative_pc(ctx));
3433 gen_op_addr_add(ctx, t0, t0, t1);
3435 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3436 gen_store_gpr(t0, rt);
3440 t1 = tcg_const_tl(pc_relative_pc(ctx));
3441 gen_op_addr_add(ctx, t0, t0, t1);
3443 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3444 gen_store_gpr(t0, rt);
3447 mem_idx = MIPS_HFLAG_UM;
3450 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3451 ctx->default_tcg_memop_mask);
3452 gen_store_gpr(t0, rt);
3455 mem_idx = MIPS_HFLAG_UM;
3458 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3459 ctx->default_tcg_memop_mask);
3460 gen_store_gpr(t0, rt);
3463 mem_idx = MIPS_HFLAG_UM;
3466 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3467 ctx->default_tcg_memop_mask);
3468 gen_store_gpr(t0, rt);
3471 mem_idx = MIPS_HFLAG_UM;
3474 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3475 gen_store_gpr(t0, rt);
3478 mem_idx = MIPS_HFLAG_UM;
3481 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3482 gen_store_gpr(t0, rt);
3485 mem_idx = MIPS_HFLAG_UM;
3488 t1 = tcg_temp_new();
3489 /* Do a byte access to possibly trigger a page
3490 fault with the unaligned address. */
3491 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3492 tcg_gen_andi_tl(t1, t0, 3);
3493 #ifndef TARGET_WORDS_BIGENDIAN
3494 tcg_gen_xori_tl(t1, t1, 3);
3496 tcg_gen_shli_tl(t1, t1, 3);
3497 tcg_gen_andi_tl(t0, t0, ~3);
3498 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3499 tcg_gen_shl_tl(t0, t0, t1);
3500 t2 = tcg_const_tl(-1);
3501 tcg_gen_shl_tl(t2, t2, t1);
3502 gen_load_gpr(t1, rt);
3503 tcg_gen_andc_tl(t1, t1, t2);
3505 tcg_gen_or_tl(t0, t0, t1);
3507 tcg_gen_ext32s_tl(t0, t0);
3508 gen_store_gpr(t0, rt);
3511 mem_idx = MIPS_HFLAG_UM;
3514 t1 = tcg_temp_new();
3515 /* Do a byte access to possibly trigger a page
3516 fault with the unaligned address. */
3517 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3518 tcg_gen_andi_tl(t1, t0, 3);
3519 #ifdef TARGET_WORDS_BIGENDIAN
3520 tcg_gen_xori_tl(t1, t1, 3);
3522 tcg_gen_shli_tl(t1, t1, 3);
3523 tcg_gen_andi_tl(t0, t0, ~3);
3524 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3525 tcg_gen_shr_tl(t0, t0, t1);
3526 tcg_gen_xori_tl(t1, t1, 31);
3527 t2 = tcg_const_tl(0xfffffffeull);
3528 tcg_gen_shl_tl(t2, t2, t1);
3529 gen_load_gpr(t1, rt);
3530 tcg_gen_and_tl(t1, t1, t2);
3532 tcg_gen_or_tl(t0, t0, t1);
3534 tcg_gen_ext32s_tl(t0, t0);
3535 gen_store_gpr(t0, rt);
3538 mem_idx = MIPS_HFLAG_UM;
3542 op_ld_ll(t0, t0, mem_idx, ctx);
3543 gen_store_gpr(t0, rt);
3549 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3550 uint32_t reg1, uint32_t reg2)
3552 TCGv taddr = tcg_temp_new();
3553 TCGv_i64 tval = tcg_temp_new_i64();
3554 TCGv tmp1 = tcg_temp_new();
3555 TCGv tmp2 = tcg_temp_new();
3557 gen_base_offset_addr(ctx, taddr, base, offset);
3558 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3559 #ifdef TARGET_WORDS_BIGENDIAN
3560 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3562 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3564 gen_store_gpr(tmp1, reg1);
3565 tcg_temp_free(tmp1);
3566 gen_store_gpr(tmp2, reg2);
3567 tcg_temp_free(tmp2);
3568 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3569 tcg_temp_free_i64(tval);
3570 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3571 tcg_temp_free(taddr);
3575 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3576 int base, int offset)
3578 TCGv t0 = tcg_temp_new();
3579 TCGv t1 = tcg_temp_new();
3580 int mem_idx = ctx->mem_idx;
3582 gen_base_offset_addr(ctx, t0, base, offset);
3583 gen_load_gpr(t1, rt);
3585 #if defined(TARGET_MIPS64)
3587 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3588 ctx->default_tcg_memop_mask);
3591 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3594 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3598 mem_idx = MIPS_HFLAG_UM;
3601 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3602 ctx->default_tcg_memop_mask);
3605 mem_idx = MIPS_HFLAG_UM;
3608 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3609 ctx->default_tcg_memop_mask);
3612 mem_idx = MIPS_HFLAG_UM;
3615 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3618 mem_idx = MIPS_HFLAG_UM;
3621 gen_helper_0e2i(swl, t1, t0, mem_idx);
3624 mem_idx = MIPS_HFLAG_UM;
3627 gen_helper_0e2i(swr, t1, t0, mem_idx);
3635 /* Store conditional */
3636 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3637 int base, int16_t offset)
3640 int mem_idx = ctx->mem_idx;
3642 #ifdef CONFIG_USER_ONLY
3643 t0 = tcg_temp_local_new();
3644 t1 = tcg_temp_local_new();
3646 t0 = tcg_temp_new();
3647 t1 = tcg_temp_new();
3649 gen_base_offset_addr(ctx, t0, base, offset);
3650 gen_load_gpr(t1, rt);
3652 #if defined(TARGET_MIPS64)
3655 op_st_scd(t1, t0, rt, mem_idx, ctx);
3659 mem_idx = MIPS_HFLAG_UM;
3663 op_st_sc(t1, t0, rt, mem_idx, ctx);
3670 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3671 uint32_t reg1, uint32_t reg2)
3673 TCGv taddr = tcg_temp_local_new();
3674 TCGv lladdr = tcg_temp_local_new();
3675 TCGv_i64 tval = tcg_temp_new_i64();
3676 TCGv_i64 llval = tcg_temp_new_i64();
3677 TCGv_i64 val = tcg_temp_new_i64();
3678 TCGv tmp1 = tcg_temp_new();
3679 TCGv tmp2 = tcg_temp_new();
3680 TCGLabel *lab_fail = gen_new_label();
3681 TCGLabel *lab_done = gen_new_label();
3683 gen_base_offset_addr(ctx, taddr, base, offset);
3685 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3686 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3688 gen_load_gpr(tmp1, reg1);
3689 gen_load_gpr(tmp2, reg2);
3691 #ifdef TARGET_WORDS_BIGENDIAN
3692 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3694 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3697 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3698 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3699 ctx->mem_idx, MO_64);
3701 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3703 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3705 gen_set_label(lab_fail);
3708 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3710 gen_set_label(lab_done);
3711 tcg_gen_movi_tl(lladdr, -1);
3712 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3715 /* Load and store */
3716 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3719 /* Don't do NOP if destination is zero: we must perform the actual
3724 TCGv_i32 fp0 = tcg_temp_new_i32();
3725 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3726 ctx->default_tcg_memop_mask);
3727 gen_store_fpr32(ctx, fp0, ft);
3728 tcg_temp_free_i32(fp0);
3733 TCGv_i32 fp0 = tcg_temp_new_i32();
3734 gen_load_fpr32(ctx, fp0, ft);
3735 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3736 ctx->default_tcg_memop_mask);
3737 tcg_temp_free_i32(fp0);
3742 TCGv_i64 fp0 = tcg_temp_new_i64();
3743 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3744 ctx->default_tcg_memop_mask);
3745 gen_store_fpr64(ctx, fp0, ft);
3746 tcg_temp_free_i64(fp0);
3751 TCGv_i64 fp0 = tcg_temp_new_i64();
3752 gen_load_fpr64(ctx, fp0, ft);
3753 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3754 ctx->default_tcg_memop_mask);
3755 tcg_temp_free_i64(fp0);
3759 MIPS_INVAL("flt_ldst");
3760 generate_exception_end(ctx, EXCP_RI);
3765 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3766 int rs, int16_t imm)
3768 TCGv t0 = tcg_temp_new();
3770 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3771 check_cp1_enabled(ctx);
3775 check_insn(ctx, ISA_MIPS2);
3778 gen_base_offset_addr(ctx, t0, rs, imm);
3779 gen_flt_ldst(ctx, op, rt, t0);
3782 generate_exception_err(ctx, EXCP_CpU, 1);
3787 /* Arithmetic with immediate operand */
3788 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3789 int rt, int rs, int imm)
3791 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3793 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3794 /* If no destination, treat it as a NOP.
3795 For addi, we must generate the overflow exception when needed. */
3801 TCGv t0 = tcg_temp_local_new();
3802 TCGv t1 = tcg_temp_new();
3803 TCGv t2 = tcg_temp_new();
3804 TCGLabel *l1 = gen_new_label();
3806 gen_load_gpr(t1, rs);
3807 tcg_gen_addi_tl(t0, t1, uimm);
3808 tcg_gen_ext32s_tl(t0, t0);
3810 tcg_gen_xori_tl(t1, t1, ~uimm);
3811 tcg_gen_xori_tl(t2, t0, uimm);
3812 tcg_gen_and_tl(t1, t1, t2);
3814 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3816 /* operands of same sign, result different sign */
3817 generate_exception(ctx, EXCP_OVERFLOW);
3819 tcg_gen_ext32s_tl(t0, t0);
3820 gen_store_gpr(t0, rt);
3826 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3827 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3829 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3832 #if defined(TARGET_MIPS64)
3835 TCGv t0 = tcg_temp_local_new();
3836 TCGv t1 = tcg_temp_new();
3837 TCGv t2 = tcg_temp_new();
3838 TCGLabel *l1 = gen_new_label();
3840 gen_load_gpr(t1, rs);
3841 tcg_gen_addi_tl(t0, t1, uimm);
3843 tcg_gen_xori_tl(t1, t1, ~uimm);
3844 tcg_gen_xori_tl(t2, t0, uimm);
3845 tcg_gen_and_tl(t1, t1, t2);
3847 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3849 /* operands of same sign, result different sign */
3850 generate_exception(ctx, EXCP_OVERFLOW);
3852 gen_store_gpr(t0, rt);
3858 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3860 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3867 /* Logic with immediate operand */
3868 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3869 int rt, int rs, int16_t imm)
3874 /* If no destination, treat it as a NOP. */
3877 uimm = (uint16_t)imm;
3880 if (likely(rs != 0))
3881 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3883 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3887 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3889 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3892 if (likely(rs != 0))
3893 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3895 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3898 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3900 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3901 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3903 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3912 /* Set on less than with immediate operand */
3913 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3914 int rt, int rs, int16_t imm)
3916 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3920 /* If no destination, treat it as a NOP. */
3923 t0 = tcg_temp_new();
3924 gen_load_gpr(t0, rs);
3927 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3930 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3936 /* Shifts with immediate operand */
3937 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3938 int rt, int rs, int16_t imm)
3940 target_ulong uimm = ((uint16_t)imm) & 0x1f;
3944 /* If no destination, treat it as a NOP. */
3948 t0 = tcg_temp_new();
3949 gen_load_gpr(t0, rs);
3952 tcg_gen_shli_tl(t0, t0, uimm);
3953 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3956 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3960 tcg_gen_ext32u_tl(t0, t0);
3961 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3963 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3968 TCGv_i32 t1 = tcg_temp_new_i32();
3970 tcg_gen_trunc_tl_i32(t1, t0);
3971 tcg_gen_rotri_i32(t1, t1, uimm);
3972 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3973 tcg_temp_free_i32(t1);
3975 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3978 #if defined(TARGET_MIPS64)
3980 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3983 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3986 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3990 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3992 tcg_gen_mov_tl(cpu_gpr[rt], t0);
3996 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3999 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4002 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4005 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4013 static void gen_arith(DisasContext *ctx, uint32_t opc,
4014 int rd, int rs, int rt)
4016 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4017 && opc != OPC_DADD && opc != OPC_DSUB) {
4018 /* If no destination, treat it as a NOP.
4019 For add & sub, we must generate the overflow exception when needed. */
4026 TCGv t0 = tcg_temp_local_new();
4027 TCGv t1 = tcg_temp_new();
4028 TCGv t2 = tcg_temp_new();
4029 TCGLabel *l1 = gen_new_label();
4031 gen_load_gpr(t1, rs);
4032 gen_load_gpr(t2, rt);
4033 tcg_gen_add_tl(t0, t1, t2);
4034 tcg_gen_ext32s_tl(t0, t0);
4035 tcg_gen_xor_tl(t1, t1, t2);
4036 tcg_gen_xor_tl(t2, t0, t2);
4037 tcg_gen_andc_tl(t1, t2, t1);
4039 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4041 /* operands of same sign, result different sign */
4042 generate_exception(ctx, EXCP_OVERFLOW);
4044 gen_store_gpr(t0, rd);
4049 if (rs != 0 && rt != 0) {
4050 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4051 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4052 } else if (rs == 0 && rt != 0) {
4053 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4054 } else if (rs != 0 && rt == 0) {
4055 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4057 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4062 TCGv t0 = tcg_temp_local_new();
4063 TCGv t1 = tcg_temp_new();
4064 TCGv t2 = tcg_temp_new();
4065 TCGLabel *l1 = gen_new_label();
4067 gen_load_gpr(t1, rs);
4068 gen_load_gpr(t2, rt);
4069 tcg_gen_sub_tl(t0, t1, t2);
4070 tcg_gen_ext32s_tl(t0, t0);
4071 tcg_gen_xor_tl(t2, t1, t2);
4072 tcg_gen_xor_tl(t1, t0, t1);
4073 tcg_gen_and_tl(t1, t1, t2);
4075 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4077 /* operands of different sign, first operand and result different sign */
4078 generate_exception(ctx, EXCP_OVERFLOW);
4080 gen_store_gpr(t0, rd);
4085 if (rs != 0 && rt != 0) {
4086 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4087 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4088 } else if (rs == 0 && rt != 0) {
4089 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4090 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4091 } else if (rs != 0 && rt == 0) {
4092 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4094 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4097 #if defined(TARGET_MIPS64)
4100 TCGv t0 = tcg_temp_local_new();
4101 TCGv t1 = tcg_temp_new();
4102 TCGv t2 = tcg_temp_new();
4103 TCGLabel *l1 = gen_new_label();
4105 gen_load_gpr(t1, rs);
4106 gen_load_gpr(t2, rt);
4107 tcg_gen_add_tl(t0, t1, t2);
4108 tcg_gen_xor_tl(t1, t1, t2);
4109 tcg_gen_xor_tl(t2, t0, t2);
4110 tcg_gen_andc_tl(t1, t2, t1);
4112 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4114 /* operands of same sign, result different sign */
4115 generate_exception(ctx, EXCP_OVERFLOW);
4117 gen_store_gpr(t0, rd);
4122 if (rs != 0 && rt != 0) {
4123 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4124 } else if (rs == 0 && rt != 0) {
4125 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4126 } else if (rs != 0 && rt == 0) {
4127 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4129 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4134 TCGv t0 = tcg_temp_local_new();
4135 TCGv t1 = tcg_temp_new();
4136 TCGv t2 = tcg_temp_new();
4137 TCGLabel *l1 = gen_new_label();
4139 gen_load_gpr(t1, rs);
4140 gen_load_gpr(t2, rt);
4141 tcg_gen_sub_tl(t0, t1, t2);
4142 tcg_gen_xor_tl(t2, t1, t2);
4143 tcg_gen_xor_tl(t1, t0, t1);
4144 tcg_gen_and_tl(t1, t1, t2);
4146 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4148 /* operands of different sign, first operand and result different sign */
4149 generate_exception(ctx, EXCP_OVERFLOW);
4151 gen_store_gpr(t0, rd);
4156 if (rs != 0 && rt != 0) {
4157 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4158 } else if (rs == 0 && rt != 0) {
4159 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4160 } else if (rs != 0 && rt == 0) {
4161 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4163 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4168 if (likely(rs != 0 && rt != 0)) {
4169 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4170 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4172 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4178 /* Conditional move */
4179 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4180 int rd, int rs, int rt)
4185 /* If no destination, treat it as a NOP. */
4189 t0 = tcg_temp_new();
4190 gen_load_gpr(t0, rt);
4191 t1 = tcg_const_tl(0);
4192 t2 = tcg_temp_new();
4193 gen_load_gpr(t2, rs);
4196 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4199 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4202 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4205 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4214 static void gen_logic(DisasContext *ctx, uint32_t opc,
4215 int rd, int rs, int rt)
4218 /* If no destination, treat it as a NOP. */
4224 if (likely(rs != 0 && rt != 0)) {
4225 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4227 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4231 if (rs != 0 && rt != 0) {
4232 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4233 } else if (rs == 0 && rt != 0) {
4234 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4235 } else if (rs != 0 && rt == 0) {
4236 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4238 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4242 if (likely(rs != 0 && rt != 0)) {
4243 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4244 } else if (rs == 0 && rt != 0) {
4245 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4246 } else if (rs != 0 && rt == 0) {
4247 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4249 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4253 if (likely(rs != 0 && rt != 0)) {
4254 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4255 } else if (rs == 0 && rt != 0) {
4256 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4257 } else if (rs != 0 && rt == 0) {
4258 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4260 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4266 /* Set on lower than */
4267 static void gen_slt(DisasContext *ctx, uint32_t opc,
4268 int rd, int rs, int rt)
4273 /* If no destination, treat it as a NOP. */
4277 t0 = tcg_temp_new();
4278 t1 = tcg_temp_new();
4279 gen_load_gpr(t0, rs);
4280 gen_load_gpr(t1, rt);
4283 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4286 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4294 static void gen_shift(DisasContext *ctx, uint32_t opc,
4295 int rd, int rs, int rt)
4300 /* If no destination, treat it as a NOP.
4301 For add & sub, we must generate the overflow exception when needed. */
4305 t0 = tcg_temp_new();
4306 t1 = tcg_temp_new();
4307 gen_load_gpr(t0, rs);
4308 gen_load_gpr(t1, rt);
4311 tcg_gen_andi_tl(t0, t0, 0x1f);
4312 tcg_gen_shl_tl(t0, t1, t0);
4313 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4316 tcg_gen_andi_tl(t0, t0, 0x1f);
4317 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4320 tcg_gen_ext32u_tl(t1, t1);
4321 tcg_gen_andi_tl(t0, t0, 0x1f);
4322 tcg_gen_shr_tl(t0, t1, t0);
4323 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4327 TCGv_i32 t2 = tcg_temp_new_i32();
4328 TCGv_i32 t3 = tcg_temp_new_i32();
4330 tcg_gen_trunc_tl_i32(t2, t0);
4331 tcg_gen_trunc_tl_i32(t3, t1);
4332 tcg_gen_andi_i32(t2, t2, 0x1f);
4333 tcg_gen_rotr_i32(t2, t3, t2);
4334 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4335 tcg_temp_free_i32(t2);
4336 tcg_temp_free_i32(t3);
4339 #if defined(TARGET_MIPS64)
4341 tcg_gen_andi_tl(t0, t0, 0x3f);
4342 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4345 tcg_gen_andi_tl(t0, t0, 0x3f);
4346 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4349 tcg_gen_andi_tl(t0, t0, 0x3f);
4350 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4353 tcg_gen_andi_tl(t0, t0, 0x3f);
4354 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4362 /* Copy GPR to and from TX79 HI1/LO1 register. */
4363 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4365 if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4372 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4375 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4379 tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4381 tcg_gen_movi_tl(cpu_HI[1], 0);
4386 tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4388 tcg_gen_movi_tl(cpu_LO[1], 0);
4392 MIPS_INVAL("mfthilo1 TX79");
4393 generate_exception_end(ctx, EXCP_RI);
4398 /* Arithmetic on HI/LO registers */
4399 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4401 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4412 #if defined(TARGET_MIPS64)
4414 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4418 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4422 #if defined(TARGET_MIPS64)
4424 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4428 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4433 #if defined(TARGET_MIPS64)
4435 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4439 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4442 tcg_gen_movi_tl(cpu_HI[acc], 0);
4447 #if defined(TARGET_MIPS64)
4449 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4453 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4456 tcg_gen_movi_tl(cpu_LO[acc], 0);
4462 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4465 TCGv t0 = tcg_const_tl(addr);
4466 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4467 gen_store_gpr(t0, reg);
4471 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4477 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4480 offset = sextract32(ctx->opcode << 2, 0, 21);
4481 addr = addr_add(ctx, pc, offset);
4482 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4486 offset = sextract32(ctx->opcode << 2, 0, 21);
4487 addr = addr_add(ctx, pc, offset);
4488 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4490 #if defined(TARGET_MIPS64)
4493 offset = sextract32(ctx->opcode << 2, 0, 21);
4494 addr = addr_add(ctx, pc, offset);
4495 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4499 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4502 offset = sextract32(ctx->opcode, 0, 16) << 16;
4503 addr = addr_add(ctx, pc, offset);
4504 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4509 offset = sextract32(ctx->opcode, 0, 16) << 16;
4510 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4511 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4514 #if defined(TARGET_MIPS64)
4515 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4516 case R6_OPC_LDPC + (1 << 16):
4517 case R6_OPC_LDPC + (2 << 16):
4518 case R6_OPC_LDPC + (3 << 16):
4520 offset = sextract32(ctx->opcode << 3, 0, 21);
4521 addr = addr_add(ctx, (pc & ~0x7), offset);
4522 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4526 MIPS_INVAL("OPC_PCREL");
4527 generate_exception_end(ctx, EXCP_RI);
4534 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4543 t0 = tcg_temp_new();
4544 t1 = tcg_temp_new();
4546 gen_load_gpr(t0, rs);
4547 gen_load_gpr(t1, rt);
4552 TCGv t2 = tcg_temp_new();
4553 TCGv t3 = tcg_temp_new();
4554 tcg_gen_ext32s_tl(t0, t0);
4555 tcg_gen_ext32s_tl(t1, t1);
4556 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4557 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4558 tcg_gen_and_tl(t2, t2, t3);
4559 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4560 tcg_gen_or_tl(t2, t2, t3);
4561 tcg_gen_movi_tl(t3, 0);
4562 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4563 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4564 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4571 TCGv t2 = tcg_temp_new();
4572 TCGv t3 = tcg_temp_new();
4573 tcg_gen_ext32s_tl(t0, t0);
4574 tcg_gen_ext32s_tl(t1, t1);
4575 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4576 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4577 tcg_gen_and_tl(t2, t2, t3);
4578 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4579 tcg_gen_or_tl(t2, t2, t3);
4580 tcg_gen_movi_tl(t3, 0);
4581 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4582 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4583 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4590 TCGv t2 = tcg_const_tl(0);
4591 TCGv t3 = tcg_const_tl(1);
4592 tcg_gen_ext32u_tl(t0, t0);
4593 tcg_gen_ext32u_tl(t1, t1);
4594 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4595 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4596 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4603 TCGv t2 = tcg_const_tl(0);
4604 TCGv t3 = tcg_const_tl(1);
4605 tcg_gen_ext32u_tl(t0, t0);
4606 tcg_gen_ext32u_tl(t1, t1);
4607 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4608 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4609 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4616 TCGv_i32 t2 = tcg_temp_new_i32();
4617 TCGv_i32 t3 = tcg_temp_new_i32();
4618 tcg_gen_trunc_tl_i32(t2, t0);
4619 tcg_gen_trunc_tl_i32(t3, t1);
4620 tcg_gen_mul_i32(t2, t2, t3);
4621 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4622 tcg_temp_free_i32(t2);
4623 tcg_temp_free_i32(t3);
4628 TCGv_i32 t2 = tcg_temp_new_i32();
4629 TCGv_i32 t3 = tcg_temp_new_i32();
4630 tcg_gen_trunc_tl_i32(t2, t0);
4631 tcg_gen_trunc_tl_i32(t3, t1);
4632 tcg_gen_muls2_i32(t2, t3, t2, t3);
4633 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4634 tcg_temp_free_i32(t2);
4635 tcg_temp_free_i32(t3);
4640 TCGv_i32 t2 = tcg_temp_new_i32();
4641 TCGv_i32 t3 = tcg_temp_new_i32();
4642 tcg_gen_trunc_tl_i32(t2, t0);
4643 tcg_gen_trunc_tl_i32(t3, t1);
4644 tcg_gen_mul_i32(t2, t2, t3);
4645 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4646 tcg_temp_free_i32(t2);
4647 tcg_temp_free_i32(t3);
4652 TCGv_i32 t2 = tcg_temp_new_i32();
4653 TCGv_i32 t3 = tcg_temp_new_i32();
4654 tcg_gen_trunc_tl_i32(t2, t0);
4655 tcg_gen_trunc_tl_i32(t3, t1);
4656 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4657 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4658 tcg_temp_free_i32(t2);
4659 tcg_temp_free_i32(t3);
4662 #if defined(TARGET_MIPS64)
4665 TCGv t2 = tcg_temp_new();
4666 TCGv t3 = tcg_temp_new();
4667 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4668 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4669 tcg_gen_and_tl(t2, t2, t3);
4670 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4671 tcg_gen_or_tl(t2, t2, t3);
4672 tcg_gen_movi_tl(t3, 0);
4673 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4674 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4681 TCGv t2 = tcg_temp_new();
4682 TCGv t3 = tcg_temp_new();
4683 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4684 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4685 tcg_gen_and_tl(t2, t2, t3);
4686 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4687 tcg_gen_or_tl(t2, t2, t3);
4688 tcg_gen_movi_tl(t3, 0);
4689 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4690 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4697 TCGv t2 = tcg_const_tl(0);
4698 TCGv t3 = tcg_const_tl(1);
4699 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4700 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4707 TCGv t2 = tcg_const_tl(0);
4708 TCGv t3 = tcg_const_tl(1);
4709 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4710 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4716 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4720 TCGv t2 = tcg_temp_new();
4721 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4726 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4730 TCGv t2 = tcg_temp_new();
4731 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4737 MIPS_INVAL("r6 mul/div");
4738 generate_exception_end(ctx, EXCP_RI);
4746 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4750 t0 = tcg_temp_new();
4751 t1 = tcg_temp_new();
4753 gen_load_gpr(t0, rs);
4754 gen_load_gpr(t1, rt);
4759 TCGv t2 = tcg_temp_new();
4760 TCGv t3 = tcg_temp_new();
4761 tcg_gen_ext32s_tl(t0, t0);
4762 tcg_gen_ext32s_tl(t1, t1);
4763 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4764 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4765 tcg_gen_and_tl(t2, t2, t3);
4766 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4767 tcg_gen_or_tl(t2, t2, t3);
4768 tcg_gen_movi_tl(t3, 0);
4769 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4770 tcg_gen_div_tl(cpu_LO[1], t0, t1);
4771 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4772 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4773 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4780 TCGv t2 = tcg_const_tl(0);
4781 TCGv t3 = tcg_const_tl(1);
4782 tcg_gen_ext32u_tl(t0, t0);
4783 tcg_gen_ext32u_tl(t1, t1);
4784 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4785 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4786 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4787 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4788 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4794 MIPS_INVAL("div1 TX79");
4795 generate_exception_end(ctx, EXCP_RI);
4803 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4804 int acc, int rs, int rt)
4808 t0 = tcg_temp_new();
4809 t1 = tcg_temp_new();
4811 gen_load_gpr(t0, rs);
4812 gen_load_gpr(t1, rt);
4821 TCGv t2 = tcg_temp_new();
4822 TCGv t3 = tcg_temp_new();
4823 tcg_gen_ext32s_tl(t0, t0);
4824 tcg_gen_ext32s_tl(t1, t1);
4825 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4826 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4827 tcg_gen_and_tl(t2, t2, t3);
4828 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4829 tcg_gen_or_tl(t2, t2, t3);
4830 tcg_gen_movi_tl(t3, 0);
4831 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4832 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4833 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4834 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4835 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4842 TCGv t2 = tcg_const_tl(0);
4843 TCGv t3 = tcg_const_tl(1);
4844 tcg_gen_ext32u_tl(t0, t0);
4845 tcg_gen_ext32u_tl(t1, t1);
4846 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4847 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4848 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4849 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4850 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4857 TCGv_i32 t2 = tcg_temp_new_i32();
4858 TCGv_i32 t3 = tcg_temp_new_i32();
4859 tcg_gen_trunc_tl_i32(t2, t0);
4860 tcg_gen_trunc_tl_i32(t3, t1);
4861 tcg_gen_muls2_i32(t2, t3, t2, t3);
4862 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4863 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4864 tcg_temp_free_i32(t2);
4865 tcg_temp_free_i32(t3);
4870 TCGv_i32 t2 = tcg_temp_new_i32();
4871 TCGv_i32 t3 = tcg_temp_new_i32();
4872 tcg_gen_trunc_tl_i32(t2, t0);
4873 tcg_gen_trunc_tl_i32(t3, t1);
4874 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4875 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4876 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4877 tcg_temp_free_i32(t2);
4878 tcg_temp_free_i32(t3);
4881 #if defined(TARGET_MIPS64)
4884 TCGv t2 = tcg_temp_new();
4885 TCGv t3 = tcg_temp_new();
4886 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4887 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4888 tcg_gen_and_tl(t2, t2, t3);
4889 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4890 tcg_gen_or_tl(t2, t2, t3);
4891 tcg_gen_movi_tl(t3, 0);
4892 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4893 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4894 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4901 TCGv t2 = tcg_const_tl(0);
4902 TCGv t3 = tcg_const_tl(1);
4903 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4904 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4905 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4911 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4914 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4919 TCGv_i64 t2 = tcg_temp_new_i64();
4920 TCGv_i64 t3 = tcg_temp_new_i64();
4922 tcg_gen_ext_tl_i64(t2, t0);
4923 tcg_gen_ext_tl_i64(t3, t1);
4924 tcg_gen_mul_i64(t2, t2, t3);
4925 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4926 tcg_gen_add_i64(t2, t2, t3);
4927 tcg_temp_free_i64(t3);
4928 gen_move_low32(cpu_LO[acc], t2);
4929 gen_move_high32(cpu_HI[acc], t2);
4930 tcg_temp_free_i64(t2);
4935 TCGv_i64 t2 = tcg_temp_new_i64();
4936 TCGv_i64 t3 = tcg_temp_new_i64();
4938 tcg_gen_ext32u_tl(t0, t0);
4939 tcg_gen_ext32u_tl(t1, t1);
4940 tcg_gen_extu_tl_i64(t2, t0);
4941 tcg_gen_extu_tl_i64(t3, t1);
4942 tcg_gen_mul_i64(t2, t2, t3);
4943 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4944 tcg_gen_add_i64(t2, t2, t3);
4945 tcg_temp_free_i64(t3);
4946 gen_move_low32(cpu_LO[acc], t2);
4947 gen_move_high32(cpu_HI[acc], t2);
4948 tcg_temp_free_i64(t2);
4953 TCGv_i64 t2 = tcg_temp_new_i64();
4954 TCGv_i64 t3 = tcg_temp_new_i64();
4956 tcg_gen_ext_tl_i64(t2, t0);
4957 tcg_gen_ext_tl_i64(t3, t1);
4958 tcg_gen_mul_i64(t2, t2, t3);
4959 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4960 tcg_gen_sub_i64(t2, t3, t2);
4961 tcg_temp_free_i64(t3);
4962 gen_move_low32(cpu_LO[acc], t2);
4963 gen_move_high32(cpu_HI[acc], t2);
4964 tcg_temp_free_i64(t2);
4969 TCGv_i64 t2 = tcg_temp_new_i64();
4970 TCGv_i64 t3 = tcg_temp_new_i64();
4972 tcg_gen_ext32u_tl(t0, t0);
4973 tcg_gen_ext32u_tl(t1, t1);
4974 tcg_gen_extu_tl_i64(t2, t0);
4975 tcg_gen_extu_tl_i64(t3, t1);
4976 tcg_gen_mul_i64(t2, t2, t3);
4977 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4978 tcg_gen_sub_i64(t2, t3, t2);
4979 tcg_temp_free_i64(t3);
4980 gen_move_low32(cpu_LO[acc], t2);
4981 gen_move_high32(cpu_HI[acc], t2);
4982 tcg_temp_free_i64(t2);
4986 MIPS_INVAL("mul/div");
4987 generate_exception_end(ctx, EXCP_RI);
4996 * These MULT and MULTU instructions implemented in for example the
4997 * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
4998 * architectures are special three-operand variants with the syntax
5000 * MULT[U][1] rd, rs, rt
5004 * (rd, LO, HI) <- rs * rt
5006 * where the low-order 32-bits of the result is placed into both the
5007 * GPR rd and the special register LO. The high-order 32-bits of the
5008 * result is placed into the special register HI.
5010 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5011 * which is the zero register that always reads as 0.
5013 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5014 int rd, int rs, int rt)
5016 TCGv t0 = tcg_temp_new();
5017 TCGv t1 = tcg_temp_new();
5020 gen_load_gpr(t0, rs);
5021 gen_load_gpr(t1, rt);
5029 TCGv_i32 t2 = tcg_temp_new_i32();
5030 TCGv_i32 t3 = tcg_temp_new_i32();
5031 tcg_gen_trunc_tl_i32(t2, t0);
5032 tcg_gen_trunc_tl_i32(t3, t1);
5033 tcg_gen_muls2_i32(t2, t3, t2, t3);
5035 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5037 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5038 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5039 tcg_temp_free_i32(t2);
5040 tcg_temp_free_i32(t3);
5043 case MMI_OPC_MULTU1:
5048 TCGv_i32 t2 = tcg_temp_new_i32();
5049 TCGv_i32 t3 = tcg_temp_new_i32();
5050 tcg_gen_trunc_tl_i32(t2, t0);
5051 tcg_gen_trunc_tl_i32(t3, t1);
5052 tcg_gen_mulu2_i32(t2, t3, t2, t3);
5054 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5056 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5057 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5058 tcg_temp_free_i32(t2);
5059 tcg_temp_free_i32(t3);
5063 MIPS_INVAL("mul TXx9");
5064 generate_exception_end(ctx, EXCP_RI);
5073 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5074 int rd, int rs, int rt)
5076 TCGv t0 = tcg_temp_new();
5077 TCGv t1 = tcg_temp_new();
5079 gen_load_gpr(t0, rs);
5080 gen_load_gpr(t1, rt);
5083 case OPC_VR54XX_MULS:
5084 gen_helper_muls(t0, cpu_env, t0, t1);
5086 case OPC_VR54XX_MULSU:
5087 gen_helper_mulsu(t0, cpu_env, t0, t1);
5089 case OPC_VR54XX_MACC:
5090 gen_helper_macc(t0, cpu_env, t0, t1);
5092 case OPC_VR54XX_MACCU:
5093 gen_helper_maccu(t0, cpu_env, t0, t1);
5095 case OPC_VR54XX_MSAC:
5096 gen_helper_msac(t0, cpu_env, t0, t1);
5098 case OPC_VR54XX_MSACU:
5099 gen_helper_msacu(t0, cpu_env, t0, t1);
5101 case OPC_VR54XX_MULHI:
5102 gen_helper_mulhi(t0, cpu_env, t0, t1);
5104 case OPC_VR54XX_MULHIU:
5105 gen_helper_mulhiu(t0, cpu_env, t0, t1);
5107 case OPC_VR54XX_MULSHI:
5108 gen_helper_mulshi(t0, cpu_env, t0, t1);
5110 case OPC_VR54XX_MULSHIU:
5111 gen_helper_mulshiu(t0, cpu_env, t0, t1);
5113 case OPC_VR54XX_MACCHI:
5114 gen_helper_macchi(t0, cpu_env, t0, t1);
5116 case OPC_VR54XX_MACCHIU:
5117 gen_helper_macchiu(t0, cpu_env, t0, t1);
5119 case OPC_VR54XX_MSACHI:
5120 gen_helper_msachi(t0, cpu_env, t0, t1);
5122 case OPC_VR54XX_MSACHIU:
5123 gen_helper_msachiu(t0, cpu_env, t0, t1);
5126 MIPS_INVAL("mul vr54xx");
5127 generate_exception_end(ctx, EXCP_RI);
5130 gen_store_gpr(t0, rd);
5137 static void gen_cl (DisasContext *ctx, uint32_t opc,
5147 gen_load_gpr(t0, rs);
5152 #if defined(TARGET_MIPS64)
5156 tcg_gen_not_tl(t0, t0);
5165 tcg_gen_ext32u_tl(t0, t0);
5166 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5167 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5169 #if defined(TARGET_MIPS64)
5174 tcg_gen_clzi_i64(t0, t0, 64);
5180 /* Godson integer instructions */
5181 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5182 int rd, int rs, int rt)
5194 case OPC_MULTU_G_2E:
5195 case OPC_MULTU_G_2F:
5196 #if defined(TARGET_MIPS64)
5197 case OPC_DMULT_G_2E:
5198 case OPC_DMULT_G_2F:
5199 case OPC_DMULTU_G_2E:
5200 case OPC_DMULTU_G_2F:
5202 t0 = tcg_temp_new();
5203 t1 = tcg_temp_new();
5206 t0 = tcg_temp_local_new();
5207 t1 = tcg_temp_local_new();
5211 gen_load_gpr(t0, rs);
5212 gen_load_gpr(t1, rt);
5217 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5218 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5220 case OPC_MULTU_G_2E:
5221 case OPC_MULTU_G_2F:
5222 tcg_gen_ext32u_tl(t0, t0);
5223 tcg_gen_ext32u_tl(t1, t1);
5224 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5225 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5230 TCGLabel *l1 = gen_new_label();
5231 TCGLabel *l2 = gen_new_label();
5232 TCGLabel *l3 = gen_new_label();
5233 tcg_gen_ext32s_tl(t0, t0);
5234 tcg_gen_ext32s_tl(t1, t1);
5235 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5236 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5239 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5240 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5241 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5244 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5245 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5252 TCGLabel *l1 = gen_new_label();
5253 TCGLabel *l2 = gen_new_label();
5254 tcg_gen_ext32u_tl(t0, t0);
5255 tcg_gen_ext32u_tl(t1, t1);
5256 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5257 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5260 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5261 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5268 TCGLabel *l1 = gen_new_label();
5269 TCGLabel *l2 = gen_new_label();
5270 TCGLabel *l3 = gen_new_label();
5271 tcg_gen_ext32u_tl(t0, t0);
5272 tcg_gen_ext32u_tl(t1, t1);
5273 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5274 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5275 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5277 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5280 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5281 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5288 TCGLabel *l1 = gen_new_label();
5289 TCGLabel *l2 = gen_new_label();
5290 tcg_gen_ext32u_tl(t0, t0);
5291 tcg_gen_ext32u_tl(t1, t1);
5292 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5293 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5296 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5297 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5301 #if defined(TARGET_MIPS64)
5302 case OPC_DMULT_G_2E:
5303 case OPC_DMULT_G_2F:
5304 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5306 case OPC_DMULTU_G_2E:
5307 case OPC_DMULTU_G_2F:
5308 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5313 TCGLabel *l1 = gen_new_label();
5314 TCGLabel *l2 = gen_new_label();
5315 TCGLabel *l3 = gen_new_label();
5316 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5317 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5320 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5321 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5322 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5325 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5329 case OPC_DDIVU_G_2E:
5330 case OPC_DDIVU_G_2F:
5332 TCGLabel *l1 = gen_new_label();
5333 TCGLabel *l2 = gen_new_label();
5334 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5335 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5338 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5345 TCGLabel *l1 = gen_new_label();
5346 TCGLabel *l2 = gen_new_label();
5347 TCGLabel *l3 = gen_new_label();
5348 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5349 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5350 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5352 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5355 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5359 case OPC_DMODU_G_2E:
5360 case OPC_DMODU_G_2F:
5362 TCGLabel *l1 = gen_new_label();
5363 TCGLabel *l2 = gen_new_label();
5364 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5365 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5368 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5379 /* Loongson multimedia instructions */
5380 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5382 uint32_t opc, shift_max;
5385 opc = MASK_LMI(ctx->opcode);
5391 t0 = tcg_temp_local_new_i64();
5392 t1 = tcg_temp_local_new_i64();
5395 t0 = tcg_temp_new_i64();
5396 t1 = tcg_temp_new_i64();
5400 check_cp1_enabled(ctx);
5401 gen_load_fpr64(ctx, t0, rs);
5402 gen_load_fpr64(ctx, t1, rt);
5404 #define LMI_HELPER(UP, LO) \
5405 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5406 #define LMI_HELPER_1(UP, LO) \
5407 case OPC_##UP: gen_helper_##LO(t0, t0); break
5408 #define LMI_DIRECT(UP, LO, OP) \
5409 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5412 LMI_HELPER(PADDSH, paddsh);
5413 LMI_HELPER(PADDUSH, paddush);
5414 LMI_HELPER(PADDH, paddh);
5415 LMI_HELPER(PADDW, paddw);
5416 LMI_HELPER(PADDSB, paddsb);
5417 LMI_HELPER(PADDUSB, paddusb);
5418 LMI_HELPER(PADDB, paddb);
5420 LMI_HELPER(PSUBSH, psubsh);
5421 LMI_HELPER(PSUBUSH, psubush);
5422 LMI_HELPER(PSUBH, psubh);
5423 LMI_HELPER(PSUBW, psubw);
5424 LMI_HELPER(PSUBSB, psubsb);
5425 LMI_HELPER(PSUBUSB, psubusb);
5426 LMI_HELPER(PSUBB, psubb);
5428 LMI_HELPER(PSHUFH, pshufh);
5429 LMI_HELPER(PACKSSWH, packsswh);
5430 LMI_HELPER(PACKSSHB, packsshb);
5431 LMI_HELPER(PACKUSHB, packushb);
5433 LMI_HELPER(PUNPCKLHW, punpcklhw);
5434 LMI_HELPER(PUNPCKHHW, punpckhhw);
5435 LMI_HELPER(PUNPCKLBH, punpcklbh);
5436 LMI_HELPER(PUNPCKHBH, punpckhbh);
5437 LMI_HELPER(PUNPCKLWD, punpcklwd);
5438 LMI_HELPER(PUNPCKHWD, punpckhwd);
5440 LMI_HELPER(PAVGH, pavgh);
5441 LMI_HELPER(PAVGB, pavgb);
5442 LMI_HELPER(PMAXSH, pmaxsh);
5443 LMI_HELPER(PMINSH, pminsh);
5444 LMI_HELPER(PMAXUB, pmaxub);
5445 LMI_HELPER(PMINUB, pminub);
5447 LMI_HELPER(PCMPEQW, pcmpeqw);
5448 LMI_HELPER(PCMPGTW, pcmpgtw);
5449 LMI_HELPER(PCMPEQH, pcmpeqh);
5450 LMI_HELPER(PCMPGTH, pcmpgth);
5451 LMI_HELPER(PCMPEQB, pcmpeqb);
5452 LMI_HELPER(PCMPGTB, pcmpgtb);
5454 LMI_HELPER(PSLLW, psllw);
5455 LMI_HELPER(PSLLH, psllh);
5456 LMI_HELPER(PSRLW, psrlw);
5457 LMI_HELPER(PSRLH, psrlh);
5458 LMI_HELPER(PSRAW, psraw);
5459 LMI_HELPER(PSRAH, psrah);
5461 LMI_HELPER(PMULLH, pmullh);
5462 LMI_HELPER(PMULHH, pmulhh);
5463 LMI_HELPER(PMULHUH, pmulhuh);
5464 LMI_HELPER(PMADDHW, pmaddhw);
5466 LMI_HELPER(PASUBUB, pasubub);
5467 LMI_HELPER_1(BIADD, biadd);
5468 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5470 LMI_DIRECT(PADDD, paddd, add);
5471 LMI_DIRECT(PSUBD, psubd, sub);
5472 LMI_DIRECT(XOR_CP2, xor, xor);
5473 LMI_DIRECT(NOR_CP2, nor, nor);
5474 LMI_DIRECT(AND_CP2, and, and);
5475 LMI_DIRECT(OR_CP2, or, or);
5478 tcg_gen_andc_i64(t0, t1, t0);
5482 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5485 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5488 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5491 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5495 tcg_gen_andi_i64(t1, t1, 3);
5496 tcg_gen_shli_i64(t1, t1, 4);
5497 tcg_gen_shr_i64(t0, t0, t1);
5498 tcg_gen_ext16u_i64(t0, t0);
5502 tcg_gen_add_i64(t0, t0, t1);
5503 tcg_gen_ext32s_i64(t0, t0);
5506 tcg_gen_sub_i64(t0, t0, t1);
5507 tcg_gen_ext32s_i64(t0, t0);
5529 /* Make sure shift count isn't TCG undefined behaviour. */
5530 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5535 tcg_gen_shl_i64(t0, t0, t1);
5539 /* Since SRA is UndefinedResult without sign-extended inputs,
5540 we can treat SRA and DSRA the same. */
5541 tcg_gen_sar_i64(t0, t0, t1);
5544 /* We want to shift in zeros for SRL; zero-extend first. */
5545 tcg_gen_ext32u_i64(t0, t0);
5548 tcg_gen_shr_i64(t0, t0, t1);
5552 if (shift_max == 32) {
5553 tcg_gen_ext32s_i64(t0, t0);
5556 /* Shifts larger than MAX produce zero. */
5557 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5558 tcg_gen_neg_i64(t1, t1);
5559 tcg_gen_and_i64(t0, t0, t1);
5565 TCGv_i64 t2 = tcg_temp_new_i64();
5566 TCGLabel *lab = gen_new_label();
5568 tcg_gen_mov_i64(t2, t0);
5569 tcg_gen_add_i64(t0, t1, t2);
5570 if (opc == OPC_ADD_CP2) {
5571 tcg_gen_ext32s_i64(t0, t0);
5573 tcg_gen_xor_i64(t1, t1, t2);
5574 tcg_gen_xor_i64(t2, t2, t0);
5575 tcg_gen_andc_i64(t1, t2, t1);
5576 tcg_temp_free_i64(t2);
5577 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5578 generate_exception(ctx, EXCP_OVERFLOW);
5586 TCGv_i64 t2 = tcg_temp_new_i64();
5587 TCGLabel *lab = gen_new_label();
5589 tcg_gen_mov_i64(t2, t0);
5590 tcg_gen_sub_i64(t0, t1, t2);
5591 if (opc == OPC_SUB_CP2) {
5592 tcg_gen_ext32s_i64(t0, t0);
5594 tcg_gen_xor_i64(t1, t1, t2);
5595 tcg_gen_xor_i64(t2, t2, t0);
5596 tcg_gen_and_i64(t1, t1, t2);
5597 tcg_temp_free_i64(t2);
5598 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5599 generate_exception(ctx, EXCP_OVERFLOW);
5605 tcg_gen_ext32u_i64(t0, t0);
5606 tcg_gen_ext32u_i64(t1, t1);
5607 tcg_gen_mul_i64(t0, t0, t1);
5616 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5617 FD field is the CC field? */
5619 MIPS_INVAL("loongson_cp2");
5620 generate_exception_end(ctx, EXCP_RI);
5627 gen_store_fpr64(ctx, t0, rd);
5629 tcg_temp_free_i64(t0);
5630 tcg_temp_free_i64(t1);
5634 static void gen_trap (DisasContext *ctx, uint32_t opc,
5635 int rs, int rt, int16_t imm)
5638 TCGv t0 = tcg_temp_new();
5639 TCGv t1 = tcg_temp_new();
5642 /* Load needed operands */
5650 /* Compare two registers */
5652 gen_load_gpr(t0, rs);
5653 gen_load_gpr(t1, rt);
5663 /* Compare register to immediate */
5664 if (rs != 0 || imm != 0) {
5665 gen_load_gpr(t0, rs);
5666 tcg_gen_movi_tl(t1, (int32_t)imm);
5673 case OPC_TEQ: /* rs == rs */
5674 case OPC_TEQI: /* r0 == 0 */
5675 case OPC_TGE: /* rs >= rs */
5676 case OPC_TGEI: /* r0 >= 0 */
5677 case OPC_TGEU: /* rs >= rs unsigned */
5678 case OPC_TGEIU: /* r0 >= 0 unsigned */
5680 generate_exception_end(ctx, EXCP_TRAP);
5682 case OPC_TLT: /* rs < rs */
5683 case OPC_TLTI: /* r0 < 0 */
5684 case OPC_TLTU: /* rs < rs unsigned */
5685 case OPC_TLTIU: /* r0 < 0 unsigned */
5686 case OPC_TNE: /* rs != rs */
5687 case OPC_TNEI: /* r0 != 0 */
5688 /* Never trap: treat as NOP. */
5692 TCGLabel *l1 = gen_new_label();
5697 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5701 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5705 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5709 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5713 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5717 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5720 generate_exception(ctx, EXCP_TRAP);
5727 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5729 if (unlikely(ctx->base.singlestep_enabled)) {
5733 #ifndef CONFIG_USER_ONLY
5734 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5740 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5742 if (use_goto_tb(ctx, dest)) {
5745 tcg_gen_exit_tb(ctx->base.tb, n);
5748 if (ctx->base.singlestep_enabled) {
5749 save_cpu_state(ctx, 0);
5750 gen_helper_raise_exception_debug(cpu_env);
5752 tcg_gen_lookup_and_goto_ptr();
5756 /* Branches (before delay slot) */
5757 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5759 int rs, int rt, int32_t offset,
5762 target_ulong btgt = -1;
5764 int bcond_compute = 0;
5765 TCGv t0 = tcg_temp_new();
5766 TCGv t1 = tcg_temp_new();
5768 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5769 #ifdef MIPS_DEBUG_DISAS
5770 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5771 TARGET_FMT_lx "\n", ctx->base.pc_next);
5773 generate_exception_end(ctx, EXCP_RI);
5777 /* Load needed operands */
5783 /* Compare two registers */
5785 gen_load_gpr(t0, rs);
5786 gen_load_gpr(t1, rt);
5789 btgt = ctx->base.pc_next + insn_bytes + offset;
5803 /* Compare to zero */
5805 gen_load_gpr(t0, rs);
5808 btgt = ctx->base.pc_next + insn_bytes + offset;
5811 #if defined(TARGET_MIPS64)
5813 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5815 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5818 btgt = ctx->base.pc_next + insn_bytes + offset;
5823 /* Jump to immediate */
5824 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5829 /* Jump to register */
5830 if (offset != 0 && offset != 16) {
5831 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5832 others are reserved. */
5833 MIPS_INVAL("jump hint");
5834 generate_exception_end(ctx, EXCP_RI);
5837 gen_load_gpr(btarget, rs);
5840 MIPS_INVAL("branch/jump");
5841 generate_exception_end(ctx, EXCP_RI);
5844 if (bcond_compute == 0) {
5845 /* No condition to be computed */
5847 case OPC_BEQ: /* rx == rx */
5848 case OPC_BEQL: /* rx == rx likely */
5849 case OPC_BGEZ: /* 0 >= 0 */
5850 case OPC_BGEZL: /* 0 >= 0 likely */
5851 case OPC_BLEZ: /* 0 <= 0 */
5852 case OPC_BLEZL: /* 0 <= 0 likely */
5854 ctx->hflags |= MIPS_HFLAG_B;
5856 case OPC_BGEZAL: /* 0 >= 0 */
5857 case OPC_BGEZALL: /* 0 >= 0 likely */
5858 /* Always take and link */
5860 ctx->hflags |= MIPS_HFLAG_B;
5862 case OPC_BNE: /* rx != rx */
5863 case OPC_BGTZ: /* 0 > 0 */
5864 case OPC_BLTZ: /* 0 < 0 */
5867 case OPC_BLTZAL: /* 0 < 0 */
5868 /* Handle as an unconditional branch to get correct delay
5871 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5872 ctx->hflags |= MIPS_HFLAG_B;
5874 case OPC_BLTZALL: /* 0 < 0 likely */
5875 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5876 /* Skip the instruction in the delay slot */
5877 ctx->base.pc_next += 4;
5879 case OPC_BNEL: /* rx != rx likely */
5880 case OPC_BGTZL: /* 0 > 0 likely */
5881 case OPC_BLTZL: /* 0 < 0 likely */
5882 /* Skip the instruction in the delay slot */
5883 ctx->base.pc_next += 4;
5886 ctx->hflags |= MIPS_HFLAG_B;
5889 ctx->hflags |= MIPS_HFLAG_BX;
5893 ctx->hflags |= MIPS_HFLAG_B;
5896 ctx->hflags |= MIPS_HFLAG_BR;
5900 ctx->hflags |= MIPS_HFLAG_BR;
5903 MIPS_INVAL("branch/jump");
5904 generate_exception_end(ctx, EXCP_RI);
5910 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5913 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5916 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5919 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5922 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5925 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5928 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5932 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5936 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5939 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5942 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5945 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5948 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5951 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5954 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5956 #if defined(TARGET_MIPS64)
5958 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5962 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5965 ctx->hflags |= MIPS_HFLAG_BC;
5968 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5971 ctx->hflags |= MIPS_HFLAG_BL;
5974 MIPS_INVAL("conditional branch/jump");
5975 generate_exception_end(ctx, EXCP_RI);
5980 ctx->btarget = btgt;
5982 switch (delayslot_size) {
5984 ctx->hflags |= MIPS_HFLAG_BDS16;
5987 ctx->hflags |= MIPS_HFLAG_BDS32;
5992 int post_delay = insn_bytes + delayslot_size;
5993 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5995 tcg_gen_movi_tl(cpu_gpr[blink],
5996 ctx->base.pc_next + post_delay + lowbit);
6000 if (insn_bytes == 2)
6001 ctx->hflags |= MIPS_HFLAG_B16;
6007 /* nanoMIPS Branches */
6008 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6010 int rs, int rt, int32_t offset)
6012 target_ulong btgt = -1;
6013 int bcond_compute = 0;
6014 TCGv t0 = tcg_temp_new();
6015 TCGv t1 = tcg_temp_new();
6017 /* Load needed operands */
6021 /* Compare two registers */
6023 gen_load_gpr(t0, rs);
6024 gen_load_gpr(t1, rt);
6027 btgt = ctx->base.pc_next + insn_bytes + offset;
6030 /* Compare to zero */
6032 gen_load_gpr(t0, rs);
6035 btgt = ctx->base.pc_next + insn_bytes + offset;
6038 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6040 btgt = ctx->base.pc_next + insn_bytes + offset;
6044 /* Jump to register */
6045 if (offset != 0 && offset != 16) {
6046 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6047 others are reserved. */
6048 MIPS_INVAL("jump hint");
6049 generate_exception_end(ctx, EXCP_RI);
6052 gen_load_gpr(btarget, rs);
6055 MIPS_INVAL("branch/jump");
6056 generate_exception_end(ctx, EXCP_RI);
6059 if (bcond_compute == 0) {
6060 /* No condition to be computed */
6062 case OPC_BEQ: /* rx == rx */
6064 ctx->hflags |= MIPS_HFLAG_B;
6066 case OPC_BGEZAL: /* 0 >= 0 */
6067 /* Always take and link */
6068 tcg_gen_movi_tl(cpu_gpr[31],
6069 ctx->base.pc_next + insn_bytes);
6070 ctx->hflags |= MIPS_HFLAG_B;
6072 case OPC_BNE: /* rx != rx */
6073 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6074 /* Skip the instruction in the delay slot */
6075 ctx->base.pc_next += 4;
6078 ctx->hflags |= MIPS_HFLAG_BR;
6082 tcg_gen_movi_tl(cpu_gpr[rt],
6083 ctx->base.pc_next + insn_bytes);
6085 ctx->hflags |= MIPS_HFLAG_BR;
6088 MIPS_INVAL("branch/jump");
6089 generate_exception_end(ctx, EXCP_RI);
6095 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6098 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6101 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6102 tcg_gen_movi_tl(cpu_gpr[31],
6103 ctx->base.pc_next + insn_bytes);
6106 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6108 ctx->hflags |= MIPS_HFLAG_BC;
6111 MIPS_INVAL("conditional branch/jump");
6112 generate_exception_end(ctx, EXCP_RI);
6117 ctx->btarget = btgt;
6120 if (insn_bytes == 2) {
6121 ctx->hflags |= MIPS_HFLAG_B16;
6128 /* special3 bitfield operations */
6129 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
6130 int rs, int lsb, int msb)
6132 TCGv t0 = tcg_temp_new();
6133 TCGv t1 = tcg_temp_new();
6135 gen_load_gpr(t1, rs);
6138 if (lsb + msb > 31) {
6142 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6144 /* The two checks together imply that lsb == 0,
6145 so this is a simple sign-extension. */
6146 tcg_gen_ext32s_tl(t0, t1);
6149 #if defined(TARGET_MIPS64)
6158 if (lsb + msb > 63) {
6161 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6168 gen_load_gpr(t0, rt);
6169 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6170 tcg_gen_ext32s_tl(t0, t0);
6172 #if defined(TARGET_MIPS64)
6183 gen_load_gpr(t0, rt);
6184 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6189 MIPS_INVAL("bitops");
6190 generate_exception_end(ctx, EXCP_RI);
6195 gen_store_gpr(t0, rt);
6200 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6205 /* If no destination, treat it as a NOP. */
6209 t0 = tcg_temp_new();
6210 gen_load_gpr(t0, rt);
6214 TCGv t1 = tcg_temp_new();
6215 TCGv t2 = tcg_const_tl(0x00FF00FF);
6217 tcg_gen_shri_tl(t1, t0, 8);
6218 tcg_gen_and_tl(t1, t1, t2);
6219 tcg_gen_and_tl(t0, t0, t2);
6220 tcg_gen_shli_tl(t0, t0, 8);
6221 tcg_gen_or_tl(t0, t0, t1);
6224 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6228 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6231 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6233 #if defined(TARGET_MIPS64)
6236 TCGv t1 = tcg_temp_new();
6237 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6239 tcg_gen_shri_tl(t1, t0, 8);
6240 tcg_gen_and_tl(t1, t1, t2);
6241 tcg_gen_and_tl(t0, t0, t2);
6242 tcg_gen_shli_tl(t0, t0, 8);
6243 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6250 TCGv t1 = tcg_temp_new();
6251 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6253 tcg_gen_shri_tl(t1, t0, 16);
6254 tcg_gen_and_tl(t1, t1, t2);
6255 tcg_gen_and_tl(t0, t0, t2);
6256 tcg_gen_shli_tl(t0, t0, 16);
6257 tcg_gen_or_tl(t0, t0, t1);
6258 tcg_gen_shri_tl(t1, t0, 32);
6259 tcg_gen_shli_tl(t0, t0, 32);
6260 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6267 MIPS_INVAL("bsfhl");
6268 generate_exception_end(ctx, EXCP_RI);
6275 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6284 t0 = tcg_temp_new();
6285 t1 = tcg_temp_new();
6286 gen_load_gpr(t0, rs);
6287 gen_load_gpr(t1, rt);
6288 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6289 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6290 if (opc == OPC_LSA) {
6291 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6300 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6308 t0 = tcg_temp_new();
6309 if (bits == 0 || bits == wordsz) {
6311 gen_load_gpr(t0, rt);
6313 gen_load_gpr(t0, rs);
6317 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6319 #if defined(TARGET_MIPS64)
6321 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6326 TCGv t1 = tcg_temp_new();
6327 gen_load_gpr(t0, rt);
6328 gen_load_gpr(t1, rs);
6332 TCGv_i64 t2 = tcg_temp_new_i64();
6333 tcg_gen_concat_tl_i64(t2, t1, t0);
6334 tcg_gen_shri_i64(t2, t2, 32 - bits);
6335 gen_move_low32(cpu_gpr[rd], t2);
6336 tcg_temp_free_i64(t2);
6339 #if defined(TARGET_MIPS64)
6341 tcg_gen_shli_tl(t0, t0, bits);
6342 tcg_gen_shri_tl(t1, t1, 64 - bits);
6343 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6353 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6356 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6359 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6362 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6365 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6372 t0 = tcg_temp_new();
6373 gen_load_gpr(t0, rt);
6376 gen_helper_bitswap(cpu_gpr[rd], t0);
6378 #if defined(TARGET_MIPS64)
6380 gen_helper_dbitswap(cpu_gpr[rd], t0);
6387 #ifndef CONFIG_USER_ONLY
6388 /* CP0 (MMU and control) */
6389 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6391 TCGv_i64 t0 = tcg_temp_new_i64();
6392 TCGv_i64 t1 = tcg_temp_new_i64();
6394 tcg_gen_ext_tl_i64(t0, arg);
6395 tcg_gen_ld_i64(t1, cpu_env, off);
6396 #if defined(TARGET_MIPS64)
6397 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6399 tcg_gen_concat32_i64(t1, t1, t0);
6401 tcg_gen_st_i64(t1, cpu_env, off);
6402 tcg_temp_free_i64(t1);
6403 tcg_temp_free_i64(t0);
6406 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6408 TCGv_i64 t0 = tcg_temp_new_i64();
6409 TCGv_i64 t1 = tcg_temp_new_i64();
6411 tcg_gen_ext_tl_i64(t0, arg);
6412 tcg_gen_ld_i64(t1, cpu_env, off);
6413 tcg_gen_concat32_i64(t1, t1, t0);
6414 tcg_gen_st_i64(t1, cpu_env, off);
6415 tcg_temp_free_i64(t1);
6416 tcg_temp_free_i64(t0);
6419 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6421 TCGv_i64 t0 = tcg_temp_new_i64();
6423 tcg_gen_ld_i64(t0, cpu_env, off);
6424 #if defined(TARGET_MIPS64)
6425 tcg_gen_shri_i64(t0, t0, 30);
6427 tcg_gen_shri_i64(t0, t0, 32);
6429 gen_move_low32(arg, t0);
6430 tcg_temp_free_i64(t0);
6433 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6435 TCGv_i64 t0 = tcg_temp_new_i64();
6437 tcg_gen_ld_i64(t0, cpu_env, off);
6438 tcg_gen_shri_i64(t0, t0, 32 + shift);
6439 gen_move_low32(arg, t0);
6440 tcg_temp_free_i64(t0);
6443 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6445 TCGv_i32 t0 = tcg_temp_new_i32();
6447 tcg_gen_ld_i32(t0, cpu_env, off);
6448 tcg_gen_ext_i32_tl(arg, t0);
6449 tcg_temp_free_i32(t0);
6452 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6454 tcg_gen_ld_tl(arg, cpu_env, off);
6455 tcg_gen_ext32s_tl(arg, arg);
6458 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6460 TCGv_i32 t0 = tcg_temp_new_i32();
6462 tcg_gen_trunc_tl_i32(t0, arg);
6463 tcg_gen_st_i32(t0, cpu_env, off);
6464 tcg_temp_free_i32(t0);
6467 #define CP0_CHECK(c) \
6470 goto cp0_unimplemented; \
6474 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6476 const char *rn = "invalid";
6482 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6483 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6487 goto cp0_unimplemented;
6493 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6494 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6498 goto cp0_unimplemented;
6504 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6505 ctx->CP0_LLAddr_shift);
6509 CP0_CHECK(ctx->mrp);
6510 gen_helper_mfhc0_maar(arg, cpu_env);
6514 goto cp0_unimplemented;
6523 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6527 goto cp0_unimplemented;
6531 goto cp0_unimplemented;
6533 trace_mips_translate_c0("mfhc0", rn, reg, sel);
6537 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
6538 tcg_gen_movi_tl(arg, 0);
6541 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6543 const char *rn = "invalid";
6544 uint64_t mask = ctx->PAMask >> 36;
6550 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6551 tcg_gen_andi_tl(arg, arg, mask);
6552 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6556 goto cp0_unimplemented;
6562 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6563 tcg_gen_andi_tl(arg, arg, mask);
6564 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6568 goto cp0_unimplemented;
6574 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6575 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6576 relevant for modern MIPS cores supporting MTHC0, therefore
6577 treating MTHC0 to LLAddr as NOP. */
6581 CP0_CHECK(ctx->mrp);
6582 gen_helper_mthc0_maar(cpu_env, arg);
6586 goto cp0_unimplemented;
6595 tcg_gen_andi_tl(arg, arg, mask);
6596 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6600 goto cp0_unimplemented;
6604 goto cp0_unimplemented;
6606 trace_mips_translate_c0("mthc0", rn, reg, sel);
6609 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
6612 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6614 if (ctx->insn_flags & ISA_MIPS32R6) {
6615 tcg_gen_movi_tl(arg, 0);
6617 tcg_gen_movi_tl(arg, ~0);
6621 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6623 const char *rn = "invalid";
6626 check_insn(ctx, ISA_MIPS32);
6632 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6636 CP0_CHECK(ctx->insn_flags & ASE_MT);
6637 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6641 CP0_CHECK(ctx->insn_flags & ASE_MT);
6642 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6646 CP0_CHECK(ctx->insn_flags & ASE_MT);
6647 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6652 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6656 goto cp0_unimplemented;
6662 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6663 gen_helper_mfc0_random(arg, cpu_env);
6667 CP0_CHECK(ctx->insn_flags & ASE_MT);
6668 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6672 CP0_CHECK(ctx->insn_flags & ASE_MT);
6673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6677 CP0_CHECK(ctx->insn_flags & ASE_MT);
6678 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6682 CP0_CHECK(ctx->insn_flags & ASE_MT);
6683 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6687 CP0_CHECK(ctx->insn_flags & ASE_MT);
6688 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6692 CP0_CHECK(ctx->insn_flags & ASE_MT);
6693 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6694 rn = "VPEScheFBack";
6697 CP0_CHECK(ctx->insn_flags & ASE_MT);
6698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6702 goto cp0_unimplemented;
6709 TCGv_i64 tmp = tcg_temp_new_i64();
6710 tcg_gen_ld_i64(tmp, cpu_env,
6711 offsetof(CPUMIPSState, CP0_EntryLo0));
6712 #if defined(TARGET_MIPS64)
6714 /* Move RI/XI fields to bits 31:30 */
6715 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6716 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6719 gen_move_low32(arg, tmp);
6720 tcg_temp_free_i64(tmp);
6725 CP0_CHECK(ctx->insn_flags & ASE_MT);
6726 gen_helper_mfc0_tcstatus(arg, cpu_env);
6730 CP0_CHECK(ctx->insn_flags & ASE_MT);
6731 gen_helper_mfc0_tcbind(arg, cpu_env);
6735 CP0_CHECK(ctx->insn_flags & ASE_MT);
6736 gen_helper_mfc0_tcrestart(arg, cpu_env);
6740 CP0_CHECK(ctx->insn_flags & ASE_MT);
6741 gen_helper_mfc0_tchalt(arg, cpu_env);
6745 CP0_CHECK(ctx->insn_flags & ASE_MT);
6746 gen_helper_mfc0_tccontext(arg, cpu_env);
6750 CP0_CHECK(ctx->insn_flags & ASE_MT);
6751 gen_helper_mfc0_tcschedule(arg, cpu_env);
6755 CP0_CHECK(ctx->insn_flags & ASE_MT);
6756 gen_helper_mfc0_tcschefback(arg, cpu_env);
6760 goto cp0_unimplemented;
6767 TCGv_i64 tmp = tcg_temp_new_i64();
6768 tcg_gen_ld_i64(tmp, cpu_env,
6769 offsetof(CPUMIPSState, CP0_EntryLo1));
6770 #if defined(TARGET_MIPS64)
6772 /* Move RI/XI fields to bits 31:30 */
6773 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6774 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6777 gen_move_low32(arg, tmp);
6778 tcg_temp_free_i64(tmp);
6784 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6785 rn = "GlobalNumber";
6788 goto cp0_unimplemented;
6794 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6795 tcg_gen_ext32s_tl(arg, arg);
6799 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6800 rn = "ContextConfig";
6801 goto cp0_unimplemented;
6803 CP0_CHECK(ctx->ulri);
6804 tcg_gen_ld_tl(arg, cpu_env,
6805 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6806 tcg_gen_ext32s_tl(arg, arg);
6810 goto cp0_unimplemented;
6816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6820 check_insn(ctx, ISA_MIPS32R2);
6821 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6826 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6827 tcg_gen_ext32s_tl(arg, arg);
6832 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6833 tcg_gen_ext32s_tl(arg, arg);
6838 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6839 tcg_gen_ext32s_tl(arg, arg);
6844 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6849 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6854 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6858 goto cp0_unimplemented;
6864 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6868 check_insn(ctx, ISA_MIPS32R2);
6869 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6873 check_insn(ctx, ISA_MIPS32R2);
6874 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6878 check_insn(ctx, ISA_MIPS32R2);
6879 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6883 check_insn(ctx, ISA_MIPS32R2);
6884 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6888 check_insn(ctx, ISA_MIPS32R2);
6889 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6894 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6898 goto cp0_unimplemented;
6904 check_insn(ctx, ISA_MIPS32R2);
6905 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6909 goto cp0_unimplemented;
6915 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6916 tcg_gen_ext32s_tl(arg, arg);
6921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6926 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6931 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6932 tcg_gen_andi_tl(arg, arg, ~0xffff);
6936 goto cp0_unimplemented;
6942 /* Mark as an IO operation because we read the time. */
6943 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6946 gen_helper_mfc0_count(arg, cpu_env);
6947 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6950 /* Break the TB to be able to take timer interrupts immediately
6951 after reading count. DISAS_STOP isn't sufficient, we need to
6952 ensure we break completely out of translated code. */
6953 gen_save_pc(ctx->base.pc_next + 4);
6954 ctx->base.is_jmp = DISAS_EXIT;
6957 /* 6,7 are implementation dependent */
6959 goto cp0_unimplemented;
6965 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6966 tcg_gen_ext32s_tl(arg, arg);
6970 goto cp0_unimplemented;
6976 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6979 /* 6,7 are implementation dependent */
6981 goto cp0_unimplemented;
6987 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6991 check_insn(ctx, ISA_MIPS32R2);
6992 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6996 check_insn(ctx, ISA_MIPS32R2);
6997 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7001 check_insn(ctx, ISA_MIPS32R2);
7002 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7006 goto cp0_unimplemented;
7012 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7016 goto cp0_unimplemented;
7022 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7023 tcg_gen_ext32s_tl(arg, arg);
7027 goto cp0_unimplemented;
7033 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7037 check_insn(ctx, ISA_MIPS32R2);
7038 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7039 tcg_gen_ext32s_tl(arg, arg);
7043 check_insn(ctx, ISA_MIPS32R2);
7044 CP0_CHECK(ctx->cmgcr);
7045 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7046 tcg_gen_ext32s_tl(arg, arg);
7050 goto cp0_unimplemented;
7056 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7060 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7064 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7068 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7072 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7079 /* 6,7 are implementation dependent */
7081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7085 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7089 goto cp0_unimplemented;
7095 gen_helper_mfc0_lladdr(arg, cpu_env);
7099 CP0_CHECK(ctx->mrp);
7100 gen_helper_mfc0_maar(arg, cpu_env);
7104 CP0_CHECK(ctx->mrp);
7105 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7109 goto cp0_unimplemented;
7122 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7123 gen_helper_1e0i(mfc0_watchlo, arg, sel);
7127 goto cp0_unimplemented;
7140 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7141 gen_helper_1e0i(mfc0_watchhi, arg, sel);
7145 goto cp0_unimplemented;
7151 #if defined(TARGET_MIPS64)
7152 check_insn(ctx, ISA_MIPS3);
7153 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7154 tcg_gen_ext32s_tl(arg, arg);
7159 goto cp0_unimplemented;
7163 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7164 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7171 goto cp0_unimplemented;
7175 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7176 rn = "'Diagnostic"; /* implementation dependent */
7181 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7185 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7186 rn = "TraceControl";
7187 goto cp0_unimplemented;
7189 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7190 rn = "TraceControl2";
7191 goto cp0_unimplemented;
7193 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7194 rn = "UserTraceData";
7195 goto cp0_unimplemented;
7197 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7199 goto cp0_unimplemented;
7201 goto cp0_unimplemented;
7208 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7209 tcg_gen_ext32s_tl(arg, arg);
7213 goto cp0_unimplemented;
7219 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7220 rn = "Performance0";
7223 // gen_helper_mfc0_performance1(arg);
7224 rn = "Performance1";
7225 goto cp0_unimplemented;
7227 // gen_helper_mfc0_performance2(arg);
7228 rn = "Performance2";
7229 goto cp0_unimplemented;
7231 // gen_helper_mfc0_performance3(arg);
7232 rn = "Performance3";
7233 goto cp0_unimplemented;
7235 // gen_helper_mfc0_performance4(arg);
7236 rn = "Performance4";
7237 goto cp0_unimplemented;
7239 // gen_helper_mfc0_performance5(arg);
7240 rn = "Performance5";
7241 goto cp0_unimplemented;
7243 // gen_helper_mfc0_performance6(arg);
7244 rn = "Performance6";
7245 goto cp0_unimplemented;
7247 // gen_helper_mfc0_performance7(arg);
7248 rn = "Performance7";
7249 goto cp0_unimplemented;
7251 goto cp0_unimplemented;
7257 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7261 goto cp0_unimplemented;
7270 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7274 goto cp0_unimplemented;
7284 TCGv_i64 tmp = tcg_temp_new_i64();
7285 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7286 gen_move_low32(arg, tmp);
7287 tcg_temp_free_i64(tmp);
7295 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7299 goto cp0_unimplemented;
7308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7319 goto cp0_unimplemented;
7325 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7326 tcg_gen_ext32s_tl(arg, arg);
7330 goto cp0_unimplemented;
7337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7346 CP0_CHECK(ctx->kscrexist & (1 << sel));
7347 tcg_gen_ld_tl(arg, cpu_env,
7348 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7349 tcg_gen_ext32s_tl(arg, arg);
7353 goto cp0_unimplemented;
7357 goto cp0_unimplemented;
7359 trace_mips_translate_c0("mfc0", rn, reg, sel);
7363 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
7364 gen_mfc0_unimplemented(ctx, arg);
7367 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7369 const char *rn = "invalid";
7372 check_insn(ctx, ISA_MIPS32);
7374 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7382 gen_helper_mtc0_index(cpu_env, arg);
7386 CP0_CHECK(ctx->insn_flags & ASE_MT);
7387 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7391 CP0_CHECK(ctx->insn_flags & ASE_MT);
7396 CP0_CHECK(ctx->insn_flags & ASE_MT);
7406 goto cp0_unimplemented;
7416 CP0_CHECK(ctx->insn_flags & ASE_MT);
7417 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7421 CP0_CHECK(ctx->insn_flags & ASE_MT);
7422 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7426 CP0_CHECK(ctx->insn_flags & ASE_MT);
7427 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7431 CP0_CHECK(ctx->insn_flags & ASE_MT);
7432 gen_helper_mtc0_yqmask(cpu_env, arg);
7436 CP0_CHECK(ctx->insn_flags & ASE_MT);
7437 tcg_gen_st_tl(arg, cpu_env,
7438 offsetof(CPUMIPSState, CP0_VPESchedule));
7442 CP0_CHECK(ctx->insn_flags & ASE_MT);
7443 tcg_gen_st_tl(arg, cpu_env,
7444 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7445 rn = "VPEScheFBack";
7448 CP0_CHECK(ctx->insn_flags & ASE_MT);
7449 gen_helper_mtc0_vpeopt(cpu_env, arg);
7453 goto cp0_unimplemented;
7459 gen_helper_mtc0_entrylo0(cpu_env, arg);
7463 CP0_CHECK(ctx->insn_flags & ASE_MT);
7464 gen_helper_mtc0_tcstatus(cpu_env, arg);
7468 CP0_CHECK(ctx->insn_flags & ASE_MT);
7469 gen_helper_mtc0_tcbind(cpu_env, arg);
7473 CP0_CHECK(ctx->insn_flags & ASE_MT);
7474 gen_helper_mtc0_tcrestart(cpu_env, arg);
7478 CP0_CHECK(ctx->insn_flags & ASE_MT);
7479 gen_helper_mtc0_tchalt(cpu_env, arg);
7483 CP0_CHECK(ctx->insn_flags & ASE_MT);
7484 gen_helper_mtc0_tccontext(cpu_env, arg);
7488 CP0_CHECK(ctx->insn_flags & ASE_MT);
7489 gen_helper_mtc0_tcschedule(cpu_env, arg);
7493 CP0_CHECK(ctx->insn_flags & ASE_MT);
7494 gen_helper_mtc0_tcschefback(cpu_env, arg);
7498 goto cp0_unimplemented;
7504 gen_helper_mtc0_entrylo1(cpu_env, arg);
7510 rn = "GlobalNumber";
7513 goto cp0_unimplemented;
7519 gen_helper_mtc0_context(cpu_env, arg);
7523 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7524 rn = "ContextConfig";
7525 goto cp0_unimplemented;
7527 CP0_CHECK(ctx->ulri);
7528 tcg_gen_st_tl(arg, cpu_env,
7529 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7533 goto cp0_unimplemented;
7539 gen_helper_mtc0_pagemask(cpu_env, arg);
7543 check_insn(ctx, ISA_MIPS32R2);
7544 gen_helper_mtc0_pagegrain(cpu_env, arg);
7546 ctx->base.is_jmp = DISAS_STOP;
7550 gen_helper_mtc0_segctl0(cpu_env, arg);
7555 gen_helper_mtc0_segctl1(cpu_env, arg);
7560 gen_helper_mtc0_segctl2(cpu_env, arg);
7565 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7570 gen_helper_mtc0_pwfield(cpu_env, arg);
7575 gen_helper_mtc0_pwsize(cpu_env, arg);
7579 goto cp0_unimplemented;
7585 gen_helper_mtc0_wired(cpu_env, arg);
7589 check_insn(ctx, ISA_MIPS32R2);
7590 gen_helper_mtc0_srsconf0(cpu_env, arg);
7594 check_insn(ctx, ISA_MIPS32R2);
7595 gen_helper_mtc0_srsconf1(cpu_env, arg);
7599 check_insn(ctx, ISA_MIPS32R2);
7600 gen_helper_mtc0_srsconf2(cpu_env, arg);
7604 check_insn(ctx, ISA_MIPS32R2);
7605 gen_helper_mtc0_srsconf3(cpu_env, arg);
7609 check_insn(ctx, ISA_MIPS32R2);
7610 gen_helper_mtc0_srsconf4(cpu_env, arg);
7615 gen_helper_mtc0_pwctl(cpu_env, arg);
7619 goto cp0_unimplemented;
7625 check_insn(ctx, ISA_MIPS32R2);
7626 gen_helper_mtc0_hwrena(cpu_env, arg);
7627 ctx->base.is_jmp = DISAS_STOP;
7631 goto cp0_unimplemented;
7653 goto cp0_unimplemented;
7659 gen_helper_mtc0_count(cpu_env, arg);
7662 /* 6,7 are implementation dependent */
7664 goto cp0_unimplemented;
7670 gen_helper_mtc0_entryhi(cpu_env, arg);
7674 goto cp0_unimplemented;
7680 gen_helper_mtc0_compare(cpu_env, arg);
7683 /* 6,7 are implementation dependent */
7685 goto cp0_unimplemented;
7691 save_cpu_state(ctx, 1);
7692 gen_helper_mtc0_status(cpu_env, arg);
7693 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7694 gen_save_pc(ctx->base.pc_next + 4);
7695 ctx->base.is_jmp = DISAS_EXIT;
7699 check_insn(ctx, ISA_MIPS32R2);
7700 gen_helper_mtc0_intctl(cpu_env, arg);
7701 /* Stop translation as we may have switched the execution mode */
7702 ctx->base.is_jmp = DISAS_STOP;
7706 check_insn(ctx, ISA_MIPS32R2);
7707 gen_helper_mtc0_srsctl(cpu_env, arg);
7708 /* Stop translation as we may have switched the execution mode */
7709 ctx->base.is_jmp = DISAS_STOP;
7713 check_insn(ctx, ISA_MIPS32R2);
7714 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7715 /* Stop translation as we may have switched the execution mode */
7716 ctx->base.is_jmp = DISAS_STOP;
7720 goto cp0_unimplemented;
7726 save_cpu_state(ctx, 1);
7727 gen_helper_mtc0_cause(cpu_env, arg);
7728 /* Stop translation as we may have triggered an interrupt.
7729 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7730 * translated code to check for pending interrupts. */
7731 gen_save_pc(ctx->base.pc_next + 4);
7732 ctx->base.is_jmp = DISAS_EXIT;
7736 goto cp0_unimplemented;
7742 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7746 goto cp0_unimplemented;
7756 check_insn(ctx, ISA_MIPS32R2);
7757 gen_helper_mtc0_ebase(cpu_env, arg);
7761 goto cp0_unimplemented;
7767 gen_helper_mtc0_config0(cpu_env, arg);
7769 /* Stop translation as we may have switched the execution mode */
7770 ctx->base.is_jmp = DISAS_STOP;
7773 /* ignored, read only */
7777 gen_helper_mtc0_config2(cpu_env, arg);
7779 /* Stop translation as we may have switched the execution mode */
7780 ctx->base.is_jmp = DISAS_STOP;
7783 gen_helper_mtc0_config3(cpu_env, arg);
7785 /* Stop translation as we may have switched the execution mode */
7786 ctx->base.is_jmp = DISAS_STOP;
7789 gen_helper_mtc0_config4(cpu_env, arg);
7791 ctx->base.is_jmp = DISAS_STOP;
7794 gen_helper_mtc0_config5(cpu_env, arg);
7796 /* Stop translation as we may have switched the execution mode */
7797 ctx->base.is_jmp = DISAS_STOP;
7799 /* 6,7 are implementation dependent */
7809 rn = "Invalid config selector";
7810 goto cp0_unimplemented;
7816 gen_helper_mtc0_lladdr(cpu_env, arg);
7820 CP0_CHECK(ctx->mrp);
7821 gen_helper_mtc0_maar(cpu_env, arg);
7825 CP0_CHECK(ctx->mrp);
7826 gen_helper_mtc0_maari(cpu_env, arg);
7830 goto cp0_unimplemented;
7843 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7844 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7848 goto cp0_unimplemented;
7861 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7862 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7866 goto cp0_unimplemented;
7872 #if defined(TARGET_MIPS64)
7873 check_insn(ctx, ISA_MIPS3);
7874 gen_helper_mtc0_xcontext(cpu_env, arg);
7879 goto cp0_unimplemented;
7883 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7884 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7887 gen_helper_mtc0_framemask(cpu_env, arg);
7891 goto cp0_unimplemented;
7896 rn = "Diagnostic"; /* implementation dependent */
7901 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7902 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7903 gen_save_pc(ctx->base.pc_next + 4);
7904 ctx->base.is_jmp = DISAS_EXIT;
7908 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7909 rn = "TraceControl";
7910 /* Stop translation as we may have switched the execution mode */
7911 ctx->base.is_jmp = DISAS_STOP;
7912 goto cp0_unimplemented;
7914 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7915 rn = "TraceControl2";
7916 /* Stop translation as we may have switched the execution mode */
7917 ctx->base.is_jmp = DISAS_STOP;
7918 goto cp0_unimplemented;
7920 /* Stop translation as we may have switched the execution mode */
7921 ctx->base.is_jmp = DISAS_STOP;
7922 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7923 rn = "UserTraceData";
7924 /* Stop translation as we may have switched the execution mode */
7925 ctx->base.is_jmp = DISAS_STOP;
7926 goto cp0_unimplemented;
7928 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7929 /* Stop translation as we may have switched the execution mode */
7930 ctx->base.is_jmp = DISAS_STOP;
7932 goto cp0_unimplemented;
7934 goto cp0_unimplemented;
7941 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7945 goto cp0_unimplemented;
7951 gen_helper_mtc0_performance0(cpu_env, arg);
7952 rn = "Performance0";
7955 // gen_helper_mtc0_performance1(arg);
7956 rn = "Performance1";
7957 goto cp0_unimplemented;
7959 // gen_helper_mtc0_performance2(arg);
7960 rn = "Performance2";
7961 goto cp0_unimplemented;
7963 // gen_helper_mtc0_performance3(arg);
7964 rn = "Performance3";
7965 goto cp0_unimplemented;
7967 // gen_helper_mtc0_performance4(arg);
7968 rn = "Performance4";
7969 goto cp0_unimplemented;
7971 // gen_helper_mtc0_performance5(arg);
7972 rn = "Performance5";
7973 goto cp0_unimplemented;
7975 // gen_helper_mtc0_performance6(arg);
7976 rn = "Performance6";
7977 goto cp0_unimplemented;
7979 // gen_helper_mtc0_performance7(arg);
7980 rn = "Performance7";
7981 goto cp0_unimplemented;
7983 goto cp0_unimplemented;
7989 gen_helper_mtc0_errctl(cpu_env, arg);
7990 ctx->base.is_jmp = DISAS_STOP;
7994 goto cp0_unimplemented;
8007 goto cp0_unimplemented;
8016 gen_helper_mtc0_taglo(cpu_env, arg);
8023 gen_helper_mtc0_datalo(cpu_env, arg);
8027 goto cp0_unimplemented;
8036 gen_helper_mtc0_taghi(cpu_env, arg);
8043 gen_helper_mtc0_datahi(cpu_env, arg);
8048 goto cp0_unimplemented;
8054 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8058 goto cp0_unimplemented;
8065 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8074 CP0_CHECK(ctx->kscrexist & (1 << sel));
8075 tcg_gen_st_tl(arg, cpu_env,
8076 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8080 goto cp0_unimplemented;
8084 goto cp0_unimplemented;
8086 trace_mips_translate_c0("mtc0", rn, reg, sel);
8088 /* For simplicity assume that all writes can cause interrupts. */
8089 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8091 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8092 * translated code to check for pending interrupts. */
8093 gen_save_pc(ctx->base.pc_next + 4);
8094 ctx->base.is_jmp = DISAS_EXIT;
8099 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8102 #if defined(TARGET_MIPS64)
8103 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8105 const char *rn = "invalid";
8108 check_insn(ctx, ISA_MIPS64);
8114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8118 CP0_CHECK(ctx->insn_flags & ASE_MT);
8119 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8123 CP0_CHECK(ctx->insn_flags & ASE_MT);
8124 gen_helper_mfc0_mvpconf0(arg, cpu_env);
8128 CP0_CHECK(ctx->insn_flags & ASE_MT);
8129 gen_helper_mfc0_mvpconf1(arg, cpu_env);
8134 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8138 goto cp0_unimplemented;
8144 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8145 gen_helper_mfc0_random(arg, cpu_env);
8149 CP0_CHECK(ctx->insn_flags & ASE_MT);
8150 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8154 CP0_CHECK(ctx->insn_flags & ASE_MT);
8155 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8159 CP0_CHECK(ctx->insn_flags & ASE_MT);
8160 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8164 CP0_CHECK(ctx->insn_flags & ASE_MT);
8165 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8169 CP0_CHECK(ctx->insn_flags & ASE_MT);
8170 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8174 CP0_CHECK(ctx->insn_flags & ASE_MT);
8175 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8176 rn = "VPEScheFBack";
8179 CP0_CHECK(ctx->insn_flags & ASE_MT);
8180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8184 goto cp0_unimplemented;
8190 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8194 CP0_CHECK(ctx->insn_flags & ASE_MT);
8195 gen_helper_mfc0_tcstatus(arg, cpu_env);
8199 CP0_CHECK(ctx->insn_flags & ASE_MT);
8200 gen_helper_mfc0_tcbind(arg, cpu_env);
8204 CP0_CHECK(ctx->insn_flags & ASE_MT);
8205 gen_helper_dmfc0_tcrestart(arg, cpu_env);
8209 CP0_CHECK(ctx->insn_flags & ASE_MT);
8210 gen_helper_dmfc0_tchalt(arg, cpu_env);
8214 CP0_CHECK(ctx->insn_flags & ASE_MT);
8215 gen_helper_dmfc0_tccontext(arg, cpu_env);
8219 CP0_CHECK(ctx->insn_flags & ASE_MT);
8220 gen_helper_dmfc0_tcschedule(arg, cpu_env);
8224 CP0_CHECK(ctx->insn_flags & ASE_MT);
8225 gen_helper_dmfc0_tcschefback(arg, cpu_env);
8229 goto cp0_unimplemented;
8235 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8240 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8241 rn = "GlobalNumber";
8244 goto cp0_unimplemented;
8250 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8254 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8255 rn = "ContextConfig";
8256 goto cp0_unimplemented;
8258 CP0_CHECK(ctx->ulri);
8259 tcg_gen_ld_tl(arg, cpu_env,
8260 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8264 goto cp0_unimplemented;
8270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8274 check_insn(ctx, ISA_MIPS32R2);
8275 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8280 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8285 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8290 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8295 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8300 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8305 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8309 goto cp0_unimplemented;
8315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8319 check_insn(ctx, ISA_MIPS32R2);
8320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8324 check_insn(ctx, ISA_MIPS32R2);
8325 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8329 check_insn(ctx, ISA_MIPS32R2);
8330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8334 check_insn(ctx, ISA_MIPS32R2);
8335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8339 check_insn(ctx, ISA_MIPS32R2);
8340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8349 goto cp0_unimplemented;
8355 check_insn(ctx, ISA_MIPS32R2);
8356 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8360 goto cp0_unimplemented;
8366 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8371 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8381 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8382 tcg_gen_andi_tl(arg, arg, ~0xffff);
8386 goto cp0_unimplemented;
8392 /* Mark as an IO operation because we read the time. */
8393 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8396 gen_helper_mfc0_count(arg, cpu_env);
8397 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8400 /* Break the TB to be able to take timer interrupts immediately
8401 after reading count. DISAS_STOP isn't sufficient, we need to
8402 ensure we break completely out of translated code. */
8403 gen_save_pc(ctx->base.pc_next + 4);
8404 ctx->base.is_jmp = DISAS_EXIT;
8407 /* 6,7 are implementation dependent */
8409 goto cp0_unimplemented;
8415 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8419 goto cp0_unimplemented;
8425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8428 /* 6,7 are implementation dependent */
8430 goto cp0_unimplemented;
8436 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8440 check_insn(ctx, ISA_MIPS32R2);
8441 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8445 check_insn(ctx, ISA_MIPS32R2);
8446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8450 check_insn(ctx, ISA_MIPS32R2);
8451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8455 goto cp0_unimplemented;
8461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8465 goto cp0_unimplemented;
8471 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8475 goto cp0_unimplemented;
8481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8485 check_insn(ctx, ISA_MIPS32R2);
8486 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8490 check_insn(ctx, ISA_MIPS32R2);
8491 CP0_CHECK(ctx->cmgcr);
8492 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8496 goto cp0_unimplemented;
8502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8506 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8514 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8518 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8525 /* 6,7 are implementation dependent */
8527 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8531 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8535 goto cp0_unimplemented;
8541 gen_helper_dmfc0_lladdr(arg, cpu_env);
8545 CP0_CHECK(ctx->mrp);
8546 gen_helper_dmfc0_maar(arg, cpu_env);
8550 CP0_CHECK(ctx->mrp);
8551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8555 goto cp0_unimplemented;
8568 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8569 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8573 goto cp0_unimplemented;
8586 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8587 gen_helper_1e0i(mfc0_watchhi, arg, sel);
8591 goto cp0_unimplemented;
8597 check_insn(ctx, ISA_MIPS3);
8598 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8602 goto cp0_unimplemented;
8606 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8607 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8614 goto cp0_unimplemented;
8618 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8619 rn = "'Diagnostic"; /* implementation dependent */
8624 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8628 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8629 rn = "TraceControl";
8630 goto cp0_unimplemented;
8632 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8633 rn = "TraceControl2";
8634 goto cp0_unimplemented;
8636 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8637 rn = "UserTraceData";
8638 goto cp0_unimplemented;
8640 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8642 goto cp0_unimplemented;
8644 goto cp0_unimplemented;
8651 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8655 goto cp0_unimplemented;
8661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8662 rn = "Performance0";
8665 // gen_helper_dmfc0_performance1(arg);
8666 rn = "Performance1";
8667 goto cp0_unimplemented;
8669 // gen_helper_dmfc0_performance2(arg);
8670 rn = "Performance2";
8671 goto cp0_unimplemented;
8673 // gen_helper_dmfc0_performance3(arg);
8674 rn = "Performance3";
8675 goto cp0_unimplemented;
8677 // gen_helper_dmfc0_performance4(arg);
8678 rn = "Performance4";
8679 goto cp0_unimplemented;
8681 // gen_helper_dmfc0_performance5(arg);
8682 rn = "Performance5";
8683 goto cp0_unimplemented;
8685 // gen_helper_dmfc0_performance6(arg);
8686 rn = "Performance6";
8687 goto cp0_unimplemented;
8689 // gen_helper_dmfc0_performance7(arg);
8690 rn = "Performance7";
8691 goto cp0_unimplemented;
8693 goto cp0_unimplemented;
8699 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8703 goto cp0_unimplemented;
8713 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8717 goto cp0_unimplemented;
8726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8733 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8737 goto cp0_unimplemented;
8746 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8753 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8757 goto cp0_unimplemented;
8763 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8767 goto cp0_unimplemented;
8774 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8783 CP0_CHECK(ctx->kscrexist & (1 << sel));
8784 tcg_gen_ld_tl(arg, cpu_env,
8785 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8789 goto cp0_unimplemented;
8793 goto cp0_unimplemented;
8795 trace_mips_translate_c0("dmfc0", rn, reg, sel);
8799 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
8800 gen_mfc0_unimplemented(ctx, arg);
8803 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8805 const char *rn = "invalid";
8808 check_insn(ctx, ISA_MIPS64);
8810 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8818 gen_helper_mtc0_index(cpu_env, arg);
8822 CP0_CHECK(ctx->insn_flags & ASE_MT);
8823 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8827 CP0_CHECK(ctx->insn_flags & ASE_MT);
8832 CP0_CHECK(ctx->insn_flags & ASE_MT);
8842 goto cp0_unimplemented;
8852 CP0_CHECK(ctx->insn_flags & ASE_MT);
8853 gen_helper_mtc0_vpecontrol(cpu_env, arg);
8857 CP0_CHECK(ctx->insn_flags & ASE_MT);
8858 gen_helper_mtc0_vpeconf0(cpu_env, arg);
8862 CP0_CHECK(ctx->insn_flags & ASE_MT);
8863 gen_helper_mtc0_vpeconf1(cpu_env, arg);
8867 CP0_CHECK(ctx->insn_flags & ASE_MT);
8868 gen_helper_mtc0_yqmask(cpu_env, arg);
8872 CP0_CHECK(ctx->insn_flags & ASE_MT);
8873 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8877 CP0_CHECK(ctx->insn_flags & ASE_MT);
8878 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8879 rn = "VPEScheFBack";
8882 CP0_CHECK(ctx->insn_flags & ASE_MT);
8883 gen_helper_mtc0_vpeopt(cpu_env, arg);
8887 goto cp0_unimplemented;
8893 gen_helper_dmtc0_entrylo0(cpu_env, arg);
8897 CP0_CHECK(ctx->insn_flags & ASE_MT);
8898 gen_helper_mtc0_tcstatus(cpu_env, arg);
8902 CP0_CHECK(ctx->insn_flags & ASE_MT);
8903 gen_helper_mtc0_tcbind(cpu_env, arg);
8907 CP0_CHECK(ctx->insn_flags & ASE_MT);
8908 gen_helper_mtc0_tcrestart(cpu_env, arg);
8912 CP0_CHECK(ctx->insn_flags & ASE_MT);
8913 gen_helper_mtc0_tchalt(cpu_env, arg);
8917 CP0_CHECK(ctx->insn_flags & ASE_MT);
8918 gen_helper_mtc0_tccontext(cpu_env, arg);
8922 CP0_CHECK(ctx->insn_flags & ASE_MT);
8923 gen_helper_mtc0_tcschedule(cpu_env, arg);
8927 CP0_CHECK(ctx->insn_flags & ASE_MT);
8928 gen_helper_mtc0_tcschefback(cpu_env, arg);
8932 goto cp0_unimplemented;
8938 gen_helper_dmtc0_entrylo1(cpu_env, arg);
8944 rn = "GlobalNumber";
8947 goto cp0_unimplemented;
8953 gen_helper_mtc0_context(cpu_env, arg);
8957 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8958 rn = "ContextConfig";
8959 goto cp0_unimplemented;
8961 CP0_CHECK(ctx->ulri);
8962 tcg_gen_st_tl(arg, cpu_env,
8963 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8967 goto cp0_unimplemented;
8973 gen_helper_mtc0_pagemask(cpu_env, arg);
8977 check_insn(ctx, ISA_MIPS32R2);
8978 gen_helper_mtc0_pagegrain(cpu_env, arg);
8983 gen_helper_mtc0_segctl0(cpu_env, arg);
8988 gen_helper_mtc0_segctl1(cpu_env, arg);
8993 gen_helper_mtc0_segctl2(cpu_env, arg);
8998 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9003 gen_helper_mtc0_pwfield(cpu_env, arg);
9008 gen_helper_mtc0_pwsize(cpu_env, arg);
9012 goto cp0_unimplemented;
9018 gen_helper_mtc0_wired(cpu_env, arg);
9022 check_insn(ctx, ISA_MIPS32R2);
9023 gen_helper_mtc0_srsconf0(cpu_env, arg);
9027 check_insn(ctx, ISA_MIPS32R2);
9028 gen_helper_mtc0_srsconf1(cpu_env, arg);
9032 check_insn(ctx, ISA_MIPS32R2);
9033 gen_helper_mtc0_srsconf2(cpu_env, arg);
9037 check_insn(ctx, ISA_MIPS32R2);
9038 gen_helper_mtc0_srsconf3(cpu_env, arg);
9042 check_insn(ctx, ISA_MIPS32R2);
9043 gen_helper_mtc0_srsconf4(cpu_env, arg);
9048 gen_helper_mtc0_pwctl(cpu_env, arg);
9052 goto cp0_unimplemented;
9058 check_insn(ctx, ISA_MIPS32R2);
9059 gen_helper_mtc0_hwrena(cpu_env, arg);
9060 ctx->base.is_jmp = DISAS_STOP;
9064 goto cp0_unimplemented;
9086 goto cp0_unimplemented;
9092 gen_helper_mtc0_count(cpu_env, arg);
9095 /* 6,7 are implementation dependent */
9097 goto cp0_unimplemented;
9099 /* Stop translation as we may have switched the execution mode */
9100 ctx->base.is_jmp = DISAS_STOP;
9105 gen_helper_mtc0_entryhi(cpu_env, arg);
9109 goto cp0_unimplemented;
9115 gen_helper_mtc0_compare(cpu_env, arg);
9118 /* 6,7 are implementation dependent */
9120 goto cp0_unimplemented;
9122 /* Stop translation as we may have switched the execution mode */
9123 ctx->base.is_jmp = DISAS_STOP;
9128 save_cpu_state(ctx, 1);
9129 gen_helper_mtc0_status(cpu_env, arg);
9130 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9131 gen_save_pc(ctx->base.pc_next + 4);
9132 ctx->base.is_jmp = DISAS_EXIT;
9136 check_insn(ctx, ISA_MIPS32R2);
9137 gen_helper_mtc0_intctl(cpu_env, arg);
9138 /* Stop translation as we may have switched the execution mode */
9139 ctx->base.is_jmp = DISAS_STOP;
9143 check_insn(ctx, ISA_MIPS32R2);
9144 gen_helper_mtc0_srsctl(cpu_env, arg);
9145 /* Stop translation as we may have switched the execution mode */
9146 ctx->base.is_jmp = DISAS_STOP;
9150 check_insn(ctx, ISA_MIPS32R2);
9151 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9152 /* Stop translation as we may have switched the execution mode */
9153 ctx->base.is_jmp = DISAS_STOP;
9157 goto cp0_unimplemented;
9163 save_cpu_state(ctx, 1);
9164 gen_helper_mtc0_cause(cpu_env, arg);
9165 /* Stop translation as we may have triggered an interrupt.
9166 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9167 * translated code to check for pending interrupts. */
9168 gen_save_pc(ctx->base.pc_next + 4);
9169 ctx->base.is_jmp = DISAS_EXIT;
9173 goto cp0_unimplemented;
9179 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9183 goto cp0_unimplemented;
9193 check_insn(ctx, ISA_MIPS32R2);
9194 gen_helper_mtc0_ebase(cpu_env, arg);
9198 goto cp0_unimplemented;
9204 gen_helper_mtc0_config0(cpu_env, arg);
9206 /* Stop translation as we may have switched the execution mode */
9207 ctx->base.is_jmp = DISAS_STOP;
9210 /* ignored, read only */
9214 gen_helper_mtc0_config2(cpu_env, arg);
9216 /* Stop translation as we may have switched the execution mode */
9217 ctx->base.is_jmp = DISAS_STOP;
9220 gen_helper_mtc0_config3(cpu_env, arg);
9222 /* Stop translation as we may have switched the execution mode */
9223 ctx->base.is_jmp = DISAS_STOP;
9226 /* currently ignored */
9230 gen_helper_mtc0_config5(cpu_env, arg);
9232 /* Stop translation as we may have switched the execution mode */
9233 ctx->base.is_jmp = DISAS_STOP;
9235 /* 6,7 are implementation dependent */
9237 rn = "Invalid config selector";
9238 goto cp0_unimplemented;
9244 gen_helper_mtc0_lladdr(cpu_env, arg);
9248 CP0_CHECK(ctx->mrp);
9249 gen_helper_mtc0_maar(cpu_env, arg);
9253 CP0_CHECK(ctx->mrp);
9254 gen_helper_mtc0_maari(cpu_env, arg);
9258 goto cp0_unimplemented;
9271 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9272 gen_helper_0e1i(mtc0_watchlo, arg, sel);
9276 goto cp0_unimplemented;
9289 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9290 gen_helper_0e1i(mtc0_watchhi, arg, sel);
9294 goto cp0_unimplemented;
9300 check_insn(ctx, ISA_MIPS3);
9301 gen_helper_mtc0_xcontext(cpu_env, arg);
9305 goto cp0_unimplemented;
9309 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9310 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9313 gen_helper_mtc0_framemask(cpu_env, arg);
9317 goto cp0_unimplemented;
9322 rn = "Diagnostic"; /* implementation dependent */
9327 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9328 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9329 gen_save_pc(ctx->base.pc_next + 4);
9330 ctx->base.is_jmp = DISAS_EXIT;
9334 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9335 /* Stop translation as we may have switched the execution mode */
9336 ctx->base.is_jmp = DISAS_STOP;
9337 rn = "TraceControl";
9338 goto cp0_unimplemented;
9340 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9341 /* Stop translation as we may have switched the execution mode */
9342 ctx->base.is_jmp = DISAS_STOP;
9343 rn = "TraceControl2";
9344 goto cp0_unimplemented;
9346 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9347 /* Stop translation as we may have switched the execution mode */
9348 ctx->base.is_jmp = DISAS_STOP;
9349 rn = "UserTraceData";
9350 goto cp0_unimplemented;
9352 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9353 /* Stop translation as we may have switched the execution mode */
9354 ctx->base.is_jmp = DISAS_STOP;
9356 goto cp0_unimplemented;
9358 goto cp0_unimplemented;
9365 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9369 goto cp0_unimplemented;
9375 gen_helper_mtc0_performance0(cpu_env, arg);
9376 rn = "Performance0";
9379 // gen_helper_mtc0_performance1(cpu_env, arg);
9380 rn = "Performance1";
9381 goto cp0_unimplemented;
9383 // gen_helper_mtc0_performance2(cpu_env, arg);
9384 rn = "Performance2";
9385 goto cp0_unimplemented;
9387 // gen_helper_mtc0_performance3(cpu_env, arg);
9388 rn = "Performance3";
9389 goto cp0_unimplemented;
9391 // gen_helper_mtc0_performance4(cpu_env, arg);
9392 rn = "Performance4";
9393 goto cp0_unimplemented;
9395 // gen_helper_mtc0_performance5(cpu_env, arg);
9396 rn = "Performance5";
9397 goto cp0_unimplemented;
9399 // gen_helper_mtc0_performance6(cpu_env, arg);
9400 rn = "Performance6";
9401 goto cp0_unimplemented;
9403 // gen_helper_mtc0_performance7(cpu_env, arg);
9404 rn = "Performance7";
9405 goto cp0_unimplemented;
9407 goto cp0_unimplemented;
9413 gen_helper_mtc0_errctl(cpu_env, arg);
9414 ctx->base.is_jmp = DISAS_STOP;
9418 goto cp0_unimplemented;
9431 goto cp0_unimplemented;
9440 gen_helper_mtc0_taglo(cpu_env, arg);
9447 gen_helper_mtc0_datalo(cpu_env, arg);
9451 goto cp0_unimplemented;
9460 gen_helper_mtc0_taghi(cpu_env, arg);
9467 gen_helper_mtc0_datahi(cpu_env, arg);
9472 goto cp0_unimplemented;
9478 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9482 goto cp0_unimplemented;
9489 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9498 CP0_CHECK(ctx->kscrexist & (1 << sel));
9499 tcg_gen_st_tl(arg, cpu_env,
9500 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9504 goto cp0_unimplemented;
9508 goto cp0_unimplemented;
9510 trace_mips_translate_c0("dmtc0", rn, reg, sel);
9512 /* For simplicity assume that all writes can cause interrupts. */
9513 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9515 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9516 * translated code to check for pending interrupts. */
9517 gen_save_pc(ctx->base.pc_next + 4);
9518 ctx->base.is_jmp = DISAS_EXIT;
9523 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9525 #endif /* TARGET_MIPS64 */
9527 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9528 int u, int sel, int h)
9530 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9531 TCGv t0 = tcg_temp_local_new();
9533 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9534 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9535 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9536 tcg_gen_movi_tl(t0, -1);
9537 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9538 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9539 tcg_gen_movi_tl(t0, -1);
9545 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9548 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9558 gen_helper_mftc0_tcstatus(t0, cpu_env);
9561 gen_helper_mftc0_tcbind(t0, cpu_env);
9564 gen_helper_mftc0_tcrestart(t0, cpu_env);
9567 gen_helper_mftc0_tchalt(t0, cpu_env);
9570 gen_helper_mftc0_tccontext(t0, cpu_env);
9573 gen_helper_mftc0_tcschedule(t0, cpu_env);
9576 gen_helper_mftc0_tcschefback(t0, cpu_env);
9579 gen_mfc0(ctx, t0, rt, sel);
9586 gen_helper_mftc0_entryhi(t0, cpu_env);
9589 gen_mfc0(ctx, t0, rt, sel);
9595 gen_helper_mftc0_status(t0, cpu_env);
9598 gen_mfc0(ctx, t0, rt, sel);
9604 gen_helper_mftc0_cause(t0, cpu_env);
9614 gen_helper_mftc0_epc(t0, cpu_env);
9624 gen_helper_mftc0_ebase(t0, cpu_env);
9641 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9651 gen_helper_mftc0_debug(t0, cpu_env);
9654 gen_mfc0(ctx, t0, rt, sel);
9659 gen_mfc0(ctx, t0, rt, sel);
9661 } else switch (sel) {
9662 /* GPR registers. */
9664 gen_helper_1e0i(mftgpr, t0, rt);
9666 /* Auxiliary CPU registers */
9670 gen_helper_1e0i(mftlo, t0, 0);
9673 gen_helper_1e0i(mfthi, t0, 0);
9676 gen_helper_1e0i(mftacx, t0, 0);
9679 gen_helper_1e0i(mftlo, t0, 1);
9682 gen_helper_1e0i(mfthi, t0, 1);
9685 gen_helper_1e0i(mftacx, t0, 1);
9688 gen_helper_1e0i(mftlo, t0, 2);
9691 gen_helper_1e0i(mfthi, t0, 2);
9694 gen_helper_1e0i(mftacx, t0, 2);
9697 gen_helper_1e0i(mftlo, t0, 3);
9700 gen_helper_1e0i(mfthi, t0, 3);
9703 gen_helper_1e0i(mftacx, t0, 3);
9706 gen_helper_mftdsp(t0, cpu_env);
9712 /* Floating point (COP1). */
9714 /* XXX: For now we support only a single FPU context. */
9716 TCGv_i32 fp0 = tcg_temp_new_i32();
9718 gen_load_fpr32(ctx, fp0, rt);
9719 tcg_gen_ext_i32_tl(t0, fp0);
9720 tcg_temp_free_i32(fp0);
9722 TCGv_i32 fp0 = tcg_temp_new_i32();
9724 gen_load_fpr32h(ctx, fp0, rt);
9725 tcg_gen_ext_i32_tl(t0, fp0);
9726 tcg_temp_free_i32(fp0);
9730 /* XXX: For now we support only a single FPU context. */
9731 gen_helper_1e0i(cfc1, t0, rt);
9733 /* COP2: Not implemented. */
9740 trace_mips_translate_tr("mftr", rt, u, sel, h);
9741 gen_store_gpr(t0, rd);
9747 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9748 generate_exception_end(ctx, EXCP_RI);
9751 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9752 int u, int sel, int h)
9754 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9755 TCGv t0 = tcg_temp_local_new();
9757 gen_load_gpr(t0, rt);
9758 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9759 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9760 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9762 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9763 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9770 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9773 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9783 gen_helper_mttc0_tcstatus(cpu_env, t0);
9786 gen_helper_mttc0_tcbind(cpu_env, t0);
9789 gen_helper_mttc0_tcrestart(cpu_env, t0);
9792 gen_helper_mttc0_tchalt(cpu_env, t0);
9795 gen_helper_mttc0_tccontext(cpu_env, t0);
9798 gen_helper_mttc0_tcschedule(cpu_env, t0);
9801 gen_helper_mttc0_tcschefback(cpu_env, t0);
9804 gen_mtc0(ctx, t0, rd, sel);
9811 gen_helper_mttc0_entryhi(cpu_env, t0);
9814 gen_mtc0(ctx, t0, rd, sel);
9820 gen_helper_mttc0_status(cpu_env, t0);
9823 gen_mtc0(ctx, t0, rd, sel);
9829 gen_helper_mttc0_cause(cpu_env, t0);
9839 gen_helper_mttc0_ebase(cpu_env, t0);
9849 gen_helper_mttc0_debug(cpu_env, t0);
9852 gen_mtc0(ctx, t0, rd, sel);
9857 gen_mtc0(ctx, t0, rd, sel);
9859 } else switch (sel) {
9860 /* GPR registers. */
9862 gen_helper_0e1i(mttgpr, t0, rd);
9864 /* Auxiliary CPU registers */
9868 gen_helper_0e1i(mttlo, t0, 0);
9871 gen_helper_0e1i(mtthi, t0, 0);
9874 gen_helper_0e1i(mttacx, t0, 0);
9877 gen_helper_0e1i(mttlo, t0, 1);
9880 gen_helper_0e1i(mtthi, t0, 1);
9883 gen_helper_0e1i(mttacx, t0, 1);
9886 gen_helper_0e1i(mttlo, t0, 2);
9889 gen_helper_0e1i(mtthi, t0, 2);
9892 gen_helper_0e1i(mttacx, t0, 2);
9895 gen_helper_0e1i(mttlo, t0, 3);
9898 gen_helper_0e1i(mtthi, t0, 3);
9901 gen_helper_0e1i(mttacx, t0, 3);
9904 gen_helper_mttdsp(cpu_env, t0);
9910 /* Floating point (COP1). */
9912 /* XXX: For now we support only a single FPU context. */
9914 TCGv_i32 fp0 = tcg_temp_new_i32();
9916 tcg_gen_trunc_tl_i32(fp0, t0);
9917 gen_store_fpr32(ctx, fp0, rd);
9918 tcg_temp_free_i32(fp0);
9920 TCGv_i32 fp0 = tcg_temp_new_i32();
9922 tcg_gen_trunc_tl_i32(fp0, t0);
9923 gen_store_fpr32h(ctx, fp0, rd);
9924 tcg_temp_free_i32(fp0);
9928 /* XXX: For now we support only a single FPU context. */
9930 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9932 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9933 tcg_temp_free_i32(fs_tmp);
9935 /* Stop translation as we may have changed hflags */
9936 ctx->base.is_jmp = DISAS_STOP;
9938 /* COP2: Not implemented. */
9945 trace_mips_translate_tr("mttr", rd, u, sel, h);
9951 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9952 generate_exception_end(ctx, EXCP_RI);
9955 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9957 const char *opn = "ldst";
9959 check_cp0_enabled(ctx);
9966 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9971 TCGv t0 = tcg_temp_new();
9973 gen_load_gpr(t0, rt);
9974 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9979 #if defined(TARGET_MIPS64)
9981 check_insn(ctx, ISA_MIPS3);
9986 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9990 check_insn(ctx, ISA_MIPS3);
9992 TCGv t0 = tcg_temp_new();
9994 gen_load_gpr(t0, rt);
9995 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10004 /* Treat as NOP. */
10007 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10013 TCGv t0 = tcg_temp_new();
10014 gen_load_gpr(t0, rt);
10015 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10021 check_cp0_enabled(ctx);
10023 /* Treat as NOP. */
10026 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10027 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10031 check_cp0_enabled(ctx);
10032 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10033 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10038 if (!env->tlb->helper_tlbwi)
10040 gen_helper_tlbwi(cpu_env);
10044 if (ctx->ie >= 2) {
10045 if (!env->tlb->helper_tlbinv) {
10048 gen_helper_tlbinv(cpu_env);
10049 } /* treat as nop if TLBINV not supported */
10053 if (ctx->ie >= 2) {
10054 if (!env->tlb->helper_tlbinvf) {
10057 gen_helper_tlbinvf(cpu_env);
10058 } /* treat as nop if TLBINV not supported */
10062 if (!env->tlb->helper_tlbwr)
10064 gen_helper_tlbwr(cpu_env);
10068 if (!env->tlb->helper_tlbp)
10070 gen_helper_tlbp(cpu_env);
10074 if (!env->tlb->helper_tlbr)
10076 gen_helper_tlbr(cpu_env);
10078 case OPC_ERET: /* OPC_ERETNC */
10079 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10080 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10083 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10084 if (ctx->opcode & (1 << bit_shift)) {
10087 check_insn(ctx, ISA_MIPS32R5);
10088 gen_helper_eretnc(cpu_env);
10092 check_insn(ctx, ISA_MIPS2);
10093 gen_helper_eret(cpu_env);
10095 ctx->base.is_jmp = DISAS_EXIT;
10100 check_insn(ctx, ISA_MIPS32);
10101 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10102 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10105 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10107 generate_exception_end(ctx, EXCP_RI);
10109 gen_helper_deret(cpu_env);
10110 ctx->base.is_jmp = DISAS_EXIT;
10115 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10116 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10117 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10120 /* If we get an exception, we want to restart at next instruction */
10121 ctx->base.pc_next += 4;
10122 save_cpu_state(ctx, 1);
10123 ctx->base.pc_next -= 4;
10124 gen_helper_wait(cpu_env);
10125 ctx->base.is_jmp = DISAS_NORETURN;
10130 generate_exception_end(ctx, EXCP_RI);
10133 (void)opn; /* avoid a compiler warning */
10135 #endif /* !CONFIG_USER_ONLY */
10137 /* CP1 Branches (before delay slot) */
10138 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10139 int32_t cc, int32_t offset)
10141 target_ulong btarget;
10142 TCGv_i32 t0 = tcg_temp_new_i32();
10144 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10145 generate_exception_end(ctx, EXCP_RI);
10150 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10152 btarget = ctx->base.pc_next + 4 + offset;
10156 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10157 tcg_gen_not_i32(t0, t0);
10158 tcg_gen_andi_i32(t0, t0, 1);
10159 tcg_gen_extu_i32_tl(bcond, t0);
10162 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10163 tcg_gen_not_i32(t0, t0);
10164 tcg_gen_andi_i32(t0, t0, 1);
10165 tcg_gen_extu_i32_tl(bcond, t0);
10168 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10169 tcg_gen_andi_i32(t0, t0, 1);
10170 tcg_gen_extu_i32_tl(bcond, t0);
10173 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10174 tcg_gen_andi_i32(t0, t0, 1);
10175 tcg_gen_extu_i32_tl(bcond, t0);
10177 ctx->hflags |= MIPS_HFLAG_BL;
10181 TCGv_i32 t1 = tcg_temp_new_i32();
10182 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10183 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10184 tcg_gen_nand_i32(t0, t0, t1);
10185 tcg_temp_free_i32(t1);
10186 tcg_gen_andi_i32(t0, t0, 1);
10187 tcg_gen_extu_i32_tl(bcond, t0);
10192 TCGv_i32 t1 = tcg_temp_new_i32();
10193 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10194 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10195 tcg_gen_or_i32(t0, t0, t1);
10196 tcg_temp_free_i32(t1);
10197 tcg_gen_andi_i32(t0, t0, 1);
10198 tcg_gen_extu_i32_tl(bcond, t0);
10203 TCGv_i32 t1 = tcg_temp_new_i32();
10204 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10205 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10206 tcg_gen_and_i32(t0, t0, t1);
10207 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10208 tcg_gen_and_i32(t0, t0, t1);
10209 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10210 tcg_gen_nand_i32(t0, t0, t1);
10211 tcg_temp_free_i32(t1);
10212 tcg_gen_andi_i32(t0, t0, 1);
10213 tcg_gen_extu_i32_tl(bcond, t0);
10218 TCGv_i32 t1 = tcg_temp_new_i32();
10219 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10220 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10221 tcg_gen_or_i32(t0, t0, t1);
10222 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10223 tcg_gen_or_i32(t0, t0, t1);
10224 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10225 tcg_gen_or_i32(t0, t0, t1);
10226 tcg_temp_free_i32(t1);
10227 tcg_gen_andi_i32(t0, t0, 1);
10228 tcg_gen_extu_i32_tl(bcond, t0);
10231 ctx->hflags |= MIPS_HFLAG_BC;
10234 MIPS_INVAL("cp1 cond branch");
10235 generate_exception_end(ctx, EXCP_RI);
10238 ctx->btarget = btarget;
10239 ctx->hflags |= MIPS_HFLAG_BDS32;
10241 tcg_temp_free_i32(t0);
10244 /* R6 CP1 Branches */
10245 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10246 int32_t ft, int32_t offset,
10247 int delayslot_size)
10249 target_ulong btarget;
10250 TCGv_i64 t0 = tcg_temp_new_i64();
10252 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10253 #ifdef MIPS_DEBUG_DISAS
10254 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10255 "\n", ctx->base.pc_next);
10257 generate_exception_end(ctx, EXCP_RI);
10261 gen_load_fpr64(ctx, t0, ft);
10262 tcg_gen_andi_i64(t0, t0, 1);
10264 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10268 tcg_gen_xori_i64(t0, t0, 1);
10269 ctx->hflags |= MIPS_HFLAG_BC;
10272 /* t0 already set */
10273 ctx->hflags |= MIPS_HFLAG_BC;
10276 MIPS_INVAL("cp1 cond branch");
10277 generate_exception_end(ctx, EXCP_RI);
10281 tcg_gen_trunc_i64_tl(bcond, t0);
10283 ctx->btarget = btarget;
10285 switch (delayslot_size) {
10287 ctx->hflags |= MIPS_HFLAG_BDS16;
10290 ctx->hflags |= MIPS_HFLAG_BDS32;
10295 tcg_temp_free_i64(t0);
10298 /* Coprocessor 1 (FPU) */
10300 #define FOP(func, fmt) (((fmt) << 21) | (func))
10303 OPC_ADD_S = FOP(0, FMT_S),
10304 OPC_SUB_S = FOP(1, FMT_S),
10305 OPC_MUL_S = FOP(2, FMT_S),
10306 OPC_DIV_S = FOP(3, FMT_S),
10307 OPC_SQRT_S = FOP(4, FMT_S),
10308 OPC_ABS_S = FOP(5, FMT_S),
10309 OPC_MOV_S = FOP(6, FMT_S),
10310 OPC_NEG_S = FOP(7, FMT_S),
10311 OPC_ROUND_L_S = FOP(8, FMT_S),
10312 OPC_TRUNC_L_S = FOP(9, FMT_S),
10313 OPC_CEIL_L_S = FOP(10, FMT_S),
10314 OPC_FLOOR_L_S = FOP(11, FMT_S),
10315 OPC_ROUND_W_S = FOP(12, FMT_S),
10316 OPC_TRUNC_W_S = FOP(13, FMT_S),
10317 OPC_CEIL_W_S = FOP(14, FMT_S),
10318 OPC_FLOOR_W_S = FOP(15, FMT_S),
10319 OPC_SEL_S = FOP(16, FMT_S),
10320 OPC_MOVCF_S = FOP(17, FMT_S),
10321 OPC_MOVZ_S = FOP(18, FMT_S),
10322 OPC_MOVN_S = FOP(19, FMT_S),
10323 OPC_SELEQZ_S = FOP(20, FMT_S),
10324 OPC_RECIP_S = FOP(21, FMT_S),
10325 OPC_RSQRT_S = FOP(22, FMT_S),
10326 OPC_SELNEZ_S = FOP(23, FMT_S),
10327 OPC_MADDF_S = FOP(24, FMT_S),
10328 OPC_MSUBF_S = FOP(25, FMT_S),
10329 OPC_RINT_S = FOP(26, FMT_S),
10330 OPC_CLASS_S = FOP(27, FMT_S),
10331 OPC_MIN_S = FOP(28, FMT_S),
10332 OPC_RECIP2_S = FOP(28, FMT_S),
10333 OPC_MINA_S = FOP(29, FMT_S),
10334 OPC_RECIP1_S = FOP(29, FMT_S),
10335 OPC_MAX_S = FOP(30, FMT_S),
10336 OPC_RSQRT1_S = FOP(30, FMT_S),
10337 OPC_MAXA_S = FOP(31, FMT_S),
10338 OPC_RSQRT2_S = FOP(31, FMT_S),
10339 OPC_CVT_D_S = FOP(33, FMT_S),
10340 OPC_CVT_W_S = FOP(36, FMT_S),
10341 OPC_CVT_L_S = FOP(37, FMT_S),
10342 OPC_CVT_PS_S = FOP(38, FMT_S),
10343 OPC_CMP_F_S = FOP (48, FMT_S),
10344 OPC_CMP_UN_S = FOP (49, FMT_S),
10345 OPC_CMP_EQ_S = FOP (50, FMT_S),
10346 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10347 OPC_CMP_OLT_S = FOP (52, FMT_S),
10348 OPC_CMP_ULT_S = FOP (53, FMT_S),
10349 OPC_CMP_OLE_S = FOP (54, FMT_S),
10350 OPC_CMP_ULE_S = FOP (55, FMT_S),
10351 OPC_CMP_SF_S = FOP (56, FMT_S),
10352 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10353 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10354 OPC_CMP_NGL_S = FOP (59, FMT_S),
10355 OPC_CMP_LT_S = FOP (60, FMT_S),
10356 OPC_CMP_NGE_S = FOP (61, FMT_S),
10357 OPC_CMP_LE_S = FOP (62, FMT_S),
10358 OPC_CMP_NGT_S = FOP (63, FMT_S),
10360 OPC_ADD_D = FOP(0, FMT_D),
10361 OPC_SUB_D = FOP(1, FMT_D),
10362 OPC_MUL_D = FOP(2, FMT_D),
10363 OPC_DIV_D = FOP(3, FMT_D),
10364 OPC_SQRT_D = FOP(4, FMT_D),
10365 OPC_ABS_D = FOP(5, FMT_D),
10366 OPC_MOV_D = FOP(6, FMT_D),
10367 OPC_NEG_D = FOP(7, FMT_D),
10368 OPC_ROUND_L_D = FOP(8, FMT_D),
10369 OPC_TRUNC_L_D = FOP(9, FMT_D),
10370 OPC_CEIL_L_D = FOP(10, FMT_D),
10371 OPC_FLOOR_L_D = FOP(11, FMT_D),
10372 OPC_ROUND_W_D = FOP(12, FMT_D),
10373 OPC_TRUNC_W_D = FOP(13, FMT_D),
10374 OPC_CEIL_W_D = FOP(14, FMT_D),
10375 OPC_FLOOR_W_D = FOP(15, FMT_D),
10376 OPC_SEL_D = FOP(16, FMT_D),
10377 OPC_MOVCF_D = FOP(17, FMT_D),
10378 OPC_MOVZ_D = FOP(18, FMT_D),
10379 OPC_MOVN_D = FOP(19, FMT_D),
10380 OPC_SELEQZ_D = FOP(20, FMT_D),
10381 OPC_RECIP_D = FOP(21, FMT_D),
10382 OPC_RSQRT_D = FOP(22, FMT_D),
10383 OPC_SELNEZ_D = FOP(23, FMT_D),
10384 OPC_MADDF_D = FOP(24, FMT_D),
10385 OPC_MSUBF_D = FOP(25, FMT_D),
10386 OPC_RINT_D = FOP(26, FMT_D),
10387 OPC_CLASS_D = FOP(27, FMT_D),
10388 OPC_MIN_D = FOP(28, FMT_D),
10389 OPC_RECIP2_D = FOP(28, FMT_D),
10390 OPC_MINA_D = FOP(29, FMT_D),
10391 OPC_RECIP1_D = FOP(29, FMT_D),
10392 OPC_MAX_D = FOP(30, FMT_D),
10393 OPC_RSQRT1_D = FOP(30, FMT_D),
10394 OPC_MAXA_D = FOP(31, FMT_D),
10395 OPC_RSQRT2_D = FOP(31, FMT_D),
10396 OPC_CVT_S_D = FOP(32, FMT_D),
10397 OPC_CVT_W_D = FOP(36, FMT_D),
10398 OPC_CVT_L_D = FOP(37, FMT_D),
10399 OPC_CMP_F_D = FOP (48, FMT_D),
10400 OPC_CMP_UN_D = FOP (49, FMT_D),
10401 OPC_CMP_EQ_D = FOP (50, FMT_D),
10402 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10403 OPC_CMP_OLT_D = FOP (52, FMT_D),
10404 OPC_CMP_ULT_D = FOP (53, FMT_D),
10405 OPC_CMP_OLE_D = FOP (54, FMT_D),
10406 OPC_CMP_ULE_D = FOP (55, FMT_D),
10407 OPC_CMP_SF_D = FOP (56, FMT_D),
10408 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10409 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10410 OPC_CMP_NGL_D = FOP (59, FMT_D),
10411 OPC_CMP_LT_D = FOP (60, FMT_D),
10412 OPC_CMP_NGE_D = FOP (61, FMT_D),
10413 OPC_CMP_LE_D = FOP (62, FMT_D),
10414 OPC_CMP_NGT_D = FOP (63, FMT_D),
10416 OPC_CVT_S_W = FOP(32, FMT_W),
10417 OPC_CVT_D_W = FOP(33, FMT_W),
10418 OPC_CVT_S_L = FOP(32, FMT_L),
10419 OPC_CVT_D_L = FOP(33, FMT_L),
10420 OPC_CVT_PS_PW = FOP(38, FMT_W),
10422 OPC_ADD_PS = FOP(0, FMT_PS),
10423 OPC_SUB_PS = FOP(1, FMT_PS),
10424 OPC_MUL_PS = FOP(2, FMT_PS),
10425 OPC_DIV_PS = FOP(3, FMT_PS),
10426 OPC_ABS_PS = FOP(5, FMT_PS),
10427 OPC_MOV_PS = FOP(6, FMT_PS),
10428 OPC_NEG_PS = FOP(7, FMT_PS),
10429 OPC_MOVCF_PS = FOP(17, FMT_PS),
10430 OPC_MOVZ_PS = FOP(18, FMT_PS),
10431 OPC_MOVN_PS = FOP(19, FMT_PS),
10432 OPC_ADDR_PS = FOP(24, FMT_PS),
10433 OPC_MULR_PS = FOP(26, FMT_PS),
10434 OPC_RECIP2_PS = FOP(28, FMT_PS),
10435 OPC_RECIP1_PS = FOP(29, FMT_PS),
10436 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10437 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10439 OPC_CVT_S_PU = FOP(32, FMT_PS),
10440 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10441 OPC_CVT_S_PL = FOP(40, FMT_PS),
10442 OPC_PLL_PS = FOP(44, FMT_PS),
10443 OPC_PLU_PS = FOP(45, FMT_PS),
10444 OPC_PUL_PS = FOP(46, FMT_PS),
10445 OPC_PUU_PS = FOP(47, FMT_PS),
10446 OPC_CMP_F_PS = FOP (48, FMT_PS),
10447 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10448 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10449 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10450 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10451 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10452 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10453 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10454 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10455 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10456 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10457 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10458 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10459 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10460 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10461 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10465 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10466 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10467 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10468 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10469 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10470 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10471 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10472 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10473 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10474 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10475 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10476 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10477 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10478 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10479 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10480 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10481 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10482 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10483 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10484 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10485 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10486 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10488 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10489 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10490 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10491 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10492 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10493 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10494 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10495 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10496 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10497 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10498 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10499 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10500 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10501 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10502 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10503 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10504 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10505 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10506 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10507 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10508 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10509 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10511 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10513 TCGv t0 = tcg_temp_new();
10518 TCGv_i32 fp0 = tcg_temp_new_i32();
10520 gen_load_fpr32(ctx, fp0, fs);
10521 tcg_gen_ext_i32_tl(t0, fp0);
10522 tcg_temp_free_i32(fp0);
10524 gen_store_gpr(t0, rt);
10527 gen_load_gpr(t0, rt);
10529 TCGv_i32 fp0 = tcg_temp_new_i32();
10531 tcg_gen_trunc_tl_i32(fp0, t0);
10532 gen_store_fpr32(ctx, fp0, fs);
10533 tcg_temp_free_i32(fp0);
10537 gen_helper_1e0i(cfc1, t0, fs);
10538 gen_store_gpr(t0, rt);
10541 gen_load_gpr(t0, rt);
10542 save_cpu_state(ctx, 0);
10544 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10546 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10547 tcg_temp_free_i32(fs_tmp);
10549 /* Stop translation as we may have changed hflags */
10550 ctx->base.is_jmp = DISAS_STOP;
10552 #if defined(TARGET_MIPS64)
10554 gen_load_fpr64(ctx, t0, fs);
10555 gen_store_gpr(t0, rt);
10558 gen_load_gpr(t0, rt);
10559 gen_store_fpr64(ctx, t0, fs);
10564 TCGv_i32 fp0 = tcg_temp_new_i32();
10566 gen_load_fpr32h(ctx, fp0, fs);
10567 tcg_gen_ext_i32_tl(t0, fp0);
10568 tcg_temp_free_i32(fp0);
10570 gen_store_gpr(t0, rt);
10573 gen_load_gpr(t0, rt);
10575 TCGv_i32 fp0 = tcg_temp_new_i32();
10577 tcg_gen_trunc_tl_i32(fp0, t0);
10578 gen_store_fpr32h(ctx, fp0, fs);
10579 tcg_temp_free_i32(fp0);
10583 MIPS_INVAL("cp1 move");
10584 generate_exception_end(ctx, EXCP_RI);
10592 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10599 /* Treat as NOP. */
10604 cond = TCG_COND_EQ;
10606 cond = TCG_COND_NE;
10608 l1 = gen_new_label();
10609 t0 = tcg_temp_new_i32();
10610 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10611 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10612 tcg_temp_free_i32(t0);
10614 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10616 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10621 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10625 TCGv_i32 t0 = tcg_temp_new_i32();
10626 TCGLabel *l1 = gen_new_label();
10629 cond = TCG_COND_EQ;
10631 cond = TCG_COND_NE;
10633 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10634 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10635 gen_load_fpr32(ctx, t0, fs);
10636 gen_store_fpr32(ctx, t0, fd);
10638 tcg_temp_free_i32(t0);
10641 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10644 TCGv_i32 t0 = tcg_temp_new_i32();
10646 TCGLabel *l1 = gen_new_label();
10649 cond = TCG_COND_EQ;
10651 cond = TCG_COND_NE;
10653 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10654 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10655 tcg_temp_free_i32(t0);
10656 fp0 = tcg_temp_new_i64();
10657 gen_load_fpr64(ctx, fp0, fs);
10658 gen_store_fpr64(ctx, fp0, fd);
10659 tcg_temp_free_i64(fp0);
10663 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10667 TCGv_i32 t0 = tcg_temp_new_i32();
10668 TCGLabel *l1 = gen_new_label();
10669 TCGLabel *l2 = gen_new_label();
10672 cond = TCG_COND_EQ;
10674 cond = TCG_COND_NE;
10676 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10677 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10678 gen_load_fpr32(ctx, t0, fs);
10679 gen_store_fpr32(ctx, t0, fd);
10682 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10683 tcg_gen_brcondi_i32(cond, t0, 0, l2);
10684 gen_load_fpr32h(ctx, t0, fs);
10685 gen_store_fpr32h(ctx, t0, fd);
10686 tcg_temp_free_i32(t0);
10690 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10693 TCGv_i32 t1 = tcg_const_i32(0);
10694 TCGv_i32 fp0 = tcg_temp_new_i32();
10695 TCGv_i32 fp1 = tcg_temp_new_i32();
10696 TCGv_i32 fp2 = tcg_temp_new_i32();
10697 gen_load_fpr32(ctx, fp0, fd);
10698 gen_load_fpr32(ctx, fp1, ft);
10699 gen_load_fpr32(ctx, fp2, fs);
10703 tcg_gen_andi_i32(fp0, fp0, 1);
10704 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10707 tcg_gen_andi_i32(fp1, fp1, 1);
10708 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10711 tcg_gen_andi_i32(fp1, fp1, 1);
10712 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10715 MIPS_INVAL("gen_sel_s");
10716 generate_exception_end(ctx, EXCP_RI);
10720 gen_store_fpr32(ctx, fp0, fd);
10721 tcg_temp_free_i32(fp2);
10722 tcg_temp_free_i32(fp1);
10723 tcg_temp_free_i32(fp0);
10724 tcg_temp_free_i32(t1);
10727 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10730 TCGv_i64 t1 = tcg_const_i64(0);
10731 TCGv_i64 fp0 = tcg_temp_new_i64();
10732 TCGv_i64 fp1 = tcg_temp_new_i64();
10733 TCGv_i64 fp2 = tcg_temp_new_i64();
10734 gen_load_fpr64(ctx, fp0, fd);
10735 gen_load_fpr64(ctx, fp1, ft);
10736 gen_load_fpr64(ctx, fp2, fs);
10740 tcg_gen_andi_i64(fp0, fp0, 1);
10741 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10744 tcg_gen_andi_i64(fp1, fp1, 1);
10745 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10748 tcg_gen_andi_i64(fp1, fp1, 1);
10749 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10752 MIPS_INVAL("gen_sel_d");
10753 generate_exception_end(ctx, EXCP_RI);
10757 gen_store_fpr64(ctx, fp0, fd);
10758 tcg_temp_free_i64(fp2);
10759 tcg_temp_free_i64(fp1);
10760 tcg_temp_free_i64(fp0);
10761 tcg_temp_free_i64(t1);
10764 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10765 int ft, int fs, int fd, int cc)
10767 uint32_t func = ctx->opcode & 0x3f;
10771 TCGv_i32 fp0 = tcg_temp_new_i32();
10772 TCGv_i32 fp1 = tcg_temp_new_i32();
10774 gen_load_fpr32(ctx, fp0, fs);
10775 gen_load_fpr32(ctx, fp1, ft);
10776 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10777 tcg_temp_free_i32(fp1);
10778 gen_store_fpr32(ctx, fp0, fd);
10779 tcg_temp_free_i32(fp0);
10784 TCGv_i32 fp0 = tcg_temp_new_i32();
10785 TCGv_i32 fp1 = tcg_temp_new_i32();
10787 gen_load_fpr32(ctx, fp0, fs);
10788 gen_load_fpr32(ctx, fp1, ft);
10789 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10790 tcg_temp_free_i32(fp1);
10791 gen_store_fpr32(ctx, fp0, fd);
10792 tcg_temp_free_i32(fp0);
10797 TCGv_i32 fp0 = tcg_temp_new_i32();
10798 TCGv_i32 fp1 = tcg_temp_new_i32();
10800 gen_load_fpr32(ctx, fp0, fs);
10801 gen_load_fpr32(ctx, fp1, ft);
10802 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10803 tcg_temp_free_i32(fp1);
10804 gen_store_fpr32(ctx, fp0, fd);
10805 tcg_temp_free_i32(fp0);
10810 TCGv_i32 fp0 = tcg_temp_new_i32();
10811 TCGv_i32 fp1 = tcg_temp_new_i32();
10813 gen_load_fpr32(ctx, fp0, fs);
10814 gen_load_fpr32(ctx, fp1, ft);
10815 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10816 tcg_temp_free_i32(fp1);
10817 gen_store_fpr32(ctx, fp0, fd);
10818 tcg_temp_free_i32(fp0);
10823 TCGv_i32 fp0 = tcg_temp_new_i32();
10825 gen_load_fpr32(ctx, fp0, fs);
10826 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10827 gen_store_fpr32(ctx, fp0, fd);
10828 tcg_temp_free_i32(fp0);
10833 TCGv_i32 fp0 = tcg_temp_new_i32();
10835 gen_load_fpr32(ctx, fp0, fs);
10836 if (ctx->abs2008) {
10837 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10839 gen_helper_float_abs_s(fp0, fp0);
10841 gen_store_fpr32(ctx, fp0, fd);
10842 tcg_temp_free_i32(fp0);
10847 TCGv_i32 fp0 = tcg_temp_new_i32();
10849 gen_load_fpr32(ctx, fp0, fs);
10850 gen_store_fpr32(ctx, fp0, fd);
10851 tcg_temp_free_i32(fp0);
10856 TCGv_i32 fp0 = tcg_temp_new_i32();
10858 gen_load_fpr32(ctx, fp0, fs);
10859 if (ctx->abs2008) {
10860 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10862 gen_helper_float_chs_s(fp0, fp0);
10864 gen_store_fpr32(ctx, fp0, fd);
10865 tcg_temp_free_i32(fp0);
10868 case OPC_ROUND_L_S:
10869 check_cp1_64bitmode(ctx);
10871 TCGv_i32 fp32 = tcg_temp_new_i32();
10872 TCGv_i64 fp64 = tcg_temp_new_i64();
10874 gen_load_fpr32(ctx, fp32, fs);
10875 if (ctx->nan2008) {
10876 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10878 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10880 tcg_temp_free_i32(fp32);
10881 gen_store_fpr64(ctx, fp64, fd);
10882 tcg_temp_free_i64(fp64);
10885 case OPC_TRUNC_L_S:
10886 check_cp1_64bitmode(ctx);
10888 TCGv_i32 fp32 = tcg_temp_new_i32();
10889 TCGv_i64 fp64 = tcg_temp_new_i64();
10891 gen_load_fpr32(ctx, fp32, fs);
10892 if (ctx->nan2008) {
10893 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10895 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10897 tcg_temp_free_i32(fp32);
10898 gen_store_fpr64(ctx, fp64, fd);
10899 tcg_temp_free_i64(fp64);
10903 check_cp1_64bitmode(ctx);
10905 TCGv_i32 fp32 = tcg_temp_new_i32();
10906 TCGv_i64 fp64 = tcg_temp_new_i64();
10908 gen_load_fpr32(ctx, fp32, fs);
10909 if (ctx->nan2008) {
10910 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10912 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10914 tcg_temp_free_i32(fp32);
10915 gen_store_fpr64(ctx, fp64, fd);
10916 tcg_temp_free_i64(fp64);
10919 case OPC_FLOOR_L_S:
10920 check_cp1_64bitmode(ctx);
10922 TCGv_i32 fp32 = tcg_temp_new_i32();
10923 TCGv_i64 fp64 = tcg_temp_new_i64();
10925 gen_load_fpr32(ctx, fp32, fs);
10926 if (ctx->nan2008) {
10927 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10929 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10931 tcg_temp_free_i32(fp32);
10932 gen_store_fpr64(ctx, fp64, fd);
10933 tcg_temp_free_i64(fp64);
10936 case OPC_ROUND_W_S:
10938 TCGv_i32 fp0 = tcg_temp_new_i32();
10940 gen_load_fpr32(ctx, fp0, fs);
10941 if (ctx->nan2008) {
10942 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10944 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10946 gen_store_fpr32(ctx, fp0, fd);
10947 tcg_temp_free_i32(fp0);
10950 case OPC_TRUNC_W_S:
10952 TCGv_i32 fp0 = tcg_temp_new_i32();
10954 gen_load_fpr32(ctx, fp0, fs);
10955 if (ctx->nan2008) {
10956 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10958 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10960 gen_store_fpr32(ctx, fp0, fd);
10961 tcg_temp_free_i32(fp0);
10966 TCGv_i32 fp0 = tcg_temp_new_i32();
10968 gen_load_fpr32(ctx, fp0, fs);
10969 if (ctx->nan2008) {
10970 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10972 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10974 gen_store_fpr32(ctx, fp0, fd);
10975 tcg_temp_free_i32(fp0);
10978 case OPC_FLOOR_W_S:
10980 TCGv_i32 fp0 = tcg_temp_new_i32();
10982 gen_load_fpr32(ctx, fp0, fs);
10983 if (ctx->nan2008) {
10984 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10986 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10988 gen_store_fpr32(ctx, fp0, fd);
10989 tcg_temp_free_i32(fp0);
10993 check_insn(ctx, ISA_MIPS32R6);
10994 gen_sel_s(ctx, op1, fd, ft, fs);
10997 check_insn(ctx, ISA_MIPS32R6);
10998 gen_sel_s(ctx, op1, fd, ft, fs);
11001 check_insn(ctx, ISA_MIPS32R6);
11002 gen_sel_s(ctx, op1, fd, ft, fs);
11005 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11006 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11009 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11011 TCGLabel *l1 = gen_new_label();
11015 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11017 fp0 = tcg_temp_new_i32();
11018 gen_load_fpr32(ctx, fp0, fs);
11019 gen_store_fpr32(ctx, fp0, fd);
11020 tcg_temp_free_i32(fp0);
11025 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11027 TCGLabel *l1 = gen_new_label();
11031 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11032 fp0 = tcg_temp_new_i32();
11033 gen_load_fpr32(ctx, fp0, fs);
11034 gen_store_fpr32(ctx, fp0, fd);
11035 tcg_temp_free_i32(fp0);
11042 TCGv_i32 fp0 = tcg_temp_new_i32();
11044 gen_load_fpr32(ctx, fp0, fs);
11045 gen_helper_float_recip_s(fp0, cpu_env, fp0);
11046 gen_store_fpr32(ctx, fp0, fd);
11047 tcg_temp_free_i32(fp0);
11052 TCGv_i32 fp0 = tcg_temp_new_i32();
11054 gen_load_fpr32(ctx, fp0, fs);
11055 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11056 gen_store_fpr32(ctx, fp0, fd);
11057 tcg_temp_free_i32(fp0);
11061 check_insn(ctx, ISA_MIPS32R6);
11063 TCGv_i32 fp0 = tcg_temp_new_i32();
11064 TCGv_i32 fp1 = tcg_temp_new_i32();
11065 TCGv_i32 fp2 = tcg_temp_new_i32();
11066 gen_load_fpr32(ctx, fp0, fs);
11067 gen_load_fpr32(ctx, fp1, ft);
11068 gen_load_fpr32(ctx, fp2, fd);
11069 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11070 gen_store_fpr32(ctx, fp2, fd);
11071 tcg_temp_free_i32(fp2);
11072 tcg_temp_free_i32(fp1);
11073 tcg_temp_free_i32(fp0);
11077 check_insn(ctx, ISA_MIPS32R6);
11079 TCGv_i32 fp0 = tcg_temp_new_i32();
11080 TCGv_i32 fp1 = tcg_temp_new_i32();
11081 TCGv_i32 fp2 = tcg_temp_new_i32();
11082 gen_load_fpr32(ctx, fp0, fs);
11083 gen_load_fpr32(ctx, fp1, ft);
11084 gen_load_fpr32(ctx, fp2, fd);
11085 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11086 gen_store_fpr32(ctx, fp2, fd);
11087 tcg_temp_free_i32(fp2);
11088 tcg_temp_free_i32(fp1);
11089 tcg_temp_free_i32(fp0);
11093 check_insn(ctx, ISA_MIPS32R6);
11095 TCGv_i32 fp0 = tcg_temp_new_i32();
11096 gen_load_fpr32(ctx, fp0, fs);
11097 gen_helper_float_rint_s(fp0, cpu_env, fp0);
11098 gen_store_fpr32(ctx, fp0, fd);
11099 tcg_temp_free_i32(fp0);
11103 check_insn(ctx, ISA_MIPS32R6);
11105 TCGv_i32 fp0 = tcg_temp_new_i32();
11106 gen_load_fpr32(ctx, fp0, fs);
11107 gen_helper_float_class_s(fp0, cpu_env, fp0);
11108 gen_store_fpr32(ctx, fp0, fd);
11109 tcg_temp_free_i32(fp0);
11112 case OPC_MIN_S: /* OPC_RECIP2_S */
11113 if (ctx->insn_flags & ISA_MIPS32R6) {
11115 TCGv_i32 fp0 = tcg_temp_new_i32();
11116 TCGv_i32 fp1 = tcg_temp_new_i32();
11117 TCGv_i32 fp2 = tcg_temp_new_i32();
11118 gen_load_fpr32(ctx, fp0, fs);
11119 gen_load_fpr32(ctx, fp1, ft);
11120 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11121 gen_store_fpr32(ctx, fp2, fd);
11122 tcg_temp_free_i32(fp2);
11123 tcg_temp_free_i32(fp1);
11124 tcg_temp_free_i32(fp0);
11127 check_cp1_64bitmode(ctx);
11129 TCGv_i32 fp0 = tcg_temp_new_i32();
11130 TCGv_i32 fp1 = tcg_temp_new_i32();
11132 gen_load_fpr32(ctx, fp0, fs);
11133 gen_load_fpr32(ctx, fp1, ft);
11134 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11135 tcg_temp_free_i32(fp1);
11136 gen_store_fpr32(ctx, fp0, fd);
11137 tcg_temp_free_i32(fp0);
11141 case OPC_MINA_S: /* OPC_RECIP1_S */
11142 if (ctx->insn_flags & ISA_MIPS32R6) {
11144 TCGv_i32 fp0 = tcg_temp_new_i32();
11145 TCGv_i32 fp1 = tcg_temp_new_i32();
11146 TCGv_i32 fp2 = tcg_temp_new_i32();
11147 gen_load_fpr32(ctx, fp0, fs);
11148 gen_load_fpr32(ctx, fp1, ft);
11149 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11150 gen_store_fpr32(ctx, fp2, fd);
11151 tcg_temp_free_i32(fp2);
11152 tcg_temp_free_i32(fp1);
11153 tcg_temp_free_i32(fp0);
11156 check_cp1_64bitmode(ctx);
11158 TCGv_i32 fp0 = tcg_temp_new_i32();
11160 gen_load_fpr32(ctx, fp0, fs);
11161 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11162 gen_store_fpr32(ctx, fp0, fd);
11163 tcg_temp_free_i32(fp0);
11167 case OPC_MAX_S: /* OPC_RSQRT1_S */
11168 if (ctx->insn_flags & ISA_MIPS32R6) {
11170 TCGv_i32 fp0 = tcg_temp_new_i32();
11171 TCGv_i32 fp1 = tcg_temp_new_i32();
11172 gen_load_fpr32(ctx, fp0, fs);
11173 gen_load_fpr32(ctx, fp1, ft);
11174 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11175 gen_store_fpr32(ctx, fp1, fd);
11176 tcg_temp_free_i32(fp1);
11177 tcg_temp_free_i32(fp0);
11180 check_cp1_64bitmode(ctx);
11182 TCGv_i32 fp0 = tcg_temp_new_i32();
11184 gen_load_fpr32(ctx, fp0, fs);
11185 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11186 gen_store_fpr32(ctx, fp0, fd);
11187 tcg_temp_free_i32(fp0);
11191 case OPC_MAXA_S: /* OPC_RSQRT2_S */
11192 if (ctx->insn_flags & ISA_MIPS32R6) {
11194 TCGv_i32 fp0 = tcg_temp_new_i32();
11195 TCGv_i32 fp1 = tcg_temp_new_i32();
11196 gen_load_fpr32(ctx, fp0, fs);
11197 gen_load_fpr32(ctx, fp1, ft);
11198 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11199 gen_store_fpr32(ctx, fp1, fd);
11200 tcg_temp_free_i32(fp1);
11201 tcg_temp_free_i32(fp0);
11204 check_cp1_64bitmode(ctx);
11206 TCGv_i32 fp0 = tcg_temp_new_i32();
11207 TCGv_i32 fp1 = tcg_temp_new_i32();
11209 gen_load_fpr32(ctx, fp0, fs);
11210 gen_load_fpr32(ctx, fp1, ft);
11211 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11212 tcg_temp_free_i32(fp1);
11213 gen_store_fpr32(ctx, fp0, fd);
11214 tcg_temp_free_i32(fp0);
11219 check_cp1_registers(ctx, fd);
11221 TCGv_i32 fp32 = tcg_temp_new_i32();
11222 TCGv_i64 fp64 = tcg_temp_new_i64();
11224 gen_load_fpr32(ctx, fp32, fs);
11225 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11226 tcg_temp_free_i32(fp32);
11227 gen_store_fpr64(ctx, fp64, fd);
11228 tcg_temp_free_i64(fp64);
11233 TCGv_i32 fp0 = tcg_temp_new_i32();
11235 gen_load_fpr32(ctx, fp0, fs);
11236 if (ctx->nan2008) {
11237 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11239 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11241 gen_store_fpr32(ctx, fp0, fd);
11242 tcg_temp_free_i32(fp0);
11246 check_cp1_64bitmode(ctx);
11248 TCGv_i32 fp32 = tcg_temp_new_i32();
11249 TCGv_i64 fp64 = tcg_temp_new_i64();
11251 gen_load_fpr32(ctx, fp32, fs);
11252 if (ctx->nan2008) {
11253 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11255 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11257 tcg_temp_free_i32(fp32);
11258 gen_store_fpr64(ctx, fp64, fd);
11259 tcg_temp_free_i64(fp64);
11265 TCGv_i64 fp64 = tcg_temp_new_i64();
11266 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11267 TCGv_i32 fp32_1 = tcg_temp_new_i32();
11269 gen_load_fpr32(ctx, fp32_0, fs);
11270 gen_load_fpr32(ctx, fp32_1, ft);
11271 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11272 tcg_temp_free_i32(fp32_1);
11273 tcg_temp_free_i32(fp32_0);
11274 gen_store_fpr64(ctx, fp64, fd);
11275 tcg_temp_free_i64(fp64);
11281 case OPC_CMP_UEQ_S:
11282 case OPC_CMP_OLT_S:
11283 case OPC_CMP_ULT_S:
11284 case OPC_CMP_OLE_S:
11285 case OPC_CMP_ULE_S:
11287 case OPC_CMP_NGLE_S:
11288 case OPC_CMP_SEQ_S:
11289 case OPC_CMP_NGL_S:
11291 case OPC_CMP_NGE_S:
11293 case OPC_CMP_NGT_S:
11294 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11295 if (ctx->opcode & (1 << 6)) {
11296 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11298 gen_cmp_s(ctx, func-48, ft, fs, cc);
11302 check_cp1_registers(ctx, fs | ft | fd);
11304 TCGv_i64 fp0 = tcg_temp_new_i64();
11305 TCGv_i64 fp1 = tcg_temp_new_i64();
11307 gen_load_fpr64(ctx, fp0, fs);
11308 gen_load_fpr64(ctx, fp1, ft);
11309 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11310 tcg_temp_free_i64(fp1);
11311 gen_store_fpr64(ctx, fp0, fd);
11312 tcg_temp_free_i64(fp0);
11316 check_cp1_registers(ctx, fs | ft | fd);
11318 TCGv_i64 fp0 = tcg_temp_new_i64();
11319 TCGv_i64 fp1 = tcg_temp_new_i64();
11321 gen_load_fpr64(ctx, fp0, fs);
11322 gen_load_fpr64(ctx, fp1, ft);
11323 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11324 tcg_temp_free_i64(fp1);
11325 gen_store_fpr64(ctx, fp0, fd);
11326 tcg_temp_free_i64(fp0);
11330 check_cp1_registers(ctx, fs | ft | fd);
11332 TCGv_i64 fp0 = tcg_temp_new_i64();
11333 TCGv_i64 fp1 = tcg_temp_new_i64();
11335 gen_load_fpr64(ctx, fp0, fs);
11336 gen_load_fpr64(ctx, fp1, ft);
11337 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11338 tcg_temp_free_i64(fp1);
11339 gen_store_fpr64(ctx, fp0, fd);
11340 tcg_temp_free_i64(fp0);
11344 check_cp1_registers(ctx, fs | ft | fd);
11346 TCGv_i64 fp0 = tcg_temp_new_i64();
11347 TCGv_i64 fp1 = tcg_temp_new_i64();
11349 gen_load_fpr64(ctx, fp0, fs);
11350 gen_load_fpr64(ctx, fp1, ft);
11351 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11352 tcg_temp_free_i64(fp1);
11353 gen_store_fpr64(ctx, fp0, fd);
11354 tcg_temp_free_i64(fp0);
11358 check_cp1_registers(ctx, fs | fd);
11360 TCGv_i64 fp0 = tcg_temp_new_i64();
11362 gen_load_fpr64(ctx, fp0, fs);
11363 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11364 gen_store_fpr64(ctx, fp0, fd);
11365 tcg_temp_free_i64(fp0);
11369 check_cp1_registers(ctx, fs | fd);
11371 TCGv_i64 fp0 = tcg_temp_new_i64();
11373 gen_load_fpr64(ctx, fp0, fs);
11374 if (ctx->abs2008) {
11375 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11377 gen_helper_float_abs_d(fp0, fp0);
11379 gen_store_fpr64(ctx, fp0, fd);
11380 tcg_temp_free_i64(fp0);
11384 check_cp1_registers(ctx, fs | fd);
11386 TCGv_i64 fp0 = tcg_temp_new_i64();
11388 gen_load_fpr64(ctx, fp0, fs);
11389 gen_store_fpr64(ctx, fp0, fd);
11390 tcg_temp_free_i64(fp0);
11394 check_cp1_registers(ctx, fs | fd);
11396 TCGv_i64 fp0 = tcg_temp_new_i64();
11398 gen_load_fpr64(ctx, fp0, fs);
11399 if (ctx->abs2008) {
11400 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11402 gen_helper_float_chs_d(fp0, fp0);
11404 gen_store_fpr64(ctx, fp0, fd);
11405 tcg_temp_free_i64(fp0);
11408 case OPC_ROUND_L_D:
11409 check_cp1_64bitmode(ctx);
11411 TCGv_i64 fp0 = tcg_temp_new_i64();
11413 gen_load_fpr64(ctx, fp0, fs);
11414 if (ctx->nan2008) {
11415 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11417 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11419 gen_store_fpr64(ctx, fp0, fd);
11420 tcg_temp_free_i64(fp0);
11423 case OPC_TRUNC_L_D:
11424 check_cp1_64bitmode(ctx);
11426 TCGv_i64 fp0 = tcg_temp_new_i64();
11428 gen_load_fpr64(ctx, fp0, fs);
11429 if (ctx->nan2008) {
11430 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11432 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11434 gen_store_fpr64(ctx, fp0, fd);
11435 tcg_temp_free_i64(fp0);
11439 check_cp1_64bitmode(ctx);
11441 TCGv_i64 fp0 = tcg_temp_new_i64();
11443 gen_load_fpr64(ctx, fp0, fs);
11444 if (ctx->nan2008) {
11445 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11447 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11449 gen_store_fpr64(ctx, fp0, fd);
11450 tcg_temp_free_i64(fp0);
11453 case OPC_FLOOR_L_D:
11454 check_cp1_64bitmode(ctx);
11456 TCGv_i64 fp0 = tcg_temp_new_i64();
11458 gen_load_fpr64(ctx, fp0, fs);
11459 if (ctx->nan2008) {
11460 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11462 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11464 gen_store_fpr64(ctx, fp0, fd);
11465 tcg_temp_free_i64(fp0);
11468 case OPC_ROUND_W_D:
11469 check_cp1_registers(ctx, fs);
11471 TCGv_i32 fp32 = tcg_temp_new_i32();
11472 TCGv_i64 fp64 = tcg_temp_new_i64();
11474 gen_load_fpr64(ctx, fp64, fs);
11475 if (ctx->nan2008) {
11476 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11478 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11480 tcg_temp_free_i64(fp64);
11481 gen_store_fpr32(ctx, fp32, fd);
11482 tcg_temp_free_i32(fp32);
11485 case OPC_TRUNC_W_D:
11486 check_cp1_registers(ctx, fs);
11488 TCGv_i32 fp32 = tcg_temp_new_i32();
11489 TCGv_i64 fp64 = tcg_temp_new_i64();
11491 gen_load_fpr64(ctx, fp64, fs);
11492 if (ctx->nan2008) {
11493 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11495 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11497 tcg_temp_free_i64(fp64);
11498 gen_store_fpr32(ctx, fp32, fd);
11499 tcg_temp_free_i32(fp32);
11503 check_cp1_registers(ctx, fs);
11505 TCGv_i32 fp32 = tcg_temp_new_i32();
11506 TCGv_i64 fp64 = tcg_temp_new_i64();
11508 gen_load_fpr64(ctx, fp64, fs);
11509 if (ctx->nan2008) {
11510 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11512 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11514 tcg_temp_free_i64(fp64);
11515 gen_store_fpr32(ctx, fp32, fd);
11516 tcg_temp_free_i32(fp32);
11519 case OPC_FLOOR_W_D:
11520 check_cp1_registers(ctx, fs);
11522 TCGv_i32 fp32 = tcg_temp_new_i32();
11523 TCGv_i64 fp64 = tcg_temp_new_i64();
11525 gen_load_fpr64(ctx, fp64, fs);
11526 if (ctx->nan2008) {
11527 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11529 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11531 tcg_temp_free_i64(fp64);
11532 gen_store_fpr32(ctx, fp32, fd);
11533 tcg_temp_free_i32(fp32);
11537 check_insn(ctx, ISA_MIPS32R6);
11538 gen_sel_d(ctx, op1, fd, ft, fs);
11541 check_insn(ctx, ISA_MIPS32R6);
11542 gen_sel_d(ctx, op1, fd, ft, fs);
11545 check_insn(ctx, ISA_MIPS32R6);
11546 gen_sel_d(ctx, op1, fd, ft, fs);
11549 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11550 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11553 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11555 TCGLabel *l1 = gen_new_label();
11559 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11561 fp0 = tcg_temp_new_i64();
11562 gen_load_fpr64(ctx, fp0, fs);
11563 gen_store_fpr64(ctx, fp0, fd);
11564 tcg_temp_free_i64(fp0);
11569 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11571 TCGLabel *l1 = gen_new_label();
11575 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11576 fp0 = tcg_temp_new_i64();
11577 gen_load_fpr64(ctx, fp0, fs);
11578 gen_store_fpr64(ctx, fp0, fd);
11579 tcg_temp_free_i64(fp0);
11585 check_cp1_registers(ctx, fs | fd);
11587 TCGv_i64 fp0 = tcg_temp_new_i64();
11589 gen_load_fpr64(ctx, fp0, fs);
11590 gen_helper_float_recip_d(fp0, cpu_env, fp0);
11591 gen_store_fpr64(ctx, fp0, fd);
11592 tcg_temp_free_i64(fp0);
11596 check_cp1_registers(ctx, fs | fd);
11598 TCGv_i64 fp0 = tcg_temp_new_i64();
11600 gen_load_fpr64(ctx, fp0, fs);
11601 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11602 gen_store_fpr64(ctx, fp0, fd);
11603 tcg_temp_free_i64(fp0);
11607 check_insn(ctx, ISA_MIPS32R6);
11609 TCGv_i64 fp0 = tcg_temp_new_i64();
11610 TCGv_i64 fp1 = tcg_temp_new_i64();
11611 TCGv_i64 fp2 = tcg_temp_new_i64();
11612 gen_load_fpr64(ctx, fp0, fs);
11613 gen_load_fpr64(ctx, fp1, ft);
11614 gen_load_fpr64(ctx, fp2, fd);
11615 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11616 gen_store_fpr64(ctx, fp2, fd);
11617 tcg_temp_free_i64(fp2);
11618 tcg_temp_free_i64(fp1);
11619 tcg_temp_free_i64(fp0);
11623 check_insn(ctx, ISA_MIPS32R6);
11625 TCGv_i64 fp0 = tcg_temp_new_i64();
11626 TCGv_i64 fp1 = tcg_temp_new_i64();
11627 TCGv_i64 fp2 = tcg_temp_new_i64();
11628 gen_load_fpr64(ctx, fp0, fs);
11629 gen_load_fpr64(ctx, fp1, ft);
11630 gen_load_fpr64(ctx, fp2, fd);
11631 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11632 gen_store_fpr64(ctx, fp2, fd);
11633 tcg_temp_free_i64(fp2);
11634 tcg_temp_free_i64(fp1);
11635 tcg_temp_free_i64(fp0);
11639 check_insn(ctx, ISA_MIPS32R6);
11641 TCGv_i64 fp0 = tcg_temp_new_i64();
11642 gen_load_fpr64(ctx, fp0, fs);
11643 gen_helper_float_rint_d(fp0, cpu_env, fp0);
11644 gen_store_fpr64(ctx, fp0, fd);
11645 tcg_temp_free_i64(fp0);
11649 check_insn(ctx, ISA_MIPS32R6);
11651 TCGv_i64 fp0 = tcg_temp_new_i64();
11652 gen_load_fpr64(ctx, fp0, fs);
11653 gen_helper_float_class_d(fp0, cpu_env, fp0);
11654 gen_store_fpr64(ctx, fp0, fd);
11655 tcg_temp_free_i64(fp0);
11658 case OPC_MIN_D: /* OPC_RECIP2_D */
11659 if (ctx->insn_flags & ISA_MIPS32R6) {
11661 TCGv_i64 fp0 = tcg_temp_new_i64();
11662 TCGv_i64 fp1 = tcg_temp_new_i64();
11663 gen_load_fpr64(ctx, fp0, fs);
11664 gen_load_fpr64(ctx, fp1, ft);
11665 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11666 gen_store_fpr64(ctx, fp1, fd);
11667 tcg_temp_free_i64(fp1);
11668 tcg_temp_free_i64(fp0);
11671 check_cp1_64bitmode(ctx);
11673 TCGv_i64 fp0 = tcg_temp_new_i64();
11674 TCGv_i64 fp1 = tcg_temp_new_i64();
11676 gen_load_fpr64(ctx, fp0, fs);
11677 gen_load_fpr64(ctx, fp1, ft);
11678 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11679 tcg_temp_free_i64(fp1);
11680 gen_store_fpr64(ctx, fp0, fd);
11681 tcg_temp_free_i64(fp0);
11685 case OPC_MINA_D: /* OPC_RECIP1_D */
11686 if (ctx->insn_flags & ISA_MIPS32R6) {
11688 TCGv_i64 fp0 = tcg_temp_new_i64();
11689 TCGv_i64 fp1 = tcg_temp_new_i64();
11690 gen_load_fpr64(ctx, fp0, fs);
11691 gen_load_fpr64(ctx, fp1, ft);
11692 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11693 gen_store_fpr64(ctx, fp1, fd);
11694 tcg_temp_free_i64(fp1);
11695 tcg_temp_free_i64(fp0);
11698 check_cp1_64bitmode(ctx);
11700 TCGv_i64 fp0 = tcg_temp_new_i64();
11702 gen_load_fpr64(ctx, fp0, fs);
11703 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11704 gen_store_fpr64(ctx, fp0, fd);
11705 tcg_temp_free_i64(fp0);
11709 case OPC_MAX_D: /* OPC_RSQRT1_D */
11710 if (ctx->insn_flags & ISA_MIPS32R6) {
11712 TCGv_i64 fp0 = tcg_temp_new_i64();
11713 TCGv_i64 fp1 = tcg_temp_new_i64();
11714 gen_load_fpr64(ctx, fp0, fs);
11715 gen_load_fpr64(ctx, fp1, ft);
11716 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11717 gen_store_fpr64(ctx, fp1, fd);
11718 tcg_temp_free_i64(fp1);
11719 tcg_temp_free_i64(fp0);
11722 check_cp1_64bitmode(ctx);
11724 TCGv_i64 fp0 = tcg_temp_new_i64();
11726 gen_load_fpr64(ctx, fp0, fs);
11727 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11728 gen_store_fpr64(ctx, fp0, fd);
11729 tcg_temp_free_i64(fp0);
11733 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11734 if (ctx->insn_flags & ISA_MIPS32R6) {
11736 TCGv_i64 fp0 = tcg_temp_new_i64();
11737 TCGv_i64 fp1 = tcg_temp_new_i64();
11738 gen_load_fpr64(ctx, fp0, fs);
11739 gen_load_fpr64(ctx, fp1, ft);
11740 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11741 gen_store_fpr64(ctx, fp1, fd);
11742 tcg_temp_free_i64(fp1);
11743 tcg_temp_free_i64(fp0);
11746 check_cp1_64bitmode(ctx);
11748 TCGv_i64 fp0 = tcg_temp_new_i64();
11749 TCGv_i64 fp1 = tcg_temp_new_i64();
11751 gen_load_fpr64(ctx, fp0, fs);
11752 gen_load_fpr64(ctx, fp1, ft);
11753 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11754 tcg_temp_free_i64(fp1);
11755 gen_store_fpr64(ctx, fp0, fd);
11756 tcg_temp_free_i64(fp0);
11763 case OPC_CMP_UEQ_D:
11764 case OPC_CMP_OLT_D:
11765 case OPC_CMP_ULT_D:
11766 case OPC_CMP_OLE_D:
11767 case OPC_CMP_ULE_D:
11769 case OPC_CMP_NGLE_D:
11770 case OPC_CMP_SEQ_D:
11771 case OPC_CMP_NGL_D:
11773 case OPC_CMP_NGE_D:
11775 case OPC_CMP_NGT_D:
11776 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11777 if (ctx->opcode & (1 << 6)) {
11778 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11780 gen_cmp_d(ctx, func-48, ft, fs, cc);
11784 check_cp1_registers(ctx, fs);
11786 TCGv_i32 fp32 = tcg_temp_new_i32();
11787 TCGv_i64 fp64 = tcg_temp_new_i64();
11789 gen_load_fpr64(ctx, fp64, fs);
11790 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11791 tcg_temp_free_i64(fp64);
11792 gen_store_fpr32(ctx, fp32, fd);
11793 tcg_temp_free_i32(fp32);
11797 check_cp1_registers(ctx, fs);
11799 TCGv_i32 fp32 = tcg_temp_new_i32();
11800 TCGv_i64 fp64 = tcg_temp_new_i64();
11802 gen_load_fpr64(ctx, fp64, fs);
11803 if (ctx->nan2008) {
11804 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11806 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11808 tcg_temp_free_i64(fp64);
11809 gen_store_fpr32(ctx, fp32, fd);
11810 tcg_temp_free_i32(fp32);
11814 check_cp1_64bitmode(ctx);
11816 TCGv_i64 fp0 = tcg_temp_new_i64();
11818 gen_load_fpr64(ctx, fp0, fs);
11819 if (ctx->nan2008) {
11820 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11822 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11824 gen_store_fpr64(ctx, fp0, fd);
11825 tcg_temp_free_i64(fp0);
11830 TCGv_i32 fp0 = tcg_temp_new_i32();
11832 gen_load_fpr32(ctx, fp0, fs);
11833 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11834 gen_store_fpr32(ctx, fp0, fd);
11835 tcg_temp_free_i32(fp0);
11839 check_cp1_registers(ctx, fd);
11841 TCGv_i32 fp32 = tcg_temp_new_i32();
11842 TCGv_i64 fp64 = tcg_temp_new_i64();
11844 gen_load_fpr32(ctx, fp32, fs);
11845 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11846 tcg_temp_free_i32(fp32);
11847 gen_store_fpr64(ctx, fp64, fd);
11848 tcg_temp_free_i64(fp64);
11852 check_cp1_64bitmode(ctx);
11854 TCGv_i32 fp32 = tcg_temp_new_i32();
11855 TCGv_i64 fp64 = tcg_temp_new_i64();
11857 gen_load_fpr64(ctx, fp64, fs);
11858 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11859 tcg_temp_free_i64(fp64);
11860 gen_store_fpr32(ctx, fp32, fd);
11861 tcg_temp_free_i32(fp32);
11865 check_cp1_64bitmode(ctx);
11867 TCGv_i64 fp0 = tcg_temp_new_i64();
11869 gen_load_fpr64(ctx, fp0, fs);
11870 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11871 gen_store_fpr64(ctx, fp0, fd);
11872 tcg_temp_free_i64(fp0);
11875 case OPC_CVT_PS_PW:
11878 TCGv_i64 fp0 = tcg_temp_new_i64();
11880 gen_load_fpr64(ctx, fp0, fs);
11881 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11882 gen_store_fpr64(ctx, fp0, fd);
11883 tcg_temp_free_i64(fp0);
11889 TCGv_i64 fp0 = tcg_temp_new_i64();
11890 TCGv_i64 fp1 = tcg_temp_new_i64();
11892 gen_load_fpr64(ctx, fp0, fs);
11893 gen_load_fpr64(ctx, fp1, ft);
11894 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11895 tcg_temp_free_i64(fp1);
11896 gen_store_fpr64(ctx, fp0, fd);
11897 tcg_temp_free_i64(fp0);
11903 TCGv_i64 fp0 = tcg_temp_new_i64();
11904 TCGv_i64 fp1 = tcg_temp_new_i64();
11906 gen_load_fpr64(ctx, fp0, fs);
11907 gen_load_fpr64(ctx, fp1, ft);
11908 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11909 tcg_temp_free_i64(fp1);
11910 gen_store_fpr64(ctx, fp0, fd);
11911 tcg_temp_free_i64(fp0);
11917 TCGv_i64 fp0 = tcg_temp_new_i64();
11918 TCGv_i64 fp1 = tcg_temp_new_i64();
11920 gen_load_fpr64(ctx, fp0, fs);
11921 gen_load_fpr64(ctx, fp1, ft);
11922 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11923 tcg_temp_free_i64(fp1);
11924 gen_store_fpr64(ctx, fp0, fd);
11925 tcg_temp_free_i64(fp0);
11931 TCGv_i64 fp0 = tcg_temp_new_i64();
11933 gen_load_fpr64(ctx, fp0, fs);
11934 gen_helper_float_abs_ps(fp0, fp0);
11935 gen_store_fpr64(ctx, fp0, fd);
11936 tcg_temp_free_i64(fp0);
11942 TCGv_i64 fp0 = tcg_temp_new_i64();
11944 gen_load_fpr64(ctx, fp0, fs);
11945 gen_store_fpr64(ctx, fp0, fd);
11946 tcg_temp_free_i64(fp0);
11952 TCGv_i64 fp0 = tcg_temp_new_i64();
11954 gen_load_fpr64(ctx, fp0, fs);
11955 gen_helper_float_chs_ps(fp0, fp0);
11956 gen_store_fpr64(ctx, fp0, fd);
11957 tcg_temp_free_i64(fp0);
11962 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11967 TCGLabel *l1 = gen_new_label();
11971 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11972 fp0 = tcg_temp_new_i64();
11973 gen_load_fpr64(ctx, fp0, fs);
11974 gen_store_fpr64(ctx, fp0, fd);
11975 tcg_temp_free_i64(fp0);
11982 TCGLabel *l1 = gen_new_label();
11986 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11987 fp0 = tcg_temp_new_i64();
11988 gen_load_fpr64(ctx, fp0, fs);
11989 gen_store_fpr64(ctx, fp0, fd);
11990 tcg_temp_free_i64(fp0);
11998 TCGv_i64 fp0 = tcg_temp_new_i64();
11999 TCGv_i64 fp1 = tcg_temp_new_i64();
12001 gen_load_fpr64(ctx, fp0, ft);
12002 gen_load_fpr64(ctx, fp1, fs);
12003 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12004 tcg_temp_free_i64(fp1);
12005 gen_store_fpr64(ctx, fp0, fd);
12006 tcg_temp_free_i64(fp0);
12012 TCGv_i64 fp0 = tcg_temp_new_i64();
12013 TCGv_i64 fp1 = tcg_temp_new_i64();
12015 gen_load_fpr64(ctx, fp0, ft);
12016 gen_load_fpr64(ctx, fp1, fs);
12017 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12018 tcg_temp_free_i64(fp1);
12019 gen_store_fpr64(ctx, fp0, fd);
12020 tcg_temp_free_i64(fp0);
12023 case OPC_RECIP2_PS:
12026 TCGv_i64 fp0 = tcg_temp_new_i64();
12027 TCGv_i64 fp1 = tcg_temp_new_i64();
12029 gen_load_fpr64(ctx, fp0, fs);
12030 gen_load_fpr64(ctx, fp1, ft);
12031 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12032 tcg_temp_free_i64(fp1);
12033 gen_store_fpr64(ctx, fp0, fd);
12034 tcg_temp_free_i64(fp0);
12037 case OPC_RECIP1_PS:
12040 TCGv_i64 fp0 = tcg_temp_new_i64();
12042 gen_load_fpr64(ctx, fp0, fs);
12043 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12044 gen_store_fpr64(ctx, fp0, fd);
12045 tcg_temp_free_i64(fp0);
12048 case OPC_RSQRT1_PS:
12051 TCGv_i64 fp0 = tcg_temp_new_i64();
12053 gen_load_fpr64(ctx, fp0, fs);
12054 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12055 gen_store_fpr64(ctx, fp0, fd);
12056 tcg_temp_free_i64(fp0);
12059 case OPC_RSQRT2_PS:
12062 TCGv_i64 fp0 = tcg_temp_new_i64();
12063 TCGv_i64 fp1 = tcg_temp_new_i64();
12065 gen_load_fpr64(ctx, fp0, fs);
12066 gen_load_fpr64(ctx, fp1, ft);
12067 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12068 tcg_temp_free_i64(fp1);
12069 gen_store_fpr64(ctx, fp0, fd);
12070 tcg_temp_free_i64(fp0);
12074 check_cp1_64bitmode(ctx);
12076 TCGv_i32 fp0 = tcg_temp_new_i32();
12078 gen_load_fpr32h(ctx, fp0, fs);
12079 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12080 gen_store_fpr32(ctx, fp0, fd);
12081 tcg_temp_free_i32(fp0);
12084 case OPC_CVT_PW_PS:
12087 TCGv_i64 fp0 = tcg_temp_new_i64();
12089 gen_load_fpr64(ctx, fp0, fs);
12090 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12091 gen_store_fpr64(ctx, fp0, fd);
12092 tcg_temp_free_i64(fp0);
12096 check_cp1_64bitmode(ctx);
12098 TCGv_i32 fp0 = tcg_temp_new_i32();
12100 gen_load_fpr32(ctx, fp0, fs);
12101 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12102 gen_store_fpr32(ctx, fp0, fd);
12103 tcg_temp_free_i32(fp0);
12109 TCGv_i32 fp0 = tcg_temp_new_i32();
12110 TCGv_i32 fp1 = tcg_temp_new_i32();
12112 gen_load_fpr32(ctx, fp0, fs);
12113 gen_load_fpr32(ctx, fp1, ft);
12114 gen_store_fpr32h(ctx, fp0, fd);
12115 gen_store_fpr32(ctx, fp1, fd);
12116 tcg_temp_free_i32(fp0);
12117 tcg_temp_free_i32(fp1);
12123 TCGv_i32 fp0 = tcg_temp_new_i32();
12124 TCGv_i32 fp1 = tcg_temp_new_i32();
12126 gen_load_fpr32(ctx, fp0, fs);
12127 gen_load_fpr32h(ctx, fp1, ft);
12128 gen_store_fpr32(ctx, fp1, fd);
12129 gen_store_fpr32h(ctx, fp0, fd);
12130 tcg_temp_free_i32(fp0);
12131 tcg_temp_free_i32(fp1);
12137 TCGv_i32 fp0 = tcg_temp_new_i32();
12138 TCGv_i32 fp1 = tcg_temp_new_i32();
12140 gen_load_fpr32h(ctx, fp0, fs);
12141 gen_load_fpr32(ctx, fp1, ft);
12142 gen_store_fpr32(ctx, fp1, fd);
12143 gen_store_fpr32h(ctx, fp0, fd);
12144 tcg_temp_free_i32(fp0);
12145 tcg_temp_free_i32(fp1);
12151 TCGv_i32 fp0 = tcg_temp_new_i32();
12152 TCGv_i32 fp1 = tcg_temp_new_i32();
12154 gen_load_fpr32h(ctx, fp0, fs);
12155 gen_load_fpr32h(ctx, fp1, ft);
12156 gen_store_fpr32(ctx, fp1, fd);
12157 gen_store_fpr32h(ctx, fp0, fd);
12158 tcg_temp_free_i32(fp0);
12159 tcg_temp_free_i32(fp1);
12163 case OPC_CMP_UN_PS:
12164 case OPC_CMP_EQ_PS:
12165 case OPC_CMP_UEQ_PS:
12166 case OPC_CMP_OLT_PS:
12167 case OPC_CMP_ULT_PS:
12168 case OPC_CMP_OLE_PS:
12169 case OPC_CMP_ULE_PS:
12170 case OPC_CMP_SF_PS:
12171 case OPC_CMP_NGLE_PS:
12172 case OPC_CMP_SEQ_PS:
12173 case OPC_CMP_NGL_PS:
12174 case OPC_CMP_LT_PS:
12175 case OPC_CMP_NGE_PS:
12176 case OPC_CMP_LE_PS:
12177 case OPC_CMP_NGT_PS:
12178 if (ctx->opcode & (1 << 6)) {
12179 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12181 gen_cmp_ps(ctx, func-48, ft, fs, cc);
12185 MIPS_INVAL("farith");
12186 generate_exception_end(ctx, EXCP_RI);
12191 /* Coprocessor 3 (FPU) */
12192 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12193 int fd, int fs, int base, int index)
12195 TCGv t0 = tcg_temp_new();
12198 gen_load_gpr(t0, index);
12199 } else if (index == 0) {
12200 gen_load_gpr(t0, base);
12202 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12204 /* Don't do NOP if destination is zero: we must perform the actual
12210 TCGv_i32 fp0 = tcg_temp_new_i32();
12212 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12213 tcg_gen_trunc_tl_i32(fp0, t0);
12214 gen_store_fpr32(ctx, fp0, fd);
12215 tcg_temp_free_i32(fp0);
12220 check_cp1_registers(ctx, fd);
12222 TCGv_i64 fp0 = tcg_temp_new_i64();
12223 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12224 gen_store_fpr64(ctx, fp0, fd);
12225 tcg_temp_free_i64(fp0);
12229 check_cp1_64bitmode(ctx);
12230 tcg_gen_andi_tl(t0, t0, ~0x7);
12232 TCGv_i64 fp0 = tcg_temp_new_i64();
12234 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12235 gen_store_fpr64(ctx, fp0, fd);
12236 tcg_temp_free_i64(fp0);
12242 TCGv_i32 fp0 = tcg_temp_new_i32();
12243 gen_load_fpr32(ctx, fp0, fs);
12244 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12245 tcg_temp_free_i32(fp0);
12250 check_cp1_registers(ctx, fs);
12252 TCGv_i64 fp0 = tcg_temp_new_i64();
12253 gen_load_fpr64(ctx, fp0, fs);
12254 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12255 tcg_temp_free_i64(fp0);
12259 check_cp1_64bitmode(ctx);
12260 tcg_gen_andi_tl(t0, t0, ~0x7);
12262 TCGv_i64 fp0 = tcg_temp_new_i64();
12263 gen_load_fpr64(ctx, fp0, fs);
12264 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12265 tcg_temp_free_i64(fp0);
12272 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12273 int fd, int fr, int fs, int ft)
12279 TCGv t0 = tcg_temp_local_new();
12280 TCGv_i32 fp = tcg_temp_new_i32();
12281 TCGv_i32 fph = tcg_temp_new_i32();
12282 TCGLabel *l1 = gen_new_label();
12283 TCGLabel *l2 = gen_new_label();
12285 gen_load_gpr(t0, fr);
12286 tcg_gen_andi_tl(t0, t0, 0x7);
12288 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12289 gen_load_fpr32(ctx, fp, fs);
12290 gen_load_fpr32h(ctx, fph, fs);
12291 gen_store_fpr32(ctx, fp, fd);
12292 gen_store_fpr32h(ctx, fph, fd);
12295 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12297 #ifdef TARGET_WORDS_BIGENDIAN
12298 gen_load_fpr32(ctx, fp, fs);
12299 gen_load_fpr32h(ctx, fph, ft);
12300 gen_store_fpr32h(ctx, fp, fd);
12301 gen_store_fpr32(ctx, fph, fd);
12303 gen_load_fpr32h(ctx, fph, fs);
12304 gen_load_fpr32(ctx, fp, ft);
12305 gen_store_fpr32(ctx, fph, fd);
12306 gen_store_fpr32h(ctx, fp, fd);
12309 tcg_temp_free_i32(fp);
12310 tcg_temp_free_i32(fph);
12316 TCGv_i32 fp0 = tcg_temp_new_i32();
12317 TCGv_i32 fp1 = tcg_temp_new_i32();
12318 TCGv_i32 fp2 = tcg_temp_new_i32();
12320 gen_load_fpr32(ctx, fp0, fs);
12321 gen_load_fpr32(ctx, fp1, ft);
12322 gen_load_fpr32(ctx, fp2, fr);
12323 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12324 tcg_temp_free_i32(fp0);
12325 tcg_temp_free_i32(fp1);
12326 gen_store_fpr32(ctx, fp2, fd);
12327 tcg_temp_free_i32(fp2);
12332 check_cp1_registers(ctx, fd | fs | ft | fr);
12334 TCGv_i64 fp0 = tcg_temp_new_i64();
12335 TCGv_i64 fp1 = tcg_temp_new_i64();
12336 TCGv_i64 fp2 = tcg_temp_new_i64();
12338 gen_load_fpr64(ctx, fp0, fs);
12339 gen_load_fpr64(ctx, fp1, ft);
12340 gen_load_fpr64(ctx, fp2, fr);
12341 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12342 tcg_temp_free_i64(fp0);
12343 tcg_temp_free_i64(fp1);
12344 gen_store_fpr64(ctx, fp2, fd);
12345 tcg_temp_free_i64(fp2);
12351 TCGv_i64 fp0 = tcg_temp_new_i64();
12352 TCGv_i64 fp1 = tcg_temp_new_i64();
12353 TCGv_i64 fp2 = tcg_temp_new_i64();
12355 gen_load_fpr64(ctx, fp0, fs);
12356 gen_load_fpr64(ctx, fp1, ft);
12357 gen_load_fpr64(ctx, fp2, fr);
12358 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12359 tcg_temp_free_i64(fp0);
12360 tcg_temp_free_i64(fp1);
12361 gen_store_fpr64(ctx, fp2, fd);
12362 tcg_temp_free_i64(fp2);
12368 TCGv_i32 fp0 = tcg_temp_new_i32();
12369 TCGv_i32 fp1 = tcg_temp_new_i32();
12370 TCGv_i32 fp2 = tcg_temp_new_i32();
12372 gen_load_fpr32(ctx, fp0, fs);
12373 gen_load_fpr32(ctx, fp1, ft);
12374 gen_load_fpr32(ctx, fp2, fr);
12375 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12376 tcg_temp_free_i32(fp0);
12377 tcg_temp_free_i32(fp1);
12378 gen_store_fpr32(ctx, fp2, fd);
12379 tcg_temp_free_i32(fp2);
12384 check_cp1_registers(ctx, fd | fs | ft | fr);
12386 TCGv_i64 fp0 = tcg_temp_new_i64();
12387 TCGv_i64 fp1 = tcg_temp_new_i64();
12388 TCGv_i64 fp2 = tcg_temp_new_i64();
12390 gen_load_fpr64(ctx, fp0, fs);
12391 gen_load_fpr64(ctx, fp1, ft);
12392 gen_load_fpr64(ctx, fp2, fr);
12393 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12394 tcg_temp_free_i64(fp0);
12395 tcg_temp_free_i64(fp1);
12396 gen_store_fpr64(ctx, fp2, fd);
12397 tcg_temp_free_i64(fp2);
12403 TCGv_i64 fp0 = tcg_temp_new_i64();
12404 TCGv_i64 fp1 = tcg_temp_new_i64();
12405 TCGv_i64 fp2 = tcg_temp_new_i64();
12407 gen_load_fpr64(ctx, fp0, fs);
12408 gen_load_fpr64(ctx, fp1, ft);
12409 gen_load_fpr64(ctx, fp2, fr);
12410 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12411 tcg_temp_free_i64(fp0);
12412 tcg_temp_free_i64(fp1);
12413 gen_store_fpr64(ctx, fp2, fd);
12414 tcg_temp_free_i64(fp2);
12420 TCGv_i32 fp0 = tcg_temp_new_i32();
12421 TCGv_i32 fp1 = tcg_temp_new_i32();
12422 TCGv_i32 fp2 = tcg_temp_new_i32();
12424 gen_load_fpr32(ctx, fp0, fs);
12425 gen_load_fpr32(ctx, fp1, ft);
12426 gen_load_fpr32(ctx, fp2, fr);
12427 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12428 tcg_temp_free_i32(fp0);
12429 tcg_temp_free_i32(fp1);
12430 gen_store_fpr32(ctx, fp2, fd);
12431 tcg_temp_free_i32(fp2);
12436 check_cp1_registers(ctx, fd | fs | ft | fr);
12438 TCGv_i64 fp0 = tcg_temp_new_i64();
12439 TCGv_i64 fp1 = tcg_temp_new_i64();
12440 TCGv_i64 fp2 = tcg_temp_new_i64();
12442 gen_load_fpr64(ctx, fp0, fs);
12443 gen_load_fpr64(ctx, fp1, ft);
12444 gen_load_fpr64(ctx, fp2, fr);
12445 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12446 tcg_temp_free_i64(fp0);
12447 tcg_temp_free_i64(fp1);
12448 gen_store_fpr64(ctx, fp2, fd);
12449 tcg_temp_free_i64(fp2);
12455 TCGv_i64 fp0 = tcg_temp_new_i64();
12456 TCGv_i64 fp1 = tcg_temp_new_i64();
12457 TCGv_i64 fp2 = tcg_temp_new_i64();
12459 gen_load_fpr64(ctx, fp0, fs);
12460 gen_load_fpr64(ctx, fp1, ft);
12461 gen_load_fpr64(ctx, fp2, fr);
12462 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12463 tcg_temp_free_i64(fp0);
12464 tcg_temp_free_i64(fp1);
12465 gen_store_fpr64(ctx, fp2, fd);
12466 tcg_temp_free_i64(fp2);
12472 TCGv_i32 fp0 = tcg_temp_new_i32();
12473 TCGv_i32 fp1 = tcg_temp_new_i32();
12474 TCGv_i32 fp2 = tcg_temp_new_i32();
12476 gen_load_fpr32(ctx, fp0, fs);
12477 gen_load_fpr32(ctx, fp1, ft);
12478 gen_load_fpr32(ctx, fp2, fr);
12479 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12480 tcg_temp_free_i32(fp0);
12481 tcg_temp_free_i32(fp1);
12482 gen_store_fpr32(ctx, fp2, fd);
12483 tcg_temp_free_i32(fp2);
12488 check_cp1_registers(ctx, fd | fs | ft | fr);
12490 TCGv_i64 fp0 = tcg_temp_new_i64();
12491 TCGv_i64 fp1 = tcg_temp_new_i64();
12492 TCGv_i64 fp2 = tcg_temp_new_i64();
12494 gen_load_fpr64(ctx, fp0, fs);
12495 gen_load_fpr64(ctx, fp1, ft);
12496 gen_load_fpr64(ctx, fp2, fr);
12497 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12498 tcg_temp_free_i64(fp0);
12499 tcg_temp_free_i64(fp1);
12500 gen_store_fpr64(ctx, fp2, fd);
12501 tcg_temp_free_i64(fp2);
12507 TCGv_i64 fp0 = tcg_temp_new_i64();
12508 TCGv_i64 fp1 = tcg_temp_new_i64();
12509 TCGv_i64 fp2 = tcg_temp_new_i64();
12511 gen_load_fpr64(ctx, fp0, fs);
12512 gen_load_fpr64(ctx, fp1, ft);
12513 gen_load_fpr64(ctx, fp2, fr);
12514 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12515 tcg_temp_free_i64(fp0);
12516 tcg_temp_free_i64(fp1);
12517 gen_store_fpr64(ctx, fp2, fd);
12518 tcg_temp_free_i64(fp2);
12522 MIPS_INVAL("flt3_arith");
12523 generate_exception_end(ctx, EXCP_RI);
12528 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12532 #if !defined(CONFIG_USER_ONLY)
12533 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12534 Therefore only check the ISA in system mode. */
12535 check_insn(ctx, ISA_MIPS32R2);
12537 t0 = tcg_temp_new();
12541 gen_helper_rdhwr_cpunum(t0, cpu_env);
12542 gen_store_gpr(t0, rt);
12545 gen_helper_rdhwr_synci_step(t0, cpu_env);
12546 gen_store_gpr(t0, rt);
12549 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12552 gen_helper_rdhwr_cc(t0, cpu_env);
12553 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12556 gen_store_gpr(t0, rt);
12557 /* Break the TB to be able to take timer interrupts immediately
12558 after reading count. DISAS_STOP isn't sufficient, we need to ensure
12559 we break completely out of translated code. */
12560 gen_save_pc(ctx->base.pc_next + 4);
12561 ctx->base.is_jmp = DISAS_EXIT;
12564 gen_helper_rdhwr_ccres(t0, cpu_env);
12565 gen_store_gpr(t0, rt);
12568 check_insn(ctx, ISA_MIPS32R6);
12570 /* Performance counter registers are not implemented other than
12571 * control register 0.
12573 generate_exception(ctx, EXCP_RI);
12575 gen_helper_rdhwr_performance(t0, cpu_env);
12576 gen_store_gpr(t0, rt);
12579 check_insn(ctx, ISA_MIPS32R6);
12580 gen_helper_rdhwr_xnp(t0, cpu_env);
12581 gen_store_gpr(t0, rt);
12584 #if defined(CONFIG_USER_ONLY)
12585 tcg_gen_ld_tl(t0, cpu_env,
12586 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12587 gen_store_gpr(t0, rt);
12590 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12591 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12592 tcg_gen_ld_tl(t0, cpu_env,
12593 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12594 gen_store_gpr(t0, rt);
12596 generate_exception_end(ctx, EXCP_RI);
12600 default: /* Invalid */
12601 MIPS_INVAL("rdhwr");
12602 generate_exception_end(ctx, EXCP_RI);
12608 static inline void clear_branch_hflags(DisasContext *ctx)
12610 ctx->hflags &= ~MIPS_HFLAG_BMASK;
12611 if (ctx->base.is_jmp == DISAS_NEXT) {
12612 save_cpu_state(ctx, 0);
12614 /* it is not safe to save ctx->hflags as hflags may be changed
12615 in execution time by the instruction in delay / forbidden slot. */
12616 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12620 static void gen_branch(DisasContext *ctx, int insn_bytes)
12622 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12623 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12624 /* Branches completion */
12625 clear_branch_hflags(ctx);
12626 ctx->base.is_jmp = DISAS_NORETURN;
12627 /* FIXME: Need to clear can_do_io. */
12628 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12629 case MIPS_HFLAG_FBNSLOT:
12630 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12633 /* unconditional branch */
12634 if (proc_hflags & MIPS_HFLAG_BX) {
12635 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12637 gen_goto_tb(ctx, 0, ctx->btarget);
12639 case MIPS_HFLAG_BL:
12640 /* blikely taken case */
12641 gen_goto_tb(ctx, 0, ctx->btarget);
12643 case MIPS_HFLAG_BC:
12644 /* Conditional branch */
12646 TCGLabel *l1 = gen_new_label();
12648 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12649 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12651 gen_goto_tb(ctx, 0, ctx->btarget);
12654 case MIPS_HFLAG_BR:
12655 /* unconditional branch to register */
12656 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12657 TCGv t0 = tcg_temp_new();
12658 TCGv_i32 t1 = tcg_temp_new_i32();
12660 tcg_gen_andi_tl(t0, btarget, 0x1);
12661 tcg_gen_trunc_tl_i32(t1, t0);
12663 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12664 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12665 tcg_gen_or_i32(hflags, hflags, t1);
12666 tcg_temp_free_i32(t1);
12668 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12670 tcg_gen_mov_tl(cpu_PC, btarget);
12672 if (ctx->base.singlestep_enabled) {
12673 save_cpu_state(ctx, 0);
12674 gen_helper_raise_exception_debug(cpu_env);
12676 tcg_gen_lookup_and_goto_ptr();
12679 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12685 /* Compact Branches */
12686 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12687 int rs, int rt, int32_t offset)
12689 int bcond_compute = 0;
12690 TCGv t0 = tcg_temp_new();
12691 TCGv t1 = tcg_temp_new();
12692 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12694 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12695 #ifdef MIPS_DEBUG_DISAS
12696 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12697 "\n", ctx->base.pc_next);
12699 generate_exception_end(ctx, EXCP_RI);
12703 /* Load needed operands and calculate btarget */
12705 /* compact branch */
12706 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12707 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12708 gen_load_gpr(t0, rs);
12709 gen_load_gpr(t1, rt);
12711 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12712 if (rs <= rt && rs == 0) {
12713 /* OPC_BEQZALC, OPC_BNEZALC */
12714 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12717 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12718 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12719 gen_load_gpr(t0, rs);
12720 gen_load_gpr(t1, rt);
12722 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12724 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12725 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12726 if (rs == 0 || rs == rt) {
12727 /* OPC_BLEZALC, OPC_BGEZALC */
12728 /* OPC_BGTZALC, OPC_BLTZALC */
12729 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12731 gen_load_gpr(t0, rs);
12732 gen_load_gpr(t1, rt);
12734 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12738 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12743 /* OPC_BEQZC, OPC_BNEZC */
12744 gen_load_gpr(t0, rs);
12746 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12748 /* OPC_JIC, OPC_JIALC */
12749 TCGv tbase = tcg_temp_new();
12750 TCGv toffset = tcg_temp_new();
12752 gen_load_gpr(tbase, rt);
12753 tcg_gen_movi_tl(toffset, offset);
12754 gen_op_addr_add(ctx, btarget, tbase, toffset);
12755 tcg_temp_free(tbase);
12756 tcg_temp_free(toffset);
12760 MIPS_INVAL("Compact branch/jump");
12761 generate_exception_end(ctx, EXCP_RI);
12765 if (bcond_compute == 0) {
12766 /* Uncoditional compact branch */
12769 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12772 ctx->hflags |= MIPS_HFLAG_BR;
12775 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12778 ctx->hflags |= MIPS_HFLAG_B;
12781 MIPS_INVAL("Compact branch/jump");
12782 generate_exception_end(ctx, EXCP_RI);
12786 /* Generating branch here as compact branches don't have delay slot */
12787 gen_branch(ctx, 4);
12789 /* Conditional compact branch */
12790 TCGLabel *fs = gen_new_label();
12791 save_cpu_state(ctx, 0);
12794 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12795 if (rs == 0 && rt != 0) {
12797 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12798 } else if (rs != 0 && rt != 0 && rs == rt) {
12800 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12803 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12806 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12807 if (rs == 0 && rt != 0) {
12809 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12810 } else if (rs != 0 && rt != 0 && rs == rt) {
12812 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12815 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12818 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12819 if (rs == 0 && rt != 0) {
12821 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12822 } else if (rs != 0 && rt != 0 && rs == rt) {
12824 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12827 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12830 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12831 if (rs == 0 && rt != 0) {
12833 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12834 } else if (rs != 0 && rt != 0 && rs == rt) {
12836 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12839 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12842 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12843 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12845 /* OPC_BOVC, OPC_BNVC */
12846 TCGv t2 = tcg_temp_new();
12847 TCGv t3 = tcg_temp_new();
12848 TCGv t4 = tcg_temp_new();
12849 TCGv input_overflow = tcg_temp_new();
12851 gen_load_gpr(t0, rs);
12852 gen_load_gpr(t1, rt);
12853 tcg_gen_ext32s_tl(t2, t0);
12854 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12855 tcg_gen_ext32s_tl(t3, t1);
12856 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12857 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12859 tcg_gen_add_tl(t4, t2, t3);
12860 tcg_gen_ext32s_tl(t4, t4);
12861 tcg_gen_xor_tl(t2, t2, t3);
12862 tcg_gen_xor_tl(t3, t4, t3);
12863 tcg_gen_andc_tl(t2, t3, t2);
12864 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12865 tcg_gen_or_tl(t4, t4, input_overflow);
12866 if (opc == OPC_BOVC) {
12868 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12871 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12873 tcg_temp_free(input_overflow);
12877 } else if (rs < rt && rs == 0) {
12878 /* OPC_BEQZALC, OPC_BNEZALC */
12879 if (opc == OPC_BEQZALC) {
12881 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12884 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12887 /* OPC_BEQC, OPC_BNEC */
12888 if (opc == OPC_BEQC) {
12890 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12893 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12898 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12901 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12904 MIPS_INVAL("Compact conditional branch/jump");
12905 generate_exception_end(ctx, EXCP_RI);
12909 /* Generating branch here as compact branches don't have delay slot */
12910 gen_goto_tb(ctx, 1, ctx->btarget);
12913 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12921 /* ISA extensions (ASEs) */
12922 /* MIPS16 extension to MIPS32 */
12924 /* MIPS16 major opcodes */
12926 M16_OPC_ADDIUSP = 0x00,
12927 M16_OPC_ADDIUPC = 0x01,
12929 M16_OPC_JAL = 0x03,
12930 M16_OPC_BEQZ = 0x04,
12931 M16_OPC_BNEQZ = 0x05,
12932 M16_OPC_SHIFT = 0x06,
12934 M16_OPC_RRIA = 0x08,
12935 M16_OPC_ADDIU8 = 0x09,
12936 M16_OPC_SLTI = 0x0a,
12937 M16_OPC_SLTIU = 0x0b,
12940 M16_OPC_CMPI = 0x0e,
12944 M16_OPC_LWSP = 0x12,
12946 M16_OPC_LBU = 0x14,
12947 M16_OPC_LHU = 0x15,
12948 M16_OPC_LWPC = 0x16,
12949 M16_OPC_LWU = 0x17,
12952 M16_OPC_SWSP = 0x1a,
12954 M16_OPC_RRR = 0x1c,
12956 M16_OPC_EXTEND = 0x1e,
12960 /* I8 funct field */
12979 /* RR funct field */
13013 /* I64 funct field */
13021 I64_DADDIUPC = 0x6,
13025 /* RR ry field for CNVT */
13027 RR_RY_CNVT_ZEB = 0x0,
13028 RR_RY_CNVT_ZEH = 0x1,
13029 RR_RY_CNVT_ZEW = 0x2,
13030 RR_RY_CNVT_SEB = 0x4,
13031 RR_RY_CNVT_SEH = 0x5,
13032 RR_RY_CNVT_SEW = 0x6,
13035 static int xlat (int r)
13037 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13042 static void gen_mips16_save (DisasContext *ctx,
13043 int xsregs, int aregs,
13044 int do_ra, int do_s0, int do_s1,
13047 TCGv t0 = tcg_temp_new();
13048 TCGv t1 = tcg_temp_new();
13049 TCGv t2 = tcg_temp_new();
13079 generate_exception_end(ctx, EXCP_RI);
13085 gen_base_offset_addr(ctx, t0, 29, 12);
13086 gen_load_gpr(t1, 7);
13087 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13090 gen_base_offset_addr(ctx, t0, 29, 8);
13091 gen_load_gpr(t1, 6);
13092 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13095 gen_base_offset_addr(ctx, t0, 29, 4);
13096 gen_load_gpr(t1, 5);
13097 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13100 gen_base_offset_addr(ctx, t0, 29, 0);
13101 gen_load_gpr(t1, 4);
13102 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13105 gen_load_gpr(t0, 29);
13107 #define DECR_AND_STORE(reg) do { \
13108 tcg_gen_movi_tl(t2, -4); \
13109 gen_op_addr_add(ctx, t0, t0, t2); \
13110 gen_load_gpr(t1, reg); \
13111 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13115 DECR_AND_STORE(31);
13120 DECR_AND_STORE(30);
13123 DECR_AND_STORE(23);
13126 DECR_AND_STORE(22);
13129 DECR_AND_STORE(21);
13132 DECR_AND_STORE(20);
13135 DECR_AND_STORE(19);
13138 DECR_AND_STORE(18);
13142 DECR_AND_STORE(17);
13145 DECR_AND_STORE(16);
13175 generate_exception_end(ctx, EXCP_RI);
13191 #undef DECR_AND_STORE
13193 tcg_gen_movi_tl(t2, -framesize);
13194 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13200 static void gen_mips16_restore (DisasContext *ctx,
13201 int xsregs, int aregs,
13202 int do_ra, int do_s0, int do_s1,
13206 TCGv t0 = tcg_temp_new();
13207 TCGv t1 = tcg_temp_new();
13208 TCGv t2 = tcg_temp_new();
13210 tcg_gen_movi_tl(t2, framesize);
13211 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13213 #define DECR_AND_LOAD(reg) do { \
13214 tcg_gen_movi_tl(t2, -4); \
13215 gen_op_addr_add(ctx, t0, t0, t2); \
13216 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13217 gen_store_gpr(t1, reg); \
13281 generate_exception_end(ctx, EXCP_RI);
13297 #undef DECR_AND_LOAD
13299 tcg_gen_movi_tl(t2, framesize);
13300 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13306 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13307 int is_64_bit, int extended)
13311 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13312 generate_exception_end(ctx, EXCP_RI);
13316 t0 = tcg_temp_new();
13318 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13319 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13321 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13327 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13330 TCGv_i32 t0 = tcg_const_i32(op);
13331 TCGv t1 = tcg_temp_new();
13332 gen_base_offset_addr(ctx, t1, base, offset);
13333 gen_helper_cache(cpu_env, t1, t0);
13336 #if defined(TARGET_MIPS64)
13337 static void decode_i64_mips16 (DisasContext *ctx,
13338 int ry, int funct, int16_t offset,
13343 check_insn(ctx, ISA_MIPS3);
13344 check_mips_64(ctx);
13345 offset = extended ? offset : offset << 3;
13346 gen_ld(ctx, OPC_LD, ry, 29, offset);
13349 check_insn(ctx, ISA_MIPS3);
13350 check_mips_64(ctx);
13351 offset = extended ? offset : offset << 3;
13352 gen_st(ctx, OPC_SD, ry, 29, offset);
13355 check_insn(ctx, ISA_MIPS3);
13356 check_mips_64(ctx);
13357 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13358 gen_st(ctx, OPC_SD, 31, 29, offset);
13361 check_insn(ctx, ISA_MIPS3);
13362 check_mips_64(ctx);
13363 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13364 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13367 check_insn(ctx, ISA_MIPS3);
13368 check_mips_64(ctx);
13369 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13370 generate_exception_end(ctx, EXCP_RI);
13372 offset = extended ? offset : offset << 3;
13373 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13377 check_insn(ctx, ISA_MIPS3);
13378 check_mips_64(ctx);
13379 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13380 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13383 check_insn(ctx, ISA_MIPS3);
13384 check_mips_64(ctx);
13385 offset = extended ? offset : offset << 2;
13386 gen_addiupc(ctx, ry, offset, 1, extended);
13389 check_insn(ctx, ISA_MIPS3);
13390 check_mips_64(ctx);
13391 offset = extended ? offset : offset << 2;
13392 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13398 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13400 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13401 int op, rx, ry, funct, sa;
13402 int16_t imm, offset;
13404 ctx->opcode = (ctx->opcode << 16) | extend;
13405 op = (ctx->opcode >> 11) & 0x1f;
13406 sa = (ctx->opcode >> 22) & 0x1f;
13407 funct = (ctx->opcode >> 8) & 0x7;
13408 rx = xlat((ctx->opcode >> 8) & 0x7);
13409 ry = xlat((ctx->opcode >> 5) & 0x7);
13410 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13411 | ((ctx->opcode >> 21) & 0x3f) << 5
13412 | (ctx->opcode & 0x1f));
13414 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13417 case M16_OPC_ADDIUSP:
13418 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13420 case M16_OPC_ADDIUPC:
13421 gen_addiupc(ctx, rx, imm, 0, 1);
13424 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13425 /* No delay slot, so just process as a normal instruction */
13428 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13429 /* No delay slot, so just process as a normal instruction */
13431 case M16_OPC_BNEQZ:
13432 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13433 /* No delay slot, so just process as a normal instruction */
13435 case M16_OPC_SHIFT:
13436 switch (ctx->opcode & 0x3) {
13438 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13441 #if defined(TARGET_MIPS64)
13442 check_mips_64(ctx);
13443 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13445 generate_exception_end(ctx, EXCP_RI);
13449 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13452 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13456 #if defined(TARGET_MIPS64)
13458 check_insn(ctx, ISA_MIPS3);
13459 check_mips_64(ctx);
13460 gen_ld(ctx, OPC_LD, ry, rx, offset);
13464 imm = ctx->opcode & 0xf;
13465 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13466 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13467 imm = (int16_t) (imm << 1) >> 1;
13468 if ((ctx->opcode >> 4) & 0x1) {
13469 #if defined(TARGET_MIPS64)
13470 check_mips_64(ctx);
13471 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13473 generate_exception_end(ctx, EXCP_RI);
13476 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13479 case M16_OPC_ADDIU8:
13480 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13483 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13485 case M16_OPC_SLTIU:
13486 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13491 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13494 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13497 gen_st(ctx, OPC_SW, 31, 29, imm);
13500 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13503 check_insn(ctx, ISA_MIPS32);
13505 int xsregs = (ctx->opcode >> 24) & 0x7;
13506 int aregs = (ctx->opcode >> 16) & 0xf;
13507 int do_ra = (ctx->opcode >> 6) & 0x1;
13508 int do_s0 = (ctx->opcode >> 5) & 0x1;
13509 int do_s1 = (ctx->opcode >> 4) & 0x1;
13510 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13511 | (ctx->opcode & 0xf)) << 3;
13513 if (ctx->opcode & (1 << 7)) {
13514 gen_mips16_save(ctx, xsregs, aregs,
13515 do_ra, do_s0, do_s1,
13518 gen_mips16_restore(ctx, xsregs, aregs,
13519 do_ra, do_s0, do_s1,
13525 generate_exception_end(ctx, EXCP_RI);
13530 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13533 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13535 #if defined(TARGET_MIPS64)
13537 check_insn(ctx, ISA_MIPS3);
13538 check_mips_64(ctx);
13539 gen_st(ctx, OPC_SD, ry, rx, offset);
13543 gen_ld(ctx, OPC_LB, ry, rx, offset);
13546 gen_ld(ctx, OPC_LH, ry, rx, offset);
13549 gen_ld(ctx, OPC_LW, rx, 29, offset);
13552 gen_ld(ctx, OPC_LW, ry, rx, offset);
13555 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13558 gen_ld(ctx, OPC_LHU, ry, rx, offset);
13561 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13563 #if defined(TARGET_MIPS64)
13565 check_insn(ctx, ISA_MIPS3);
13566 check_mips_64(ctx);
13567 gen_ld(ctx, OPC_LWU, ry, rx, offset);
13571 gen_st(ctx, OPC_SB, ry, rx, offset);
13574 gen_st(ctx, OPC_SH, ry, rx, offset);
13577 gen_st(ctx, OPC_SW, rx, 29, offset);
13580 gen_st(ctx, OPC_SW, ry, rx, offset);
13582 #if defined(TARGET_MIPS64)
13584 decode_i64_mips16(ctx, ry, funct, offset, 1);
13588 generate_exception_end(ctx, EXCP_RI);
13595 static inline bool is_uhi(int sdbbp_code)
13597 #ifdef CONFIG_USER_ONLY
13600 return semihosting_enabled() && sdbbp_code == 1;
13604 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13608 int op, cnvt_op, op1, offset;
13612 op = (ctx->opcode >> 11) & 0x1f;
13613 sa = (ctx->opcode >> 2) & 0x7;
13614 sa = sa == 0 ? 8 : sa;
13615 rx = xlat((ctx->opcode >> 8) & 0x7);
13616 cnvt_op = (ctx->opcode >> 5) & 0x7;
13617 ry = xlat((ctx->opcode >> 5) & 0x7);
13618 op1 = offset = ctx->opcode & 0x1f;
13623 case M16_OPC_ADDIUSP:
13625 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13627 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13630 case M16_OPC_ADDIUPC:
13631 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13634 offset = (ctx->opcode & 0x7ff) << 1;
13635 offset = (int16_t)(offset << 4) >> 4;
13636 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13637 /* No delay slot, so just process as a normal instruction */
13640 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13641 offset = (((ctx->opcode & 0x1f) << 21)
13642 | ((ctx->opcode >> 5) & 0x1f) << 16
13644 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13645 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13649 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13650 ((int8_t)ctx->opcode) << 1, 0);
13651 /* No delay slot, so just process as a normal instruction */
13653 case M16_OPC_BNEQZ:
13654 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13655 ((int8_t)ctx->opcode) << 1, 0);
13656 /* No delay slot, so just process as a normal instruction */
13658 case M16_OPC_SHIFT:
13659 switch (ctx->opcode & 0x3) {
13661 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13664 #if defined(TARGET_MIPS64)
13665 check_insn(ctx, ISA_MIPS3);
13666 check_mips_64(ctx);
13667 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13669 generate_exception_end(ctx, EXCP_RI);
13673 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13676 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13680 #if defined(TARGET_MIPS64)
13682 check_insn(ctx, ISA_MIPS3);
13683 check_mips_64(ctx);
13684 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13689 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13691 if ((ctx->opcode >> 4) & 1) {
13692 #if defined(TARGET_MIPS64)
13693 check_insn(ctx, ISA_MIPS3);
13694 check_mips_64(ctx);
13695 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13697 generate_exception_end(ctx, EXCP_RI);
13700 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13704 case M16_OPC_ADDIU8:
13706 int16_t imm = (int8_t) ctx->opcode;
13708 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13713 int16_t imm = (uint8_t) ctx->opcode;
13714 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13717 case M16_OPC_SLTIU:
13719 int16_t imm = (uint8_t) ctx->opcode;
13720 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13727 funct = (ctx->opcode >> 8) & 0x7;
13730 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13731 ((int8_t)ctx->opcode) << 1, 0);
13734 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13735 ((int8_t)ctx->opcode) << 1, 0);
13738 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13741 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13742 ((int8_t)ctx->opcode) << 3);
13745 check_insn(ctx, ISA_MIPS32);
13747 int do_ra = ctx->opcode & (1 << 6);
13748 int do_s0 = ctx->opcode & (1 << 5);
13749 int do_s1 = ctx->opcode & (1 << 4);
13750 int framesize = ctx->opcode & 0xf;
13752 if (framesize == 0) {
13755 framesize = framesize << 3;
13758 if (ctx->opcode & (1 << 7)) {
13759 gen_mips16_save(ctx, 0, 0,
13760 do_ra, do_s0, do_s1, framesize);
13762 gen_mips16_restore(ctx, 0, 0,
13763 do_ra, do_s0, do_s1, framesize);
13769 int rz = xlat(ctx->opcode & 0x7);
13771 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13772 ((ctx->opcode >> 5) & 0x7);
13773 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13777 reg32 = ctx->opcode & 0x1f;
13778 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13781 generate_exception_end(ctx, EXCP_RI);
13788 int16_t imm = (uint8_t) ctx->opcode;
13790 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13795 int16_t imm = (uint8_t) ctx->opcode;
13796 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13799 #if defined(TARGET_MIPS64)
13801 check_insn(ctx, ISA_MIPS3);
13802 check_mips_64(ctx);
13803 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13807 gen_ld(ctx, OPC_LB, ry, rx, offset);
13810 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13813 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13816 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13819 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13822 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13825 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13827 #if defined (TARGET_MIPS64)
13829 check_insn(ctx, ISA_MIPS3);
13830 check_mips_64(ctx);
13831 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13835 gen_st(ctx, OPC_SB, ry, rx, offset);
13838 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13841 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13844 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13848 int rz = xlat((ctx->opcode >> 2) & 0x7);
13851 switch (ctx->opcode & 0x3) {
13853 mips32_op = OPC_ADDU;
13856 mips32_op = OPC_SUBU;
13858 #if defined(TARGET_MIPS64)
13860 mips32_op = OPC_DADDU;
13861 check_insn(ctx, ISA_MIPS3);
13862 check_mips_64(ctx);
13865 mips32_op = OPC_DSUBU;
13866 check_insn(ctx, ISA_MIPS3);
13867 check_mips_64(ctx);
13871 generate_exception_end(ctx, EXCP_RI);
13875 gen_arith(ctx, mips32_op, rz, rx, ry);
13884 int nd = (ctx->opcode >> 7) & 0x1;
13885 int link = (ctx->opcode >> 6) & 0x1;
13886 int ra = (ctx->opcode >> 5) & 0x1;
13889 check_insn(ctx, ISA_MIPS32);
13898 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13903 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13904 gen_helper_do_semihosting(cpu_env);
13906 /* XXX: not clear which exception should be raised
13907 * when in debug mode...
13909 check_insn(ctx, ISA_MIPS32);
13910 generate_exception_end(ctx, EXCP_DBp);
13914 gen_slt(ctx, OPC_SLT, 24, rx, ry);
13917 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13920 generate_exception_end(ctx, EXCP_BREAK);
13923 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13926 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13929 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13931 #if defined (TARGET_MIPS64)
13933 check_insn(ctx, ISA_MIPS3);
13934 check_mips_64(ctx);
13935 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13939 gen_logic(ctx, OPC_XOR, 24, rx, ry);
13942 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13945 gen_logic(ctx, OPC_AND, rx, rx, ry);
13948 gen_logic(ctx, OPC_OR, rx, rx, ry);
13951 gen_logic(ctx, OPC_XOR, rx, rx, ry);
13954 gen_logic(ctx, OPC_NOR, rx, ry, 0);
13957 gen_HILO(ctx, OPC_MFHI, 0, rx);
13960 check_insn(ctx, ISA_MIPS32);
13962 case RR_RY_CNVT_ZEB:
13963 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13965 case RR_RY_CNVT_ZEH:
13966 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13968 case RR_RY_CNVT_SEB:
13969 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13971 case RR_RY_CNVT_SEH:
13972 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13974 #if defined (TARGET_MIPS64)
13975 case RR_RY_CNVT_ZEW:
13976 check_insn(ctx, ISA_MIPS64);
13977 check_mips_64(ctx);
13978 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13980 case RR_RY_CNVT_SEW:
13981 check_insn(ctx, ISA_MIPS64);
13982 check_mips_64(ctx);
13983 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13987 generate_exception_end(ctx, EXCP_RI);
13992 gen_HILO(ctx, OPC_MFLO, 0, rx);
13994 #if defined (TARGET_MIPS64)
13996 check_insn(ctx, ISA_MIPS3);
13997 check_mips_64(ctx);
13998 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14001 check_insn(ctx, ISA_MIPS3);
14002 check_mips_64(ctx);
14003 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14006 check_insn(ctx, ISA_MIPS3);
14007 check_mips_64(ctx);
14008 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14011 check_insn(ctx, ISA_MIPS3);
14012 check_mips_64(ctx);
14013 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14017 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14020 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14023 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14026 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14028 #if defined (TARGET_MIPS64)
14030 check_insn(ctx, ISA_MIPS3);
14031 check_mips_64(ctx);
14032 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14035 check_insn(ctx, ISA_MIPS3);
14036 check_mips_64(ctx);
14037 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14040 check_insn(ctx, ISA_MIPS3);
14041 check_mips_64(ctx);
14042 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14045 check_insn(ctx, ISA_MIPS3);
14046 check_mips_64(ctx);
14047 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14051 generate_exception_end(ctx, EXCP_RI);
14055 case M16_OPC_EXTEND:
14056 decode_extended_mips16_opc(env, ctx);
14059 #if defined(TARGET_MIPS64)
14061 funct = (ctx->opcode >> 8) & 0x7;
14062 decode_i64_mips16(ctx, ry, funct, offset, 0);
14066 generate_exception_end(ctx, EXCP_RI);
14073 /* microMIPS extension to MIPS32/MIPS64 */
14076 * microMIPS32/microMIPS64 major opcodes
14078 * 1. MIPS Architecture for Programmers Volume II-B:
14079 * The microMIPS32 Instruction Set (Revision 3.05)
14081 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14083 * 2. MIPS Architecture For Programmers Volume II-A:
14084 * The MIPS64 Instruction Set (Revision 3.51)
14114 POOL32S = 0x16, /* MIPS64 */
14115 DADDIU32 = 0x17, /* MIPS64 */
14144 /* 0x29 is reserved */
14157 /* 0x31 is reserved */
14170 SD32 = 0x36, /* MIPS64 */
14171 LD32 = 0x37, /* MIPS64 */
14173 /* 0x39 is reserved */
14189 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14211 /* POOL32A encoding of minor opcode field */
14214 /* These opcodes are distinguished only by bits 9..6; those bits are
14215 * what are recorded below. */
14252 /* The following can be distinguished by their lower 6 bits. */
14262 /* POOL32AXF encoding of minor opcode field extension */
14265 * 1. MIPS Architecture for Programmers Volume II-B:
14266 * The microMIPS32 Instruction Set (Revision 3.05)
14268 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14270 * 2. MIPS Architecture for Programmers VolumeIV-e:
14271 * The MIPS DSP Application-Specific Extension
14272 * to the microMIPS32 Architecture (Revision 2.34)
14274 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14289 /* begin of microMIPS32 DSP */
14291 /* bits 13..12 for 0x01 */
14297 /* bits 13..12 for 0x2a */
14303 /* bits 13..12 for 0x32 */
14307 /* end of microMIPS32 DSP */
14309 /* bits 15..12 for 0x2c */
14326 /* bits 15..12 for 0x34 */
14334 /* bits 15..12 for 0x3c */
14336 JR = 0x0, /* alias */
14344 /* bits 15..12 for 0x05 */
14348 /* bits 15..12 for 0x0d */
14360 /* bits 15..12 for 0x15 */
14366 /* bits 15..12 for 0x1d */
14370 /* bits 15..12 for 0x2d */
14375 /* bits 15..12 for 0x35 */
14382 /* POOL32B encoding of minor opcode field (bits 15..12) */
14398 /* POOL32C encoding of minor opcode field (bits 15..12) */
14419 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14432 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14445 /* POOL32F encoding of minor opcode field (bits 5..0) */
14448 /* These are the bit 7..6 values */
14457 /* These are the bit 8..6 values */
14482 MOVZ_FMT_05 = 0x05,
14516 CABS_COND_FMT = 0x1c, /* MIPS3D */
14523 /* POOL32Fxf encoding of minor opcode extension field */
14561 /* POOL32I encoding of minor opcode field (bits 25..21) */
14591 /* These overlap and are distinguished by bit16 of the instruction */
14600 /* POOL16A encoding of minor opcode field */
14607 /* POOL16B encoding of minor opcode field */
14614 /* POOL16C encoding of minor opcode field */
14634 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14658 /* POOL16D encoding of minor opcode field */
14665 /* POOL16E encoding of minor opcode field */
14672 static int mmreg (int r)
14674 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14679 /* Used for 16-bit store instructions. */
14680 static int mmreg2 (int r)
14682 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14687 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14688 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14689 #define uMIPS_RS2(op) uMIPS_RS(op)
14690 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14691 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14692 #define uMIPS_RS5(op) (op & 0x1f)
14694 /* Signed immediate */
14695 #define SIMM(op, start, width) \
14696 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14699 /* Zero-extended immediate */
14700 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14702 static void gen_addiur1sp(DisasContext *ctx)
14704 int rd = mmreg(uMIPS_RD(ctx->opcode));
14706 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14709 static void gen_addiur2(DisasContext *ctx)
14711 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14712 int rd = mmreg(uMIPS_RD(ctx->opcode));
14713 int rs = mmreg(uMIPS_RS(ctx->opcode));
14715 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14718 static void gen_addiusp(DisasContext *ctx)
14720 int encoded = ZIMM(ctx->opcode, 1, 9);
14723 if (encoded <= 1) {
14724 decoded = 256 + encoded;
14725 } else if (encoded <= 255) {
14727 } else if (encoded <= 509) {
14728 decoded = encoded - 512;
14730 decoded = encoded - 768;
14733 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14736 static void gen_addius5(DisasContext *ctx)
14738 int imm = SIMM(ctx->opcode, 1, 4);
14739 int rd = (ctx->opcode >> 5) & 0x1f;
14741 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14744 static void gen_andi16(DisasContext *ctx)
14746 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14747 31, 32, 63, 64, 255, 32768, 65535 };
14748 int rd = mmreg(uMIPS_RD(ctx->opcode));
14749 int rs = mmreg(uMIPS_RS(ctx->opcode));
14750 int encoded = ZIMM(ctx->opcode, 0, 4);
14752 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14755 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14756 int base, int16_t offset)
14761 if (ctx->hflags & MIPS_HFLAG_BMASK) {
14762 generate_exception_end(ctx, EXCP_RI);
14766 t0 = tcg_temp_new();
14768 gen_base_offset_addr(ctx, t0, base, offset);
14770 t1 = tcg_const_tl(reglist);
14771 t2 = tcg_const_i32(ctx->mem_idx);
14773 save_cpu_state(ctx, 1);
14776 gen_helper_lwm(cpu_env, t0, t1, t2);
14779 gen_helper_swm(cpu_env, t0, t1, t2);
14781 #ifdef TARGET_MIPS64
14783 gen_helper_ldm(cpu_env, t0, t1, t2);
14786 gen_helper_sdm(cpu_env, t0, t1, t2);
14792 tcg_temp_free_i32(t2);
14796 static void gen_pool16c_insn(DisasContext *ctx)
14798 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14799 int rs = mmreg(ctx->opcode & 0x7);
14801 switch (((ctx->opcode) >> 4) & 0x3f) {
14806 gen_logic(ctx, OPC_NOR, rd, rs, 0);
14812 gen_logic(ctx, OPC_XOR, rd, rd, rs);
14818 gen_logic(ctx, OPC_AND, rd, rd, rs);
14824 gen_logic(ctx, OPC_OR, rd, rd, rs);
14831 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14832 int offset = ZIMM(ctx->opcode, 0, 4);
14834 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14843 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14844 int offset = ZIMM(ctx->opcode, 0, 4);
14846 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14853 int reg = ctx->opcode & 0x1f;
14855 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14861 int reg = ctx->opcode & 0x1f;
14862 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14863 /* Let normal delay slot handling in our caller take us
14864 to the branch target. */
14869 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14870 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14874 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14875 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14879 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14883 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14886 generate_exception_end(ctx, EXCP_BREAK);
14889 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14890 gen_helper_do_semihosting(cpu_env);
14892 /* XXX: not clear which exception should be raised
14893 * when in debug mode...
14895 check_insn(ctx, ISA_MIPS32);
14896 generate_exception_end(ctx, EXCP_DBp);
14899 case JRADDIUSP + 0:
14900 case JRADDIUSP + 1:
14902 int imm = ZIMM(ctx->opcode, 0, 5);
14903 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14904 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14905 /* Let normal delay slot handling in our caller take us
14906 to the branch target. */
14910 generate_exception_end(ctx, EXCP_RI);
14915 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14918 int rd, rs, re, rt;
14919 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14920 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14921 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14922 rd = rd_enc[enc_dest];
14923 re = re_enc[enc_dest];
14924 rs = rs_rt_enc[enc_rs];
14925 rt = rs_rt_enc[enc_rt];
14927 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14929 tcg_gen_movi_tl(cpu_gpr[rd], 0);
14932 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14934 tcg_gen_movi_tl(cpu_gpr[re], 0);
14938 static void gen_pool16c_r6_insn(DisasContext *ctx)
14940 int rt = mmreg((ctx->opcode >> 7) & 0x7);
14941 int rs = mmreg((ctx->opcode >> 4) & 0x7);
14943 switch (ctx->opcode & 0xf) {
14945 gen_logic(ctx, OPC_NOR, rt, rs, 0);
14948 gen_logic(ctx, OPC_AND, rt, rt, rs);
14952 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14953 int offset = extract32(ctx->opcode, 4, 4);
14954 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14957 case R6_JRC16: /* JRCADDIUSP */
14958 if ((ctx->opcode >> 4) & 1) {
14960 int imm = extract32(ctx->opcode, 5, 5);
14961 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14962 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14965 rs = extract32(ctx->opcode, 5, 5);
14966 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14978 int enc_dest = uMIPS_RD(ctx->opcode);
14979 int enc_rt = uMIPS_RS2(ctx->opcode);
14980 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14981 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14985 gen_logic(ctx, OPC_XOR, rt, rt, rs);
14988 gen_logic(ctx, OPC_OR, rt, rt, rs);
14992 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14993 int offset = extract32(ctx->opcode, 4, 4);
14994 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14997 case JALRC16: /* BREAK16, SDBBP16 */
14998 switch (ctx->opcode & 0x3f) {
15000 case JALRC16 + 0x20:
15002 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15007 generate_exception(ctx, EXCP_BREAK);
15011 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15012 gen_helper_do_semihosting(cpu_env);
15014 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15015 generate_exception(ctx, EXCP_RI);
15017 generate_exception(ctx, EXCP_DBp);
15024 generate_exception(ctx, EXCP_RI);
15029 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15031 TCGv t0 = tcg_temp_new();
15032 TCGv t1 = tcg_temp_new();
15034 gen_load_gpr(t0, base);
15037 gen_load_gpr(t1, index);
15038 tcg_gen_shli_tl(t1, t1, 2);
15039 gen_op_addr_add(ctx, t0, t1, t0);
15042 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15043 gen_store_gpr(t1, rd);
15049 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15050 int base, int16_t offset)
15054 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15055 generate_exception_end(ctx, EXCP_RI);
15059 t0 = tcg_temp_new();
15060 t1 = tcg_temp_new();
15062 gen_base_offset_addr(ctx, t0, base, offset);
15067 generate_exception_end(ctx, EXCP_RI);
15070 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15071 gen_store_gpr(t1, rd);
15072 tcg_gen_movi_tl(t1, 4);
15073 gen_op_addr_add(ctx, t0, t0, t1);
15074 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15075 gen_store_gpr(t1, rd+1);
15078 gen_load_gpr(t1, rd);
15079 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15080 tcg_gen_movi_tl(t1, 4);
15081 gen_op_addr_add(ctx, t0, t0, t1);
15082 gen_load_gpr(t1, rd+1);
15083 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15085 #ifdef TARGET_MIPS64
15088 generate_exception_end(ctx, EXCP_RI);
15091 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15092 gen_store_gpr(t1, rd);
15093 tcg_gen_movi_tl(t1, 8);
15094 gen_op_addr_add(ctx, t0, t0, t1);
15095 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15096 gen_store_gpr(t1, rd+1);
15099 gen_load_gpr(t1, rd);
15100 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15101 tcg_gen_movi_tl(t1, 8);
15102 gen_op_addr_add(ctx, t0, t0, t1);
15103 gen_load_gpr(t1, rd+1);
15104 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15112 static void gen_sync(int stype)
15114 TCGBar tcg_mo = TCG_BAR_SC;
15117 case 0x4: /* SYNC_WMB */
15118 tcg_mo |= TCG_MO_ST_ST;
15120 case 0x10: /* SYNC_MB */
15121 tcg_mo |= TCG_MO_ALL;
15123 case 0x11: /* SYNC_ACQUIRE */
15124 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15126 case 0x12: /* SYNC_RELEASE */
15127 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15129 case 0x13: /* SYNC_RMB */
15130 tcg_mo |= TCG_MO_LD_LD;
15133 tcg_mo |= TCG_MO_ALL;
15137 tcg_gen_mb(tcg_mo);
15140 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15142 int extension = (ctx->opcode >> 6) & 0x3f;
15143 int minor = (ctx->opcode >> 12) & 0xf;
15144 uint32_t mips32_op;
15146 switch (extension) {
15148 mips32_op = OPC_TEQ;
15151 mips32_op = OPC_TGE;
15154 mips32_op = OPC_TGEU;
15157 mips32_op = OPC_TLT;
15160 mips32_op = OPC_TLTU;
15163 mips32_op = OPC_TNE;
15165 gen_trap(ctx, mips32_op, rs, rt, -1);
15167 #ifndef CONFIG_USER_ONLY
15170 check_cp0_enabled(ctx);
15172 /* Treat as NOP. */
15175 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15179 check_cp0_enabled(ctx);
15181 TCGv t0 = tcg_temp_new();
15183 gen_load_gpr(t0, rt);
15184 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15190 switch (minor & 3) {
15192 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15195 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15198 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15201 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15204 goto pool32axf_invalid;
15208 switch (minor & 3) {
15210 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15213 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15216 goto pool32axf_invalid;
15222 check_insn(ctx, ISA_MIPS32R6);
15223 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15226 gen_bshfl(ctx, OPC_SEB, rs, rt);
15229 gen_bshfl(ctx, OPC_SEH, rs, rt);
15232 mips32_op = OPC_CLO;
15235 mips32_op = OPC_CLZ;
15237 check_insn(ctx, ISA_MIPS32);
15238 gen_cl(ctx, mips32_op, rt, rs);
15241 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15242 gen_rdhwr(ctx, rt, rs, 0);
15245 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15248 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15249 mips32_op = OPC_MULT;
15252 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15253 mips32_op = OPC_MULTU;
15256 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15257 mips32_op = OPC_DIV;
15260 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15261 mips32_op = OPC_DIVU;
15264 check_insn(ctx, ISA_MIPS32);
15265 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15268 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15269 mips32_op = OPC_MADD;
15272 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15273 mips32_op = OPC_MADDU;
15276 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15277 mips32_op = OPC_MSUB;
15280 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15281 mips32_op = OPC_MSUBU;
15283 check_insn(ctx, ISA_MIPS32);
15284 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15287 goto pool32axf_invalid;
15298 generate_exception_err(ctx, EXCP_CpU, 2);
15301 goto pool32axf_invalid;
15306 case JALR: /* JALRC */
15307 case JALR_HB: /* JALRC_HB */
15308 if (ctx->insn_flags & ISA_MIPS32R6) {
15309 /* JALRC, JALRC_HB */
15310 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15312 /* JALR, JALR_HB */
15313 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15314 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15319 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15320 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15321 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15324 goto pool32axf_invalid;
15330 check_cp0_enabled(ctx);
15331 check_insn(ctx, ISA_MIPS32R2);
15332 gen_load_srsgpr(rs, rt);
15335 check_cp0_enabled(ctx);
15336 check_insn(ctx, ISA_MIPS32R2);
15337 gen_store_srsgpr(rs, rt);
15340 goto pool32axf_invalid;
15343 #ifndef CONFIG_USER_ONLY
15347 mips32_op = OPC_TLBP;
15350 mips32_op = OPC_TLBR;
15353 mips32_op = OPC_TLBWI;
15356 mips32_op = OPC_TLBWR;
15359 mips32_op = OPC_TLBINV;
15362 mips32_op = OPC_TLBINVF;
15365 mips32_op = OPC_WAIT;
15368 mips32_op = OPC_DERET;
15371 mips32_op = OPC_ERET;
15373 gen_cp0(env, ctx, mips32_op, rt, rs);
15376 goto pool32axf_invalid;
15382 check_cp0_enabled(ctx);
15384 TCGv t0 = tcg_temp_new();
15386 save_cpu_state(ctx, 1);
15387 gen_helper_di(t0, cpu_env);
15388 gen_store_gpr(t0, rs);
15389 /* Stop translation as we may have switched the execution mode */
15390 ctx->base.is_jmp = DISAS_STOP;
15395 check_cp0_enabled(ctx);
15397 TCGv t0 = tcg_temp_new();
15399 save_cpu_state(ctx, 1);
15400 gen_helper_ei(t0, cpu_env);
15401 gen_store_gpr(t0, rs);
15402 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15403 of translated code to check for pending interrupts. */
15404 gen_save_pc(ctx->base.pc_next + 4);
15405 ctx->base.is_jmp = DISAS_EXIT;
15410 goto pool32axf_invalid;
15417 gen_sync(extract32(ctx->opcode, 16, 5));
15420 generate_exception_end(ctx, EXCP_SYSCALL);
15423 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15424 gen_helper_do_semihosting(cpu_env);
15426 check_insn(ctx, ISA_MIPS32);
15427 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15428 generate_exception_end(ctx, EXCP_RI);
15430 generate_exception_end(ctx, EXCP_DBp);
15435 goto pool32axf_invalid;
15439 switch (minor & 3) {
15441 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15444 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15447 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15450 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15453 goto pool32axf_invalid;
15457 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15460 gen_HILO(ctx, OPC_MFHI, 0, rs);
15463 gen_HILO(ctx, OPC_MFLO, 0, rs);
15466 gen_HILO(ctx, OPC_MTHI, 0, rs);
15469 gen_HILO(ctx, OPC_MTLO, 0, rs);
15472 goto pool32axf_invalid;
15477 MIPS_INVAL("pool32axf");
15478 generate_exception_end(ctx, EXCP_RI);
15483 /* Values for microMIPS fmt field. Variable-width, depending on which
15484 formats the instruction supports. */
15503 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15505 int extension = (ctx->opcode >> 6) & 0x3ff;
15506 uint32_t mips32_op;
15508 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15509 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15510 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15512 switch (extension) {
15513 case FLOAT_1BIT_FMT(CFC1, 0):
15514 mips32_op = OPC_CFC1;
15516 case FLOAT_1BIT_FMT(CTC1, 0):
15517 mips32_op = OPC_CTC1;
15519 case FLOAT_1BIT_FMT(MFC1, 0):
15520 mips32_op = OPC_MFC1;
15522 case FLOAT_1BIT_FMT(MTC1, 0):
15523 mips32_op = OPC_MTC1;
15525 case FLOAT_1BIT_FMT(MFHC1, 0):
15526 mips32_op = OPC_MFHC1;
15528 case FLOAT_1BIT_FMT(MTHC1, 0):
15529 mips32_op = OPC_MTHC1;
15531 gen_cp1(ctx, mips32_op, rt, rs);
15534 /* Reciprocal square root */
15535 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15536 mips32_op = OPC_RSQRT_S;
15538 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15539 mips32_op = OPC_RSQRT_D;
15543 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15544 mips32_op = OPC_SQRT_S;
15546 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15547 mips32_op = OPC_SQRT_D;
15551 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15552 mips32_op = OPC_RECIP_S;
15554 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15555 mips32_op = OPC_RECIP_D;
15559 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15560 mips32_op = OPC_FLOOR_L_S;
15562 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15563 mips32_op = OPC_FLOOR_L_D;
15565 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15566 mips32_op = OPC_FLOOR_W_S;
15568 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15569 mips32_op = OPC_FLOOR_W_D;
15573 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15574 mips32_op = OPC_CEIL_L_S;
15576 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15577 mips32_op = OPC_CEIL_L_D;
15579 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15580 mips32_op = OPC_CEIL_W_S;
15582 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15583 mips32_op = OPC_CEIL_W_D;
15587 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15588 mips32_op = OPC_TRUNC_L_S;
15590 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15591 mips32_op = OPC_TRUNC_L_D;
15593 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15594 mips32_op = OPC_TRUNC_W_S;
15596 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15597 mips32_op = OPC_TRUNC_W_D;
15601 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15602 mips32_op = OPC_ROUND_L_S;
15604 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15605 mips32_op = OPC_ROUND_L_D;
15607 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15608 mips32_op = OPC_ROUND_W_S;
15610 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15611 mips32_op = OPC_ROUND_W_D;
15614 /* Integer to floating-point conversion */
15615 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15616 mips32_op = OPC_CVT_L_S;
15618 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15619 mips32_op = OPC_CVT_L_D;
15621 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15622 mips32_op = OPC_CVT_W_S;
15624 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15625 mips32_op = OPC_CVT_W_D;
15628 /* Paired-foo conversions */
15629 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15630 mips32_op = OPC_CVT_S_PL;
15632 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15633 mips32_op = OPC_CVT_S_PU;
15635 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15636 mips32_op = OPC_CVT_PW_PS;
15638 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15639 mips32_op = OPC_CVT_PS_PW;
15642 /* Floating-point moves */
15643 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15644 mips32_op = OPC_MOV_S;
15646 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15647 mips32_op = OPC_MOV_D;
15649 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15650 mips32_op = OPC_MOV_PS;
15653 /* Absolute value */
15654 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15655 mips32_op = OPC_ABS_S;
15657 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15658 mips32_op = OPC_ABS_D;
15660 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15661 mips32_op = OPC_ABS_PS;
15665 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15666 mips32_op = OPC_NEG_S;
15668 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15669 mips32_op = OPC_NEG_D;
15671 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15672 mips32_op = OPC_NEG_PS;
15675 /* Reciprocal square root step */
15676 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15677 mips32_op = OPC_RSQRT1_S;
15679 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15680 mips32_op = OPC_RSQRT1_D;
15682 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15683 mips32_op = OPC_RSQRT1_PS;
15686 /* Reciprocal step */
15687 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15688 mips32_op = OPC_RECIP1_S;
15690 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15691 mips32_op = OPC_RECIP1_S;
15693 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15694 mips32_op = OPC_RECIP1_PS;
15697 /* Conversions from double */
15698 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15699 mips32_op = OPC_CVT_D_S;
15701 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15702 mips32_op = OPC_CVT_D_W;
15704 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15705 mips32_op = OPC_CVT_D_L;
15708 /* Conversions from single */
15709 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15710 mips32_op = OPC_CVT_S_D;
15712 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15713 mips32_op = OPC_CVT_S_W;
15715 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15716 mips32_op = OPC_CVT_S_L;
15718 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15721 /* Conditional moves on floating-point codes */
15722 case COND_FLOAT_MOV(MOVT, 0):
15723 case COND_FLOAT_MOV(MOVT, 1):
15724 case COND_FLOAT_MOV(MOVT, 2):
15725 case COND_FLOAT_MOV(MOVT, 3):
15726 case COND_FLOAT_MOV(MOVT, 4):
15727 case COND_FLOAT_MOV(MOVT, 5):
15728 case COND_FLOAT_MOV(MOVT, 6):
15729 case COND_FLOAT_MOV(MOVT, 7):
15730 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15731 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15733 case COND_FLOAT_MOV(MOVF, 0):
15734 case COND_FLOAT_MOV(MOVF, 1):
15735 case COND_FLOAT_MOV(MOVF, 2):
15736 case COND_FLOAT_MOV(MOVF, 3):
15737 case COND_FLOAT_MOV(MOVF, 4):
15738 case COND_FLOAT_MOV(MOVF, 5):
15739 case COND_FLOAT_MOV(MOVF, 6):
15740 case COND_FLOAT_MOV(MOVF, 7):
15741 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15742 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15745 MIPS_INVAL("pool32fxf");
15746 generate_exception_end(ctx, EXCP_RI);
15751 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15755 int rt, rs, rd, rr;
15757 uint32_t op, minor, minor2, mips32_op;
15758 uint32_t cond, fmt, cc;
15760 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15761 ctx->opcode = (ctx->opcode << 16) | insn;
15763 rt = (ctx->opcode >> 21) & 0x1f;
15764 rs = (ctx->opcode >> 16) & 0x1f;
15765 rd = (ctx->opcode >> 11) & 0x1f;
15766 rr = (ctx->opcode >> 6) & 0x1f;
15767 imm = (int16_t) ctx->opcode;
15769 op = (ctx->opcode >> 26) & 0x3f;
15772 minor = ctx->opcode & 0x3f;
15775 minor = (ctx->opcode >> 6) & 0xf;
15778 mips32_op = OPC_SLL;
15781 mips32_op = OPC_SRA;
15784 mips32_op = OPC_SRL;
15787 mips32_op = OPC_ROTR;
15789 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15792 check_insn(ctx, ISA_MIPS32R6);
15793 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15796 check_insn(ctx, ISA_MIPS32R6);
15797 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15800 check_insn(ctx, ISA_MIPS32R6);
15801 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15804 goto pool32a_invalid;
15808 minor = (ctx->opcode >> 6) & 0xf;
15812 mips32_op = OPC_ADD;
15815 mips32_op = OPC_ADDU;
15818 mips32_op = OPC_SUB;
15821 mips32_op = OPC_SUBU;
15824 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15825 mips32_op = OPC_MUL;
15827 gen_arith(ctx, mips32_op, rd, rs, rt);
15831 mips32_op = OPC_SLLV;
15834 mips32_op = OPC_SRLV;
15837 mips32_op = OPC_SRAV;
15840 mips32_op = OPC_ROTRV;
15842 gen_shift(ctx, mips32_op, rd, rs, rt);
15844 /* Logical operations */
15846 mips32_op = OPC_AND;
15849 mips32_op = OPC_OR;
15852 mips32_op = OPC_NOR;
15855 mips32_op = OPC_XOR;
15857 gen_logic(ctx, mips32_op, rd, rs, rt);
15859 /* Set less than */
15861 mips32_op = OPC_SLT;
15864 mips32_op = OPC_SLTU;
15866 gen_slt(ctx, mips32_op, rd, rs, rt);
15869 goto pool32a_invalid;
15873 minor = (ctx->opcode >> 6) & 0xf;
15875 /* Conditional moves */
15876 case MOVN: /* MUL */
15877 if (ctx->insn_flags & ISA_MIPS32R6) {
15879 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15882 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15885 case MOVZ: /* MUH */
15886 if (ctx->insn_flags & ISA_MIPS32R6) {
15888 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15891 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15895 check_insn(ctx, ISA_MIPS32R6);
15896 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15899 check_insn(ctx, ISA_MIPS32R6);
15900 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15902 case LWXS: /* DIV */
15903 if (ctx->insn_flags & ISA_MIPS32R6) {
15905 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15908 gen_ldxs(ctx, rs, rt, rd);
15912 check_insn(ctx, ISA_MIPS32R6);
15913 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15916 check_insn(ctx, ISA_MIPS32R6);
15917 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15920 check_insn(ctx, ISA_MIPS32R6);
15921 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15924 goto pool32a_invalid;
15928 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15931 check_insn(ctx, ISA_MIPS32R6);
15932 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15933 extract32(ctx->opcode, 9, 2));
15936 check_insn(ctx, ISA_MIPS32R6);
15937 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15940 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15943 gen_pool32axf(env, ctx, rt, rs);
15946 generate_exception_end(ctx, EXCP_BREAK);
15949 check_insn(ctx, ISA_MIPS32R6);
15950 generate_exception_end(ctx, EXCP_RI);
15954 MIPS_INVAL("pool32a");
15955 generate_exception_end(ctx, EXCP_RI);
15960 minor = (ctx->opcode >> 12) & 0xf;
15963 check_cp0_enabled(ctx);
15964 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15965 gen_cache_operation(ctx, rt, rs, imm);
15970 /* COP2: Not implemented. */
15971 generate_exception_err(ctx, EXCP_CpU, 2);
15973 #ifdef TARGET_MIPS64
15976 check_insn(ctx, ISA_MIPS3);
15977 check_mips_64(ctx);
15982 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15984 #ifdef TARGET_MIPS64
15987 check_insn(ctx, ISA_MIPS3);
15988 check_mips_64(ctx);
15993 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15996 MIPS_INVAL("pool32b");
15997 generate_exception_end(ctx, EXCP_RI);
16002 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16003 minor = ctx->opcode & 0x3f;
16004 check_cp1_enabled(ctx);
16007 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16008 mips32_op = OPC_ALNV_PS;
16011 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16012 mips32_op = OPC_MADD_S;
16015 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16016 mips32_op = OPC_MADD_D;
16019 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16020 mips32_op = OPC_MADD_PS;
16023 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16024 mips32_op = OPC_MSUB_S;
16027 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16028 mips32_op = OPC_MSUB_D;
16031 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16032 mips32_op = OPC_MSUB_PS;
16035 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16036 mips32_op = OPC_NMADD_S;
16039 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16040 mips32_op = OPC_NMADD_D;
16043 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16044 mips32_op = OPC_NMADD_PS;
16047 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16048 mips32_op = OPC_NMSUB_S;
16051 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16052 mips32_op = OPC_NMSUB_D;
16055 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16056 mips32_op = OPC_NMSUB_PS;
16058 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16060 case CABS_COND_FMT:
16061 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16062 cond = (ctx->opcode >> 6) & 0xf;
16063 cc = (ctx->opcode >> 13) & 0x7;
16064 fmt = (ctx->opcode >> 10) & 0x3;
16067 gen_cmpabs_s(ctx, cond, rt, rs, cc);
16070 gen_cmpabs_d(ctx, cond, rt, rs, cc);
16073 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16076 goto pool32f_invalid;
16080 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16081 cond = (ctx->opcode >> 6) & 0xf;
16082 cc = (ctx->opcode >> 13) & 0x7;
16083 fmt = (ctx->opcode >> 10) & 0x3;
16086 gen_cmp_s(ctx, cond, rt, rs, cc);
16089 gen_cmp_d(ctx, cond, rt, rs, cc);
16092 gen_cmp_ps(ctx, cond, rt, rs, cc);
16095 goto pool32f_invalid;
16099 check_insn(ctx, ISA_MIPS32R6);
16100 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16103 check_insn(ctx, ISA_MIPS32R6);
16104 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16107 gen_pool32fxf(ctx, rt, rs);
16111 switch ((ctx->opcode >> 6) & 0x7) {
16113 mips32_op = OPC_PLL_PS;
16116 mips32_op = OPC_PLU_PS;
16119 mips32_op = OPC_PUL_PS;
16122 mips32_op = OPC_PUU_PS;
16125 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16126 mips32_op = OPC_CVT_PS_S;
16128 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16131 goto pool32f_invalid;
16135 check_insn(ctx, ISA_MIPS32R6);
16136 switch ((ctx->opcode >> 9) & 0x3) {
16138 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16141 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16144 goto pool32f_invalid;
16149 switch ((ctx->opcode >> 6) & 0x7) {
16151 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16152 mips32_op = OPC_LWXC1;
16155 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16156 mips32_op = OPC_SWXC1;
16159 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16160 mips32_op = OPC_LDXC1;
16163 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16164 mips32_op = OPC_SDXC1;
16167 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16168 mips32_op = OPC_LUXC1;
16171 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16172 mips32_op = OPC_SUXC1;
16174 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16177 goto pool32f_invalid;
16181 check_insn(ctx, ISA_MIPS32R6);
16182 switch ((ctx->opcode >> 9) & 0x3) {
16184 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16187 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16190 goto pool32f_invalid;
16195 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16196 fmt = (ctx->opcode >> 9) & 0x3;
16197 switch ((ctx->opcode >> 6) & 0x7) {
16201 mips32_op = OPC_RSQRT2_S;
16204 mips32_op = OPC_RSQRT2_D;
16207 mips32_op = OPC_RSQRT2_PS;
16210 goto pool32f_invalid;
16216 mips32_op = OPC_RECIP2_S;
16219 mips32_op = OPC_RECIP2_D;
16222 mips32_op = OPC_RECIP2_PS;
16225 goto pool32f_invalid;
16229 mips32_op = OPC_ADDR_PS;
16232 mips32_op = OPC_MULR_PS;
16234 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16237 goto pool32f_invalid;
16241 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16242 cc = (ctx->opcode >> 13) & 0x7;
16243 fmt = (ctx->opcode >> 9) & 0x3;
16244 switch ((ctx->opcode >> 6) & 0x7) {
16245 case MOVF_FMT: /* RINT_FMT */
16246 if (ctx->insn_flags & ISA_MIPS32R6) {
16250 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16253 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16256 goto pool32f_invalid;
16262 gen_movcf_s(ctx, rs, rt, cc, 0);
16265 gen_movcf_d(ctx, rs, rt, cc, 0);
16269 gen_movcf_ps(ctx, rs, rt, cc, 0);
16272 goto pool32f_invalid;
16276 case MOVT_FMT: /* CLASS_FMT */
16277 if (ctx->insn_flags & ISA_MIPS32R6) {
16281 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16284 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16287 goto pool32f_invalid;
16293 gen_movcf_s(ctx, rs, rt, cc, 1);
16296 gen_movcf_d(ctx, rs, rt, cc, 1);
16300 gen_movcf_ps(ctx, rs, rt, cc, 1);
16303 goto pool32f_invalid;
16308 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16311 goto pool32f_invalid;
16314 #define FINSN_3ARG_SDPS(prfx) \
16315 switch ((ctx->opcode >> 8) & 0x3) { \
16317 mips32_op = OPC_##prfx##_S; \
16320 mips32_op = OPC_##prfx##_D; \
16322 case FMT_SDPS_PS: \
16324 mips32_op = OPC_##prfx##_PS; \
16327 goto pool32f_invalid; \
16330 check_insn(ctx, ISA_MIPS32R6);
16331 switch ((ctx->opcode >> 9) & 0x3) {
16333 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16336 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16339 goto pool32f_invalid;
16343 check_insn(ctx, ISA_MIPS32R6);
16344 switch ((ctx->opcode >> 9) & 0x3) {
16346 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16349 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16352 goto pool32f_invalid;
16356 /* regular FP ops */
16357 switch ((ctx->opcode >> 6) & 0x3) {
16359 FINSN_3ARG_SDPS(ADD);
16362 FINSN_3ARG_SDPS(SUB);
16365 FINSN_3ARG_SDPS(MUL);
16368 fmt = (ctx->opcode >> 8) & 0x3;
16370 mips32_op = OPC_DIV_D;
16371 } else if (fmt == 0) {
16372 mips32_op = OPC_DIV_S;
16374 goto pool32f_invalid;
16378 goto pool32f_invalid;
16383 switch ((ctx->opcode >> 6) & 0x7) {
16384 case MOVN_FMT: /* SELEQZ_FMT */
16385 if (ctx->insn_flags & ISA_MIPS32R6) {
16387 switch ((ctx->opcode >> 9) & 0x3) {
16389 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16392 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16395 goto pool32f_invalid;
16399 FINSN_3ARG_SDPS(MOVN);
16403 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16404 FINSN_3ARG_SDPS(MOVN);
16406 case MOVZ_FMT: /* SELNEZ_FMT */
16407 if (ctx->insn_flags & ISA_MIPS32R6) {
16409 switch ((ctx->opcode >> 9) & 0x3) {
16411 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16414 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16417 goto pool32f_invalid;
16421 FINSN_3ARG_SDPS(MOVZ);
16425 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16426 FINSN_3ARG_SDPS(MOVZ);
16429 check_insn(ctx, ISA_MIPS32R6);
16430 switch ((ctx->opcode >> 9) & 0x3) {
16432 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16435 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16438 goto pool32f_invalid;
16442 check_insn(ctx, ISA_MIPS32R6);
16443 switch ((ctx->opcode >> 9) & 0x3) {
16445 mips32_op = OPC_MADDF_S;
16448 mips32_op = OPC_MADDF_D;
16451 goto pool32f_invalid;
16455 check_insn(ctx, ISA_MIPS32R6);
16456 switch ((ctx->opcode >> 9) & 0x3) {
16458 mips32_op = OPC_MSUBF_S;
16461 mips32_op = OPC_MSUBF_D;
16464 goto pool32f_invalid;
16468 goto pool32f_invalid;
16472 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16476 MIPS_INVAL("pool32f");
16477 generate_exception_end(ctx, EXCP_RI);
16481 generate_exception_err(ctx, EXCP_CpU, 1);
16485 minor = (ctx->opcode >> 21) & 0x1f;
16488 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16489 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16492 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16493 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16494 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16497 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16498 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16499 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16502 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16503 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16506 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16507 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16508 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16511 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16512 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16513 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16516 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16517 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16520 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16521 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16525 case TLTI: /* BC1EQZC */
16526 if (ctx->insn_flags & ISA_MIPS32R6) {
16528 check_cp1_enabled(ctx);
16529 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16532 mips32_op = OPC_TLTI;
16536 case TGEI: /* BC1NEZC */
16537 if (ctx->insn_flags & ISA_MIPS32R6) {
16539 check_cp1_enabled(ctx);
16540 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16543 mips32_op = OPC_TGEI;
16548 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16549 mips32_op = OPC_TLTIU;
16552 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16553 mips32_op = OPC_TGEIU;
16555 case TNEI: /* SYNCI */
16556 if (ctx->insn_flags & ISA_MIPS32R6) {
16558 /* Break the TB to be able to sync copied instructions
16560 ctx->base.is_jmp = DISAS_STOP;
16563 mips32_op = OPC_TNEI;
16568 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16569 mips32_op = OPC_TEQI;
16571 gen_trap(ctx, mips32_op, rs, -1, imm);
16576 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16577 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16578 4, rs, 0, imm << 1, 0);
16579 /* Compact branches don't have a delay slot, so just let
16580 the normal delay slot handling take us to the branch
16584 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16585 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16588 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16589 /* Break the TB to be able to sync copied instructions
16591 ctx->base.is_jmp = DISAS_STOP;
16595 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16596 /* COP2: Not implemented. */
16597 generate_exception_err(ctx, EXCP_CpU, 2);
16600 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16601 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16604 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16605 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16608 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16609 mips32_op = OPC_BC1FANY4;
16612 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16613 mips32_op = OPC_BC1TANY4;
16616 check_insn(ctx, ASE_MIPS3D);
16619 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16620 check_cp1_enabled(ctx);
16621 gen_compute_branch1(ctx, mips32_op,
16622 (ctx->opcode >> 18) & 0x7, imm << 1);
16624 generate_exception_err(ctx, EXCP_CpU, 1);
16629 /* MIPS DSP: not implemented */
16632 MIPS_INVAL("pool32i");
16633 generate_exception_end(ctx, EXCP_RI);
16638 minor = (ctx->opcode >> 12) & 0xf;
16639 offset = sextract32(ctx->opcode, 0,
16640 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16643 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16644 mips32_op = OPC_LWL;
16647 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16648 mips32_op = OPC_SWL;
16651 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16652 mips32_op = OPC_LWR;
16655 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16656 mips32_op = OPC_SWR;
16658 #if defined(TARGET_MIPS64)
16660 check_insn(ctx, ISA_MIPS3);
16661 check_mips_64(ctx);
16662 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16663 mips32_op = OPC_LDL;
16666 check_insn(ctx, ISA_MIPS3);
16667 check_mips_64(ctx);
16668 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16669 mips32_op = OPC_SDL;
16672 check_insn(ctx, ISA_MIPS3);
16673 check_mips_64(ctx);
16674 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16675 mips32_op = OPC_LDR;
16678 check_insn(ctx, ISA_MIPS3);
16679 check_mips_64(ctx);
16680 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16681 mips32_op = OPC_SDR;
16684 check_insn(ctx, ISA_MIPS3);
16685 check_mips_64(ctx);
16686 mips32_op = OPC_LWU;
16689 check_insn(ctx, ISA_MIPS3);
16690 check_mips_64(ctx);
16691 mips32_op = OPC_LLD;
16695 mips32_op = OPC_LL;
16698 gen_ld(ctx, mips32_op, rt, rs, offset);
16701 gen_st(ctx, mips32_op, rt, rs, offset);
16704 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
16706 #if defined(TARGET_MIPS64)
16708 check_insn(ctx, ISA_MIPS3);
16709 check_mips_64(ctx);
16710 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
16715 MIPS_INVAL("pool32c ld-eva");
16716 generate_exception_end(ctx, EXCP_RI);
16719 check_cp0_enabled(ctx);
16721 minor2 = (ctx->opcode >> 9) & 0x7;
16722 offset = sextract32(ctx->opcode, 0, 9);
16725 mips32_op = OPC_LBUE;
16728 mips32_op = OPC_LHUE;
16731 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16732 mips32_op = OPC_LWLE;
16735 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16736 mips32_op = OPC_LWRE;
16739 mips32_op = OPC_LBE;
16742 mips32_op = OPC_LHE;
16745 mips32_op = OPC_LLE;
16748 mips32_op = OPC_LWE;
16754 MIPS_INVAL("pool32c st-eva");
16755 generate_exception_end(ctx, EXCP_RI);
16758 check_cp0_enabled(ctx);
16760 minor2 = (ctx->opcode >> 9) & 0x7;
16761 offset = sextract32(ctx->opcode, 0, 9);
16764 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16765 mips32_op = OPC_SWLE;
16768 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16769 mips32_op = OPC_SWRE;
16772 /* Treat as no-op */
16773 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16774 /* hint codes 24-31 are reserved and signal RI */
16775 generate_exception(ctx, EXCP_RI);
16779 /* Treat as no-op */
16780 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16781 gen_cache_operation(ctx, rt, rs, offset);
16785 mips32_op = OPC_SBE;
16788 mips32_op = OPC_SHE;
16791 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16794 mips32_op = OPC_SWE;
16799 /* Treat as no-op */
16800 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16801 /* hint codes 24-31 are reserved and signal RI */
16802 generate_exception(ctx, EXCP_RI);
16806 MIPS_INVAL("pool32c");
16807 generate_exception_end(ctx, EXCP_RI);
16811 case ADDI32: /* AUI, LUI */
16812 if (ctx->insn_flags & ISA_MIPS32R6) {
16814 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16817 mips32_op = OPC_ADDI;
16822 mips32_op = OPC_ADDIU;
16824 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16827 /* Logical operations */
16829 mips32_op = OPC_ORI;
16832 mips32_op = OPC_XORI;
16835 mips32_op = OPC_ANDI;
16837 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16840 /* Set less than immediate */
16842 mips32_op = OPC_SLTI;
16845 mips32_op = OPC_SLTIU;
16847 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16850 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16851 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16852 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16853 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16855 case JALS32: /* BOVC, BEQC, BEQZALC */
16856 if (ctx->insn_flags & ISA_MIPS32R6) {
16859 mips32_op = OPC_BOVC;
16860 } else if (rs < rt && rs == 0) {
16862 mips32_op = OPC_BEQZALC;
16865 mips32_op = OPC_BEQC;
16867 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16870 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16871 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16872 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16875 case BEQ32: /* BC */
16876 if (ctx->insn_flags & ISA_MIPS32R6) {
16878 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16879 sextract32(ctx->opcode << 1, 0, 27));
16882 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16885 case BNE32: /* BALC */
16886 if (ctx->insn_flags & ISA_MIPS32R6) {
16888 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16889 sextract32(ctx->opcode << 1, 0, 27));
16892 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16895 case J32: /* BGTZC, BLTZC, BLTC */
16896 if (ctx->insn_flags & ISA_MIPS32R6) {
16897 if (rs == 0 && rt != 0) {
16899 mips32_op = OPC_BGTZC;
16900 } else if (rs != 0 && rt != 0 && rs == rt) {
16902 mips32_op = OPC_BLTZC;
16905 mips32_op = OPC_BLTC;
16907 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16910 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16911 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16914 case JAL32: /* BLEZC, BGEZC, BGEC */
16915 if (ctx->insn_flags & ISA_MIPS32R6) {
16916 if (rs == 0 && rt != 0) {
16918 mips32_op = OPC_BLEZC;
16919 } else if (rs != 0 && rt != 0 && rs == rt) {
16921 mips32_op = OPC_BGEZC;
16924 mips32_op = OPC_BGEC;
16926 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16929 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16930 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16931 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16934 /* Floating point (COP1) */
16936 mips32_op = OPC_LWC1;
16939 mips32_op = OPC_LDC1;
16942 mips32_op = OPC_SWC1;
16945 mips32_op = OPC_SDC1;
16947 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16949 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16950 if (ctx->insn_flags & ISA_MIPS32R6) {
16951 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16952 switch ((ctx->opcode >> 16) & 0x1f) {
16961 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16964 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16967 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16977 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16980 generate_exception(ctx, EXCP_RI);
16985 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16986 offset = SIMM(ctx->opcode, 0, 23) << 2;
16988 gen_addiupc(ctx, reg, offset, 0, 0);
16991 case BNVC: /* BNEC, BNEZALC */
16992 check_insn(ctx, ISA_MIPS32R6);
16995 mips32_op = OPC_BNVC;
16996 } else if (rs < rt && rs == 0) {
16998 mips32_op = OPC_BNEZALC;
17001 mips32_op = OPC_BNEC;
17003 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17005 case R6_BNEZC: /* JIALC */
17006 check_insn(ctx, ISA_MIPS32R6);
17009 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17010 sextract32(ctx->opcode << 1, 0, 22));
17013 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17016 case R6_BEQZC: /* JIC */
17017 check_insn(ctx, ISA_MIPS32R6);
17020 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17021 sextract32(ctx->opcode << 1, 0, 22));
17024 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17027 case BLEZALC: /* BGEZALC, BGEUC */
17028 check_insn(ctx, ISA_MIPS32R6);
17029 if (rs == 0 && rt != 0) {
17031 mips32_op = OPC_BLEZALC;
17032 } else if (rs != 0 && rt != 0 && rs == rt) {
17034 mips32_op = OPC_BGEZALC;
17037 mips32_op = OPC_BGEUC;
17039 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17041 case BGTZALC: /* BLTZALC, BLTUC */
17042 check_insn(ctx, ISA_MIPS32R6);
17043 if (rs == 0 && rt != 0) {
17045 mips32_op = OPC_BGTZALC;
17046 } else if (rs != 0 && rt != 0 && rs == rt) {
17048 mips32_op = OPC_BLTZALC;
17051 mips32_op = OPC_BLTUC;
17053 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17055 /* Loads and stores */
17057 mips32_op = OPC_LB;
17060 mips32_op = OPC_LBU;
17063 mips32_op = OPC_LH;
17066 mips32_op = OPC_LHU;
17069 mips32_op = OPC_LW;
17071 #ifdef TARGET_MIPS64
17073 check_insn(ctx, ISA_MIPS3);
17074 check_mips_64(ctx);
17075 mips32_op = OPC_LD;
17078 check_insn(ctx, ISA_MIPS3);
17079 check_mips_64(ctx);
17080 mips32_op = OPC_SD;
17084 mips32_op = OPC_SB;
17087 mips32_op = OPC_SH;
17090 mips32_op = OPC_SW;
17093 gen_ld(ctx, mips32_op, rt, rs, imm);
17096 gen_st(ctx, mips32_op, rt, rs, imm);
17099 generate_exception_end(ctx, EXCP_RI);
17104 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
17108 /* make sure instructions are on a halfword boundary */
17109 if (ctx->base.pc_next & 0x1) {
17110 env->CP0_BadVAddr = ctx->base.pc_next;
17111 generate_exception_end(ctx, EXCP_AdEL);
17115 op = (ctx->opcode >> 10) & 0x3f;
17116 /* Enforce properly-sized instructions in a delay slot */
17117 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17118 switch (op & 0x7) { /* MSB-3..MSB-5 */
17120 /* POOL32A, POOL32B, POOL32I, POOL32C */
17122 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17124 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17126 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17128 /* LB32, LH32, LWC132, LDC132, LW32 */
17129 if (ctx->hflags & MIPS_HFLAG_BDS16) {
17130 generate_exception_end(ctx, EXCP_RI);
17135 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17137 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17139 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17140 if (ctx->hflags & MIPS_HFLAG_BDS32) {
17141 generate_exception_end(ctx, EXCP_RI);
17151 int rd = mmreg(uMIPS_RD(ctx->opcode));
17152 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17153 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17156 switch (ctx->opcode & 0x1) {
17164 if (ctx->insn_flags & ISA_MIPS32R6) {
17165 /* In the Release 6 the register number location in
17166 * the instruction encoding has changed.
17168 gen_arith(ctx, opc, rs1, rd, rs2);
17170 gen_arith(ctx, opc, rd, rs1, rs2);
17176 int rd = mmreg(uMIPS_RD(ctx->opcode));
17177 int rs = mmreg(uMIPS_RS(ctx->opcode));
17178 int amount = (ctx->opcode >> 1) & 0x7;
17180 amount = amount == 0 ? 8 : amount;
17182 switch (ctx->opcode & 0x1) {
17191 gen_shift_imm(ctx, opc, rd, rs, amount);
17195 if (ctx->insn_flags & ISA_MIPS32R6) {
17196 gen_pool16c_r6_insn(ctx);
17198 gen_pool16c_insn(ctx);
17203 int rd = mmreg(uMIPS_RD(ctx->opcode));
17204 int rb = 28; /* GP */
17205 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17207 gen_ld(ctx, OPC_LW, rd, rb, offset);
17211 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17212 if (ctx->opcode & 1) {
17213 generate_exception_end(ctx, EXCP_RI);
17216 int enc_dest = uMIPS_RD(ctx->opcode);
17217 int enc_rt = uMIPS_RS2(ctx->opcode);
17218 int enc_rs = uMIPS_RS1(ctx->opcode);
17219 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17224 int rd = mmreg(uMIPS_RD(ctx->opcode));
17225 int rb = mmreg(uMIPS_RS(ctx->opcode));
17226 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17227 offset = (offset == 0xf ? -1 : offset);
17229 gen_ld(ctx, OPC_LBU, rd, rb, offset);
17234 int rd = mmreg(uMIPS_RD(ctx->opcode));
17235 int rb = mmreg(uMIPS_RS(ctx->opcode));
17236 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17238 gen_ld(ctx, OPC_LHU, rd, rb, offset);
17243 int rd = (ctx->opcode >> 5) & 0x1f;
17244 int rb = 29; /* SP */
17245 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17247 gen_ld(ctx, OPC_LW, rd, rb, offset);
17252 int rd = mmreg(uMIPS_RD(ctx->opcode));
17253 int rb = mmreg(uMIPS_RS(ctx->opcode));
17254 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17256 gen_ld(ctx, OPC_LW, rd, rb, offset);
17261 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17262 int rb = mmreg(uMIPS_RS(ctx->opcode));
17263 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17265 gen_st(ctx, OPC_SB, rd, rb, offset);
17270 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17271 int rb = mmreg(uMIPS_RS(ctx->opcode));
17272 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17274 gen_st(ctx, OPC_SH, rd, rb, offset);
17279 int rd = (ctx->opcode >> 5) & 0x1f;
17280 int rb = 29; /* SP */
17281 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17283 gen_st(ctx, OPC_SW, rd, rb, offset);
17288 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17289 int rb = mmreg(uMIPS_RS(ctx->opcode));
17290 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17292 gen_st(ctx, OPC_SW, rd, rb, offset);
17297 int rd = uMIPS_RD5(ctx->opcode);
17298 int rs = uMIPS_RS5(ctx->opcode);
17300 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17307 switch (ctx->opcode & 0x1) {
17317 switch (ctx->opcode & 0x1) {
17322 gen_addiur1sp(ctx);
17326 case B16: /* BC16 */
17327 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17328 sextract32(ctx->opcode, 0, 10) << 1,
17329 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17331 case BNEZ16: /* BNEZC16 */
17332 case BEQZ16: /* BEQZC16 */
17333 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17334 mmreg(uMIPS_RD(ctx->opcode)),
17335 0, sextract32(ctx->opcode, 0, 7) << 1,
17336 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17341 int reg = mmreg(uMIPS_RD(ctx->opcode));
17342 int imm = ZIMM(ctx->opcode, 0, 7);
17344 imm = (imm == 0x7f ? -1 : imm);
17345 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17351 generate_exception_end(ctx, EXCP_RI);
17354 decode_micromips32_opc(env, ctx);
17367 /* MAJOR, P16, and P32 pools opcodes */
17371 NM_MOVE_BALC = 0x02,
17379 NM_P16_SHIFT = 0x0c,
17397 NM_P_LS_U12 = 0x21,
17407 NM_P16_ADDU = 0x2c,
17421 NM_MOVEPREV = 0x3f,
17424 /* POOL32A instruction pool */
17426 NM_POOL32A0 = 0x00,
17427 NM_SPECIAL2 = 0x01,
17430 NM_POOL32A5 = 0x05,
17431 NM_POOL32A7 = 0x07,
17434 /* P.GP.W instruction pool */
17436 NM_ADDIUGP_W = 0x00,
17441 /* P48I instruction pool */
17445 NM_ADDIUGP48 = 0x02,
17446 NM_ADDIUPC48 = 0x03,
17451 /* P.U12 instruction pool */
17460 NM_ADDIUNEG = 0x08,
17467 /* POOL32F instruction pool */
17469 NM_POOL32F_0 = 0x00,
17470 NM_POOL32F_3 = 0x03,
17471 NM_POOL32F_5 = 0x05,
17474 /* POOL32S instruction pool */
17476 NM_POOL32S_0 = 0x00,
17477 NM_POOL32S_4 = 0x04,
17480 /* P.LUI instruction pool */
17486 /* P.GP.BH instruction pool */
17491 NM_ADDIUGP_B = 0x03,
17494 NM_P_GP_CP1 = 0x06,
17497 /* P.LS.U12 instruction pool */
17502 NM_P_PREFU12 = 0x03,
17515 /* P.LS.S9 instruction pool */
17521 NM_P_LS_UAWM = 0x05,
17524 /* P.BAL instruction pool */
17530 /* P.J instruction pool */
17533 NM_JALRC_HB = 0x01,
17534 NM_P_BALRSC = 0x08,
17537 /* P.BR1 instruction pool */
17545 /* P.BR2 instruction pool */
17552 /* P.BRI instruction pool */
17564 /* P16.SHIFT instruction pool */
17570 /* POOL16C instruction pool */
17572 NM_POOL16C_0 = 0x00,
17576 /* P16.A1 instruction pool */
17578 NM_ADDIUR1SP = 0x01,
17581 /* P16.A2 instruction pool */
17584 NM_P_ADDIURS5 = 0x01,
17587 /* P16.ADDU instruction pool */
17593 /* P16.SR instruction pool */
17596 NM_RESTORE_JRC16 = 0x01,
17599 /* P16.4X4 instruction pool */
17605 /* P16.LB instruction pool */
17612 /* P16.LH instruction pool */
17619 /* P.RI instruction pool */
17622 NM_P_SYSCALL = 0x01,
17627 /* POOL32A0 instruction pool */
17662 NM_D_E_MT_VPE = 0x56,
17670 /* CRC32 instruction pool */
17680 /* POOL32A5 instruction pool */
17682 NM_CMP_EQ_PH = 0x00,
17683 NM_CMP_LT_PH = 0x08,
17684 NM_CMP_LE_PH = 0x10,
17685 NM_CMPGU_EQ_QB = 0x18,
17686 NM_CMPGU_LT_QB = 0x20,
17687 NM_CMPGU_LE_QB = 0x28,
17688 NM_CMPGDU_EQ_QB = 0x30,
17689 NM_CMPGDU_LT_QB = 0x38,
17690 NM_CMPGDU_LE_QB = 0x40,
17691 NM_CMPU_EQ_QB = 0x48,
17692 NM_CMPU_LT_QB = 0x50,
17693 NM_CMPU_LE_QB = 0x58,
17694 NM_ADDQ_S_W = 0x60,
17695 NM_SUBQ_S_W = 0x68,
17699 NM_ADDQ_S_PH = 0x01,
17700 NM_ADDQH_R_PH = 0x09,
17701 NM_ADDQH_R_W = 0x11,
17702 NM_ADDU_S_QB = 0x19,
17703 NM_ADDU_S_PH = 0x21,
17704 NM_ADDUH_R_QB = 0x29,
17705 NM_SHRAV_R_PH = 0x31,
17706 NM_SHRAV_R_QB = 0x39,
17707 NM_SUBQ_S_PH = 0x41,
17708 NM_SUBQH_R_PH = 0x49,
17709 NM_SUBQH_R_W = 0x51,
17710 NM_SUBU_S_QB = 0x59,
17711 NM_SUBU_S_PH = 0x61,
17712 NM_SUBUH_R_QB = 0x69,
17713 NM_SHLLV_S_PH = 0x71,
17714 NM_PRECR_SRA_R_PH_W = 0x79,
17716 NM_MULEU_S_PH_QBL = 0x12,
17717 NM_MULEU_S_PH_QBR = 0x1a,
17718 NM_MULQ_RS_PH = 0x22,
17719 NM_MULQ_S_PH = 0x2a,
17720 NM_MULQ_RS_W = 0x32,
17721 NM_MULQ_S_W = 0x3a,
17724 NM_SHRAV_R_W = 0x5a,
17725 NM_SHRLV_PH = 0x62,
17726 NM_SHRLV_QB = 0x6a,
17727 NM_SHLLV_QB = 0x72,
17728 NM_SHLLV_S_W = 0x7a,
17732 NM_MULEQ_S_W_PHL = 0x04,
17733 NM_MULEQ_S_W_PHR = 0x0c,
17735 NM_MUL_S_PH = 0x05,
17736 NM_PRECR_QB_PH = 0x0d,
17737 NM_PRECRQ_QB_PH = 0x15,
17738 NM_PRECRQ_PH_W = 0x1d,
17739 NM_PRECRQ_RS_PH_W = 0x25,
17740 NM_PRECRQU_S_QB_PH = 0x2d,
17741 NM_PACKRL_PH = 0x35,
17745 NM_SHRA_R_W = 0x5e,
17746 NM_SHRA_R_PH = 0x66,
17747 NM_SHLL_S_PH = 0x76,
17748 NM_SHLL_S_W = 0x7e,
17753 /* POOL32A7 instruction pool */
17758 NM_POOL32AXF = 0x07,
17761 /* P.SR instruction pool */
17767 /* P.SHIFT instruction pool */
17775 /* P.ROTX instruction pool */
17780 /* P.INS instruction pool */
17785 /* P.EXT instruction pool */
17790 /* POOL32F_0 (fmt) instruction pool */
17795 NM_SELEQZ_S = 0x07,
17796 NM_SELEQZ_D = 0x47,
17800 NM_SELNEZ_S = 0x0f,
17801 NM_SELNEZ_D = 0x4f,
17816 /* POOL32F_3 instruction pool */
17820 NM_MINA_FMT = 0x04,
17821 NM_MAXA_FMT = 0x05,
17822 NM_POOL32FXF = 0x07,
17825 /* POOL32F_5 instruction pool */
17827 NM_CMP_CONDN_S = 0x00,
17828 NM_CMP_CONDN_D = 0x02,
17831 /* P.GP.LH instruction pool */
17837 /* P.GP.SH instruction pool */
17842 /* P.GP.CP1 instruction pool */
17850 /* P.LS.S0 instruction pool */
17867 NM_P_PREFS9 = 0x03,
17873 /* P.LS.S1 instruction pool */
17875 NM_ASET_ACLR = 0x02,
17883 /* P.LS.E0 instruction pool */
17899 /* P.PREFE instruction pool */
17905 /* P.LLE instruction pool */
17911 /* P.SCE instruction pool */
17917 /* P.LS.WM instruction pool */
17923 /* P.LS.UAWM instruction pool */
17929 /* P.BR3A instruction pool */
17935 NM_BPOSGE32C = 0x04,
17938 /* P16.RI instruction pool */
17940 NM_P16_SYSCALL = 0x01,
17945 /* POOL16C_0 instruction pool */
17947 NM_POOL16C_00 = 0x00,
17950 /* P16.JRC instruction pool */
17956 /* P.SYSCALL instruction pool */
17962 /* P.TRAP instruction pool */
17968 /* P.CMOVE instruction pool */
17974 /* POOL32Axf instruction pool */
17976 NM_POOL32AXF_1 = 0x01,
17977 NM_POOL32AXF_2 = 0x02,
17978 NM_POOL32AXF_4 = 0x04,
17979 NM_POOL32AXF_5 = 0x05,
17980 NM_POOL32AXF_7 = 0x07,
17983 /* POOL32Axf_1 instruction pool */
17985 NM_POOL32AXF_1_0 = 0x00,
17986 NM_POOL32AXF_1_1 = 0x01,
17987 NM_POOL32AXF_1_3 = 0x03,
17988 NM_POOL32AXF_1_4 = 0x04,
17989 NM_POOL32AXF_1_5 = 0x05,
17990 NM_POOL32AXF_1_7 = 0x07,
17993 /* POOL32Axf_2 instruction pool */
17995 NM_POOL32AXF_2_0_7 = 0x00,
17996 NM_POOL32AXF_2_8_15 = 0x01,
17997 NM_POOL32AXF_2_16_23 = 0x02,
17998 NM_POOL32AXF_2_24_31 = 0x03,
18001 /* POOL32Axf_7 instruction pool */
18003 NM_SHRA_R_QB = 0x0,
18008 /* POOL32Axf_1_0 instruction pool */
18016 /* POOL32Axf_1_1 instruction pool */
18022 /* POOL32Axf_1_3 instruction pool */
18030 /* POOL32Axf_1_4 instruction pool */
18036 /* POOL32Axf_1_5 instruction pool */
18038 NM_MAQ_S_W_PHR = 0x0,
18039 NM_MAQ_S_W_PHL = 0x1,
18040 NM_MAQ_SA_W_PHR = 0x2,
18041 NM_MAQ_SA_W_PHL = 0x3,
18044 /* POOL32Axf_1_7 instruction pool */
18048 NM_EXTR_RS_W = 0x2,
18052 /* POOL32Axf_2_0_7 instruction pool */
18055 NM_DPAQ_S_W_PH = 0x1,
18057 NM_DPSQ_S_W_PH = 0x3,
18064 /* POOL32Axf_2_8_15 instruction pool */
18066 NM_DPAX_W_PH = 0x0,
18067 NM_DPAQ_SA_L_W = 0x1,
18068 NM_DPSX_W_PH = 0x2,
18069 NM_DPSQ_SA_L_W = 0x3,
18072 NM_EXTRV_R_W = 0x7,
18075 /* POOL32Axf_2_16_23 instruction pool */
18077 NM_DPAU_H_QBL = 0x0,
18078 NM_DPAQX_S_W_PH = 0x1,
18079 NM_DPSU_H_QBL = 0x2,
18080 NM_DPSQX_S_W_PH = 0x3,
18083 NM_MULSA_W_PH = 0x6,
18084 NM_EXTRV_RS_W = 0x7,
18087 /* POOL32Axf_2_24_31 instruction pool */
18089 NM_DPAU_H_QBR = 0x0,
18090 NM_DPAQX_SA_W_PH = 0x1,
18091 NM_DPSU_H_QBR = 0x2,
18092 NM_DPSQX_SA_W_PH = 0x3,
18095 NM_MULSAQ_S_W_PH = 0x6,
18096 NM_EXTRV_S_H = 0x7,
18099 /* POOL32Axf_{4, 5} instruction pool */
18118 /* nanoMIPS DSP instructions */
18119 NM_ABSQ_S_QB = 0x00,
18120 NM_ABSQ_S_PH = 0x08,
18121 NM_ABSQ_S_W = 0x10,
18122 NM_PRECEQ_W_PHL = 0x28,
18123 NM_PRECEQ_W_PHR = 0x30,
18124 NM_PRECEQU_PH_QBL = 0x38,
18125 NM_PRECEQU_PH_QBR = 0x48,
18126 NM_PRECEU_PH_QBL = 0x58,
18127 NM_PRECEU_PH_QBR = 0x68,
18128 NM_PRECEQU_PH_QBLA = 0x39,
18129 NM_PRECEQU_PH_QBRA = 0x49,
18130 NM_PRECEU_PH_QBLA = 0x59,
18131 NM_PRECEU_PH_QBRA = 0x69,
18132 NM_REPLV_PH = 0x01,
18133 NM_REPLV_QB = 0x09,
18136 NM_RADDU_W_QB = 0x78,
18142 /* PP.SR instruction pool */
18146 NM_RESTORE_JRC = 0x03,
18149 /* P.SR.F instruction pool */
18152 NM_RESTOREF = 0x01,
18155 /* P16.SYSCALL instruction pool */
18157 NM_SYSCALL16 = 0x00,
18158 NM_HYPCALL16 = 0x01,
18161 /* POOL16C_00 instruction pool */
18169 /* PP.LSX and PP.LSXS instruction pool */
18207 /* ERETx instruction pool */
18213 /* POOL32FxF_{0, 1} insturction pool */
18222 NM_CVT_S_PL = 0x84,
18223 NM_CVT_S_PU = 0xa4,
18225 NM_CVT_L_S = 0x004,
18226 NM_CVT_L_D = 0x104,
18227 NM_CVT_W_S = 0x024,
18228 NM_CVT_W_D = 0x124,
18230 NM_RSQRT_S = 0x008,
18231 NM_RSQRT_D = 0x108,
18236 NM_RECIP_S = 0x048,
18237 NM_RECIP_D = 0x148,
18239 NM_FLOOR_L_S = 0x00c,
18240 NM_FLOOR_L_D = 0x10c,
18242 NM_FLOOR_W_S = 0x02c,
18243 NM_FLOOR_W_D = 0x12c,
18245 NM_CEIL_L_S = 0x04c,
18246 NM_CEIL_L_D = 0x14c,
18247 NM_CEIL_W_S = 0x06c,
18248 NM_CEIL_W_D = 0x16c,
18249 NM_TRUNC_L_S = 0x08c,
18250 NM_TRUNC_L_D = 0x18c,
18251 NM_TRUNC_W_S = 0x0ac,
18252 NM_TRUNC_W_D = 0x1ac,
18253 NM_ROUND_L_S = 0x0cc,
18254 NM_ROUND_L_D = 0x1cc,
18255 NM_ROUND_W_S = 0x0ec,
18256 NM_ROUND_W_D = 0x1ec,
18264 NM_CVT_D_S = 0x04d,
18265 NM_CVT_D_W = 0x0cd,
18266 NM_CVT_D_L = 0x14d,
18267 NM_CVT_S_D = 0x06d,
18268 NM_CVT_S_W = 0x0ed,
18269 NM_CVT_S_L = 0x16d,
18272 /* P.LL instruction pool */
18278 /* P.SC instruction pool */
18284 /* P.DVP instruction pool */
18293 * nanoMIPS decoding engine
18298 /* extraction utilities */
18300 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18301 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18302 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18303 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18304 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18305 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18307 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18308 static inline int decode_gpr_gpr3(int r)
18310 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18312 return map[r & 0x7];
18315 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18316 static inline int decode_gpr_gpr3_src_store(int r)
18318 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18320 return map[r & 0x7];
18323 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18324 static inline int decode_gpr_gpr4(int r)
18326 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18327 16, 17, 18, 19, 20, 21, 22, 23 };
18329 return map[r & 0xf];
18332 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18333 static inline int decode_gpr_gpr4_zero(int r)
18335 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18336 16, 17, 18, 19, 20, 21, 22, 23 };
18338 return map[r & 0xf];
18342 /* extraction utilities */
18344 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18345 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18346 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18347 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18348 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18349 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18352 static void gen_adjust_sp(DisasContext *ctx, int u)
18354 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18357 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18358 uint8_t gp, uint16_t u)
18361 TCGv va = tcg_temp_new();
18362 TCGv t0 = tcg_temp_new();
18364 while (counter != count) {
18365 bool use_gp = gp && (counter == count - 1);
18366 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18367 int this_offset = -((counter + 1) << 2);
18368 gen_base_offset_addr(ctx, va, 29, this_offset);
18369 gen_load_gpr(t0, this_rt);
18370 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18371 (MO_TEUL | ctx->default_tcg_memop_mask));
18375 /* adjust stack pointer */
18376 gen_adjust_sp(ctx, -u);
18382 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18383 uint8_t gp, uint16_t u)
18386 TCGv va = tcg_temp_new();
18387 TCGv t0 = tcg_temp_new();
18389 while (counter != count) {
18390 bool use_gp = gp && (counter == count - 1);
18391 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18392 int this_offset = u - ((counter + 1) << 2);
18393 gen_base_offset_addr(ctx, va, 29, this_offset);
18394 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18395 ctx->default_tcg_memop_mask);
18396 tcg_gen_ext32s_tl(t0, t0);
18397 gen_store_gpr(t0, this_rt);
18401 /* adjust stack pointer */
18402 gen_adjust_sp(ctx, u);
18408 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18410 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18411 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18413 switch (extract32(ctx->opcode, 2, 2)) {
18415 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18418 gen_logic(ctx, OPC_AND, rt, rt, rs);
18421 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18424 gen_logic(ctx, OPC_OR, rt, rt, rs);
18429 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18431 int rt = extract32(ctx->opcode, 21, 5);
18432 int rs = extract32(ctx->opcode, 16, 5);
18433 int rd = extract32(ctx->opcode, 11, 5);
18435 switch (extract32(ctx->opcode, 3, 7)) {
18437 switch (extract32(ctx->opcode, 10, 1)) {
18440 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18444 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18450 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18454 gen_bshfl(ctx, OPC_SEB, rs, rt);
18457 gen_bshfl(ctx, OPC_SEH, rs, rt);
18460 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18463 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18466 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18469 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18472 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18475 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18479 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18482 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18485 switch (extract32(ctx->opcode, 10, 1)) {
18487 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18490 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18495 gen_logic(ctx, OPC_AND, rd, rs, rt);
18498 gen_logic(ctx, OPC_OR, rd, rs, rt);
18501 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18504 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18507 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18512 #ifndef CONFIG_USER_ONLY
18513 TCGv t0 = tcg_temp_new();
18514 switch (extract32(ctx->opcode, 10, 1)) {
18517 check_cp0_enabled(ctx);
18518 gen_helper_dvp(t0, cpu_env);
18519 gen_store_gpr(t0, rt);
18524 check_cp0_enabled(ctx);
18525 gen_helper_evp(t0, cpu_env);
18526 gen_store_gpr(t0, rt);
18533 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18538 TCGv t0 = tcg_temp_new();
18539 TCGv t1 = tcg_temp_new();
18540 TCGv t2 = tcg_temp_new();
18542 gen_load_gpr(t1, rs);
18543 gen_load_gpr(t2, rt);
18544 tcg_gen_add_tl(t0, t1, t2);
18545 tcg_gen_ext32s_tl(t0, t0);
18546 tcg_gen_xor_tl(t1, t1, t2);
18547 tcg_gen_xor_tl(t2, t0, t2);
18548 tcg_gen_andc_tl(t1, t2, t1);
18550 /* operands of same sign, result different sign */
18551 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18552 gen_store_gpr(t0, rd);
18560 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18563 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18566 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18569 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18572 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18575 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18578 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18581 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18583 #ifndef CONFIG_USER_ONLY
18585 check_cp0_enabled(ctx);
18587 /* Treat as NOP. */
18590 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18593 check_cp0_enabled(ctx);
18595 TCGv t0 = tcg_temp_new();
18597 gen_load_gpr(t0, rt);
18598 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18602 case NM_D_E_MT_VPE:
18604 uint8_t sc = extract32(ctx->opcode, 10, 1);
18605 TCGv t0 = tcg_temp_new();
18612 gen_helper_dmt(t0);
18613 gen_store_gpr(t0, rt);
18614 } else if (rs == 0) {
18617 gen_helper_dvpe(t0, cpu_env);
18618 gen_store_gpr(t0, rt);
18620 generate_exception_end(ctx, EXCP_RI);
18627 gen_helper_emt(t0);
18628 gen_store_gpr(t0, rt);
18629 } else if (rs == 0) {
18632 gen_helper_evpe(t0, cpu_env);
18633 gen_store_gpr(t0, rt);
18635 generate_exception_end(ctx, EXCP_RI);
18646 TCGv t0 = tcg_temp_new();
18647 TCGv t1 = tcg_temp_new();
18649 gen_load_gpr(t0, rt);
18650 gen_load_gpr(t1, rs);
18651 gen_helper_fork(t0, t1);
18658 check_cp0_enabled(ctx);
18660 /* Treat as NOP. */
18663 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18664 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18668 check_cp0_enabled(ctx);
18669 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18670 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18675 TCGv t0 = tcg_temp_new();
18677 gen_load_gpr(t0, rs);
18678 gen_helper_yield(t0, cpu_env, t0);
18679 gen_store_gpr(t0, rt);
18685 generate_exception_end(ctx, EXCP_RI);
18691 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18692 int ret, int v1, int v2)
18698 t0 = tcg_temp_new_i32();
18700 v0_t = tcg_temp_new();
18701 v1_t = tcg_temp_new();
18703 tcg_gen_movi_i32(t0, v2 >> 3);
18705 gen_load_gpr(v0_t, ret);
18706 gen_load_gpr(v1_t, v1);
18709 case NM_MAQ_S_W_PHR:
18711 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18713 case NM_MAQ_S_W_PHL:
18715 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18717 case NM_MAQ_SA_W_PHR:
18719 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18721 case NM_MAQ_SA_W_PHL:
18723 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18726 generate_exception_end(ctx, EXCP_RI);
18730 tcg_temp_free_i32(t0);
18732 tcg_temp_free(v0_t);
18733 tcg_temp_free(v1_t);
18737 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18738 int ret, int v1, int v2)
18741 TCGv t0 = tcg_temp_new();
18742 TCGv t1 = tcg_temp_new();
18743 TCGv v0_t = tcg_temp_new();
18745 gen_load_gpr(v0_t, v1);
18748 case NM_POOL32AXF_1_0:
18750 switch (extract32(ctx->opcode, 12, 2)) {
18752 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18755 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18758 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18761 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18765 case NM_POOL32AXF_1_1:
18767 switch (extract32(ctx->opcode, 12, 2)) {
18769 tcg_gen_movi_tl(t0, v2);
18770 gen_helper_mthlip(t0, v0_t, cpu_env);
18773 tcg_gen_movi_tl(t0, v2 >> 3);
18774 gen_helper_shilo(t0, v0_t, cpu_env);
18777 generate_exception_end(ctx, EXCP_RI);
18781 case NM_POOL32AXF_1_3:
18783 imm = extract32(ctx->opcode, 14, 7);
18784 switch (extract32(ctx->opcode, 12, 2)) {
18786 tcg_gen_movi_tl(t0, imm);
18787 gen_helper_rddsp(t0, t0, cpu_env);
18788 gen_store_gpr(t0, ret);
18791 gen_load_gpr(t0, ret);
18792 tcg_gen_movi_tl(t1, imm);
18793 gen_helper_wrdsp(t0, t1, cpu_env);
18796 tcg_gen_movi_tl(t0, v2 >> 3);
18797 tcg_gen_movi_tl(t1, v1);
18798 gen_helper_extp(t0, t0, t1, cpu_env);
18799 gen_store_gpr(t0, ret);
18802 tcg_gen_movi_tl(t0, v2 >> 3);
18803 tcg_gen_movi_tl(t1, v1);
18804 gen_helper_extpdp(t0, t0, t1, cpu_env);
18805 gen_store_gpr(t0, ret);
18809 case NM_POOL32AXF_1_4:
18811 tcg_gen_movi_tl(t0, v2 >> 2);
18812 switch (extract32(ctx->opcode, 12, 1)) {
18814 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18815 gen_store_gpr(t0, ret);
18818 gen_helper_shrl_qb(t0, t0, v0_t);
18819 gen_store_gpr(t0, ret);
18823 case NM_POOL32AXF_1_5:
18824 opc = extract32(ctx->opcode, 12, 2);
18825 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18827 case NM_POOL32AXF_1_7:
18829 tcg_gen_movi_tl(t0, v2 >> 3);
18830 tcg_gen_movi_tl(t1, v1);
18831 switch (extract32(ctx->opcode, 12, 2)) {
18833 gen_helper_extr_w(t0, t0, t1, cpu_env);
18834 gen_store_gpr(t0, ret);
18837 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18838 gen_store_gpr(t0, ret);
18841 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18842 gen_store_gpr(t0, ret);
18845 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18846 gen_store_gpr(t0, ret);
18851 generate_exception_end(ctx, EXCP_RI);
18857 tcg_temp_free(v0_t);
18860 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18861 TCGv v0, TCGv v1, int rd)
18865 t0 = tcg_temp_new_i32();
18867 tcg_gen_movi_i32(t0, rd >> 3);
18870 case NM_POOL32AXF_2_0_7:
18871 switch (extract32(ctx->opcode, 9, 3)) {
18874 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18876 case NM_DPAQ_S_W_PH:
18878 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18882 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18884 case NM_DPSQ_S_W_PH:
18886 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18889 generate_exception_end(ctx, EXCP_RI);
18893 case NM_POOL32AXF_2_8_15:
18894 switch (extract32(ctx->opcode, 9, 3)) {
18897 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18899 case NM_DPAQ_SA_L_W:
18901 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18905 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18907 case NM_DPSQ_SA_L_W:
18909 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18912 generate_exception_end(ctx, EXCP_RI);
18916 case NM_POOL32AXF_2_16_23:
18917 switch (extract32(ctx->opcode, 9, 3)) {
18918 case NM_DPAU_H_QBL:
18920 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18922 case NM_DPAQX_S_W_PH:
18924 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18926 case NM_DPSU_H_QBL:
18928 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18930 case NM_DPSQX_S_W_PH:
18932 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18934 case NM_MULSA_W_PH:
18936 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18939 generate_exception_end(ctx, EXCP_RI);
18943 case NM_POOL32AXF_2_24_31:
18944 switch (extract32(ctx->opcode, 9, 3)) {
18945 case NM_DPAU_H_QBR:
18947 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18949 case NM_DPAQX_SA_W_PH:
18951 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18953 case NM_DPSU_H_QBR:
18955 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18957 case NM_DPSQX_SA_W_PH:
18959 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18961 case NM_MULSAQ_S_W_PH:
18963 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18966 generate_exception_end(ctx, EXCP_RI);
18971 generate_exception_end(ctx, EXCP_RI);
18975 tcg_temp_free_i32(t0);
18978 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18979 int rt, int rs, int rd)
18982 TCGv t0 = tcg_temp_new();
18983 TCGv t1 = tcg_temp_new();
18984 TCGv v0_t = tcg_temp_new();
18985 TCGv v1_t = tcg_temp_new();
18987 gen_load_gpr(v0_t, rt);
18988 gen_load_gpr(v1_t, rs);
18991 case NM_POOL32AXF_2_0_7:
18992 switch (extract32(ctx->opcode, 9, 3)) {
18994 case NM_DPAQ_S_W_PH:
18996 case NM_DPSQ_S_W_PH:
18997 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19002 gen_load_gpr(t0, rs);
19004 if (rd != 0 && rd != 2) {
19005 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19006 tcg_gen_ext32u_tl(t0, t0);
19007 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19008 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19010 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19016 int acc = extract32(ctx->opcode, 14, 2);
19017 TCGv_i64 t2 = tcg_temp_new_i64();
19018 TCGv_i64 t3 = tcg_temp_new_i64();
19020 gen_load_gpr(t0, rt);
19021 gen_load_gpr(t1, rs);
19022 tcg_gen_ext_tl_i64(t2, t0);
19023 tcg_gen_ext_tl_i64(t3, t1);
19024 tcg_gen_mul_i64(t2, t2, t3);
19025 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19026 tcg_gen_add_i64(t2, t2, t3);
19027 tcg_temp_free_i64(t3);
19028 gen_move_low32(cpu_LO[acc], t2);
19029 gen_move_high32(cpu_HI[acc], t2);
19030 tcg_temp_free_i64(t2);
19036 int acc = extract32(ctx->opcode, 14, 2);
19037 TCGv_i32 t2 = tcg_temp_new_i32();
19038 TCGv_i32 t3 = tcg_temp_new_i32();
19040 gen_load_gpr(t0, rs);
19041 gen_load_gpr(t1, rt);
19042 tcg_gen_trunc_tl_i32(t2, t0);
19043 tcg_gen_trunc_tl_i32(t3, t1);
19044 tcg_gen_muls2_i32(t2, t3, t2, t3);
19045 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19046 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19047 tcg_temp_free_i32(t2);
19048 tcg_temp_free_i32(t3);
19053 gen_load_gpr(v1_t, rs);
19054 tcg_gen_movi_tl(t0, rd >> 3);
19055 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19056 gen_store_gpr(t0, ret);
19060 case NM_POOL32AXF_2_8_15:
19061 switch (extract32(ctx->opcode, 9, 3)) {
19063 case NM_DPAQ_SA_L_W:
19065 case NM_DPSQ_SA_L_W:
19066 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19071 int acc = extract32(ctx->opcode, 14, 2);
19072 TCGv_i64 t2 = tcg_temp_new_i64();
19073 TCGv_i64 t3 = tcg_temp_new_i64();
19075 gen_load_gpr(t0, rs);
19076 gen_load_gpr(t1, rt);
19077 tcg_gen_ext32u_tl(t0, t0);
19078 tcg_gen_ext32u_tl(t1, t1);
19079 tcg_gen_extu_tl_i64(t2, t0);
19080 tcg_gen_extu_tl_i64(t3, t1);
19081 tcg_gen_mul_i64(t2, t2, t3);
19082 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19083 tcg_gen_add_i64(t2, t2, t3);
19084 tcg_temp_free_i64(t3);
19085 gen_move_low32(cpu_LO[acc], t2);
19086 gen_move_high32(cpu_HI[acc], t2);
19087 tcg_temp_free_i64(t2);
19093 int acc = extract32(ctx->opcode, 14, 2);
19094 TCGv_i32 t2 = tcg_temp_new_i32();
19095 TCGv_i32 t3 = tcg_temp_new_i32();
19097 gen_load_gpr(t0, rs);
19098 gen_load_gpr(t1, rt);
19099 tcg_gen_trunc_tl_i32(t2, t0);
19100 tcg_gen_trunc_tl_i32(t3, t1);
19101 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19102 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19103 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19104 tcg_temp_free_i32(t2);
19105 tcg_temp_free_i32(t3);
19110 tcg_gen_movi_tl(t0, rd >> 3);
19111 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19112 gen_store_gpr(t0, ret);
19115 generate_exception_end(ctx, EXCP_RI);
19119 case NM_POOL32AXF_2_16_23:
19120 switch (extract32(ctx->opcode, 9, 3)) {
19121 case NM_DPAU_H_QBL:
19122 case NM_DPAQX_S_W_PH:
19123 case NM_DPSU_H_QBL:
19124 case NM_DPSQX_S_W_PH:
19125 case NM_MULSA_W_PH:
19126 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19130 tcg_gen_movi_tl(t0, rd >> 3);
19131 gen_helper_extp(t0, t0, v1_t, cpu_env);
19132 gen_store_gpr(t0, ret);
19137 int acc = extract32(ctx->opcode, 14, 2);
19138 TCGv_i64 t2 = tcg_temp_new_i64();
19139 TCGv_i64 t3 = tcg_temp_new_i64();
19141 gen_load_gpr(t0, rs);
19142 gen_load_gpr(t1, rt);
19143 tcg_gen_ext_tl_i64(t2, t0);
19144 tcg_gen_ext_tl_i64(t3, t1);
19145 tcg_gen_mul_i64(t2, t2, t3);
19146 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19147 tcg_gen_sub_i64(t2, t3, t2);
19148 tcg_temp_free_i64(t3);
19149 gen_move_low32(cpu_LO[acc], t2);
19150 gen_move_high32(cpu_HI[acc], t2);
19151 tcg_temp_free_i64(t2);
19154 case NM_EXTRV_RS_W:
19156 tcg_gen_movi_tl(t0, rd >> 3);
19157 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19158 gen_store_gpr(t0, ret);
19162 case NM_POOL32AXF_2_24_31:
19163 switch (extract32(ctx->opcode, 9, 3)) {
19164 case NM_DPAU_H_QBR:
19165 case NM_DPAQX_SA_W_PH:
19166 case NM_DPSU_H_QBR:
19167 case NM_DPSQX_SA_W_PH:
19168 case NM_MULSAQ_S_W_PH:
19169 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19173 tcg_gen_movi_tl(t0, rd >> 3);
19174 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19175 gen_store_gpr(t0, ret);
19180 int acc = extract32(ctx->opcode, 14, 2);
19181 TCGv_i64 t2 = tcg_temp_new_i64();
19182 TCGv_i64 t3 = tcg_temp_new_i64();
19184 gen_load_gpr(t0, rs);
19185 gen_load_gpr(t1, rt);
19186 tcg_gen_ext32u_tl(t0, t0);
19187 tcg_gen_ext32u_tl(t1, t1);
19188 tcg_gen_extu_tl_i64(t2, t0);
19189 tcg_gen_extu_tl_i64(t3, t1);
19190 tcg_gen_mul_i64(t2, t2, t3);
19191 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19192 tcg_gen_sub_i64(t2, t3, t2);
19193 tcg_temp_free_i64(t3);
19194 gen_move_low32(cpu_LO[acc], t2);
19195 gen_move_high32(cpu_HI[acc], t2);
19196 tcg_temp_free_i64(t2);
19201 tcg_gen_movi_tl(t0, rd >> 3);
19202 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19203 gen_store_gpr(t0, ret);
19208 generate_exception_end(ctx, EXCP_RI);
19215 tcg_temp_free(v0_t);
19216 tcg_temp_free(v1_t);
19219 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19223 TCGv t0 = tcg_temp_new();
19224 TCGv v0_t = tcg_temp_new();
19226 gen_load_gpr(v0_t, rs);
19231 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19232 gen_store_gpr(v0_t, ret);
19236 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19237 gen_store_gpr(v0_t, ret);
19241 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19242 gen_store_gpr(v0_t, ret);
19244 case NM_PRECEQ_W_PHL:
19246 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19247 tcg_gen_ext32s_tl(v0_t, v0_t);
19248 gen_store_gpr(v0_t, ret);
19250 case NM_PRECEQ_W_PHR:
19252 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19253 tcg_gen_shli_tl(v0_t, v0_t, 16);
19254 tcg_gen_ext32s_tl(v0_t, v0_t);
19255 gen_store_gpr(v0_t, ret);
19257 case NM_PRECEQU_PH_QBL:
19259 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19260 gen_store_gpr(v0_t, ret);
19262 case NM_PRECEQU_PH_QBR:
19264 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19265 gen_store_gpr(v0_t, ret);
19267 case NM_PRECEQU_PH_QBLA:
19269 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19270 gen_store_gpr(v0_t, ret);
19272 case NM_PRECEQU_PH_QBRA:
19274 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19275 gen_store_gpr(v0_t, ret);
19277 case NM_PRECEU_PH_QBL:
19279 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19280 gen_store_gpr(v0_t, ret);
19282 case NM_PRECEU_PH_QBR:
19284 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19285 gen_store_gpr(v0_t, ret);
19287 case NM_PRECEU_PH_QBLA:
19289 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19290 gen_store_gpr(v0_t, ret);
19292 case NM_PRECEU_PH_QBRA:
19294 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19295 gen_store_gpr(v0_t, ret);
19299 tcg_gen_ext16u_tl(v0_t, v0_t);
19300 tcg_gen_shli_tl(t0, v0_t, 16);
19301 tcg_gen_or_tl(v0_t, v0_t, t0);
19302 tcg_gen_ext32s_tl(v0_t, v0_t);
19303 gen_store_gpr(v0_t, ret);
19307 tcg_gen_ext8u_tl(v0_t, v0_t);
19308 tcg_gen_shli_tl(t0, v0_t, 8);
19309 tcg_gen_or_tl(v0_t, v0_t, t0);
19310 tcg_gen_shli_tl(t0, v0_t, 16);
19311 tcg_gen_or_tl(v0_t, v0_t, t0);
19312 tcg_gen_ext32s_tl(v0_t, v0_t);
19313 gen_store_gpr(v0_t, ret);
19317 gen_helper_bitrev(v0_t, v0_t);
19318 gen_store_gpr(v0_t, ret);
19323 TCGv tv0 = tcg_temp_new();
19325 gen_load_gpr(tv0, rt);
19326 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19327 gen_store_gpr(v0_t, ret);
19328 tcg_temp_free(tv0);
19331 case NM_RADDU_W_QB:
19333 gen_helper_raddu_w_qb(v0_t, v0_t);
19334 gen_store_gpr(v0_t, ret);
19337 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19341 gen_cl(ctx, OPC_CLO, ret, rs);
19345 gen_cl(ctx, OPC_CLZ, ret, rs);
19348 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19351 generate_exception_end(ctx, EXCP_RI);
19355 tcg_temp_free(v0_t);
19359 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19360 int rt, int rs, int rd)
19362 TCGv t0 = tcg_temp_new();
19363 TCGv rs_t = tcg_temp_new();
19365 gen_load_gpr(rs_t, rs);
19370 tcg_gen_movi_tl(t0, rd >> 2);
19371 switch (extract32(ctx->opcode, 12, 1)) {
19374 gen_helper_shra_qb(t0, t0, rs_t);
19375 gen_store_gpr(t0, rt);
19379 gen_helper_shra_r_qb(t0, t0, rs_t);
19380 gen_store_gpr(t0, rt);
19386 tcg_gen_movi_tl(t0, rd >> 1);
19387 gen_helper_shrl_ph(t0, t0, rs_t);
19388 gen_store_gpr(t0, rt);
19394 target_long result;
19395 imm = extract32(ctx->opcode, 13, 8);
19396 result = (uint32_t)imm << 24 |
19397 (uint32_t)imm << 16 |
19398 (uint32_t)imm << 8 |
19400 result = (int32_t)result;
19401 tcg_gen_movi_tl(t0, result);
19402 gen_store_gpr(t0, rt);
19406 generate_exception_end(ctx, EXCP_RI);
19410 tcg_temp_free(rs_t);
19414 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19416 int rt = extract32(ctx->opcode, 21, 5);
19417 int rs = extract32(ctx->opcode, 16, 5);
19418 int rd = extract32(ctx->opcode, 11, 5);
19420 switch (extract32(ctx->opcode, 6, 3)) {
19421 case NM_POOL32AXF_1:
19423 int32_t op1 = extract32(ctx->opcode, 9, 3);
19424 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19427 case NM_POOL32AXF_2:
19429 int32_t op1 = extract32(ctx->opcode, 12, 2);
19430 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19433 case NM_POOL32AXF_4:
19435 int32_t op1 = extract32(ctx->opcode, 9, 7);
19436 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19439 case NM_POOL32AXF_5:
19440 switch (extract32(ctx->opcode, 9, 7)) {
19441 #ifndef CONFIG_USER_ONLY
19443 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19446 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19449 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19452 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19455 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19458 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19461 check_cp0_enabled(ctx);
19463 TCGv t0 = tcg_temp_new();
19465 save_cpu_state(ctx, 1);
19466 gen_helper_di(t0, cpu_env);
19467 gen_store_gpr(t0, rt);
19468 /* Stop translation as we may have switched the execution mode */
19469 ctx->base.is_jmp = DISAS_STOP;
19474 check_cp0_enabled(ctx);
19476 TCGv t0 = tcg_temp_new();
19478 save_cpu_state(ctx, 1);
19479 gen_helper_ei(t0, cpu_env);
19480 gen_store_gpr(t0, rt);
19481 /* Stop translation as we may have switched the execution mode */
19482 ctx->base.is_jmp = DISAS_STOP;
19487 gen_load_srsgpr(rs, rt);
19490 gen_store_srsgpr(rs, rt);
19493 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19496 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19499 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19503 generate_exception_end(ctx, EXCP_RI);
19507 case NM_POOL32AXF_7:
19509 int32_t op1 = extract32(ctx->opcode, 9, 3);
19510 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19514 generate_exception_end(ctx, EXCP_RI);
19519 /* Immediate Value Compact Branches */
19520 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19521 int rt, int32_t imm, int32_t offset)
19524 int bcond_compute = 0;
19525 TCGv t0 = tcg_temp_new();
19526 TCGv t1 = tcg_temp_new();
19528 gen_load_gpr(t0, rt);
19529 tcg_gen_movi_tl(t1, imm);
19530 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19532 /* Load needed operands and calculate btarget */
19535 if (rt == 0 && imm == 0) {
19536 /* Unconditional branch */
19537 } else if (rt == 0 && imm != 0) {
19542 cond = TCG_COND_EQ;
19548 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19549 generate_exception_end(ctx, EXCP_RI);
19551 } else if (rt == 0 && opc == NM_BBEQZC) {
19552 /* Unconditional branch */
19553 } else if (rt == 0 && opc == NM_BBNEZC) {
19557 tcg_gen_shri_tl(t0, t0, imm);
19558 tcg_gen_andi_tl(t0, t0, 1);
19559 tcg_gen_movi_tl(t1, 0);
19561 if (opc == NM_BBEQZC) {
19562 cond = TCG_COND_EQ;
19564 cond = TCG_COND_NE;
19569 if (rt == 0 && imm == 0) {
19572 } else if (rt == 0 && imm != 0) {
19573 /* Unconditional branch */
19576 cond = TCG_COND_NE;
19580 if (rt == 0 && imm == 0) {
19581 /* Unconditional branch */
19584 cond = TCG_COND_GE;
19589 cond = TCG_COND_LT;
19592 if (rt == 0 && imm == 0) {
19593 /* Unconditional branch */
19596 cond = TCG_COND_GEU;
19601 cond = TCG_COND_LTU;
19604 MIPS_INVAL("Immediate Value Compact branch");
19605 generate_exception_end(ctx, EXCP_RI);
19609 if (bcond_compute == 0) {
19610 /* Uncoditional compact branch */
19611 gen_goto_tb(ctx, 0, ctx->btarget);
19613 /* Conditional compact branch */
19614 TCGLabel *fs = gen_new_label();
19616 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19618 gen_goto_tb(ctx, 1, ctx->btarget);
19621 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19629 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19630 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19633 TCGv t0 = tcg_temp_new();
19634 TCGv t1 = tcg_temp_new();
19637 gen_load_gpr(t0, rs);
19641 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19644 /* calculate btarget */
19645 tcg_gen_shli_tl(t0, t0, 1);
19646 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19647 gen_op_addr_add(ctx, btarget, t1, t0);
19649 /* unconditional branch to register */
19650 tcg_gen_mov_tl(cpu_PC, btarget);
19651 tcg_gen_lookup_and_goto_ptr();
19657 /* nanoMIPS Branches */
19658 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19659 int rs, int rt, int32_t offset)
19661 int bcond_compute = 0;
19662 TCGv t0 = tcg_temp_new();
19663 TCGv t1 = tcg_temp_new();
19665 /* Load needed operands and calculate btarget */
19667 /* compact branch */
19670 gen_load_gpr(t0, rs);
19671 gen_load_gpr(t1, rt);
19673 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19677 if (rs == 0 || rs == rt) {
19678 /* OPC_BLEZALC, OPC_BGEZALC */
19679 /* OPC_BGTZALC, OPC_BLTZALC */
19680 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19682 gen_load_gpr(t0, rs);
19683 gen_load_gpr(t1, rt);
19685 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19688 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19692 /* OPC_BEQZC, OPC_BNEZC */
19693 gen_load_gpr(t0, rs);
19695 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19697 /* OPC_JIC, OPC_JIALC */
19698 TCGv tbase = tcg_temp_new();
19699 TCGv toffset = tcg_temp_new();
19701 gen_load_gpr(tbase, rt);
19702 tcg_gen_movi_tl(toffset, offset);
19703 gen_op_addr_add(ctx, btarget, tbase, toffset);
19704 tcg_temp_free(tbase);
19705 tcg_temp_free(toffset);
19709 MIPS_INVAL("Compact branch/jump");
19710 generate_exception_end(ctx, EXCP_RI);
19714 if (bcond_compute == 0) {
19715 /* Uncoditional compact branch */
19718 gen_goto_tb(ctx, 0, ctx->btarget);
19721 MIPS_INVAL("Compact branch/jump");
19722 generate_exception_end(ctx, EXCP_RI);
19726 /* Conditional compact branch */
19727 TCGLabel *fs = gen_new_label();
19731 if (rs == 0 && rt != 0) {
19733 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19734 } else if (rs != 0 && rt != 0 && rs == rt) {
19736 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19739 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19743 if (rs == 0 && rt != 0) {
19745 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19746 } else if (rs != 0 && rt != 0 && rs == rt) {
19748 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19751 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19755 if (rs == 0 && rt != 0) {
19757 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19758 } else if (rs != 0 && rt != 0 && rs == rt) {
19760 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19763 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19767 if (rs == 0 && rt != 0) {
19769 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19770 } else if (rs != 0 && rt != 0 && rs == rt) {
19772 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19775 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19779 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19782 MIPS_INVAL("Compact conditional branch/jump");
19783 generate_exception_end(ctx, EXCP_RI);
19787 /* Generating branch here as compact branches don't have delay slot */
19788 gen_goto_tb(ctx, 1, ctx->btarget);
19791 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19800 /* nanoMIPS CP1 Branches */
19801 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19802 int32_t ft, int32_t offset)
19804 target_ulong btarget;
19805 TCGv_i64 t0 = tcg_temp_new_i64();
19807 gen_load_fpr64(ctx, t0, ft);
19808 tcg_gen_andi_i64(t0, t0, 1);
19810 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19814 tcg_gen_xori_i64(t0, t0, 1);
19815 ctx->hflags |= MIPS_HFLAG_BC;
19818 /* t0 already set */
19819 ctx->hflags |= MIPS_HFLAG_BC;
19822 MIPS_INVAL("cp1 cond branch");
19823 generate_exception_end(ctx, EXCP_RI);
19827 tcg_gen_trunc_i64_tl(bcond, t0);
19829 ctx->btarget = btarget;
19832 tcg_temp_free_i64(t0);
19836 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19839 t0 = tcg_temp_new();
19840 t1 = tcg_temp_new();
19842 gen_load_gpr(t0, rs);
19843 gen_load_gpr(t1, rt);
19845 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19846 /* PP.LSXS instructions require shifting */
19847 switch (extract32(ctx->opcode, 7, 4)) {
19852 tcg_gen_shli_tl(t0, t0, 1);
19859 tcg_gen_shli_tl(t0, t0, 2);
19863 tcg_gen_shli_tl(t0, t0, 3);
19867 gen_op_addr_add(ctx, t0, t0, t1);
19869 switch (extract32(ctx->opcode, 7, 4)) {
19871 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19873 gen_store_gpr(t0, rd);
19877 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19879 gen_store_gpr(t0, rd);
19883 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19885 gen_store_gpr(t0, rd);
19888 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19890 gen_store_gpr(t0, rd);
19894 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19896 gen_store_gpr(t0, rd);
19900 gen_load_gpr(t1, rd);
19901 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19907 gen_load_gpr(t1, rd);
19908 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19914 gen_load_gpr(t1, rd);
19915 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19919 /*case NM_LWC1XS:*/
19921 /*case NM_LDC1XS:*/
19923 /*case NM_SWC1XS:*/
19925 /*case NM_SDC1XS:*/
19926 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19927 check_cp1_enabled(ctx);
19928 switch (extract32(ctx->opcode, 7, 4)) {
19930 /*case NM_LWC1XS:*/
19931 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19934 /*case NM_LDC1XS:*/
19935 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19938 /*case NM_SWC1XS:*/
19939 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19942 /*case NM_SDC1XS:*/
19943 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19947 generate_exception_err(ctx, EXCP_CpU, 1);
19951 generate_exception_end(ctx, EXCP_RI);
19959 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19963 rt = extract32(ctx->opcode, 21, 5);
19964 rs = extract32(ctx->opcode, 16, 5);
19965 rd = extract32(ctx->opcode, 11, 5);
19967 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19968 generate_exception_end(ctx, EXCP_RI);
19971 check_cp1_enabled(ctx);
19972 switch (extract32(ctx->opcode, 0, 3)) {
19974 switch (extract32(ctx->opcode, 3, 7)) {
19976 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19979 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19982 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19985 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19988 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19991 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19994 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19997 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20000 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20003 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20006 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20009 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20012 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20015 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20018 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20021 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20024 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20027 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20030 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20033 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20036 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20039 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20042 generate_exception_end(ctx, EXCP_RI);
20047 switch (extract32(ctx->opcode, 3, 3)) {
20049 switch (extract32(ctx->opcode, 9, 1)) {
20051 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20054 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20059 switch (extract32(ctx->opcode, 9, 1)) {
20061 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20064 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20069 switch (extract32(ctx->opcode, 9, 1)) {
20071 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20074 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20079 switch (extract32(ctx->opcode, 9, 1)) {
20081 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20084 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20089 switch (extract32(ctx->opcode, 6, 8)) {
20091 gen_cp1(ctx, OPC_CFC1, rt, rs);
20094 gen_cp1(ctx, OPC_CTC1, rt, rs);
20097 gen_cp1(ctx, OPC_MFC1, rt, rs);
20100 gen_cp1(ctx, OPC_MTC1, rt, rs);
20103 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20106 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20109 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20112 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20115 switch (extract32(ctx->opcode, 6, 9)) {
20117 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20120 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20123 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20126 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20129 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20132 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20135 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20138 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20141 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20144 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20147 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20150 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20153 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20156 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20159 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20162 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20165 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20168 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20171 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20174 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20177 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20180 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20183 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20186 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20189 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20192 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20195 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20198 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20201 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20204 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20207 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20210 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20213 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20216 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20219 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20222 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20225 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20228 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20231 generate_exception_end(ctx, EXCP_RI);
20240 switch (extract32(ctx->opcode, 3, 3)) {
20241 case NM_CMP_CONDN_S:
20242 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20244 case NM_CMP_CONDN_D:
20245 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20248 generate_exception_end(ctx, EXCP_RI);
20253 generate_exception_end(ctx, EXCP_RI);
20258 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20259 int rd, int rs, int rt)
20262 TCGv t0 = tcg_temp_new();
20263 TCGv v1_t = tcg_temp_new();
20264 TCGv v2_t = tcg_temp_new();
20266 gen_load_gpr(v1_t, rs);
20267 gen_load_gpr(v2_t, rt);
20272 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20276 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20280 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20282 case NM_CMPU_EQ_QB:
20284 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20286 case NM_CMPU_LT_QB:
20288 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20290 case NM_CMPU_LE_QB:
20292 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20294 case NM_CMPGU_EQ_QB:
20296 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20297 gen_store_gpr(v1_t, ret);
20299 case NM_CMPGU_LT_QB:
20301 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20302 gen_store_gpr(v1_t, ret);
20304 case NM_CMPGU_LE_QB:
20306 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20307 gen_store_gpr(v1_t, ret);
20309 case NM_CMPGDU_EQ_QB:
20311 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20312 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20313 gen_store_gpr(v1_t, ret);
20315 case NM_CMPGDU_LT_QB:
20317 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20318 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20319 gen_store_gpr(v1_t, ret);
20321 case NM_CMPGDU_LE_QB:
20323 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20324 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20325 gen_store_gpr(v1_t, ret);
20329 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20330 gen_store_gpr(v1_t, ret);
20334 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20335 gen_store_gpr(v1_t, ret);
20339 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20340 gen_store_gpr(v1_t, ret);
20344 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20345 gen_store_gpr(v1_t, ret);
20349 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20350 gen_store_gpr(v1_t, ret);
20354 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20355 gen_store_gpr(v1_t, ret);
20359 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20360 gen_store_gpr(v1_t, ret);
20364 switch (extract32(ctx->opcode, 10, 1)) {
20367 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20368 gen_store_gpr(v1_t, ret);
20372 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20373 gen_store_gpr(v1_t, ret);
20377 case NM_ADDQH_R_PH:
20379 switch (extract32(ctx->opcode, 10, 1)) {
20382 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20383 gen_store_gpr(v1_t, ret);
20387 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20388 gen_store_gpr(v1_t, ret);
20394 switch (extract32(ctx->opcode, 10, 1)) {
20397 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20398 gen_store_gpr(v1_t, ret);
20402 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20403 gen_store_gpr(v1_t, ret);
20409 switch (extract32(ctx->opcode, 10, 1)) {
20412 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20413 gen_store_gpr(v1_t, ret);
20417 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20418 gen_store_gpr(v1_t, ret);
20424 switch (extract32(ctx->opcode, 10, 1)) {
20427 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20428 gen_store_gpr(v1_t, ret);
20432 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20433 gen_store_gpr(v1_t, ret);
20437 case NM_ADDUH_R_QB:
20439 switch (extract32(ctx->opcode, 10, 1)) {
20442 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20443 gen_store_gpr(v1_t, ret);
20447 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20448 gen_store_gpr(v1_t, ret);
20452 case NM_SHRAV_R_PH:
20454 switch (extract32(ctx->opcode, 10, 1)) {
20457 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20458 gen_store_gpr(v1_t, ret);
20462 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20463 gen_store_gpr(v1_t, ret);
20467 case NM_SHRAV_R_QB:
20469 switch (extract32(ctx->opcode, 10, 1)) {
20472 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20473 gen_store_gpr(v1_t, ret);
20477 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20478 gen_store_gpr(v1_t, ret);
20484 switch (extract32(ctx->opcode, 10, 1)) {
20487 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20488 gen_store_gpr(v1_t, ret);
20492 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20493 gen_store_gpr(v1_t, ret);
20497 case NM_SUBQH_R_PH:
20499 switch (extract32(ctx->opcode, 10, 1)) {
20502 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20503 gen_store_gpr(v1_t, ret);
20507 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20508 gen_store_gpr(v1_t, ret);
20514 switch (extract32(ctx->opcode, 10, 1)) {
20517 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20518 gen_store_gpr(v1_t, ret);
20522 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20523 gen_store_gpr(v1_t, ret);
20529 switch (extract32(ctx->opcode, 10, 1)) {
20532 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20533 gen_store_gpr(v1_t, ret);
20537 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20538 gen_store_gpr(v1_t, ret);
20544 switch (extract32(ctx->opcode, 10, 1)) {
20547 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20548 gen_store_gpr(v1_t, ret);
20552 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20553 gen_store_gpr(v1_t, ret);
20557 case NM_SUBUH_R_QB:
20559 switch (extract32(ctx->opcode, 10, 1)) {
20562 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20563 gen_store_gpr(v1_t, ret);
20567 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20568 gen_store_gpr(v1_t, ret);
20572 case NM_SHLLV_S_PH:
20574 switch (extract32(ctx->opcode, 10, 1)) {
20577 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20578 gen_store_gpr(v1_t, ret);
20582 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20583 gen_store_gpr(v1_t, ret);
20587 case NM_PRECR_SRA_R_PH_W:
20589 switch (extract32(ctx->opcode, 10, 1)) {
20591 /* PRECR_SRA_PH_W */
20593 TCGv_i32 sa_t = tcg_const_i32(rd);
20594 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20596 gen_store_gpr(v1_t, rt);
20597 tcg_temp_free_i32(sa_t);
20601 /* PRECR_SRA_R_PH_W */
20603 TCGv_i32 sa_t = tcg_const_i32(rd);
20604 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20606 gen_store_gpr(v1_t, rt);
20607 tcg_temp_free_i32(sa_t);
20612 case NM_MULEU_S_PH_QBL:
20614 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20615 gen_store_gpr(v1_t, ret);
20617 case NM_MULEU_S_PH_QBR:
20619 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20620 gen_store_gpr(v1_t, ret);
20622 case NM_MULQ_RS_PH:
20624 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20625 gen_store_gpr(v1_t, ret);
20629 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20630 gen_store_gpr(v1_t, ret);
20634 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20635 gen_store_gpr(v1_t, ret);
20639 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20640 gen_store_gpr(v1_t, ret);
20644 gen_load_gpr(t0, rs);
20646 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20648 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20652 gen_helper_modsub(v1_t, v1_t, v2_t);
20653 gen_store_gpr(v1_t, ret);
20657 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20658 gen_store_gpr(v1_t, ret);
20662 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20663 gen_store_gpr(v1_t, ret);
20667 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20668 gen_store_gpr(v1_t, ret);
20672 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20673 gen_store_gpr(v1_t, ret);
20677 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20678 gen_store_gpr(v1_t, ret);
20683 TCGv tv0 = tcg_temp_new();
20684 TCGv tv1 = tcg_temp_new();
20685 int16_t imm = extract32(ctx->opcode, 16, 7);
20687 tcg_gen_movi_tl(tv0, rd >> 3);
20688 tcg_gen_movi_tl(tv1, imm);
20689 gen_helper_shilo(tv0, tv1, cpu_env);
20692 case NM_MULEQ_S_W_PHL:
20694 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20695 gen_store_gpr(v1_t, ret);
20697 case NM_MULEQ_S_W_PHR:
20699 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20700 gen_store_gpr(v1_t, ret);
20704 switch (extract32(ctx->opcode, 10, 1)) {
20707 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20708 gen_store_gpr(v1_t, ret);
20712 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20713 gen_store_gpr(v1_t, ret);
20717 case NM_PRECR_QB_PH:
20719 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20720 gen_store_gpr(v1_t, ret);
20722 case NM_PRECRQ_QB_PH:
20724 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20725 gen_store_gpr(v1_t, ret);
20727 case NM_PRECRQ_PH_W:
20729 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20730 gen_store_gpr(v1_t, ret);
20732 case NM_PRECRQ_RS_PH_W:
20734 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20735 gen_store_gpr(v1_t, ret);
20737 case NM_PRECRQU_S_QB_PH:
20739 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20740 gen_store_gpr(v1_t, ret);
20744 tcg_gen_movi_tl(t0, rd);
20745 gen_helper_shra_r_w(v1_t, t0, v1_t);
20746 gen_store_gpr(v1_t, rt);
20750 tcg_gen_movi_tl(t0, rd >> 1);
20751 switch (extract32(ctx->opcode, 10, 1)) {
20754 gen_helper_shra_ph(v1_t, t0, v1_t);
20755 gen_store_gpr(v1_t, rt);
20759 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20760 gen_store_gpr(v1_t, rt);
20766 tcg_gen_movi_tl(t0, rd >> 1);
20767 switch (extract32(ctx->opcode, 10, 2)) {
20770 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20771 gen_store_gpr(v1_t, rt);
20775 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20776 gen_store_gpr(v1_t, rt);
20779 generate_exception_end(ctx, EXCP_RI);
20785 tcg_gen_movi_tl(t0, rd);
20786 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20787 gen_store_gpr(v1_t, rt);
20793 imm = sextract32(ctx->opcode, 11, 11);
20794 imm = (int16_t)(imm << 6) >> 6;
20796 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20801 generate_exception_end(ctx, EXCP_RI);
20806 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20814 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20815 ctx->opcode = (ctx->opcode << 16) | insn;
20817 rt = extract32(ctx->opcode, 21, 5);
20818 rs = extract32(ctx->opcode, 16, 5);
20819 rd = extract32(ctx->opcode, 11, 5);
20821 op = extract32(ctx->opcode, 26, 6);
20826 switch (extract32(ctx->opcode, 19, 2)) {
20829 generate_exception_end(ctx, EXCP_RI);
20832 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20833 generate_exception_end(ctx, EXCP_SYSCALL);
20835 generate_exception_end(ctx, EXCP_RI);
20839 generate_exception_end(ctx, EXCP_BREAK);
20842 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20843 gen_helper_do_semihosting(cpu_env);
20845 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20846 generate_exception_end(ctx, EXCP_RI);
20848 generate_exception_end(ctx, EXCP_DBp);
20855 imm = extract32(ctx->opcode, 0, 16);
20857 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20859 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20861 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20866 offset = sextract32(ctx->opcode, 0, 1) << 21 |
20867 extract32(ctx->opcode, 1, 20) << 1;
20868 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20869 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20873 switch (ctx->opcode & 0x07) {
20875 gen_pool32a0_nanomips_insn(env, ctx);
20879 int32_t op1 = extract32(ctx->opcode, 3, 7);
20880 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20884 switch (extract32(ctx->opcode, 3, 3)) {
20886 gen_p_lsx(ctx, rd, rs, rt);
20889 /* In nanoMIPS, the shift field directly encodes the shift
20890 * amount, meaning that the supported shift values are in
20891 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20892 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20893 extract32(ctx->opcode, 9, 2) - 1);
20896 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20899 gen_pool32axf_nanomips_insn(env, ctx);
20902 generate_exception_end(ctx, EXCP_RI);
20907 generate_exception_end(ctx, EXCP_RI);
20912 switch (ctx->opcode & 0x03) {
20915 offset = extract32(ctx->opcode, 0, 21);
20916 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20920 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20923 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20926 generate_exception_end(ctx, EXCP_RI);
20932 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20933 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20934 switch (extract32(ctx->opcode, 16, 5)) {
20938 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20944 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20945 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20951 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20957 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20960 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20967 t0 = tcg_temp_new();
20969 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20972 tcg_gen_movi_tl(t0, addr);
20973 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20981 t0 = tcg_temp_new();
20982 t1 = tcg_temp_new();
20984 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20987 tcg_gen_movi_tl(t0, addr);
20988 gen_load_gpr(t1, rt);
20990 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20997 generate_exception_end(ctx, EXCP_RI);
21003 switch (extract32(ctx->opcode, 12, 4)) {
21005 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21008 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21011 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21014 switch (extract32(ctx->opcode, 20, 1)) {
21016 switch (ctx->opcode & 3) {
21018 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21019 extract32(ctx->opcode, 2, 1),
21020 extract32(ctx->opcode, 3, 9) << 3);
21023 case NM_RESTORE_JRC:
21024 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21025 extract32(ctx->opcode, 2, 1),
21026 extract32(ctx->opcode, 3, 9) << 3);
21027 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21028 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21032 generate_exception_end(ctx, EXCP_RI);
21037 generate_exception_end(ctx, EXCP_RI);
21042 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21045 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21049 TCGv t0 = tcg_temp_new();
21051 imm = extract32(ctx->opcode, 0, 12);
21052 gen_load_gpr(t0, rs);
21053 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21054 gen_store_gpr(t0, rt);
21060 imm = (int16_t) extract32(ctx->opcode, 0, 12);
21061 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21065 int shift = extract32(ctx->opcode, 0, 5);
21066 switch (extract32(ctx->opcode, 5, 4)) {
21068 if (rt == 0 && shift == 0) {
21070 } else if (rt == 0 && shift == 3) {
21071 /* EHB - treat as NOP */
21072 } else if (rt == 0 && shift == 5) {
21073 /* PAUSE - treat as NOP */
21074 } else if (rt == 0 && shift == 6) {
21076 gen_sync(extract32(ctx->opcode, 16, 5));
21079 gen_shift_imm(ctx, OPC_SLL, rt, rs,
21080 extract32(ctx->opcode, 0, 5));
21084 gen_shift_imm(ctx, OPC_SRL, rt, rs,
21085 extract32(ctx->opcode, 0, 5));
21088 gen_shift_imm(ctx, OPC_SRA, rt, rs,
21089 extract32(ctx->opcode, 0, 5));
21092 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21093 extract32(ctx->opcode, 0, 5));
21101 TCGv t0 = tcg_temp_new();
21102 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21103 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21105 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21107 gen_load_gpr(t0, rs);
21108 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21111 tcg_temp_free_i32(shift);
21112 tcg_temp_free_i32(shiftx);
21113 tcg_temp_free_i32(stripe);
21117 switch (((ctx->opcode >> 10) & 2) |
21118 (extract32(ctx->opcode, 5, 1))) {
21121 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21122 extract32(ctx->opcode, 6, 5));
21125 generate_exception_end(ctx, EXCP_RI);
21130 switch (((ctx->opcode >> 10) & 2) |
21131 (extract32(ctx->opcode, 5, 1))) {
21134 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21135 extract32(ctx->opcode, 6, 5));
21138 generate_exception_end(ctx, EXCP_RI);
21143 generate_exception_end(ctx, EXCP_RI);
21148 gen_pool32f_nanomips_insn(ctx);
21153 switch (extract32(ctx->opcode, 1, 1)) {
21156 tcg_gen_movi_tl(cpu_gpr[rt],
21157 sextract32(ctx->opcode, 0, 1) << 31 |
21158 extract32(ctx->opcode, 2, 10) << 21 |
21159 extract32(ctx->opcode, 12, 9) << 12);
21164 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21165 extract32(ctx->opcode, 2, 10) << 21 |
21166 extract32(ctx->opcode, 12, 9) << 12;
21168 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21169 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21176 uint32_t u = extract32(ctx->opcode, 0, 18);
21178 switch (extract32(ctx->opcode, 18, 3)) {
21180 gen_ld(ctx, OPC_LB, rt, 28, u);
21183 gen_st(ctx, OPC_SB, rt, 28, u);
21186 gen_ld(ctx, OPC_LBU, rt, 28, u);
21190 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21195 switch (ctx->opcode & 1) {
21197 gen_ld(ctx, OPC_LH, rt, 28, u);
21200 gen_ld(ctx, OPC_LHU, rt, 28, u);
21206 switch (ctx->opcode & 1) {
21208 gen_st(ctx, OPC_SH, rt, 28, u);
21211 generate_exception_end(ctx, EXCP_RI);
21217 switch (ctx->opcode & 0x3) {
21219 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21222 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21225 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21228 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21233 generate_exception_end(ctx, EXCP_RI);
21240 uint32_t u = extract32(ctx->opcode, 0, 12);
21242 switch (extract32(ctx->opcode, 12, 4)) {
21246 /* Break the TB to be able to sync copied instructions
21248 ctx->base.is_jmp = DISAS_STOP;
21251 /* Treat as NOP. */
21255 gen_ld(ctx, OPC_LB, rt, rs, u);
21258 gen_ld(ctx, OPC_LH, rt, rs, u);
21261 gen_ld(ctx, OPC_LW, rt, rs, u);
21264 gen_ld(ctx, OPC_LBU, rt, rs, u);
21267 gen_ld(ctx, OPC_LHU, rt, rs, u);
21270 gen_st(ctx, OPC_SB, rt, rs, u);
21273 gen_st(ctx, OPC_SH, rt, rs, u);
21276 gen_st(ctx, OPC_SW, rt, rs, u);
21279 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21282 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21285 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21288 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21291 generate_exception_end(ctx, EXCP_RI);
21298 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21299 extract32(ctx->opcode, 0, 8);
21301 switch (extract32(ctx->opcode, 8, 3)) {
21303 switch (extract32(ctx->opcode, 11, 4)) {
21305 gen_ld(ctx, OPC_LB, rt, rs, s);
21308 gen_ld(ctx, OPC_LH, rt, rs, s);
21311 gen_ld(ctx, OPC_LW, rt, rs, s);
21314 gen_ld(ctx, OPC_LBU, rt, rs, s);
21317 gen_ld(ctx, OPC_LHU, rt, rs, s);
21320 gen_st(ctx, OPC_SB, rt, rs, s);
21323 gen_st(ctx, OPC_SH, rt, rs, s);
21326 gen_st(ctx, OPC_SW, rt, rs, s);
21329 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21332 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21335 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21338 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21343 /* Break the TB to be able to sync copied instructions
21345 ctx->base.is_jmp = DISAS_STOP;
21348 /* Treat as NOP. */
21352 generate_exception_end(ctx, EXCP_RI);
21357 switch (extract32(ctx->opcode, 11, 4)) {
21362 TCGv t0 = tcg_temp_new();
21363 TCGv t1 = tcg_temp_new();
21365 gen_base_offset_addr(ctx, t0, rs, s);
21367 switch (extract32(ctx->opcode, 11, 4)) {
21369 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21371 gen_store_gpr(t0, rt);
21374 gen_load_gpr(t1, rt);
21375 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21384 switch (ctx->opcode & 0x03) {
21386 gen_ld(ctx, OPC_LL, rt, rs, s);
21390 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21395 switch (ctx->opcode & 0x03) {
21397 gen_st_cond(ctx, OPC_SC, rt, rs, s);
21401 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21406 check_cp0_enabled(ctx);
21407 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21408 gen_cache_operation(ctx, rt, rs, s);
21414 switch (extract32(ctx->opcode, 11, 4)) {
21417 check_cp0_enabled(ctx);
21418 gen_ld(ctx, OPC_LBE, rt, rs, s);
21422 check_cp0_enabled(ctx);
21423 gen_st(ctx, OPC_SBE, rt, rs, s);
21427 check_cp0_enabled(ctx);
21428 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21432 /* case NM_SYNCIE */
21434 check_cp0_enabled(ctx);
21435 /* Break the TB to be able to sync copied instructions
21437 ctx->base.is_jmp = DISAS_STOP;
21439 /* case NM_PREFE */
21441 check_cp0_enabled(ctx);
21442 /* Treat as NOP. */
21447 check_cp0_enabled(ctx);
21448 gen_ld(ctx, OPC_LHE, rt, rs, s);
21452 check_cp0_enabled(ctx);
21453 gen_st(ctx, OPC_SHE, rt, rs, s);
21457 check_cp0_enabled(ctx);
21458 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21461 check_nms_dl_il_sl_tl_l2c(ctx);
21462 gen_cache_operation(ctx, rt, rs, s);
21466 check_cp0_enabled(ctx);
21467 gen_ld(ctx, OPC_LWE, rt, rs, s);
21471 check_cp0_enabled(ctx);
21472 gen_st(ctx, OPC_SWE, rt, rs, s);
21475 switch (extract32(ctx->opcode, 2, 2)) {
21479 check_cp0_enabled(ctx);
21480 gen_ld(ctx, OPC_LLE, rt, rs, s);
21485 check_cp0_enabled(ctx);
21486 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21489 generate_exception_end(ctx, EXCP_RI);
21494 switch (extract32(ctx->opcode, 2, 2)) {
21498 check_cp0_enabled(ctx);
21499 gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21504 check_cp0_enabled(ctx);
21505 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21508 generate_exception_end(ctx, EXCP_RI);
21518 int count = extract32(ctx->opcode, 12, 3);
21521 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21522 extract32(ctx->opcode, 0, 8);
21523 TCGv va = tcg_temp_new();
21524 TCGv t1 = tcg_temp_new();
21525 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21526 NM_P_LS_UAWM ? MO_UNALN : 0;
21528 count = (count == 0) ? 8 : count;
21529 while (counter != count) {
21530 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21531 int this_offset = offset + (counter << 2);
21533 gen_base_offset_addr(ctx, va, rs, this_offset);
21535 switch (extract32(ctx->opcode, 11, 1)) {
21537 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21539 gen_store_gpr(t1, this_rt);
21540 if ((this_rt == rs) &&
21541 (counter != (count - 1))) {
21542 /* UNPREDICTABLE */
21546 this_rt = (rt == 0) ? 0 : this_rt;
21547 gen_load_gpr(t1, this_rt);
21548 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21559 generate_exception_end(ctx, EXCP_RI);
21567 TCGv t0 = tcg_temp_new();
21568 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21569 extract32(ctx->opcode, 1, 20) << 1;
21570 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21571 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21572 extract32(ctx->opcode, 21, 3));
21573 gen_load_gpr(t0, rt);
21574 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21575 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21581 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21582 extract32(ctx->opcode, 1, 24) << 1;
21584 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21586 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21589 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21594 switch (extract32(ctx->opcode, 12, 4)) {
21597 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21600 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21603 generate_exception_end(ctx, EXCP_RI);
21609 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21610 extract32(ctx->opcode, 1, 13) << 1;
21611 switch (extract32(ctx->opcode, 14, 2)) {
21614 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21617 s = sextract32(ctx->opcode, 0, 1) << 14 |
21618 extract32(ctx->opcode, 1, 13) << 1;
21619 check_cp1_enabled(ctx);
21620 switch (extract32(ctx->opcode, 16, 5)) {
21622 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21625 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21630 int32_t imm = extract32(ctx->opcode, 1, 13) |
21631 extract32(ctx->opcode, 0, 1) << 13;
21633 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21638 generate_exception_end(ctx, EXCP_RI);
21644 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21646 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21650 if (rs == rt || rt == 0) {
21651 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21652 } else if (rs == 0) {
21653 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21655 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21663 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21664 extract32(ctx->opcode, 1, 13) << 1;
21665 switch (extract32(ctx->opcode, 14, 2)) {
21668 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21671 if (rs != 0 && rt != 0 && rs == rt) {
21673 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21675 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21679 if (rs == 0 || rs == rt) {
21681 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21683 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21687 generate_exception_end(ctx, EXCP_RI);
21694 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21695 extract32(ctx->opcode, 1, 10) << 1;
21696 uint32_t u = extract32(ctx->opcode, 11, 7);
21698 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21703 generate_exception_end(ctx, EXCP_RI);
21709 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21712 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21713 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21714 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
21718 /* make sure instructions are on a halfword boundary */
21719 if (ctx->base.pc_next & 0x1) {
21720 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21721 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21722 tcg_temp_free(tmp);
21723 generate_exception_end(ctx, EXCP_AdEL);
21727 op = extract32(ctx->opcode, 10, 6);
21730 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21733 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21734 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21737 switch (extract32(ctx->opcode, 3, 2)) {
21738 case NM_P16_SYSCALL:
21739 if (extract32(ctx->opcode, 2, 1) == 0) {
21740 generate_exception_end(ctx, EXCP_SYSCALL);
21742 generate_exception_end(ctx, EXCP_RI);
21746 generate_exception_end(ctx, EXCP_BREAK);
21749 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21750 gen_helper_do_semihosting(cpu_env);
21752 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21753 generate_exception_end(ctx, EXCP_RI);
21755 generate_exception_end(ctx, EXCP_DBp);
21760 generate_exception_end(ctx, EXCP_RI);
21767 int shift = extract32(ctx->opcode, 0, 3);
21769 shift = (shift == 0) ? 8 : shift;
21771 switch (extract32(ctx->opcode, 3, 1)) {
21779 gen_shift_imm(ctx, opc, rt, rs, shift);
21783 switch (ctx->opcode & 1) {
21785 gen_pool16c_nanomips_insn(ctx);
21788 gen_ldxs(ctx, rt, rs, rd);
21793 switch (extract32(ctx->opcode, 6, 1)) {
21795 imm = extract32(ctx->opcode, 0, 6) << 2;
21796 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21799 generate_exception_end(ctx, EXCP_RI);
21804 switch (extract32(ctx->opcode, 3, 1)) {
21806 imm = extract32(ctx->opcode, 0, 3) << 2;
21807 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21809 case NM_P_ADDIURS5:
21810 rt = extract32(ctx->opcode, 5, 5);
21812 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21813 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21814 (extract32(ctx->opcode, 0, 3));
21815 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21821 switch (ctx->opcode & 0x1) {
21823 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21826 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21831 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21832 extract32(ctx->opcode, 5, 3);
21833 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21834 extract32(ctx->opcode, 0, 3);
21835 rt = decode_gpr_gpr4(rt);
21836 rs = decode_gpr_gpr4(rs);
21837 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21838 (extract32(ctx->opcode, 3, 1))) {
21841 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21845 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21848 generate_exception_end(ctx, EXCP_RI);
21854 int imm = extract32(ctx->opcode, 0, 7);
21855 imm = (imm == 0x7f ? -1 : imm);
21857 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21863 uint32_t u = extract32(ctx->opcode, 0, 4);
21864 u = (u == 12) ? 0xff :
21865 (u == 13) ? 0xffff : u;
21866 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21870 offset = extract32(ctx->opcode, 0, 2);
21871 switch (extract32(ctx->opcode, 2, 2)) {
21873 gen_ld(ctx, OPC_LB, rt, rs, offset);
21876 rt = decode_gpr_gpr3_src_store(
21877 NANOMIPS_EXTRACT_RD(ctx->opcode));
21878 gen_st(ctx, OPC_SB, rt, rs, offset);
21881 gen_ld(ctx, OPC_LBU, rt, rs, offset);
21884 generate_exception_end(ctx, EXCP_RI);
21889 offset = extract32(ctx->opcode, 1, 2) << 1;
21890 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21892 gen_ld(ctx, OPC_LH, rt, rs, offset);
21895 rt = decode_gpr_gpr3_src_store(
21896 NANOMIPS_EXTRACT_RD(ctx->opcode));
21897 gen_st(ctx, OPC_SH, rt, rs, offset);
21900 gen_ld(ctx, OPC_LHU, rt, rs, offset);
21903 generate_exception_end(ctx, EXCP_RI);
21908 offset = extract32(ctx->opcode, 0, 4) << 2;
21909 gen_ld(ctx, OPC_LW, rt, rs, offset);
21912 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21913 offset = extract32(ctx->opcode, 0, 5) << 2;
21914 gen_ld(ctx, OPC_LW, rt, 29, offset);
21918 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21919 extract32(ctx->opcode, 5, 3);
21920 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21921 extract32(ctx->opcode, 0, 3);
21922 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21923 (extract32(ctx->opcode, 8, 1) << 2);
21924 rt = decode_gpr_gpr4(rt);
21925 rs = decode_gpr_gpr4(rs);
21926 gen_ld(ctx, OPC_LW, rt, rs, offset);
21930 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21931 extract32(ctx->opcode, 5, 3);
21932 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21933 extract32(ctx->opcode, 0, 3);
21934 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21935 (extract32(ctx->opcode, 8, 1) << 2);
21936 rt = decode_gpr_gpr4_zero(rt);
21937 rs = decode_gpr_gpr4(rs);
21938 gen_st(ctx, OPC_SW, rt, rs, offset);
21941 offset = extract32(ctx->opcode, 0, 7) << 2;
21942 gen_ld(ctx, OPC_LW, rt, 28, offset);
21945 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21946 offset = extract32(ctx->opcode, 0, 5) << 2;
21947 gen_st(ctx, OPC_SW, rt, 29, offset);
21950 rt = decode_gpr_gpr3_src_store(
21951 NANOMIPS_EXTRACT_RD(ctx->opcode));
21952 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21953 offset = extract32(ctx->opcode, 0, 4) << 2;
21954 gen_st(ctx, OPC_SW, rt, rs, offset);
21957 rt = decode_gpr_gpr3_src_store(
21958 NANOMIPS_EXTRACT_RD(ctx->opcode));
21959 offset = extract32(ctx->opcode, 0, 7) << 2;
21960 gen_st(ctx, OPC_SW, rt, 28, offset);
21963 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21964 (sextract32(ctx->opcode, 0, 1) << 10) |
21965 (extract32(ctx->opcode, 1, 9) << 1));
21968 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21969 (sextract32(ctx->opcode, 0, 1) << 10) |
21970 (extract32(ctx->opcode, 1, 9) << 1));
21973 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21974 (sextract32(ctx->opcode, 0, 1) << 7) |
21975 (extract32(ctx->opcode, 1, 6) << 1));
21978 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21979 (sextract32(ctx->opcode, 0, 1) << 7) |
21980 (extract32(ctx->opcode, 1, 6) << 1));
21983 switch (ctx->opcode & 0xf) {
21986 switch (extract32(ctx->opcode, 4, 1)) {
21988 gen_compute_branch_nm(ctx, OPC_JR, 2,
21989 extract32(ctx->opcode, 5, 5), 0, 0);
21992 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21993 extract32(ctx->opcode, 5, 5), 31, 0);
22000 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22001 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22002 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22003 extract32(ctx->opcode, 0, 4) << 1);
22010 int count = extract32(ctx->opcode, 0, 4);
22011 int u = extract32(ctx->opcode, 4, 4) << 4;
22013 rt = 30 + extract32(ctx->opcode, 9, 1);
22014 switch (extract32(ctx->opcode, 8, 1)) {
22016 gen_save(ctx, rt, count, 0, u);
22018 case NM_RESTORE_JRC16:
22019 gen_restore(ctx, rt, count, 0, u);
22020 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22029 static const int gpr2reg1[] = {4, 5, 6, 7};
22030 static const int gpr2reg2[] = {5, 6, 7, 8};
22032 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22033 extract32(ctx->opcode, 8, 1);
22034 int r1 = gpr2reg1[rd2];
22035 int r2 = gpr2reg2[rd2];
22036 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22037 extract32(ctx->opcode, 0, 3);
22038 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22039 extract32(ctx->opcode, 5, 3);
22040 TCGv t0 = tcg_temp_new();
22041 TCGv t1 = tcg_temp_new();
22042 if (op == NM_MOVEP) {
22045 rs = decode_gpr_gpr4_zero(r3);
22046 rt = decode_gpr_gpr4_zero(r4);
22048 rd = decode_gpr_gpr4(r3);
22049 re = decode_gpr_gpr4(r4);
22053 gen_load_gpr(t0, rs);
22054 gen_load_gpr(t1, rt);
22055 tcg_gen_mov_tl(cpu_gpr[rd], t0);
22056 tcg_gen_mov_tl(cpu_gpr[re], t1);
22062 return decode_nanomips_32_48_opc(env, ctx);
22069 /* SmartMIPS extension to MIPS32 */
22071 #if defined(TARGET_MIPS64)
22073 /* MDMX extension to MIPS64 */
22077 /* MIPSDSP functions. */
22078 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22079 int rd, int base, int offset)
22084 t0 = tcg_temp_new();
22087 gen_load_gpr(t0, offset);
22088 } else if (offset == 0) {
22089 gen_load_gpr(t0, base);
22091 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22096 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22097 gen_store_gpr(t0, rd);
22100 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22101 gen_store_gpr(t0, rd);
22104 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22105 gen_store_gpr(t0, rd);
22107 #if defined(TARGET_MIPS64)
22109 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22110 gen_store_gpr(t0, rd);
22117 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22118 int ret, int v1, int v2)
22124 /* Treat as NOP. */
22128 v1_t = tcg_temp_new();
22129 v2_t = tcg_temp_new();
22131 gen_load_gpr(v1_t, v1);
22132 gen_load_gpr(v2_t, v2);
22135 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22136 case OPC_MULT_G_2E:
22140 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22142 case OPC_ADDUH_R_QB:
22143 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22146 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22148 case OPC_ADDQH_R_PH:
22149 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22152 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22154 case OPC_ADDQH_R_W:
22155 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22158 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22160 case OPC_SUBUH_R_QB:
22161 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22164 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22166 case OPC_SUBQH_R_PH:
22167 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22170 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22172 case OPC_SUBQH_R_W:
22173 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22177 case OPC_ABSQ_S_PH_DSP:
22179 case OPC_ABSQ_S_QB:
22181 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22183 case OPC_ABSQ_S_PH:
22185 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22189 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22191 case OPC_PRECEQ_W_PHL:
22193 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22194 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22196 case OPC_PRECEQ_W_PHR:
22198 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22199 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22200 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22202 case OPC_PRECEQU_PH_QBL:
22204 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22206 case OPC_PRECEQU_PH_QBR:
22208 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22210 case OPC_PRECEQU_PH_QBLA:
22212 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22214 case OPC_PRECEQU_PH_QBRA:
22216 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22218 case OPC_PRECEU_PH_QBL:
22220 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22222 case OPC_PRECEU_PH_QBR:
22224 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22226 case OPC_PRECEU_PH_QBLA:
22228 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22230 case OPC_PRECEU_PH_QBRA:
22232 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22236 case OPC_ADDU_QB_DSP:
22240 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22242 case OPC_ADDQ_S_PH:
22244 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22248 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22252 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22254 case OPC_ADDU_S_QB:
22256 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22260 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22262 case OPC_ADDU_S_PH:
22264 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22268 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22270 case OPC_SUBQ_S_PH:
22272 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22276 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22280 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22282 case OPC_SUBU_S_QB:
22284 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22288 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22290 case OPC_SUBU_S_PH:
22292 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22296 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22300 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22304 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22306 case OPC_RADDU_W_QB:
22308 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22312 case OPC_CMPU_EQ_QB_DSP:
22314 case OPC_PRECR_QB_PH:
22316 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22318 case OPC_PRECRQ_QB_PH:
22320 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22322 case OPC_PRECR_SRA_PH_W:
22325 TCGv_i32 sa_t = tcg_const_i32(v2);
22326 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22328 tcg_temp_free_i32(sa_t);
22331 case OPC_PRECR_SRA_R_PH_W:
22334 TCGv_i32 sa_t = tcg_const_i32(v2);
22335 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22337 tcg_temp_free_i32(sa_t);
22340 case OPC_PRECRQ_PH_W:
22342 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22344 case OPC_PRECRQ_RS_PH_W:
22346 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22348 case OPC_PRECRQU_S_QB_PH:
22350 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22354 #ifdef TARGET_MIPS64
22355 case OPC_ABSQ_S_QH_DSP:
22357 case OPC_PRECEQ_L_PWL:
22359 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22361 case OPC_PRECEQ_L_PWR:
22363 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22365 case OPC_PRECEQ_PW_QHL:
22367 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22369 case OPC_PRECEQ_PW_QHR:
22371 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22373 case OPC_PRECEQ_PW_QHLA:
22375 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22377 case OPC_PRECEQ_PW_QHRA:
22379 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22381 case OPC_PRECEQU_QH_OBL:
22383 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22385 case OPC_PRECEQU_QH_OBR:
22387 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22389 case OPC_PRECEQU_QH_OBLA:
22391 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22393 case OPC_PRECEQU_QH_OBRA:
22395 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22397 case OPC_PRECEU_QH_OBL:
22399 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22401 case OPC_PRECEU_QH_OBR:
22403 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22405 case OPC_PRECEU_QH_OBLA:
22407 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22409 case OPC_PRECEU_QH_OBRA:
22411 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22413 case OPC_ABSQ_S_OB:
22415 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22417 case OPC_ABSQ_S_PW:
22419 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22421 case OPC_ABSQ_S_QH:
22423 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22427 case OPC_ADDU_OB_DSP:
22429 case OPC_RADDU_L_OB:
22431 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22435 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22437 case OPC_SUBQ_S_PW:
22439 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22443 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22445 case OPC_SUBQ_S_QH:
22447 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22451 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22453 case OPC_SUBU_S_OB:
22455 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22459 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22461 case OPC_SUBU_S_QH:
22463 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22467 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22469 case OPC_SUBUH_R_OB:
22471 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22475 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22477 case OPC_ADDQ_S_PW:
22479 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22483 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22485 case OPC_ADDQ_S_QH:
22487 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22491 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22493 case OPC_ADDU_S_OB:
22495 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22499 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22501 case OPC_ADDU_S_QH:
22503 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22507 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22509 case OPC_ADDUH_R_OB:
22511 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22515 case OPC_CMPU_EQ_OB_DSP:
22517 case OPC_PRECR_OB_QH:
22519 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22521 case OPC_PRECR_SRA_QH_PW:
22524 TCGv_i32 ret_t = tcg_const_i32(ret);
22525 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22526 tcg_temp_free_i32(ret_t);
22529 case OPC_PRECR_SRA_R_QH_PW:
22532 TCGv_i32 sa_v = tcg_const_i32(ret);
22533 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22534 tcg_temp_free_i32(sa_v);
22537 case OPC_PRECRQ_OB_QH:
22539 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22541 case OPC_PRECRQ_PW_L:
22543 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22545 case OPC_PRECRQ_QH_PW:
22547 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22549 case OPC_PRECRQ_RS_QH_PW:
22551 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22553 case OPC_PRECRQU_S_OB_QH:
22555 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22562 tcg_temp_free(v1_t);
22563 tcg_temp_free(v2_t);
22566 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22567 int ret, int v1, int v2)
22575 /* Treat as NOP. */
22579 t0 = tcg_temp_new();
22580 v1_t = tcg_temp_new();
22581 v2_t = tcg_temp_new();
22583 tcg_gen_movi_tl(t0, v1);
22584 gen_load_gpr(v1_t, v1);
22585 gen_load_gpr(v2_t, v2);
22588 case OPC_SHLL_QB_DSP:
22590 op2 = MASK_SHLL_QB(ctx->opcode);
22594 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22598 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22602 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22606 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22608 case OPC_SHLL_S_PH:
22610 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22612 case OPC_SHLLV_S_PH:
22614 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22618 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22620 case OPC_SHLLV_S_W:
22622 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22626 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22630 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22634 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22638 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22642 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22644 case OPC_SHRA_R_QB:
22646 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22650 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22652 case OPC_SHRAV_R_QB:
22654 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22658 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22660 case OPC_SHRA_R_PH:
22662 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22666 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22668 case OPC_SHRAV_R_PH:
22670 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22674 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22676 case OPC_SHRAV_R_W:
22678 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22680 default: /* Invalid */
22681 MIPS_INVAL("MASK SHLL.QB");
22682 generate_exception_end(ctx, EXCP_RI);
22687 #ifdef TARGET_MIPS64
22688 case OPC_SHLL_OB_DSP:
22689 op2 = MASK_SHLL_OB(ctx->opcode);
22693 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22697 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22699 case OPC_SHLL_S_PW:
22701 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22703 case OPC_SHLLV_S_PW:
22705 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22709 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22713 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22717 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22721 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22723 case OPC_SHLL_S_QH:
22725 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22727 case OPC_SHLLV_S_QH:
22729 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22733 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22737 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22739 case OPC_SHRA_R_OB:
22741 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22743 case OPC_SHRAV_R_OB:
22745 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22749 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22753 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22755 case OPC_SHRA_R_PW:
22757 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22759 case OPC_SHRAV_R_PW:
22761 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22765 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22769 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22771 case OPC_SHRA_R_QH:
22773 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22775 case OPC_SHRAV_R_QH:
22777 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22781 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22785 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22789 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22793 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22795 default: /* Invalid */
22796 MIPS_INVAL("MASK SHLL.OB");
22797 generate_exception_end(ctx, EXCP_RI);
22805 tcg_temp_free(v1_t);
22806 tcg_temp_free(v2_t);
22809 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22810 int ret, int v1, int v2, int check_ret)
22816 if ((ret == 0) && (check_ret == 1)) {
22817 /* Treat as NOP. */
22821 t0 = tcg_temp_new_i32();
22822 v1_t = tcg_temp_new();
22823 v2_t = tcg_temp_new();
22825 tcg_gen_movi_i32(t0, ret);
22826 gen_load_gpr(v1_t, v1);
22827 gen_load_gpr(v2_t, v2);
22830 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22831 * the same mask and op1. */
22832 case OPC_MULT_G_2E:
22836 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22839 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22842 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22844 case OPC_MULQ_RS_W:
22845 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22849 case OPC_DPA_W_PH_DSP:
22851 case OPC_DPAU_H_QBL:
22853 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22855 case OPC_DPAU_H_QBR:
22857 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22859 case OPC_DPSU_H_QBL:
22861 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22863 case OPC_DPSU_H_QBR:
22865 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22869 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22871 case OPC_DPAX_W_PH:
22873 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22875 case OPC_DPAQ_S_W_PH:
22877 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22879 case OPC_DPAQX_S_W_PH:
22881 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22883 case OPC_DPAQX_SA_W_PH:
22885 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22889 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22891 case OPC_DPSX_W_PH:
22893 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22895 case OPC_DPSQ_S_W_PH:
22897 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22899 case OPC_DPSQX_S_W_PH:
22901 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22903 case OPC_DPSQX_SA_W_PH:
22905 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22907 case OPC_MULSAQ_S_W_PH:
22909 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22911 case OPC_DPAQ_SA_L_W:
22913 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22915 case OPC_DPSQ_SA_L_W:
22917 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22919 case OPC_MAQ_S_W_PHL:
22921 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22923 case OPC_MAQ_S_W_PHR:
22925 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22927 case OPC_MAQ_SA_W_PHL:
22929 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22931 case OPC_MAQ_SA_W_PHR:
22933 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22935 case OPC_MULSA_W_PH:
22937 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22941 #ifdef TARGET_MIPS64
22942 case OPC_DPAQ_W_QH_DSP:
22944 int ac = ret & 0x03;
22945 tcg_gen_movi_i32(t0, ac);
22950 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22954 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22958 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22962 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22966 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22968 case OPC_DPAQ_S_W_QH:
22970 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22972 case OPC_DPAQ_SA_L_PW:
22974 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22976 case OPC_DPAU_H_OBL:
22978 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22980 case OPC_DPAU_H_OBR:
22982 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22986 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22988 case OPC_DPSQ_S_W_QH:
22990 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22992 case OPC_DPSQ_SA_L_PW:
22994 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22996 case OPC_DPSU_H_OBL:
22998 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23000 case OPC_DPSU_H_OBR:
23002 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23004 case OPC_MAQ_S_L_PWL:
23006 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23008 case OPC_MAQ_S_L_PWR:
23010 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23012 case OPC_MAQ_S_W_QHLL:
23014 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23016 case OPC_MAQ_SA_W_QHLL:
23018 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23020 case OPC_MAQ_S_W_QHLR:
23022 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23024 case OPC_MAQ_SA_W_QHLR:
23026 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23028 case OPC_MAQ_S_W_QHRL:
23030 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23032 case OPC_MAQ_SA_W_QHRL:
23034 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23036 case OPC_MAQ_S_W_QHRR:
23038 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23040 case OPC_MAQ_SA_W_QHRR:
23042 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23044 case OPC_MULSAQ_S_L_PW:
23046 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23048 case OPC_MULSAQ_S_W_QH:
23050 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23056 case OPC_ADDU_QB_DSP:
23058 case OPC_MULEU_S_PH_QBL:
23060 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23062 case OPC_MULEU_S_PH_QBR:
23064 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23066 case OPC_MULQ_RS_PH:
23068 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23070 case OPC_MULEQ_S_W_PHL:
23072 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23074 case OPC_MULEQ_S_W_PHR:
23076 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23078 case OPC_MULQ_S_PH:
23080 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23084 #ifdef TARGET_MIPS64
23085 case OPC_ADDU_OB_DSP:
23087 case OPC_MULEQ_S_PW_QHL:
23089 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23091 case OPC_MULEQ_S_PW_QHR:
23093 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23095 case OPC_MULEU_S_QH_OBL:
23097 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23099 case OPC_MULEU_S_QH_OBR:
23101 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23103 case OPC_MULQ_RS_QH:
23105 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23112 tcg_temp_free_i32(t0);
23113 tcg_temp_free(v1_t);
23114 tcg_temp_free(v2_t);
23117 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23125 /* Treat as NOP. */
23129 t0 = tcg_temp_new();
23130 val_t = tcg_temp_new();
23131 gen_load_gpr(val_t, val);
23134 case OPC_ABSQ_S_PH_DSP:
23138 gen_helper_bitrev(cpu_gpr[ret], val_t);
23143 target_long result;
23144 imm = (ctx->opcode >> 16) & 0xFF;
23145 result = (uint32_t)imm << 24 |
23146 (uint32_t)imm << 16 |
23147 (uint32_t)imm << 8 |
23149 result = (int32_t)result;
23150 tcg_gen_movi_tl(cpu_gpr[ret], result);
23155 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23156 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23157 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23158 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23159 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23160 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23165 imm = (ctx->opcode >> 16) & 0x03FF;
23166 imm = (int16_t)(imm << 6) >> 6;
23167 tcg_gen_movi_tl(cpu_gpr[ret], \
23168 (target_long)((int32_t)imm << 16 | \
23174 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23175 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23176 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23177 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23181 #ifdef TARGET_MIPS64
23182 case OPC_ABSQ_S_QH_DSP:
23189 imm = (ctx->opcode >> 16) & 0xFF;
23190 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23191 temp = (temp << 16) | temp;
23192 temp = (temp << 32) | temp;
23193 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23201 imm = (ctx->opcode >> 16) & 0x03FF;
23202 imm = (int16_t)(imm << 6) >> 6;
23203 temp = ((target_long)imm << 32) \
23204 | ((target_long)imm & 0xFFFFFFFF);
23205 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23213 imm = (ctx->opcode >> 16) & 0x03FF;
23214 imm = (int16_t)(imm << 6) >> 6;
23216 temp = ((uint64_t)(uint16_t)imm << 48) |
23217 ((uint64_t)(uint16_t)imm << 32) |
23218 ((uint64_t)(uint16_t)imm << 16) |
23219 (uint64_t)(uint16_t)imm;
23220 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23225 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23226 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23227 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23228 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23229 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23230 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23231 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23235 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23236 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23237 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23241 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23242 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23243 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23244 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23245 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23252 tcg_temp_free(val_t);
23255 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23256 uint32_t op1, uint32_t op2,
23257 int ret, int v1, int v2, int check_ret)
23263 if ((ret == 0) && (check_ret == 1)) {
23264 /* Treat as NOP. */
23268 t1 = tcg_temp_new();
23269 v1_t = tcg_temp_new();
23270 v2_t = tcg_temp_new();
23272 gen_load_gpr(v1_t, v1);
23273 gen_load_gpr(v2_t, v2);
23276 case OPC_CMPU_EQ_QB_DSP:
23278 case OPC_CMPU_EQ_QB:
23280 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23282 case OPC_CMPU_LT_QB:
23284 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23286 case OPC_CMPU_LE_QB:
23288 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23290 case OPC_CMPGU_EQ_QB:
23292 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23294 case OPC_CMPGU_LT_QB:
23296 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23298 case OPC_CMPGU_LE_QB:
23300 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23302 case OPC_CMPGDU_EQ_QB:
23304 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23305 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23306 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23307 tcg_gen_shli_tl(t1, t1, 24);
23308 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23310 case OPC_CMPGDU_LT_QB:
23312 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23313 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23314 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23315 tcg_gen_shli_tl(t1, t1, 24);
23316 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23318 case OPC_CMPGDU_LE_QB:
23320 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23321 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23322 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23323 tcg_gen_shli_tl(t1, t1, 24);
23324 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23326 case OPC_CMP_EQ_PH:
23328 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23330 case OPC_CMP_LT_PH:
23332 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23334 case OPC_CMP_LE_PH:
23336 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23340 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23344 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23346 case OPC_PACKRL_PH:
23348 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23352 #ifdef TARGET_MIPS64
23353 case OPC_CMPU_EQ_OB_DSP:
23355 case OPC_CMP_EQ_PW:
23357 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23359 case OPC_CMP_LT_PW:
23361 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23363 case OPC_CMP_LE_PW:
23365 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23367 case OPC_CMP_EQ_QH:
23369 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23371 case OPC_CMP_LT_QH:
23373 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23375 case OPC_CMP_LE_QH:
23377 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23379 case OPC_CMPGDU_EQ_OB:
23381 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23383 case OPC_CMPGDU_LT_OB:
23385 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23387 case OPC_CMPGDU_LE_OB:
23389 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23391 case OPC_CMPGU_EQ_OB:
23393 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23395 case OPC_CMPGU_LT_OB:
23397 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23399 case OPC_CMPGU_LE_OB:
23401 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23403 case OPC_CMPU_EQ_OB:
23405 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23407 case OPC_CMPU_LT_OB:
23409 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23411 case OPC_CMPU_LE_OB:
23413 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23415 case OPC_PACKRL_PW:
23417 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23421 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23425 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23429 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23437 tcg_temp_free(v1_t);
23438 tcg_temp_free(v2_t);
23441 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23442 uint32_t op1, int rt, int rs, int sa)
23449 /* Treat as NOP. */
23453 t0 = tcg_temp_new();
23454 gen_load_gpr(t0, rs);
23457 case OPC_APPEND_DSP:
23458 switch (MASK_APPEND(ctx->opcode)) {
23461 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23463 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23467 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23468 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23469 tcg_gen_shli_tl(t0, t0, 32 - sa);
23470 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23472 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23476 if (sa != 0 && sa != 2) {
23477 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23478 tcg_gen_ext32u_tl(t0, t0);
23479 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23480 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23482 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23484 default: /* Invalid */
23485 MIPS_INVAL("MASK APPEND");
23486 generate_exception_end(ctx, EXCP_RI);
23490 #ifdef TARGET_MIPS64
23491 case OPC_DAPPEND_DSP:
23492 switch (MASK_DAPPEND(ctx->opcode)) {
23495 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23499 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23500 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23501 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23505 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23506 tcg_gen_shli_tl(t0, t0, 64 - sa);
23507 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23512 if (sa != 0 && sa != 2 && sa != 4) {
23513 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23514 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23515 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23518 default: /* Invalid */
23519 MIPS_INVAL("MASK DAPPEND");
23520 generate_exception_end(ctx, EXCP_RI);
23529 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23530 int ret, int v1, int v2, int check_ret)
23539 if ((ret == 0) && (check_ret == 1)) {
23540 /* Treat as NOP. */
23544 t0 = tcg_temp_new();
23545 t1 = tcg_temp_new();
23546 v1_t = tcg_temp_new();
23547 v2_t = tcg_temp_new();
23549 gen_load_gpr(v1_t, v1);
23550 gen_load_gpr(v2_t, v2);
23553 case OPC_EXTR_W_DSP:
23557 tcg_gen_movi_tl(t0, v2);
23558 tcg_gen_movi_tl(t1, v1);
23559 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23562 tcg_gen_movi_tl(t0, v2);
23563 tcg_gen_movi_tl(t1, v1);
23564 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23566 case OPC_EXTR_RS_W:
23567 tcg_gen_movi_tl(t0, v2);
23568 tcg_gen_movi_tl(t1, v1);
23569 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23572 tcg_gen_movi_tl(t0, v2);
23573 tcg_gen_movi_tl(t1, v1);
23574 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23576 case OPC_EXTRV_S_H:
23577 tcg_gen_movi_tl(t0, v2);
23578 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23581 tcg_gen_movi_tl(t0, v2);
23582 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23584 case OPC_EXTRV_R_W:
23585 tcg_gen_movi_tl(t0, v2);
23586 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23588 case OPC_EXTRV_RS_W:
23589 tcg_gen_movi_tl(t0, v2);
23590 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23593 tcg_gen_movi_tl(t0, v2);
23594 tcg_gen_movi_tl(t1, v1);
23595 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23598 tcg_gen_movi_tl(t0, v2);
23599 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23602 tcg_gen_movi_tl(t0, v2);
23603 tcg_gen_movi_tl(t1, v1);
23604 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23607 tcg_gen_movi_tl(t0, v2);
23608 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23611 imm = (ctx->opcode >> 20) & 0x3F;
23612 tcg_gen_movi_tl(t0, ret);
23613 tcg_gen_movi_tl(t1, imm);
23614 gen_helper_shilo(t0, t1, cpu_env);
23617 tcg_gen_movi_tl(t0, ret);
23618 gen_helper_shilo(t0, v1_t, cpu_env);
23621 tcg_gen_movi_tl(t0, ret);
23622 gen_helper_mthlip(t0, v1_t, cpu_env);
23625 imm = (ctx->opcode >> 11) & 0x3FF;
23626 tcg_gen_movi_tl(t0, imm);
23627 gen_helper_wrdsp(v1_t, t0, cpu_env);
23630 imm = (ctx->opcode >> 16) & 0x03FF;
23631 tcg_gen_movi_tl(t0, imm);
23632 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23636 #ifdef TARGET_MIPS64
23637 case OPC_DEXTR_W_DSP:
23641 tcg_gen_movi_tl(t0, ret);
23642 gen_helper_dmthlip(v1_t, t0, cpu_env);
23646 int shift = (ctx->opcode >> 19) & 0x7F;
23647 int ac = (ctx->opcode >> 11) & 0x03;
23648 tcg_gen_movi_tl(t0, shift);
23649 tcg_gen_movi_tl(t1, ac);
23650 gen_helper_dshilo(t0, t1, cpu_env);
23655 int ac = (ctx->opcode >> 11) & 0x03;
23656 tcg_gen_movi_tl(t0, ac);
23657 gen_helper_dshilo(v1_t, t0, cpu_env);
23661 tcg_gen_movi_tl(t0, v2);
23662 tcg_gen_movi_tl(t1, v1);
23664 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23667 tcg_gen_movi_tl(t0, v2);
23668 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23671 tcg_gen_movi_tl(t0, v2);
23672 tcg_gen_movi_tl(t1, v1);
23673 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23676 tcg_gen_movi_tl(t0, v2);
23677 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23680 tcg_gen_movi_tl(t0, v2);
23681 tcg_gen_movi_tl(t1, v1);
23682 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23684 case OPC_DEXTR_R_L:
23685 tcg_gen_movi_tl(t0, v2);
23686 tcg_gen_movi_tl(t1, v1);
23687 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23689 case OPC_DEXTR_RS_L:
23690 tcg_gen_movi_tl(t0, v2);
23691 tcg_gen_movi_tl(t1, v1);
23692 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23695 tcg_gen_movi_tl(t0, v2);
23696 tcg_gen_movi_tl(t1, v1);
23697 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23699 case OPC_DEXTR_R_W:
23700 tcg_gen_movi_tl(t0, v2);
23701 tcg_gen_movi_tl(t1, v1);
23702 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23704 case OPC_DEXTR_RS_W:
23705 tcg_gen_movi_tl(t0, v2);
23706 tcg_gen_movi_tl(t1, v1);
23707 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23709 case OPC_DEXTR_S_H:
23710 tcg_gen_movi_tl(t0, v2);
23711 tcg_gen_movi_tl(t1, v1);
23712 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23714 case OPC_DEXTRV_S_H:
23715 tcg_gen_movi_tl(t0, v2);
23716 tcg_gen_movi_tl(t1, v1);
23717 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23720 tcg_gen_movi_tl(t0, v2);
23721 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23723 case OPC_DEXTRV_R_L:
23724 tcg_gen_movi_tl(t0, v2);
23725 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23727 case OPC_DEXTRV_RS_L:
23728 tcg_gen_movi_tl(t0, v2);
23729 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23732 tcg_gen_movi_tl(t0, v2);
23733 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23735 case OPC_DEXTRV_R_W:
23736 tcg_gen_movi_tl(t0, v2);
23737 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23739 case OPC_DEXTRV_RS_W:
23740 tcg_gen_movi_tl(t0, v2);
23741 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23750 tcg_temp_free(v1_t);
23751 tcg_temp_free(v2_t);
23754 /* End MIPSDSP functions. */
23756 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23758 int rs, rt, rd, sa;
23761 rs = (ctx->opcode >> 21) & 0x1f;
23762 rt = (ctx->opcode >> 16) & 0x1f;
23763 rd = (ctx->opcode >> 11) & 0x1f;
23764 sa = (ctx->opcode >> 6) & 0x1f;
23766 op1 = MASK_SPECIAL(ctx->opcode);
23769 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23775 op2 = MASK_R6_MULDIV(ctx->opcode);
23785 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23788 MIPS_INVAL("special_r6 muldiv");
23789 generate_exception_end(ctx, EXCP_RI);
23795 gen_cond_move(ctx, op1, rd, rs, rt);
23799 if (rt == 0 && sa == 1) {
23800 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23801 We need additionally to check other fields */
23802 gen_cl(ctx, op1, rd, rs);
23804 generate_exception_end(ctx, EXCP_RI);
23808 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23809 gen_helper_do_semihosting(cpu_env);
23811 if (ctx->hflags & MIPS_HFLAG_SBRI) {
23812 generate_exception_end(ctx, EXCP_RI);
23814 generate_exception_end(ctx, EXCP_DBp);
23818 #if defined(TARGET_MIPS64)
23820 check_mips_64(ctx);
23821 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23825 if (rt == 0 && sa == 1) {
23826 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23827 We need additionally to check other fields */
23828 check_mips_64(ctx);
23829 gen_cl(ctx, op1, rd, rs);
23831 generate_exception_end(ctx, EXCP_RI);
23839 op2 = MASK_R6_MULDIV(ctx->opcode);
23849 check_mips_64(ctx);
23850 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23853 MIPS_INVAL("special_r6 muldiv");
23854 generate_exception_end(ctx, EXCP_RI);
23859 default: /* Invalid */
23860 MIPS_INVAL("special_r6");
23861 generate_exception_end(ctx, EXCP_RI);
23866 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
23868 int rs = extract32(ctx->opcode, 21, 5);
23869 int rt = extract32(ctx->opcode, 16, 5);
23870 int rd = extract32(ctx->opcode, 11, 5);
23871 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
23874 case OPC_MOVN: /* Conditional move */
23876 gen_cond_move(ctx, op1, rd, rs, rt);
23878 case OPC_MFHI: /* Move from HI/LO */
23880 gen_HILO(ctx, op1, 0, rd);
23883 case OPC_MTLO: /* Move to HI/LO */
23884 gen_HILO(ctx, op1, 0, rs);
23888 gen_mul_txx9(ctx, op1, rd, rs, rt);
23892 gen_muldiv(ctx, op1, 0, rs, rt);
23894 #if defined(TARGET_MIPS64)
23899 check_insn_opc_user_only(ctx, INSN_R5900);
23900 gen_muldiv(ctx, op1, 0, rs, rt);
23904 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
23906 default: /* Invalid */
23907 MIPS_INVAL("special_tx79");
23908 generate_exception_end(ctx, EXCP_RI);
23913 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23915 int rs, rt, rd, sa;
23918 rs = (ctx->opcode >> 21) & 0x1f;
23919 rt = (ctx->opcode >> 16) & 0x1f;
23920 rd = (ctx->opcode >> 11) & 0x1f;
23921 sa = (ctx->opcode >> 6) & 0x1f;
23923 op1 = MASK_SPECIAL(ctx->opcode);
23925 case OPC_MOVN: /* Conditional move */
23927 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
23928 INSN_LOONGSON2E | INSN_LOONGSON2F);
23929 gen_cond_move(ctx, op1, rd, rs, rt);
23931 case OPC_MFHI: /* Move from HI/LO */
23933 gen_HILO(ctx, op1, rs & 3, rd);
23936 case OPC_MTLO: /* Move to HI/LO */
23937 gen_HILO(ctx, op1, rd & 3, rs);
23940 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23941 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23942 check_cp1_enabled(ctx);
23943 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23944 (ctx->opcode >> 16) & 1);
23946 generate_exception_err(ctx, EXCP_CpU, 1);
23952 check_insn(ctx, INSN_VR54XX);
23953 op1 = MASK_MUL_VR54XX(ctx->opcode);
23954 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23956 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23961 gen_muldiv(ctx, op1, 0, rs, rt);
23963 #if defined(TARGET_MIPS64)
23968 check_insn(ctx, ISA_MIPS3);
23969 check_mips_64(ctx);
23970 gen_muldiv(ctx, op1, 0, rs, rt);
23974 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23977 #ifdef MIPS_STRICT_STANDARD
23978 MIPS_INVAL("SPIM");
23979 generate_exception_end(ctx, EXCP_RI);
23981 /* Implemented as RI exception for now. */
23982 MIPS_INVAL("spim (unofficial)");
23983 generate_exception_end(ctx, EXCP_RI);
23986 default: /* Invalid */
23987 MIPS_INVAL("special_legacy");
23988 generate_exception_end(ctx, EXCP_RI);
23993 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
23995 int rs, rt, rd, sa;
23998 rs = (ctx->opcode >> 21) & 0x1f;
23999 rt = (ctx->opcode >> 16) & 0x1f;
24000 rd = (ctx->opcode >> 11) & 0x1f;
24001 sa = (ctx->opcode >> 6) & 0x1f;
24003 op1 = MASK_SPECIAL(ctx->opcode);
24005 case OPC_SLL: /* Shift with immediate */
24006 if (sa == 5 && rd == 0 &&
24007 rs == 0 && rt == 0) { /* PAUSE */
24008 if ((ctx->insn_flags & ISA_MIPS32R6) &&
24009 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24010 generate_exception_end(ctx, EXCP_RI);
24016 gen_shift_imm(ctx, op1, rd, rt, sa);
24019 switch ((ctx->opcode >> 21) & 0x1f) {
24021 /* rotr is decoded as srl on non-R2 CPUs */
24022 if (ctx->insn_flags & ISA_MIPS32R2) {
24027 gen_shift_imm(ctx, op1, rd, rt, sa);
24030 generate_exception_end(ctx, EXCP_RI);
24038 gen_arith(ctx, op1, rd, rs, rt);
24040 case OPC_SLLV: /* Shifts */
24042 gen_shift(ctx, op1, rd, rs, rt);
24045 switch ((ctx->opcode >> 6) & 0x1f) {
24047 /* rotrv is decoded as srlv on non-R2 CPUs */
24048 if (ctx->insn_flags & ISA_MIPS32R2) {
24053 gen_shift(ctx, op1, rd, rs, rt);
24056 generate_exception_end(ctx, EXCP_RI);
24060 case OPC_SLT: /* Set on less than */
24062 gen_slt(ctx, op1, rd, rs, rt);
24064 case OPC_AND: /* Logic*/
24068 gen_logic(ctx, op1, rd, rs, rt);
24071 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24073 case OPC_TGE: /* Traps */
24079 check_insn(ctx, ISA_MIPS2);
24080 gen_trap(ctx, op1, rs, rt, -1);
24082 case OPC_LSA: /* OPC_PMON */
24083 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24084 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24085 decode_opc_special_r6(env, ctx);
24087 /* Pmon entry point, also R4010 selsl */
24088 #ifdef MIPS_STRICT_STANDARD
24089 MIPS_INVAL("PMON / selsl");
24090 generate_exception_end(ctx, EXCP_RI);
24092 gen_helper_0e0i(pmon, sa);
24097 generate_exception_end(ctx, EXCP_SYSCALL);
24100 generate_exception_end(ctx, EXCP_BREAK);
24103 check_insn(ctx, ISA_MIPS2);
24104 gen_sync(extract32(ctx->opcode, 6, 5));
24107 #if defined(TARGET_MIPS64)
24108 /* MIPS64 specific opcodes */
24113 check_insn(ctx, ISA_MIPS3);
24114 check_mips_64(ctx);
24115 gen_shift_imm(ctx, op1, rd, rt, sa);
24118 switch ((ctx->opcode >> 21) & 0x1f) {
24120 /* drotr is decoded as dsrl on non-R2 CPUs */
24121 if (ctx->insn_flags & ISA_MIPS32R2) {
24126 check_insn(ctx, ISA_MIPS3);
24127 check_mips_64(ctx);
24128 gen_shift_imm(ctx, op1, rd, rt, sa);
24131 generate_exception_end(ctx, EXCP_RI);
24136 switch ((ctx->opcode >> 21) & 0x1f) {
24138 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24139 if (ctx->insn_flags & ISA_MIPS32R2) {
24144 check_insn(ctx, ISA_MIPS3);
24145 check_mips_64(ctx);
24146 gen_shift_imm(ctx, op1, rd, rt, sa);
24149 generate_exception_end(ctx, EXCP_RI);
24157 check_insn(ctx, ISA_MIPS3);
24158 check_mips_64(ctx);
24159 gen_arith(ctx, op1, rd, rs, rt);
24163 check_insn(ctx, ISA_MIPS3);
24164 check_mips_64(ctx);
24165 gen_shift(ctx, op1, rd, rs, rt);
24168 switch ((ctx->opcode >> 6) & 0x1f) {
24170 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24171 if (ctx->insn_flags & ISA_MIPS32R2) {
24176 check_insn(ctx, ISA_MIPS3);
24177 check_mips_64(ctx);
24178 gen_shift(ctx, op1, rd, rs, rt);
24181 generate_exception_end(ctx, EXCP_RI);
24186 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24187 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24188 decode_opc_special_r6(env, ctx);
24193 if (ctx->insn_flags & ISA_MIPS32R6) {
24194 decode_opc_special_r6(env, ctx);
24195 } else if (ctx->insn_flags & INSN_R5900) {
24196 decode_opc_special_tx79(env, ctx);
24198 decode_opc_special_legacy(env, ctx);
24204 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24205 #define MXU_APTN1_A 0
24206 #define MXU_APTN1_S 1
24208 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24209 #define MXU_APTN2_AA 0
24210 #define MXU_APTN2_AS 1
24211 #define MXU_APTN2_SA 2
24212 #define MXU_APTN2_SS 3
24214 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24215 #define MXU_EPTN2_AA 0
24216 #define MXU_EPTN2_AS 1
24217 #define MXU_EPTN2_SA 2
24218 #define MXU_EPTN2_SS 3
24220 /* MXU operand getting pattern 'optn2' */
24221 #define MXU_OPTN2_WW 0
24222 #define MXU_OPTN2_LW 1
24223 #define MXU_OPTN2_HW 2
24224 #define MXU_OPTN2_XW 3
24226 /* MXU operand getting pattern 'optn3' */
24227 #define MXU_OPTN3_PTN0 0
24228 #define MXU_OPTN3_PTN1 1
24229 #define MXU_OPTN3_PTN2 2
24230 #define MXU_OPTN3_PTN3 3
24231 #define MXU_OPTN3_PTN4 4
24232 #define MXU_OPTN3_PTN5 5
24233 #define MXU_OPTN3_PTN6 6
24234 #define MXU_OPTN3_PTN7 7
24238 * S32I2M XRa, rb - Register move from GRF to XRF
24240 static void gen_mxu_s32i2m(DisasContext *ctx)
24245 t0 = tcg_temp_new();
24247 XRa = extract32(ctx->opcode, 6, 5);
24248 Rb = extract32(ctx->opcode, 16, 5);
24250 gen_load_gpr(t0, Rb);
24252 gen_store_mxu_gpr(t0, XRa);
24253 } else if (XRa == 16) {
24254 gen_store_mxu_cr(t0);
24261 * S32M2I XRa, rb - Register move from XRF to GRF
24263 static void gen_mxu_s32m2i(DisasContext *ctx)
24268 t0 = tcg_temp_new();
24270 XRa = extract32(ctx->opcode, 6, 5);
24271 Rb = extract32(ctx->opcode, 16, 5);
24274 gen_load_mxu_gpr(t0, XRa);
24275 } else if (XRa == 16) {
24276 gen_load_mxu_cr(t0);
24279 gen_store_gpr(t0, Rb);
24285 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24287 static void gen_mxu_s8ldd(DisasContext *ctx)
24290 uint32_t XRa, Rb, s8, optn3;
24292 t0 = tcg_temp_new();
24293 t1 = tcg_temp_new();
24295 XRa = extract32(ctx->opcode, 6, 4);
24296 s8 = extract32(ctx->opcode, 10, 8);
24297 optn3 = extract32(ctx->opcode, 18, 3);
24298 Rb = extract32(ctx->opcode, 21, 5);
24300 gen_load_gpr(t0, Rb);
24301 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24304 /* XRa[7:0] = tmp8 */
24305 case MXU_OPTN3_PTN0:
24306 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24307 gen_load_mxu_gpr(t0, XRa);
24308 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24310 /* XRa[15:8] = tmp8 */
24311 case MXU_OPTN3_PTN1:
24312 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24313 gen_load_mxu_gpr(t0, XRa);
24314 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24316 /* XRa[23:16] = tmp8 */
24317 case MXU_OPTN3_PTN2:
24318 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24319 gen_load_mxu_gpr(t0, XRa);
24320 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24322 /* XRa[31:24] = tmp8 */
24323 case MXU_OPTN3_PTN3:
24324 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24325 gen_load_mxu_gpr(t0, XRa);
24326 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24328 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24329 case MXU_OPTN3_PTN4:
24330 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24331 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24333 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24334 case MXU_OPTN3_PTN5:
24335 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24336 tcg_gen_shli_tl(t1, t1, 8);
24337 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24339 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24340 case MXU_OPTN3_PTN6:
24341 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24342 tcg_gen_mov_tl(t0, t1);
24343 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24344 tcg_gen_shli_tl(t1, t1, 16);
24345 tcg_gen_or_tl(t0, t0, t1);
24347 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24348 case MXU_OPTN3_PTN7:
24349 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24350 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24351 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24355 gen_store_mxu_gpr(t0, XRa);
24362 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24364 static void gen_mxu_d16mul(DisasContext *ctx)
24366 TCGv t0, t1, t2, t3;
24367 uint32_t XRa, XRb, XRc, XRd, optn2;
24369 t0 = tcg_temp_new();
24370 t1 = tcg_temp_new();
24371 t2 = tcg_temp_new();
24372 t3 = tcg_temp_new();
24374 XRa = extract32(ctx->opcode, 6, 4);
24375 XRb = extract32(ctx->opcode, 10, 4);
24376 XRc = extract32(ctx->opcode, 14, 4);
24377 XRd = extract32(ctx->opcode, 18, 4);
24378 optn2 = extract32(ctx->opcode, 22, 2);
24380 gen_load_mxu_gpr(t1, XRb);
24381 tcg_gen_sextract_tl(t0, t1, 0, 16);
24382 tcg_gen_sextract_tl(t1, t1, 16, 16);
24383 gen_load_mxu_gpr(t3, XRc);
24384 tcg_gen_sextract_tl(t2, t3, 0, 16);
24385 tcg_gen_sextract_tl(t3, t3, 16, 16);
24388 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24389 tcg_gen_mul_tl(t3, t1, t3);
24390 tcg_gen_mul_tl(t2, t0, t2);
24392 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24393 tcg_gen_mul_tl(t3, t0, t3);
24394 tcg_gen_mul_tl(t2, t0, t2);
24396 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24397 tcg_gen_mul_tl(t3, t1, t3);
24398 tcg_gen_mul_tl(t2, t1, t2);
24400 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24401 tcg_gen_mul_tl(t3, t0, t3);
24402 tcg_gen_mul_tl(t2, t1, t2);
24405 gen_store_mxu_gpr(t3, XRa);
24406 gen_store_mxu_gpr(t2, XRd);
24415 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24418 static void gen_mxu_d16mac(DisasContext *ctx)
24420 TCGv t0, t1, t2, t3;
24421 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24423 t0 = tcg_temp_new();
24424 t1 = tcg_temp_new();
24425 t2 = tcg_temp_new();
24426 t3 = tcg_temp_new();
24428 XRa = extract32(ctx->opcode, 6, 4);
24429 XRb = extract32(ctx->opcode, 10, 4);
24430 XRc = extract32(ctx->opcode, 14, 4);
24431 XRd = extract32(ctx->opcode, 18, 4);
24432 optn2 = extract32(ctx->opcode, 22, 2);
24433 aptn2 = extract32(ctx->opcode, 24, 2);
24435 gen_load_mxu_gpr(t1, XRb);
24436 tcg_gen_sextract_tl(t0, t1, 0, 16);
24437 tcg_gen_sextract_tl(t1, t1, 16, 16);
24439 gen_load_mxu_gpr(t3, XRc);
24440 tcg_gen_sextract_tl(t2, t3, 0, 16);
24441 tcg_gen_sextract_tl(t3, t3, 16, 16);
24444 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24445 tcg_gen_mul_tl(t3, t1, t3);
24446 tcg_gen_mul_tl(t2, t0, t2);
24448 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24449 tcg_gen_mul_tl(t3, t0, t3);
24450 tcg_gen_mul_tl(t2, t0, t2);
24452 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24453 tcg_gen_mul_tl(t3, t1, t3);
24454 tcg_gen_mul_tl(t2, t1, t2);
24456 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24457 tcg_gen_mul_tl(t3, t0, t3);
24458 tcg_gen_mul_tl(t2, t1, t2);
24461 gen_load_mxu_gpr(t0, XRa);
24462 gen_load_mxu_gpr(t1, XRd);
24466 tcg_gen_add_tl(t3, t0, t3);
24467 tcg_gen_add_tl(t2, t1, t2);
24470 tcg_gen_add_tl(t3, t0, t3);
24471 tcg_gen_sub_tl(t2, t1, t2);
24474 tcg_gen_sub_tl(t3, t0, t3);
24475 tcg_gen_add_tl(t2, t1, t2);
24478 tcg_gen_sub_tl(t3, t0, t3);
24479 tcg_gen_sub_tl(t2, t1, t2);
24482 gen_store_mxu_gpr(t3, XRa);
24483 gen_store_mxu_gpr(t2, XRd);
24492 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24493 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24495 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24497 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24498 uint32_t XRa, XRb, XRc, XRd, sel;
24500 t0 = tcg_temp_new();
24501 t1 = tcg_temp_new();
24502 t2 = tcg_temp_new();
24503 t3 = tcg_temp_new();
24504 t4 = tcg_temp_new();
24505 t5 = tcg_temp_new();
24506 t6 = tcg_temp_new();
24507 t7 = tcg_temp_new();
24509 XRa = extract32(ctx->opcode, 6, 4);
24510 XRb = extract32(ctx->opcode, 10, 4);
24511 XRc = extract32(ctx->opcode, 14, 4);
24512 XRd = extract32(ctx->opcode, 18, 4);
24513 sel = extract32(ctx->opcode, 22, 2);
24515 gen_load_mxu_gpr(t3, XRb);
24516 gen_load_mxu_gpr(t7, XRc);
24520 tcg_gen_ext8s_tl(t0, t3);
24521 tcg_gen_shri_tl(t3, t3, 8);
24522 tcg_gen_ext8s_tl(t1, t3);
24523 tcg_gen_shri_tl(t3, t3, 8);
24524 tcg_gen_ext8s_tl(t2, t3);
24525 tcg_gen_shri_tl(t3, t3, 8);
24526 tcg_gen_ext8s_tl(t3, t3);
24529 tcg_gen_ext8u_tl(t0, t3);
24530 tcg_gen_shri_tl(t3, t3, 8);
24531 tcg_gen_ext8u_tl(t1, t3);
24532 tcg_gen_shri_tl(t3, t3, 8);
24533 tcg_gen_ext8u_tl(t2, t3);
24534 tcg_gen_shri_tl(t3, t3, 8);
24535 tcg_gen_ext8u_tl(t3, t3);
24538 tcg_gen_ext8u_tl(t4, t7);
24539 tcg_gen_shri_tl(t7, t7, 8);
24540 tcg_gen_ext8u_tl(t5, t7);
24541 tcg_gen_shri_tl(t7, t7, 8);
24542 tcg_gen_ext8u_tl(t6, t7);
24543 tcg_gen_shri_tl(t7, t7, 8);
24544 tcg_gen_ext8u_tl(t7, t7);
24546 tcg_gen_mul_tl(t0, t0, t4);
24547 tcg_gen_mul_tl(t1, t1, t5);
24548 tcg_gen_mul_tl(t2, t2, t6);
24549 tcg_gen_mul_tl(t3, t3, t7);
24551 tcg_gen_andi_tl(t0, t0, 0xFFFF);
24552 tcg_gen_andi_tl(t1, t1, 0xFFFF);
24553 tcg_gen_andi_tl(t2, t2, 0xFFFF);
24554 tcg_gen_andi_tl(t3, t3, 0xFFFF);
24556 tcg_gen_shli_tl(t1, t1, 16);
24557 tcg_gen_shli_tl(t3, t3, 16);
24559 tcg_gen_or_tl(t0, t0, t1);
24560 tcg_gen_or_tl(t1, t2, t3);
24562 gen_store_mxu_gpr(t0, XRd);
24563 gen_store_mxu_gpr(t1, XRa);
24576 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
24577 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24579 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24582 uint32_t XRa, Rb, s12, sel;
24584 t0 = tcg_temp_new();
24585 t1 = tcg_temp_new();
24587 XRa = extract32(ctx->opcode, 6, 4);
24588 s12 = extract32(ctx->opcode, 10, 10);
24589 sel = extract32(ctx->opcode, 20, 1);
24590 Rb = extract32(ctx->opcode, 21, 5);
24592 gen_load_gpr(t0, Rb);
24594 tcg_gen_movi_tl(t1, s12);
24595 tcg_gen_shli_tl(t1, t1, 2);
24597 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24599 tcg_gen_add_tl(t1, t0, t1);
24600 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24604 tcg_gen_bswap32_tl(t1, t1);
24606 gen_store_mxu_gpr(t1, XRa);
24614 * Decoding engine for MXU
24615 * =======================
24620 * Decode MXU pool00
24622 * 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
24623 * +-----------+---------+-----+-------+-------+-------+-----------+
24624 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
24625 * +-----------+---------+-----+-------+-------+-------+-----------+
24628 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
24630 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24633 case OPC_MXU_S32MAX:
24634 /* TODO: Implement emulation of S32MAX instruction. */
24635 MIPS_INVAL("OPC_MXU_S32MAX");
24636 generate_exception_end(ctx, EXCP_RI);
24638 case OPC_MXU_S32MIN:
24639 /* TODO: Implement emulation of S32MIN instruction. */
24640 MIPS_INVAL("OPC_MXU_S32MIN");
24641 generate_exception_end(ctx, EXCP_RI);
24643 case OPC_MXU_D16MAX:
24644 /* TODO: Implement emulation of D16MAX instruction. */
24645 MIPS_INVAL("OPC_MXU_D16MAX");
24646 generate_exception_end(ctx, EXCP_RI);
24648 case OPC_MXU_D16MIN:
24649 /* TODO: Implement emulation of D16MIN instruction. */
24650 MIPS_INVAL("OPC_MXU_D16MIN");
24651 generate_exception_end(ctx, EXCP_RI);
24653 case OPC_MXU_Q8MAX:
24654 /* TODO: Implement emulation of Q8MAX instruction. */
24655 MIPS_INVAL("OPC_MXU_Q8MAX");
24656 generate_exception_end(ctx, EXCP_RI);
24658 case OPC_MXU_Q8MIN:
24659 /* TODO: Implement emulation of Q8MIN instruction. */
24660 MIPS_INVAL("OPC_MXU_Q8MIN");
24661 generate_exception_end(ctx, EXCP_RI);
24663 case OPC_MXU_Q8SLT:
24664 /* TODO: Implement emulation of Q8SLT instruction. */
24665 MIPS_INVAL("OPC_MXU_Q8SLT");
24666 generate_exception_end(ctx, EXCP_RI);
24668 case OPC_MXU_Q8SLTU:
24669 /* TODO: Implement emulation of Q8SLTU instruction. */
24670 MIPS_INVAL("OPC_MXU_Q8SLTU");
24671 generate_exception_end(ctx, EXCP_RI);
24674 MIPS_INVAL("decode_opc_mxu");
24675 generate_exception_end(ctx, EXCP_RI);
24682 * Decode MXU pool01
24684 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
24685 * 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
24686 * +-----------+---------+-----+-------+-------+-------+-----------+
24687 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
24688 * +-----------+---------+-----+-------+-------+-------+-----------+
24691 * 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
24692 * +-----------+---+-----+-----+-------+-------+-------+-----------+
24693 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
24694 * +-----------+---+-----+-----+-------+-------+-------+-----------+
24697 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
24699 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24702 case OPC_MXU_S32SLT:
24703 /* TODO: Implement emulation of S32SLT instruction. */
24704 MIPS_INVAL("OPC_MXU_S32SLT");
24705 generate_exception_end(ctx, EXCP_RI);
24707 case OPC_MXU_D16SLT:
24708 /* TODO: Implement emulation of D16SLT instruction. */
24709 MIPS_INVAL("OPC_MXU_D16SLT");
24710 generate_exception_end(ctx, EXCP_RI);
24712 case OPC_MXU_D16AVG:
24713 /* TODO: Implement emulation of D16AVG instruction. */
24714 MIPS_INVAL("OPC_MXU_D16AVG");
24715 generate_exception_end(ctx, EXCP_RI);
24717 case OPC_MXU_D16AVGR:
24718 /* TODO: Implement emulation of D16AVGR instruction. */
24719 MIPS_INVAL("OPC_MXU_D16AVGR");
24720 generate_exception_end(ctx, EXCP_RI);
24722 case OPC_MXU_Q8AVG:
24723 /* TODO: Implement emulation of Q8AVG instruction. */
24724 MIPS_INVAL("OPC_MXU_Q8AVG");
24725 generate_exception_end(ctx, EXCP_RI);
24727 case OPC_MXU_Q8AVGR:
24728 /* TODO: Implement emulation of Q8AVGR instruction. */
24729 MIPS_INVAL("OPC_MXU_Q8AVGR");
24730 generate_exception_end(ctx, EXCP_RI);
24732 case OPC_MXU_Q8ADD:
24733 /* TODO: Implement emulation of Q8ADD instruction. */
24734 MIPS_INVAL("OPC_MXU_Q8ADD");
24735 generate_exception_end(ctx, EXCP_RI);
24738 MIPS_INVAL("decode_opc_mxu");
24739 generate_exception_end(ctx, EXCP_RI);
24746 * Decode MXU pool02
24748 * 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
24749 * +-----------+---------+-----+-------+-------+-------+-----------+
24750 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
24751 * +-----------+---------+-----+-------+-------+-------+-----------+
24754 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
24756 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24759 case OPC_MXU_S32CPS:
24760 /* TODO: Implement emulation of S32CPS instruction. */
24761 MIPS_INVAL("OPC_MXU_S32CPS");
24762 generate_exception_end(ctx, EXCP_RI);
24764 case OPC_MXU_D16CPS:
24765 /* TODO: Implement emulation of D16CPS instruction. */
24766 MIPS_INVAL("OPC_MXU_D16CPS");
24767 generate_exception_end(ctx, EXCP_RI);
24769 case OPC_MXU_Q8ABD:
24770 /* TODO: Implement emulation of Q8ABD instruction. */
24771 MIPS_INVAL("OPC_MXU_Q8ABD");
24772 generate_exception_end(ctx, EXCP_RI);
24774 case OPC_MXU_Q16SAT:
24775 /* TODO: Implement emulation of Q16SAT instruction. */
24776 MIPS_INVAL("OPC_MXU_Q16SAT");
24777 generate_exception_end(ctx, EXCP_RI);
24780 MIPS_INVAL("decode_opc_mxu");
24781 generate_exception_end(ctx, EXCP_RI);
24788 * Decode MXU pool03
24791 * 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
24792 * +-----------+---+---+-------+-------+-------+-------+-----------+
24793 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
24794 * +-----------+---+---+-------+-------+-------+-------+-----------+
24797 * 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
24798 * +-----------+---+---+-------+-------+-------+-------+-----------+
24799 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
24800 * +-----------+---+---+-------+-------+-------+-------+-----------+
24803 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
24805 uint32_t opcode = extract32(ctx->opcode, 24, 2);
24808 case OPC_MXU_D16MULF:
24809 /* TODO: Implement emulation of D16MULF instruction. */
24810 MIPS_INVAL("OPC_MXU_D16MULF");
24811 generate_exception_end(ctx, EXCP_RI);
24813 case OPC_MXU_D16MULE:
24814 /* TODO: Implement emulation of D16MULE instruction. */
24815 MIPS_INVAL("OPC_MXU_D16MULE");
24816 generate_exception_end(ctx, EXCP_RI);
24819 MIPS_INVAL("decode_opc_mxu");
24820 generate_exception_end(ctx, EXCP_RI);
24827 * Decode MXU pool04
24829 * 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
24830 * +-----------+---------+-+-------------------+-------+-----------+
24831 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
24832 * +-----------+---------+-+-------------------+-------+-----------+
24835 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
24837 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24840 case OPC_MXU_S32LDD:
24841 case OPC_MXU_S32LDDR:
24842 gen_mxu_s32ldd_s32lddr(ctx);
24845 MIPS_INVAL("decode_opc_mxu");
24846 generate_exception_end(ctx, EXCP_RI);
24853 * Decode MXU pool05
24855 * 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
24856 * +-----------+---------+-+-------------------+-------+-----------+
24857 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
24858 * +-----------+---------+-+-------------------+-------+-----------+
24861 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
24863 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24866 case OPC_MXU_S32STD:
24867 /* TODO: Implement emulation of S32STD instruction. */
24868 MIPS_INVAL("OPC_MXU_S32STD");
24869 generate_exception_end(ctx, EXCP_RI);
24871 case OPC_MXU_S32STDR:
24872 /* TODO: Implement emulation of S32STDR instruction. */
24873 MIPS_INVAL("OPC_MXU_S32STDR");
24874 generate_exception_end(ctx, EXCP_RI);
24877 MIPS_INVAL("decode_opc_mxu");
24878 generate_exception_end(ctx, EXCP_RI);
24885 * Decode MXU pool06
24887 * 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
24888 * +-----------+---------+---------+---+-------+-------+-----------+
24889 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
24890 * +-----------+---------+---------+---+-------+-------+-----------+
24893 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
24895 uint32_t opcode = extract32(ctx->opcode, 10, 4);
24898 case OPC_MXU_S32LDDV:
24899 /* TODO: Implement emulation of S32LDDV instruction. */
24900 MIPS_INVAL("OPC_MXU_S32LDDV");
24901 generate_exception_end(ctx, EXCP_RI);
24903 case OPC_MXU_S32LDDVR:
24904 /* TODO: Implement emulation of S32LDDVR instruction. */
24905 MIPS_INVAL("OPC_MXU_S32LDDVR");
24906 generate_exception_end(ctx, EXCP_RI);
24909 MIPS_INVAL("decode_opc_mxu");
24910 generate_exception_end(ctx, EXCP_RI);
24917 * Decode MXU pool07
24919 * 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
24920 * +-----------+---------+---------+---+-------+-------+-----------+
24921 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
24922 * +-----------+---------+---------+---+-------+-------+-----------+
24925 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
24927 uint32_t opcode = extract32(ctx->opcode, 10, 4);
24930 case OPC_MXU_S32STDV:
24931 /* TODO: Implement emulation of S32TDV instruction. */
24932 MIPS_INVAL("OPC_MXU_S32TDV");
24933 generate_exception_end(ctx, EXCP_RI);
24935 case OPC_MXU_S32STDVR:
24936 /* TODO: Implement emulation of S32TDVR instruction. */
24937 MIPS_INVAL("OPC_MXU_S32TDVR");
24938 generate_exception_end(ctx, EXCP_RI);
24941 MIPS_INVAL("decode_opc_mxu");
24942 generate_exception_end(ctx, EXCP_RI);
24949 * Decode MXU pool08
24951 * 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
24952 * +-----------+---------+-+-------------------+-------+-----------+
24953 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
24954 * +-----------+---------+-+-------------------+-------+-----------+
24957 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
24959 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24962 case OPC_MXU_S32LDI:
24963 /* TODO: Implement emulation of S32LDI instruction. */
24964 MIPS_INVAL("OPC_MXU_S32LDI");
24965 generate_exception_end(ctx, EXCP_RI);
24967 case OPC_MXU_S32LDIR:
24968 /* TODO: Implement emulation of S32LDIR instruction. */
24969 MIPS_INVAL("OPC_MXU_S32LDIR");
24970 generate_exception_end(ctx, EXCP_RI);
24973 MIPS_INVAL("decode_opc_mxu");
24974 generate_exception_end(ctx, EXCP_RI);
24981 * Decode MXU pool09
24983 * 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
24984 * +-----------+---------+-+-------------------+-------+-----------+
24985 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
24986 * +-----------+---------+-+-------------------+-------+-----------+
24989 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
24991 uint32_t opcode = extract32(ctx->opcode, 5, 0);
24994 case OPC_MXU_S32SDI:
24995 /* TODO: Implement emulation of S32SDI instruction. */
24996 MIPS_INVAL("OPC_MXU_S32SDI");
24997 generate_exception_end(ctx, EXCP_RI);
24999 case OPC_MXU_S32SDIR:
25000 /* TODO: Implement emulation of S32SDIR instruction. */
25001 MIPS_INVAL("OPC_MXU_S32SDIR");
25002 generate_exception_end(ctx, EXCP_RI);
25005 MIPS_INVAL("decode_opc_mxu");
25006 generate_exception_end(ctx, EXCP_RI);
25013 * Decode MXU pool10
25015 * 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
25016 * +-----------+---------+---------+---+-------+-------+-----------+
25017 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
25018 * +-----------+---------+---------+---+-------+-------+-----------+
25021 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25023 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25026 case OPC_MXU_S32LDIV:
25027 /* TODO: Implement emulation of S32LDIV instruction. */
25028 MIPS_INVAL("OPC_MXU_S32LDIV");
25029 generate_exception_end(ctx, EXCP_RI);
25031 case OPC_MXU_S32LDIVR:
25032 /* TODO: Implement emulation of S32LDIVR instruction. */
25033 MIPS_INVAL("OPC_MXU_S32LDIVR");
25034 generate_exception_end(ctx, EXCP_RI);
25037 MIPS_INVAL("decode_opc_mxu");
25038 generate_exception_end(ctx, EXCP_RI);
25045 * Decode MXU pool11
25047 * 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
25048 * +-----------+---------+---------+---+-------+-------+-----------+
25049 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
25050 * +-----------+---------+---------+---+-------+-------+-----------+
25053 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25055 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25058 case OPC_MXU_S32SDIV:
25059 /* TODO: Implement emulation of S32SDIV instruction. */
25060 MIPS_INVAL("OPC_MXU_S32SDIV");
25061 generate_exception_end(ctx, EXCP_RI);
25063 case OPC_MXU_S32SDIVR:
25064 /* TODO: Implement emulation of S32SDIVR instruction. */
25065 MIPS_INVAL("OPC_MXU_S32SDIVR");
25066 generate_exception_end(ctx, EXCP_RI);
25069 MIPS_INVAL("decode_opc_mxu");
25070 generate_exception_end(ctx, EXCP_RI);
25077 * Decode MXU pool12
25079 * 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
25080 * +-----------+---+---+-------+-------+-------+-------+-----------+
25081 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
25082 * +-----------+---+---+-------+-------+-------+-------+-----------+
25085 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
25087 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25090 case OPC_MXU_D32ACC:
25091 /* TODO: Implement emulation of D32ACC instruction. */
25092 MIPS_INVAL("OPC_MXU_D32ACC");
25093 generate_exception_end(ctx, EXCP_RI);
25095 case OPC_MXU_D32ACCM:
25096 /* TODO: Implement emulation of D32ACCM instruction. */
25097 MIPS_INVAL("OPC_MXU_D32ACCM");
25098 generate_exception_end(ctx, EXCP_RI);
25100 case OPC_MXU_D32ASUM:
25101 /* TODO: Implement emulation of D32ASUM instruction. */
25102 MIPS_INVAL("OPC_MXU_D32ASUM");
25103 generate_exception_end(ctx, EXCP_RI);
25106 MIPS_INVAL("decode_opc_mxu");
25107 generate_exception_end(ctx, EXCP_RI);
25114 * Decode MXU pool13
25116 * 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
25117 * +-----------+---+---+-------+-------+-------+-------+-----------+
25118 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
25119 * +-----------+---+---+-------+-------+-------+-------+-----------+
25122 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
25124 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25127 case OPC_MXU_Q16ACC:
25128 /* TODO: Implement emulation of Q16ACC instruction. */
25129 MIPS_INVAL("OPC_MXU_Q16ACC");
25130 generate_exception_end(ctx, EXCP_RI);
25132 case OPC_MXU_Q16ACCM:
25133 /* TODO: Implement emulation of Q16ACCM instruction. */
25134 MIPS_INVAL("OPC_MXU_Q16ACCM");
25135 generate_exception_end(ctx, EXCP_RI);
25137 case OPC_MXU_Q16ASUM:
25138 /* TODO: Implement emulation of Q16ASUM instruction. */
25139 MIPS_INVAL("OPC_MXU_Q16ASUM");
25140 generate_exception_end(ctx, EXCP_RI);
25143 MIPS_INVAL("decode_opc_mxu");
25144 generate_exception_end(ctx, EXCP_RI);
25151 * Decode MXU pool14
25154 * 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
25155 * +-----------+---+---+-------+-------+-------+-------+-----------+
25156 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
25157 * +-----------+---+---+-------+-------+-------+-------+-----------+
25160 * 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
25161 * +-----------+---+---+-------+-------+-------+-------+-----------+
25162 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
25163 * +-----------+---+---+-------+-------+-------+-------+-----------+
25166 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
25168 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25171 case OPC_MXU_Q8ADDE:
25172 /* TODO: Implement emulation of Q8ADDE instruction. */
25173 MIPS_INVAL("OPC_MXU_Q8ADDE");
25174 generate_exception_end(ctx, EXCP_RI);
25176 case OPC_MXU_D8SUM:
25177 /* TODO: Implement emulation of D8SUM instruction. */
25178 MIPS_INVAL("OPC_MXU_D8SUM");
25179 generate_exception_end(ctx, EXCP_RI);
25181 case OPC_MXU_D8SUMC:
25182 /* TODO: Implement emulation of D8SUMC instruction. */
25183 MIPS_INVAL("OPC_MXU_D8SUMC");
25184 generate_exception_end(ctx, EXCP_RI);
25187 MIPS_INVAL("decode_opc_mxu");
25188 generate_exception_end(ctx, EXCP_RI);
25195 * Decode MXU pool15
25197 * S32MUL, S32MULU, S32EXTRV:
25198 * 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
25199 * +-----------+---------+---------+---+-------+-------+-----------+
25200 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
25201 * +-----------+---------+---------+---+-------+-------+-----------+
25204 * 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
25205 * +-----------+---------+---------+---+-------+-------+-----------+
25206 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
25207 * +-----------+---------+---------+---+-------+-------+-----------+
25210 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
25212 uint32_t opcode = extract32(ctx->opcode, 14, 2);
25215 case OPC_MXU_S32MUL:
25216 /* TODO: Implement emulation of S32MUL instruction. */
25217 MIPS_INVAL("OPC_MXU_S32MUL");
25218 generate_exception_end(ctx, EXCP_RI);
25220 case OPC_MXU_S32MULU:
25221 /* TODO: Implement emulation of S32MULU instruction. */
25222 MIPS_INVAL("OPC_MXU_S32MULU");
25223 generate_exception_end(ctx, EXCP_RI);
25225 case OPC_MXU_S32EXTR:
25226 /* TODO: Implement emulation of S32EXTR instruction. */
25227 MIPS_INVAL("OPC_MXU_S32EXTR");
25228 generate_exception_end(ctx, EXCP_RI);
25230 case OPC_MXU_S32EXTRV:
25231 /* TODO: Implement emulation of S32EXTRV instruction. */
25232 MIPS_INVAL("OPC_MXU_S32EXTRV");
25233 generate_exception_end(ctx, EXCP_RI);
25236 MIPS_INVAL("decode_opc_mxu");
25237 generate_exception_end(ctx, EXCP_RI);
25244 * Decode MXU pool16
25247 * 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
25248 * +-----------+---------+-----+-------+-------+-------+-----------+
25249 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
25250 * +-----------+---------+-----+-------+-------+-------+-----------+
25253 * 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
25254 * +-----------+---------+-----+-------+-------+-------+-----------+
25255 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
25256 * +-----------+---------+-----+-------+-------+-------+-----------+
25259 * 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
25260 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25261 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25262 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25264 * S32NOR, S32AND, S32OR, S32XOR:
25265 * 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
25266 * +-----------+---------+-----+-------+-------+-------+-----------+
25267 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25268 * +-----------+---------+-----+-------+-------+-------+-----------+
25271 * 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
25272 * +-----------+-----+---+-----+-------+---------------+-----------+
25273 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
25274 * +-----------+-----+---+-----+-------+---------------+-----------+
25277 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
25279 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25282 case OPC_MXU_D32SARW:
25283 /* TODO: Implement emulation of D32SARW instruction. */
25284 MIPS_INVAL("OPC_MXU_D32SARW");
25285 generate_exception_end(ctx, EXCP_RI);
25287 case OPC_MXU_S32ALN:
25288 /* TODO: Implement emulation of S32ALN instruction. */
25289 MIPS_INVAL("OPC_MXU_S32ALN");
25290 generate_exception_end(ctx, EXCP_RI);
25292 case OPC_MXU_S32ALNI:
25293 /* TODO: Implement emulation of S32ALNI instruction. */
25294 MIPS_INVAL("OPC_MXU_S32ALNI");
25295 generate_exception_end(ctx, EXCP_RI);
25297 case OPC_MXU_S32NOR:
25298 /* TODO: Implement emulation of S32NOR instruction. */
25299 MIPS_INVAL("OPC_MXU_S32NOR");
25300 generate_exception_end(ctx, EXCP_RI);
25302 case OPC_MXU_S32AND:
25303 /* TODO: Implement emulation of S32AND instruction. */
25304 MIPS_INVAL("OPC_MXU_S32AND");
25305 generate_exception_end(ctx, EXCP_RI);
25307 case OPC_MXU_S32OR:
25308 /* TODO: Implement emulation of S32OR instruction. */
25309 MIPS_INVAL("OPC_MXU_S32OR");
25310 generate_exception_end(ctx, EXCP_RI);
25312 case OPC_MXU_S32XOR:
25313 /* TODO: Implement emulation of S32XOR instruction. */
25314 MIPS_INVAL("OPC_MXU_S32XOR");
25315 generate_exception_end(ctx, EXCP_RI);
25317 case OPC_MXU_S32LUI:
25318 /* TODO: Implement emulation of S32LUI instruction. */
25319 MIPS_INVAL("OPC_MXU_S32LUI");
25320 generate_exception_end(ctx, EXCP_RI);
25323 MIPS_INVAL("decode_opc_mxu");
25324 generate_exception_end(ctx, EXCP_RI);
25331 * Decode MXU pool17
25333 * 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
25334 * +-----------+---------+-----+-------+-------+-------+-----------+
25335 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL17|
25336 * +-----------+---------+-----+-------+-------+-------+-----------+
25339 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
25341 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25344 case OPC_MXU_D32SLLV:
25345 /* TODO: Implement emulation of D32SLLV instruction. */
25346 MIPS_INVAL("OPC_MXU_D32SLLV");
25347 generate_exception_end(ctx, EXCP_RI);
25349 case OPC_MXU_D32SLRV:
25350 /* TODO: Implement emulation of D32SLRV instruction. */
25351 MIPS_INVAL("OPC_MXU_D32SLRV");
25352 generate_exception_end(ctx, EXCP_RI);
25354 case OPC_MXU_D32SARV:
25355 /* TODO: Implement emulation of D32SARV instruction. */
25356 MIPS_INVAL("OPC_MXU_D32SARV");
25357 generate_exception_end(ctx, EXCP_RI);
25359 case OPC_MXU_Q16SLLV:
25360 /* TODO: Implement emulation of Q16SLLV instruction. */
25361 MIPS_INVAL("OPC_MXU_Q16SLLV");
25362 generate_exception_end(ctx, EXCP_RI);
25364 case OPC_MXU_Q16SLRV:
25365 /* TODO: Implement emulation of Q16SLRV instruction. */
25366 MIPS_INVAL("OPC_MXU_Q16SLRV");
25367 generate_exception_end(ctx, EXCP_RI);
25369 case OPC_MXU_Q16SARV:
25370 /* TODO: Implement emulation of Q16SARV instruction. */
25371 MIPS_INVAL("OPC_MXU_Q16SARV");
25372 generate_exception_end(ctx, EXCP_RI);
25375 MIPS_INVAL("decode_opc_mxu");
25376 generate_exception_end(ctx, EXCP_RI);
25383 * Decode MXU pool18
25385 * 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
25386 * +-----------+---+---+-------+-------+-------+-------+-----------+
25387 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL18|
25388 * +-----------+---+---+-------+-------+-------+-------+-----------+
25391 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
25393 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25396 case OPC_MXU_Q8MUL:
25397 case OPC_MXU_Q8MULSU:
25398 gen_mxu_q8mul_q8mulsu(ctx);
25401 MIPS_INVAL("decode_opc_mxu");
25402 generate_exception_end(ctx, EXCP_RI);
25409 * Decode MXU pool19
25411 * 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
25412 * +-----------+---------+-----+-------+-------+-------+-----------+
25413 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL19|
25414 * +-----------+---------+-----+-------+-------+-------+-----------+
25417 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
25419 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25422 case OPC_MXU_Q8MOVZ:
25423 /* TODO: Implement emulation of Q8MOVZ instruction. */
25424 MIPS_INVAL("OPC_MXU_Q8MOVZ");
25425 generate_exception_end(ctx, EXCP_RI);
25427 case OPC_MXU_Q8MOVN:
25428 /* TODO: Implement emulation of Q8MOVN instruction. */
25429 MIPS_INVAL("OPC_MXU_Q8MOVN");
25430 generate_exception_end(ctx, EXCP_RI);
25432 case OPC_MXU_D16MOVZ:
25433 /* TODO: Implement emulation of D16MOVZ instruction. */
25434 MIPS_INVAL("OPC_MXU_D16MOVZ");
25435 generate_exception_end(ctx, EXCP_RI);
25437 case OPC_MXU_D16MOVN:
25438 /* TODO: Implement emulation of D16MOVN instruction. */
25439 MIPS_INVAL("OPC_MXU_D16MOVN");
25440 generate_exception_end(ctx, EXCP_RI);
25442 case OPC_MXU_S32MOVZ:
25443 /* TODO: Implement emulation of S32MOVZ instruction. */
25444 MIPS_INVAL("OPC_MXU_S32MOVZ");
25445 generate_exception_end(ctx, EXCP_RI);
25447 case OPC_MXU_S32MOVN:
25448 /* TODO: Implement emulation of S32MOVN instruction. */
25449 MIPS_INVAL("OPC_MXU_S32MOVN");
25450 generate_exception_end(ctx, EXCP_RI);
25453 MIPS_INVAL("decode_opc_mxu");
25454 generate_exception_end(ctx, EXCP_RI);
25461 * Decode MXU pool20
25463 * 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
25464 * +-----------+---+---+-------+-------+-------+-------+-----------+
25465 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL20|
25466 * +-----------+---+---+-------+-------+-------+-------+-----------+
25469 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
25471 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25474 case OPC_MXU_Q8MAC:
25475 /* TODO: Implement emulation of Q8MAC instruction. */
25476 MIPS_INVAL("OPC_MXU_Q8MAC");
25477 generate_exception_end(ctx, EXCP_RI);
25479 case OPC_MXU_Q8MACSU:
25480 /* TODO: Implement emulation of Q8MACSU instruction. */
25481 MIPS_INVAL("OPC_MXU_Q8MACSU");
25482 generate_exception_end(ctx, EXCP_RI);
25485 MIPS_INVAL("decode_opc_mxu");
25486 generate_exception_end(ctx, EXCP_RI);
25493 * Main MXU decoding function
25495 * 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
25496 * +-----------+---------------------------------------+-----------+
25497 * | SPECIAL2 | |x x x x x x|
25498 * +-----------+---------------------------------------+-----------+
25501 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
25504 * TODO: Investigate necessity of including handling of
25505 * CLZ, CLO, SDBB in this function, as they belong to
25506 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
25508 uint32_t opcode = extract32(ctx->opcode, 0, 6);
25510 if (opcode == OPC__MXU_MUL) {
25511 uint32_t rs, rt, rd, op1;
25513 rs = extract32(ctx->opcode, 21, 5);
25514 rt = extract32(ctx->opcode, 16, 5);
25515 rd = extract32(ctx->opcode, 11, 5);
25516 op1 = MASK_SPECIAL2(ctx->opcode);
25518 gen_arith(ctx, op1, rd, rs, rt);
25523 if (opcode == OPC_MXU_S32M2I) {
25524 gen_mxu_s32m2i(ctx);
25528 if (opcode == OPC_MXU_S32I2M) {
25529 gen_mxu_s32i2m(ctx);
25534 TCGv t_mxu_cr = tcg_temp_new();
25535 TCGLabel *l_exit = gen_new_label();
25537 gen_load_mxu_cr(t_mxu_cr);
25538 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
25539 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
25542 case OPC_MXU_S32MADD:
25543 /* TODO: Implement emulation of S32MADD instruction. */
25544 MIPS_INVAL("OPC_MXU_S32MADD");
25545 generate_exception_end(ctx, EXCP_RI);
25547 case OPC_MXU_S32MADDU:
25548 /* TODO: Implement emulation of S32MADDU instruction. */
25549 MIPS_INVAL("OPC_MXU_S32MADDU");
25550 generate_exception_end(ctx, EXCP_RI);
25552 case OPC_MXU__POOL00:
25553 decode_opc_mxu__pool00(env, ctx);
25555 case OPC_MXU_S32MSUB:
25556 /* TODO: Implement emulation of S32MSUB instruction. */
25557 MIPS_INVAL("OPC_MXU_S32MSUB");
25558 generate_exception_end(ctx, EXCP_RI);
25560 case OPC_MXU_S32MSUBU:
25561 /* TODO: Implement emulation of S32MSUBU instruction. */
25562 MIPS_INVAL("OPC_MXU_S32MSUBU");
25563 generate_exception_end(ctx, EXCP_RI);
25565 case OPC_MXU__POOL01:
25566 decode_opc_mxu__pool01(env, ctx);
25568 case OPC_MXU__POOL02:
25569 decode_opc_mxu__pool02(env, ctx);
25571 case OPC_MXU_D16MUL:
25572 gen_mxu_d16mul(ctx);
25574 case OPC_MXU__POOL03:
25575 decode_opc_mxu__pool03(env, ctx);
25577 case OPC_MXU_D16MAC:
25578 gen_mxu_d16mac(ctx);
25580 case OPC_MXU_D16MACF:
25581 /* TODO: Implement emulation of D16MACF instruction. */
25582 MIPS_INVAL("OPC_MXU_D16MACF");
25583 generate_exception_end(ctx, EXCP_RI);
25585 case OPC_MXU_D16MADL:
25586 /* TODO: Implement emulation of D16MADL instruction. */
25587 MIPS_INVAL("OPC_MXU_D16MADL");
25588 generate_exception_end(ctx, EXCP_RI);
25590 case OPC_MXU_S16MAD:
25591 /* TODO: Implement emulation of S16MAD instruction. */
25592 MIPS_INVAL("OPC_MXU_S16MAD");
25593 generate_exception_end(ctx, EXCP_RI);
25595 case OPC_MXU_Q16ADD:
25596 /* TODO: Implement emulation of Q16ADD instruction. */
25597 MIPS_INVAL("OPC_MXU_Q16ADD");
25598 generate_exception_end(ctx, EXCP_RI);
25600 case OPC_MXU_D16MACE:
25601 /* TODO: Implement emulation of D16MACE instruction. */
25602 MIPS_INVAL("OPC_MXU_D16MACE");
25603 generate_exception_end(ctx, EXCP_RI);
25605 case OPC_MXU__POOL04:
25606 decode_opc_mxu__pool04(env, ctx);
25608 case OPC_MXU__POOL05:
25609 decode_opc_mxu__pool05(env, ctx);
25611 case OPC_MXU__POOL06:
25612 decode_opc_mxu__pool06(env, ctx);
25614 case OPC_MXU__POOL07:
25615 decode_opc_mxu__pool07(env, ctx);
25617 case OPC_MXU__POOL08:
25618 decode_opc_mxu__pool08(env, ctx);
25620 case OPC_MXU__POOL09:
25621 decode_opc_mxu__pool09(env, ctx);
25623 case OPC_MXU__POOL10:
25624 decode_opc_mxu__pool10(env, ctx);
25626 case OPC_MXU__POOL11:
25627 decode_opc_mxu__pool11(env, ctx);
25629 case OPC_MXU_D32ADD:
25630 /* TODO: Implement emulation of D32ADD instruction. */
25631 MIPS_INVAL("OPC_MXU_D32ADD");
25632 generate_exception_end(ctx, EXCP_RI);
25634 case OPC_MXU__POOL12:
25635 decode_opc_mxu__pool12(env, ctx);
25637 case OPC_MXU__POOL13:
25638 decode_opc_mxu__pool13(env, ctx);
25640 case OPC_MXU__POOL14:
25641 decode_opc_mxu__pool14(env, ctx);
25643 case OPC_MXU_Q8ACCE:
25644 /* TODO: Implement emulation of Q8ACCE instruction. */
25645 MIPS_INVAL("OPC_MXU_Q8ACCE");
25646 generate_exception_end(ctx, EXCP_RI);
25648 case OPC_MXU_S8LDD:
25649 gen_mxu_s8ldd(ctx);
25651 case OPC_MXU_S8STD:
25652 /* TODO: Implement emulation of S8STD instruction. */
25653 MIPS_INVAL("OPC_MXU_S8STD");
25654 generate_exception_end(ctx, EXCP_RI);
25656 case OPC_MXU_S8LDI:
25657 /* TODO: Implement emulation of S8LDI instruction. */
25658 MIPS_INVAL("OPC_MXU_S8LDI");
25659 generate_exception_end(ctx, EXCP_RI);
25661 case OPC_MXU_S8SDI:
25662 /* TODO: Implement emulation of S8SDI instruction. */
25663 MIPS_INVAL("OPC_MXU_S8SDI");
25664 generate_exception_end(ctx, EXCP_RI);
25666 case OPC_MXU__POOL15:
25667 decode_opc_mxu__pool15(env, ctx);
25669 case OPC_MXU__POOL16:
25670 decode_opc_mxu__pool16(env, ctx);
25673 /* TODO: Implement emulation of LXB instruction. */
25674 MIPS_INVAL("OPC_MXU_LXB");
25675 generate_exception_end(ctx, EXCP_RI);
25677 case OPC_MXU_S16LDD:
25678 /* TODO: Implement emulation of S16LDD instruction. */
25679 MIPS_INVAL("OPC_MXU_S16LDD");
25680 generate_exception_end(ctx, EXCP_RI);
25682 case OPC_MXU_S16STD:
25683 /* TODO: Implement emulation of S16STD instruction. */
25684 MIPS_INVAL("OPC_MXU_S16STD");
25685 generate_exception_end(ctx, EXCP_RI);
25687 case OPC_MXU_S16LDI:
25688 /* TODO: Implement emulation of S16LDI instruction. */
25689 MIPS_INVAL("OPC_MXU_S16LDI");
25690 generate_exception_end(ctx, EXCP_RI);
25692 case OPC_MXU_S16SDI:
25693 /* TODO: Implement emulation of S16SDI instruction. */
25694 MIPS_INVAL("OPC_MXU_S16SDI");
25695 generate_exception_end(ctx, EXCP_RI);
25697 case OPC_MXU_D32SLL:
25698 /* TODO: Implement emulation of D32SLL instruction. */
25699 MIPS_INVAL("OPC_MXU_D32SLL");
25700 generate_exception_end(ctx, EXCP_RI);
25702 case OPC_MXU_D32SLR:
25703 /* TODO: Implement emulation of D32SLR instruction. */
25704 MIPS_INVAL("OPC_MXU_D32SLR");
25705 generate_exception_end(ctx, EXCP_RI);
25707 case OPC_MXU_D32SARL:
25708 /* TODO: Implement emulation of D32SARL instruction. */
25709 MIPS_INVAL("OPC_MXU_D32SARL");
25710 generate_exception_end(ctx, EXCP_RI);
25712 case OPC_MXU_D32SAR:
25713 /* TODO: Implement emulation of D32SAR instruction. */
25714 MIPS_INVAL("OPC_MXU_D32SAR");
25715 generate_exception_end(ctx, EXCP_RI);
25717 case OPC_MXU_Q16SLL:
25718 /* TODO: Implement emulation of Q16SLL instruction. */
25719 MIPS_INVAL("OPC_MXU_Q16SLL");
25720 generate_exception_end(ctx, EXCP_RI);
25722 case OPC_MXU_Q16SLR:
25723 /* TODO: Implement emulation of Q16SLR instruction. */
25724 MIPS_INVAL("OPC_MXU_Q16SLR");
25725 generate_exception_end(ctx, EXCP_RI);
25727 case OPC_MXU__POOL17:
25728 decode_opc_mxu__pool17(env, ctx);
25730 case OPC_MXU_Q16SAR:
25731 /* TODO: Implement emulation of Q16SAR instruction. */
25732 MIPS_INVAL("OPC_MXU_Q16SAR");
25733 generate_exception_end(ctx, EXCP_RI);
25735 case OPC_MXU__POOL18:
25736 decode_opc_mxu__pool18(env, ctx);
25738 case OPC_MXU__POOL19:
25739 decode_opc_mxu__pool19(env, ctx);
25741 case OPC_MXU__POOL20:
25742 decode_opc_mxu__pool20(env, ctx);
25744 case OPC_MXU_Q16SCOP:
25745 /* TODO: Implement emulation of Q16SCOP instruction. */
25746 MIPS_INVAL("OPC_MXU_Q16SCOP");
25747 generate_exception_end(ctx, EXCP_RI);
25749 case OPC_MXU_Q8MADL:
25750 /* TODO: Implement emulation of Q8MADL instruction. */
25751 MIPS_INVAL("OPC_MXU_Q8MADL");
25752 generate_exception_end(ctx, EXCP_RI);
25754 case OPC_MXU_S32SFL:
25755 /* TODO: Implement emulation of S32SFL instruction. */
25756 MIPS_INVAL("OPC_MXU_S32SFL");
25757 generate_exception_end(ctx, EXCP_RI);
25759 case OPC_MXU_Q8SAD:
25760 /* TODO: Implement emulation of Q8SAD instruction. */
25761 MIPS_INVAL("OPC_MXU_Q8SAD");
25762 generate_exception_end(ctx, EXCP_RI);
25765 MIPS_INVAL("decode_opc_mxu");
25766 generate_exception_end(ctx, EXCP_RI);
25769 gen_set_label(l_exit);
25770 tcg_temp_free(t_mxu_cr);
25775 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
25780 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25782 rs = (ctx->opcode >> 21) & 0x1f;
25783 rt = (ctx->opcode >> 16) & 0x1f;
25784 rd = (ctx->opcode >> 11) & 0x1f;
25786 op1 = MASK_SPECIAL2(ctx->opcode);
25788 case OPC_MADD: /* Multiply and add/sub */
25792 check_insn(ctx, ISA_MIPS32);
25793 gen_muldiv(ctx, op1, rd & 3, rs, rt);
25796 gen_arith(ctx, op1, rd, rs, rt);
25799 case OPC_DIVU_G_2F:
25800 case OPC_MULT_G_2F:
25801 case OPC_MULTU_G_2F:
25803 case OPC_MODU_G_2F:
25804 check_insn(ctx, INSN_LOONGSON2F);
25805 gen_loongson_integer(ctx, op1, rd, rs, rt);
25809 check_insn(ctx, ISA_MIPS32);
25810 gen_cl(ctx, op1, rd, rs);
25813 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
25814 gen_helper_do_semihosting(cpu_env);
25816 /* XXX: not clear which exception should be raised
25817 * when in debug mode...
25819 check_insn(ctx, ISA_MIPS32);
25820 generate_exception_end(ctx, EXCP_DBp);
25823 #if defined(TARGET_MIPS64)
25826 check_insn(ctx, ISA_MIPS64);
25827 check_mips_64(ctx);
25828 gen_cl(ctx, op1, rd, rs);
25830 case OPC_DMULT_G_2F:
25831 case OPC_DMULTU_G_2F:
25832 case OPC_DDIV_G_2F:
25833 case OPC_DDIVU_G_2F:
25834 case OPC_DMOD_G_2F:
25835 case OPC_DMODU_G_2F:
25836 check_insn(ctx, INSN_LOONGSON2F);
25837 gen_loongson_integer(ctx, op1, rd, rs, rt);
25840 default: /* Invalid */
25841 MIPS_INVAL("special2_legacy");
25842 generate_exception_end(ctx, EXCP_RI);
25847 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
25849 int rs, rt, rd, sa;
25853 rs = (ctx->opcode >> 21) & 0x1f;
25854 rt = (ctx->opcode >> 16) & 0x1f;
25855 rd = (ctx->opcode >> 11) & 0x1f;
25856 sa = (ctx->opcode >> 6) & 0x1f;
25857 imm = (int16_t)ctx->opcode >> 7;
25859 op1 = MASK_SPECIAL3(ctx->opcode);
25863 /* hint codes 24-31 are reserved and signal RI */
25864 generate_exception_end(ctx, EXCP_RI);
25866 /* Treat as NOP. */
25869 check_cp0_enabled(ctx);
25870 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25871 gen_cache_operation(ctx, rt, rs, imm);
25875 gen_st_cond(ctx, op1, rt, rs, imm);
25878 gen_ld(ctx, op1, rt, rs, imm);
25883 /* Treat as NOP. */
25886 op2 = MASK_BSHFL(ctx->opcode);
25892 gen_align(ctx, 32, rd, rs, rt, sa & 3);
25895 gen_bitswap(ctx, op2, rd, rt);
25900 #if defined(TARGET_MIPS64)
25902 gen_st_cond(ctx, op1, rt, rs, imm);
25905 gen_ld(ctx, op1, rt, rs, imm);
25908 check_mips_64(ctx);
25911 /* Treat as NOP. */
25914 op2 = MASK_DBSHFL(ctx->opcode);
25924 gen_align(ctx, 64, rd, rs, rt, sa & 7);
25927 gen_bitswap(ctx, op2, rd, rt);
25934 default: /* Invalid */
25935 MIPS_INVAL("special3_r6");
25936 generate_exception_end(ctx, EXCP_RI);
25941 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
25946 rs = (ctx->opcode >> 21) & 0x1f;
25947 rt = (ctx->opcode >> 16) & 0x1f;
25948 rd = (ctx->opcode >> 11) & 0x1f;
25950 op1 = MASK_SPECIAL3(ctx->opcode);
25953 case OPC_DIVU_G_2E:
25955 case OPC_MODU_G_2E:
25956 case OPC_MULT_G_2E:
25957 case OPC_MULTU_G_2E:
25958 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
25959 * the same mask and op1. */
25960 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
25961 op2 = MASK_ADDUH_QB(ctx->opcode);
25964 case OPC_ADDUH_R_QB:
25966 case OPC_ADDQH_R_PH:
25968 case OPC_ADDQH_R_W:
25970 case OPC_SUBUH_R_QB:
25972 case OPC_SUBQH_R_PH:
25974 case OPC_SUBQH_R_W:
25975 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25980 case OPC_MULQ_RS_W:
25981 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
25984 MIPS_INVAL("MASK ADDUH.QB");
25985 generate_exception_end(ctx, EXCP_RI);
25988 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
25989 gen_loongson_integer(ctx, op1, rd, rs, rt);
25991 generate_exception_end(ctx, EXCP_RI);
25995 op2 = MASK_LX(ctx->opcode);
25997 #if defined(TARGET_MIPS64)
26003 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26005 default: /* Invalid */
26006 MIPS_INVAL("MASK LX");
26007 generate_exception_end(ctx, EXCP_RI);
26011 case OPC_ABSQ_S_PH_DSP:
26012 op2 = MASK_ABSQ_S_PH(ctx->opcode);
26014 case OPC_ABSQ_S_QB:
26015 case OPC_ABSQ_S_PH:
26017 case OPC_PRECEQ_W_PHL:
26018 case OPC_PRECEQ_W_PHR:
26019 case OPC_PRECEQU_PH_QBL:
26020 case OPC_PRECEQU_PH_QBR:
26021 case OPC_PRECEQU_PH_QBLA:
26022 case OPC_PRECEQU_PH_QBRA:
26023 case OPC_PRECEU_PH_QBL:
26024 case OPC_PRECEU_PH_QBR:
26025 case OPC_PRECEU_PH_QBLA:
26026 case OPC_PRECEU_PH_QBRA:
26027 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26034 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26037 MIPS_INVAL("MASK ABSQ_S.PH");
26038 generate_exception_end(ctx, EXCP_RI);
26042 case OPC_ADDU_QB_DSP:
26043 op2 = MASK_ADDU_QB(ctx->opcode);
26046 case OPC_ADDQ_S_PH:
26049 case OPC_ADDU_S_QB:
26051 case OPC_ADDU_S_PH:
26053 case OPC_SUBQ_S_PH:
26056 case OPC_SUBU_S_QB:
26058 case OPC_SUBU_S_PH:
26062 case OPC_RADDU_W_QB:
26063 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26065 case OPC_MULEU_S_PH_QBL:
26066 case OPC_MULEU_S_PH_QBR:
26067 case OPC_MULQ_RS_PH:
26068 case OPC_MULEQ_S_W_PHL:
26069 case OPC_MULEQ_S_W_PHR:
26070 case OPC_MULQ_S_PH:
26071 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26073 default: /* Invalid */
26074 MIPS_INVAL("MASK ADDU.QB");
26075 generate_exception_end(ctx, EXCP_RI);
26080 case OPC_CMPU_EQ_QB_DSP:
26081 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
26083 case OPC_PRECR_SRA_PH_W:
26084 case OPC_PRECR_SRA_R_PH_W:
26085 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
26087 case OPC_PRECR_QB_PH:
26088 case OPC_PRECRQ_QB_PH:
26089 case OPC_PRECRQ_PH_W:
26090 case OPC_PRECRQ_RS_PH_W:
26091 case OPC_PRECRQU_S_QB_PH:
26092 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26094 case OPC_CMPU_EQ_QB:
26095 case OPC_CMPU_LT_QB:
26096 case OPC_CMPU_LE_QB:
26097 case OPC_CMP_EQ_PH:
26098 case OPC_CMP_LT_PH:
26099 case OPC_CMP_LE_PH:
26100 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
26102 case OPC_CMPGU_EQ_QB:
26103 case OPC_CMPGU_LT_QB:
26104 case OPC_CMPGU_LE_QB:
26105 case OPC_CMPGDU_EQ_QB:
26106 case OPC_CMPGDU_LT_QB:
26107 case OPC_CMPGDU_LE_QB:
26110 case OPC_PACKRL_PH:
26111 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26113 default: /* Invalid */
26114 MIPS_INVAL("MASK CMPU.EQ.QB");
26115 generate_exception_end(ctx, EXCP_RI);
26119 case OPC_SHLL_QB_DSP:
26120 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26122 case OPC_DPA_W_PH_DSP:
26123 op2 = MASK_DPA_W_PH(ctx->opcode);
26125 case OPC_DPAU_H_QBL:
26126 case OPC_DPAU_H_QBR:
26127 case OPC_DPSU_H_QBL:
26128 case OPC_DPSU_H_QBR:
26130 case OPC_DPAX_W_PH:
26131 case OPC_DPAQ_S_W_PH:
26132 case OPC_DPAQX_S_W_PH:
26133 case OPC_DPAQX_SA_W_PH:
26135 case OPC_DPSX_W_PH:
26136 case OPC_DPSQ_S_W_PH:
26137 case OPC_DPSQX_S_W_PH:
26138 case OPC_DPSQX_SA_W_PH:
26139 case OPC_MULSAQ_S_W_PH:
26140 case OPC_DPAQ_SA_L_W:
26141 case OPC_DPSQ_SA_L_W:
26142 case OPC_MAQ_S_W_PHL:
26143 case OPC_MAQ_S_W_PHR:
26144 case OPC_MAQ_SA_W_PHL:
26145 case OPC_MAQ_SA_W_PHR:
26146 case OPC_MULSA_W_PH:
26147 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26149 default: /* Invalid */
26150 MIPS_INVAL("MASK DPAW.PH");
26151 generate_exception_end(ctx, EXCP_RI);
26156 op2 = MASK_INSV(ctx->opcode);
26167 t0 = tcg_temp_new();
26168 t1 = tcg_temp_new();
26170 gen_load_gpr(t0, rt);
26171 gen_load_gpr(t1, rs);
26173 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
26179 default: /* Invalid */
26180 MIPS_INVAL("MASK INSV");
26181 generate_exception_end(ctx, EXCP_RI);
26185 case OPC_APPEND_DSP:
26186 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26188 case OPC_EXTR_W_DSP:
26189 op2 = MASK_EXTR_W(ctx->opcode);
26193 case OPC_EXTR_RS_W:
26195 case OPC_EXTRV_S_H:
26197 case OPC_EXTRV_R_W:
26198 case OPC_EXTRV_RS_W:
26203 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
26206 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
26212 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
26214 default: /* Invalid */
26215 MIPS_INVAL("MASK EXTR.W");
26216 generate_exception_end(ctx, EXCP_RI);
26220 #if defined(TARGET_MIPS64)
26221 case OPC_DDIV_G_2E:
26222 case OPC_DDIVU_G_2E:
26223 case OPC_DMULT_G_2E:
26224 case OPC_DMULTU_G_2E:
26225 case OPC_DMOD_G_2E:
26226 case OPC_DMODU_G_2E:
26227 check_insn(ctx, INSN_LOONGSON2E);
26228 gen_loongson_integer(ctx, op1, rd, rs, rt);
26230 case OPC_ABSQ_S_QH_DSP:
26231 op2 = MASK_ABSQ_S_QH(ctx->opcode);
26233 case OPC_PRECEQ_L_PWL:
26234 case OPC_PRECEQ_L_PWR:
26235 case OPC_PRECEQ_PW_QHL:
26236 case OPC_PRECEQ_PW_QHR:
26237 case OPC_PRECEQ_PW_QHLA:
26238 case OPC_PRECEQ_PW_QHRA:
26239 case OPC_PRECEQU_QH_OBL:
26240 case OPC_PRECEQU_QH_OBR:
26241 case OPC_PRECEQU_QH_OBLA:
26242 case OPC_PRECEQU_QH_OBRA:
26243 case OPC_PRECEU_QH_OBL:
26244 case OPC_PRECEU_QH_OBR:
26245 case OPC_PRECEU_QH_OBLA:
26246 case OPC_PRECEU_QH_OBRA:
26247 case OPC_ABSQ_S_OB:
26248 case OPC_ABSQ_S_PW:
26249 case OPC_ABSQ_S_QH:
26250 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26258 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26260 default: /* Invalid */
26261 MIPS_INVAL("MASK ABSQ_S.QH");
26262 generate_exception_end(ctx, EXCP_RI);
26266 case OPC_ADDU_OB_DSP:
26267 op2 = MASK_ADDU_OB(ctx->opcode);
26269 case OPC_RADDU_L_OB:
26271 case OPC_SUBQ_S_PW:
26273 case OPC_SUBQ_S_QH:
26275 case OPC_SUBU_S_OB:
26277 case OPC_SUBU_S_QH:
26279 case OPC_SUBUH_R_OB:
26281 case OPC_ADDQ_S_PW:
26283 case OPC_ADDQ_S_QH:
26285 case OPC_ADDU_S_OB:
26287 case OPC_ADDU_S_QH:
26289 case OPC_ADDUH_R_OB:
26290 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26292 case OPC_MULEQ_S_PW_QHL:
26293 case OPC_MULEQ_S_PW_QHR:
26294 case OPC_MULEU_S_QH_OBL:
26295 case OPC_MULEU_S_QH_OBR:
26296 case OPC_MULQ_RS_QH:
26297 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26299 default: /* Invalid */
26300 MIPS_INVAL("MASK ADDU.OB");
26301 generate_exception_end(ctx, EXCP_RI);
26305 case OPC_CMPU_EQ_OB_DSP:
26306 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
26308 case OPC_PRECR_SRA_QH_PW:
26309 case OPC_PRECR_SRA_R_QH_PW:
26310 /* Return value is rt. */
26311 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
26313 case OPC_PRECR_OB_QH:
26314 case OPC_PRECRQ_OB_QH:
26315 case OPC_PRECRQ_PW_L:
26316 case OPC_PRECRQ_QH_PW:
26317 case OPC_PRECRQ_RS_QH_PW:
26318 case OPC_PRECRQU_S_OB_QH:
26319 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26321 case OPC_CMPU_EQ_OB:
26322 case OPC_CMPU_LT_OB:
26323 case OPC_CMPU_LE_OB:
26324 case OPC_CMP_EQ_QH:
26325 case OPC_CMP_LT_QH:
26326 case OPC_CMP_LE_QH:
26327 case OPC_CMP_EQ_PW:
26328 case OPC_CMP_LT_PW:
26329 case OPC_CMP_LE_PW:
26330 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
26332 case OPC_CMPGDU_EQ_OB:
26333 case OPC_CMPGDU_LT_OB:
26334 case OPC_CMPGDU_LE_OB:
26335 case OPC_CMPGU_EQ_OB:
26336 case OPC_CMPGU_LT_OB:
26337 case OPC_CMPGU_LE_OB:
26338 case OPC_PACKRL_PW:
26342 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26344 default: /* Invalid */
26345 MIPS_INVAL("MASK CMPU_EQ.OB");
26346 generate_exception_end(ctx, EXCP_RI);
26350 case OPC_DAPPEND_DSP:
26351 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26353 case OPC_DEXTR_W_DSP:
26354 op2 = MASK_DEXTR_W(ctx->opcode);
26361 case OPC_DEXTR_R_L:
26362 case OPC_DEXTR_RS_L:
26364 case OPC_DEXTR_R_W:
26365 case OPC_DEXTR_RS_W:
26366 case OPC_DEXTR_S_H:
26368 case OPC_DEXTRV_R_L:
26369 case OPC_DEXTRV_RS_L:
26370 case OPC_DEXTRV_S_H:
26372 case OPC_DEXTRV_R_W:
26373 case OPC_DEXTRV_RS_W:
26374 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
26379 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
26381 default: /* Invalid */
26382 MIPS_INVAL("MASK EXTR.W");
26383 generate_exception_end(ctx, EXCP_RI);
26387 case OPC_DPAQ_W_QH_DSP:
26388 op2 = MASK_DPAQ_W_QH(ctx->opcode);
26390 case OPC_DPAU_H_OBL:
26391 case OPC_DPAU_H_OBR:
26392 case OPC_DPSU_H_OBL:
26393 case OPC_DPSU_H_OBR:
26395 case OPC_DPAQ_S_W_QH:
26397 case OPC_DPSQ_S_W_QH:
26398 case OPC_MULSAQ_S_W_QH:
26399 case OPC_DPAQ_SA_L_PW:
26400 case OPC_DPSQ_SA_L_PW:
26401 case OPC_MULSAQ_S_L_PW:
26402 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26404 case OPC_MAQ_S_W_QHLL:
26405 case OPC_MAQ_S_W_QHLR:
26406 case OPC_MAQ_S_W_QHRL:
26407 case OPC_MAQ_S_W_QHRR:
26408 case OPC_MAQ_SA_W_QHLL:
26409 case OPC_MAQ_SA_W_QHLR:
26410 case OPC_MAQ_SA_W_QHRL:
26411 case OPC_MAQ_SA_W_QHRR:
26412 case OPC_MAQ_S_L_PWL:
26413 case OPC_MAQ_S_L_PWR:
26418 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26420 default: /* Invalid */
26421 MIPS_INVAL("MASK DPAQ.W.QH");
26422 generate_exception_end(ctx, EXCP_RI);
26426 case OPC_DINSV_DSP:
26427 op2 = MASK_INSV(ctx->opcode);
26438 t0 = tcg_temp_new();
26439 t1 = tcg_temp_new();
26441 gen_load_gpr(t0, rt);
26442 gen_load_gpr(t1, rs);
26444 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
26450 default: /* Invalid */
26451 MIPS_INVAL("MASK DINSV");
26452 generate_exception_end(ctx, EXCP_RI);
26456 case OPC_SHLL_OB_DSP:
26457 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26460 default: /* Invalid */
26461 MIPS_INVAL("special3_legacy");
26462 generate_exception_end(ctx, EXCP_RI);
26467 static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
26469 uint32_t opc = MASK_MMI0(ctx->opcode);
26472 case MMI_OPC_0_PADDW: /* TODO: MMI_OPC_0_PADDW */
26473 case MMI_OPC_0_PSUBW: /* TODO: MMI_OPC_0_PSUBW */
26474 case MMI_OPC_0_PCGTW: /* TODO: MMI_OPC_0_PCGTW */
26475 case MMI_OPC_0_PMAXW: /* TODO: MMI_OPC_0_PMAXW */
26476 case MMI_OPC_0_PADDH: /* TODO: MMI_OPC_0_PADDH */
26477 case MMI_OPC_0_PSUBH: /* TODO: MMI_OPC_0_PSUBH */
26478 case MMI_OPC_0_PCGTH: /* TODO: MMI_OPC_0_PCGTH */
26479 case MMI_OPC_0_PMAXH: /* TODO: MMI_OPC_0_PMAXH */
26480 case MMI_OPC_0_PADDB: /* TODO: MMI_OPC_0_PADDB */
26481 case MMI_OPC_0_PSUBB: /* TODO: MMI_OPC_0_PSUBB */
26482 case MMI_OPC_0_PCGTB: /* TODO: MMI_OPC_0_PCGTB */
26483 case MMI_OPC_0_PADDSW: /* TODO: MMI_OPC_0_PADDSW */
26484 case MMI_OPC_0_PSUBSW: /* TODO: MMI_OPC_0_PSUBSW */
26485 case MMI_OPC_0_PEXTLW: /* TODO: MMI_OPC_0_PEXTLW */
26486 case MMI_OPC_0_PPACW: /* TODO: MMI_OPC_0_PPACW */
26487 case MMI_OPC_0_PADDSH: /* TODO: MMI_OPC_0_PADDSH */
26488 case MMI_OPC_0_PSUBSH: /* TODO: MMI_OPC_0_PSUBSH */
26489 case MMI_OPC_0_PEXTLH: /* TODO: MMI_OPC_0_PEXTLH */
26490 case MMI_OPC_0_PPACH: /* TODO: MMI_OPC_0_PPACH */
26491 case MMI_OPC_0_PADDSB: /* TODO: MMI_OPC_0_PADDSB */
26492 case MMI_OPC_0_PSUBSB: /* TODO: MMI_OPC_0_PSUBSB */
26493 case MMI_OPC_0_PEXTLB: /* TODO: MMI_OPC_0_PEXTLB */
26494 case MMI_OPC_0_PPACB: /* TODO: MMI_OPC_0_PPACB */
26495 case MMI_OPC_0_PEXT5: /* TODO: MMI_OPC_0_PEXT5 */
26496 case MMI_OPC_0_PPAC5: /* TODO: MMI_OPC_0_PPAC5 */
26497 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
26500 MIPS_INVAL("TX79 MMI class MMI0");
26501 generate_exception_end(ctx, EXCP_RI);
26506 static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
26508 uint32_t opc = MASK_MMI1(ctx->opcode);
26511 case MMI_OPC_1_PABSW: /* TODO: MMI_OPC_1_PABSW */
26512 case MMI_OPC_1_PCEQW: /* TODO: MMI_OPC_1_PCEQW */
26513 case MMI_OPC_1_PMINW: /* TODO: MMI_OPC_1_PMINW */
26514 case MMI_OPC_1_PADSBH: /* TODO: MMI_OPC_1_PADSBH */
26515 case MMI_OPC_1_PABSH: /* TODO: MMI_OPC_1_PABSH */
26516 case MMI_OPC_1_PCEQH: /* TODO: MMI_OPC_1_PCEQH */
26517 case MMI_OPC_1_PMINH: /* TODO: MMI_OPC_1_PMINH */
26518 case MMI_OPC_1_PCEQB: /* TODO: MMI_OPC_1_PCEQB */
26519 case MMI_OPC_1_PADDUW: /* TODO: MMI_OPC_1_PADDUW */
26520 case MMI_OPC_1_PSUBUW: /* TODO: MMI_OPC_1_PSUBUW */
26521 case MMI_OPC_1_PEXTUW: /* TODO: MMI_OPC_1_PEXTUW */
26522 case MMI_OPC_1_PADDUH: /* TODO: MMI_OPC_1_PADDUH */
26523 case MMI_OPC_1_PSUBUH: /* TODO: MMI_OPC_1_PSUBUH */
26524 case MMI_OPC_1_PEXTUH: /* TODO: MMI_OPC_1_PEXTUH */
26525 case MMI_OPC_1_PADDUB: /* TODO: MMI_OPC_1_PADDUB */
26526 case MMI_OPC_1_PSUBUB: /* TODO: MMI_OPC_1_PSUBUB */
26527 case MMI_OPC_1_PEXTUB: /* TODO: MMI_OPC_1_PEXTUB */
26528 case MMI_OPC_1_QFSRV: /* TODO: MMI_OPC_1_QFSRV */
26529 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
26532 MIPS_INVAL("TX79 MMI class MMI1");
26533 generate_exception_end(ctx, EXCP_RI);
26538 static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
26540 uint32_t opc = MASK_MMI2(ctx->opcode);
26543 case MMI_OPC_2_PMADDW: /* TODO: MMI_OPC_2_PMADDW */
26544 case MMI_OPC_2_PSLLVW: /* TODO: MMI_OPC_2_PSLLVW */
26545 case MMI_OPC_2_PSRLVW: /* TODO: MMI_OPC_2_PSRLVW */
26546 case MMI_OPC_2_PMSUBW: /* TODO: MMI_OPC_2_PMSUBW */
26547 case MMI_OPC_2_PMFHI: /* TODO: MMI_OPC_2_PMFHI */
26548 case MMI_OPC_2_PMFLO: /* TODO: MMI_OPC_2_PMFLO */
26549 case MMI_OPC_2_PINTH: /* TODO: MMI_OPC_2_PINTH */
26550 case MMI_OPC_2_PMULTW: /* TODO: MMI_OPC_2_PMULTW */
26551 case MMI_OPC_2_PDIVW: /* TODO: MMI_OPC_2_PDIVW */
26552 case MMI_OPC_2_PCPYLD: /* TODO: MMI_OPC_2_PCPYLD */
26553 case MMI_OPC_2_PMADDH: /* TODO: MMI_OPC_2_PMADDH */
26554 case MMI_OPC_2_PHMADH: /* TODO: MMI_OPC_2_PHMADH */
26555 case MMI_OPC_2_PAND: /* TODO: MMI_OPC_2_PAND */
26556 case MMI_OPC_2_PXOR: /* TODO: MMI_OPC_2_PXOR */
26557 case MMI_OPC_2_PMSUBH: /* TODO: MMI_OPC_2_PMSUBH */
26558 case MMI_OPC_2_PHMSBH: /* TODO: MMI_OPC_2_PHMSBH */
26559 case MMI_OPC_2_PEXEH: /* TODO: MMI_OPC_2_PEXEH */
26560 case MMI_OPC_2_PREVH: /* TODO: MMI_OPC_2_PREVH */
26561 case MMI_OPC_2_PMULTH: /* TODO: MMI_OPC_2_PMULTH */
26562 case MMI_OPC_2_PDIVBW: /* TODO: MMI_OPC_2_PDIVBW */
26563 case MMI_OPC_2_PEXEW: /* TODO: MMI_OPC_2_PEXEW */
26564 case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */
26565 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
26568 MIPS_INVAL("TX79 MMI class MMI2");
26569 generate_exception_end(ctx, EXCP_RI);
26574 static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
26576 uint32_t opc = MASK_MMI3(ctx->opcode);
26579 case MMI_OPC_3_PMADDUW: /* TODO: MMI_OPC_3_PMADDUW */
26580 case MMI_OPC_3_PSRAVW: /* TODO: MMI_OPC_3_PSRAVW */
26581 case MMI_OPC_3_PMTHI: /* TODO: MMI_OPC_3_PMTHI */
26582 case MMI_OPC_3_PMTLO: /* TODO: MMI_OPC_3_PMTLO */
26583 case MMI_OPC_3_PINTEH: /* TODO: MMI_OPC_3_PINTEH */
26584 case MMI_OPC_3_PMULTUW: /* TODO: MMI_OPC_3_PMULTUW */
26585 case MMI_OPC_3_PDIVUW: /* TODO: MMI_OPC_3_PDIVUW */
26586 case MMI_OPC_3_PCPYUD: /* TODO: MMI_OPC_3_PCPYUD */
26587 case MMI_OPC_3_POR: /* TODO: MMI_OPC_3_POR */
26588 case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */
26589 case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */
26590 case MMI_OPC_3_PCPYH: /* TODO: MMI_OPC_3_PCPYH */
26591 case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */
26592 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
26595 MIPS_INVAL("TX79 MMI class MMI3");
26596 generate_exception_end(ctx, EXCP_RI);
26601 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
26603 uint32_t opc = MASK_MMI(ctx->opcode);
26604 int rs = extract32(ctx->opcode, 21, 5);
26605 int rt = extract32(ctx->opcode, 16, 5);
26606 int rd = extract32(ctx->opcode, 11, 5);
26609 case MMI_OPC_CLASS_MMI0:
26610 decode_mmi0(env, ctx);
26612 case MMI_OPC_CLASS_MMI1:
26613 decode_mmi1(env, ctx);
26615 case MMI_OPC_CLASS_MMI2:
26616 decode_mmi2(env, ctx);
26618 case MMI_OPC_CLASS_MMI3:
26619 decode_mmi3(env, ctx);
26621 case MMI_OPC_MULT1:
26622 case MMI_OPC_MULTU1:
26623 gen_mul_txx9(ctx, opc, rd, rs, rt);
26626 case MMI_OPC_DIVU1:
26627 gen_div1_tx79(ctx, opc, rs, rt);
26629 case MMI_OPC_MTLO1:
26630 case MMI_OPC_MTHI1:
26631 gen_HILO1_tx79(ctx, opc, rs);
26633 case MMI_OPC_MFLO1:
26634 case MMI_OPC_MFHI1:
26635 gen_HILO1_tx79(ctx, opc, rd);
26637 case MMI_OPC_MADD: /* TODO: MMI_OPC_MADD */
26638 case MMI_OPC_MADDU: /* TODO: MMI_OPC_MADDU */
26639 case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */
26640 case MMI_OPC_MADD1: /* TODO: MMI_OPC_MADD1 */
26641 case MMI_OPC_MADDU1: /* TODO: MMI_OPC_MADDU1 */
26642 case MMI_OPC_PMFHL: /* TODO: MMI_OPC_PMFHL */
26643 case MMI_OPC_PMTHL: /* TODO: MMI_OPC_PMTHL */
26644 case MMI_OPC_PSLLH: /* TODO: MMI_OPC_PSLLH */
26645 case MMI_OPC_PSRLH: /* TODO: MMI_OPC_PSRLH */
26646 case MMI_OPC_PSRAH: /* TODO: MMI_OPC_PSRAH */
26647 case MMI_OPC_PSLLW: /* TODO: MMI_OPC_PSLLW */
26648 case MMI_OPC_PSRLW: /* TODO: MMI_OPC_PSRLW */
26649 case MMI_OPC_PSRAW: /* TODO: MMI_OPC_PSRAW */
26650 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI */
26653 MIPS_INVAL("TX79 MMI class");
26654 generate_exception_end(ctx, EXCP_RI);
26659 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
26661 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_LQ */
26664 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
26666 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_SQ */
26670 * The TX79-specific instruction Store Quadword
26672 * +--------+-------+-------+------------------------+
26673 * | 011111 | base | rt | offset | SQ
26674 * +--------+-------+-------+------------------------+
26677 * has the same opcode as the Read Hardware Register instruction
26679 * +--------+-------+-------+-------+-------+--------+
26680 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
26681 * +--------+-------+-------+-------+-------+--------+
26684 * that is required, trapped and emulated by the Linux kernel. However, all
26685 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
26686 * offset is odd. Therefore all valid SQ instructions can execute normally.
26687 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
26688 * between SQ and RDHWR, as the Linux kernel does.
26690 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
26692 int base = extract32(ctx->opcode, 21, 5);
26693 int rt = extract32(ctx->opcode, 16, 5);
26694 int offset = extract32(ctx->opcode, 0, 16);
26696 #ifdef CONFIG_USER_ONLY
26697 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
26698 uint32_t op2 = extract32(ctx->opcode, 6, 5);
26700 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
26701 int rd = extract32(ctx->opcode, 11, 5);
26703 gen_rdhwr(ctx, rt, rd, 0);
26708 gen_mmi_sq(ctx, base, rt, offset);
26711 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
26713 int rs, rt, rd, sa;
26717 rs = (ctx->opcode >> 21) & 0x1f;
26718 rt = (ctx->opcode >> 16) & 0x1f;
26719 rd = (ctx->opcode >> 11) & 0x1f;
26720 sa = (ctx->opcode >> 6) & 0x1f;
26721 imm = sextract32(ctx->opcode, 7, 9);
26723 op1 = MASK_SPECIAL3(ctx->opcode);
26726 * EVA loads and stores overlap Loongson 2E instructions decoded by
26727 * decode_opc_special3_legacy(), so be careful to allow their decoding when
26734 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26742 check_cp0_enabled(ctx);
26743 gen_ld(ctx, op1, rt, rs, imm);
26747 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26752 check_cp0_enabled(ctx);
26753 gen_st(ctx, op1, rt, rs, imm);
26756 check_cp0_enabled(ctx);
26757 gen_st_cond(ctx, op1, rt, rs, imm);
26760 check_cp0_enabled(ctx);
26761 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26762 gen_cache_operation(ctx, rt, rs, imm);
26764 /* Treat as NOP. */
26767 check_cp0_enabled(ctx);
26768 /* Treat as NOP. */
26776 check_insn(ctx, ISA_MIPS32R2);
26777 gen_bitops(ctx, op1, rt, rs, sa, rd);
26780 op2 = MASK_BSHFL(ctx->opcode);
26787 check_insn(ctx, ISA_MIPS32R6);
26788 decode_opc_special3_r6(env, ctx);
26791 check_insn(ctx, ISA_MIPS32R2);
26792 gen_bshfl(ctx, op2, rt, rd);
26796 #if defined(TARGET_MIPS64)
26803 check_insn(ctx, ISA_MIPS64R2);
26804 check_mips_64(ctx);
26805 gen_bitops(ctx, op1, rt, rs, sa, rd);
26808 op2 = MASK_DBSHFL(ctx->opcode);
26819 check_insn(ctx, ISA_MIPS32R6);
26820 decode_opc_special3_r6(env, ctx);
26823 check_insn(ctx, ISA_MIPS64R2);
26824 check_mips_64(ctx);
26825 op2 = MASK_DBSHFL(ctx->opcode);
26826 gen_bshfl(ctx, op2, rt, rd);
26832 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
26837 TCGv t0 = tcg_temp_new();
26838 TCGv t1 = tcg_temp_new();
26840 gen_load_gpr(t0, rt);
26841 gen_load_gpr(t1, rs);
26842 gen_helper_fork(t0, t1);
26850 TCGv t0 = tcg_temp_new();
26852 gen_load_gpr(t0, rs);
26853 gen_helper_yield(t0, cpu_env, t0);
26854 gen_store_gpr(t0, rd);
26859 if (ctx->insn_flags & ISA_MIPS32R6) {
26860 decode_opc_special3_r6(env, ctx);
26862 decode_opc_special3_legacy(env, ctx);
26867 /* MIPS SIMD Architecture (MSA) */
26868 static inline int check_msa_access(DisasContext *ctx)
26870 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
26871 !(ctx->hflags & MIPS_HFLAG_F64))) {
26872 generate_exception_end(ctx, EXCP_RI);
26876 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
26877 if (ctx->insn_flags & ASE_MSA) {
26878 generate_exception_end(ctx, EXCP_MSADIS);
26881 generate_exception_end(ctx, EXCP_RI);
26888 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
26890 /* generates tcg ops to check if any element is 0 */
26891 /* Note this function only works with MSA_WRLEN = 128 */
26892 uint64_t eval_zero_or_big = 0;
26893 uint64_t eval_big = 0;
26894 TCGv_i64 t0 = tcg_temp_new_i64();
26895 TCGv_i64 t1 = tcg_temp_new_i64();
26898 eval_zero_or_big = 0x0101010101010101ULL;
26899 eval_big = 0x8080808080808080ULL;
26902 eval_zero_or_big = 0x0001000100010001ULL;
26903 eval_big = 0x8000800080008000ULL;
26906 eval_zero_or_big = 0x0000000100000001ULL;
26907 eval_big = 0x8000000080000000ULL;
26910 eval_zero_or_big = 0x0000000000000001ULL;
26911 eval_big = 0x8000000000000000ULL;
26914 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
26915 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
26916 tcg_gen_andi_i64(t0, t0, eval_big);
26917 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
26918 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
26919 tcg_gen_andi_i64(t1, t1, eval_big);
26920 tcg_gen_or_i64(t0, t0, t1);
26921 /* if all bits are zero then all elements are not zero */
26922 /* if some bit is non-zero then some element is zero */
26923 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
26924 tcg_gen_trunc_i64_tl(tresult, t0);
26925 tcg_temp_free_i64(t0);
26926 tcg_temp_free_i64(t1);
26929 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
26931 uint8_t df = (ctx->opcode >> 21) & 0x3;
26932 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26933 int64_t s16 = (int16_t)ctx->opcode;
26935 check_msa_access(ctx);
26937 if (ctx->hflags & MIPS_HFLAG_BMASK) {
26938 generate_exception_end(ctx, EXCP_RI);
26945 TCGv_i64 t0 = tcg_temp_new_i64();
26946 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
26947 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
26948 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
26949 tcg_gen_trunc_i64_tl(bcond, t0);
26950 tcg_temp_free_i64(t0);
26957 gen_check_zero_element(bcond, df, wt);
26963 gen_check_zero_element(bcond, df, wt);
26964 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
26968 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
26970 ctx->hflags |= MIPS_HFLAG_BC;
26971 ctx->hflags |= MIPS_HFLAG_BDS32;
26974 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
26976 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
26977 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
26978 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26979 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26981 TCGv_i32 twd = tcg_const_i32(wd);
26982 TCGv_i32 tws = tcg_const_i32(ws);
26983 TCGv_i32 ti8 = tcg_const_i32(i8);
26985 switch (MASK_MSA_I8(ctx->opcode)) {
26987 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
26990 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
26993 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
26996 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
26999 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27002 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27005 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27011 uint8_t df = (ctx->opcode >> 24) & 0x3;
27012 if (df == DF_DOUBLE) {
27013 generate_exception_end(ctx, EXCP_RI);
27015 TCGv_i32 tdf = tcg_const_i32(df);
27016 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27017 tcg_temp_free_i32(tdf);
27022 MIPS_INVAL("MSA instruction");
27023 generate_exception_end(ctx, EXCP_RI);
27027 tcg_temp_free_i32(twd);
27028 tcg_temp_free_i32(tws);
27029 tcg_temp_free_i32(ti8);
27032 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
27034 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27035 uint8_t df = (ctx->opcode >> 21) & 0x3;
27036 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
27037 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
27038 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27039 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27041 TCGv_i32 tdf = tcg_const_i32(df);
27042 TCGv_i32 twd = tcg_const_i32(wd);
27043 TCGv_i32 tws = tcg_const_i32(ws);
27044 TCGv_i32 timm = tcg_temp_new_i32();
27045 tcg_gen_movi_i32(timm, u5);
27047 switch (MASK_MSA_I5(ctx->opcode)) {
27049 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
27052 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
27054 case OPC_MAXI_S_df:
27055 tcg_gen_movi_i32(timm, s5);
27056 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
27058 case OPC_MAXI_U_df:
27059 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
27061 case OPC_MINI_S_df:
27062 tcg_gen_movi_i32(timm, s5);
27063 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
27065 case OPC_MINI_U_df:
27066 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
27069 tcg_gen_movi_i32(timm, s5);
27070 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
27072 case OPC_CLTI_S_df:
27073 tcg_gen_movi_i32(timm, s5);
27074 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
27076 case OPC_CLTI_U_df:
27077 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
27079 case OPC_CLEI_S_df:
27080 tcg_gen_movi_i32(timm, s5);
27081 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
27083 case OPC_CLEI_U_df:
27084 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
27088 int32_t s10 = sextract32(ctx->opcode, 11, 10);
27089 tcg_gen_movi_i32(timm, s10);
27090 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
27094 MIPS_INVAL("MSA instruction");
27095 generate_exception_end(ctx, EXCP_RI);
27099 tcg_temp_free_i32(tdf);
27100 tcg_temp_free_i32(twd);
27101 tcg_temp_free_i32(tws);
27102 tcg_temp_free_i32(timm);
27105 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
27107 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27108 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
27109 uint32_t df = 0, m = 0;
27110 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27111 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27118 if ((dfm & 0x40) == 0x00) {
27121 } else if ((dfm & 0x60) == 0x40) {
27124 } else if ((dfm & 0x70) == 0x60) {
27127 } else if ((dfm & 0x78) == 0x70) {
27131 generate_exception_end(ctx, EXCP_RI);
27135 tdf = tcg_const_i32(df);
27136 tm = tcg_const_i32(m);
27137 twd = tcg_const_i32(wd);
27138 tws = tcg_const_i32(ws);
27140 switch (MASK_MSA_BIT(ctx->opcode)) {
27142 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
27145 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
27148 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
27151 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
27154 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
27157 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
27159 case OPC_BINSLI_df:
27160 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
27162 case OPC_BINSRI_df:
27163 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
27166 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
27169 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
27172 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
27175 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
27178 MIPS_INVAL("MSA instruction");
27179 generate_exception_end(ctx, EXCP_RI);
27183 tcg_temp_free_i32(tdf);
27184 tcg_temp_free_i32(tm);
27185 tcg_temp_free_i32(twd);
27186 tcg_temp_free_i32(tws);
27189 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
27191 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27192 uint8_t df = (ctx->opcode >> 21) & 0x3;
27193 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27194 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27195 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27197 TCGv_i32 tdf = tcg_const_i32(df);
27198 TCGv_i32 twd = tcg_const_i32(wd);
27199 TCGv_i32 tws = tcg_const_i32(ws);
27200 TCGv_i32 twt = tcg_const_i32(wt);
27202 switch (MASK_MSA_3R(ctx->opcode)) {
27204 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
27207 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
27210 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
27213 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
27215 case OPC_SUBS_S_df:
27216 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
27219 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
27222 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
27225 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
27228 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
27231 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
27233 case OPC_ADDS_A_df:
27234 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
27236 case OPC_SUBS_U_df:
27237 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
27240 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
27243 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
27246 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
27249 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
27252 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
27255 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
27257 case OPC_ADDS_S_df:
27258 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
27260 case OPC_SUBSUS_U_df:
27261 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
27264 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
27267 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
27270 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
27273 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
27276 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
27279 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
27281 case OPC_ADDS_U_df:
27282 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
27284 case OPC_SUBSUU_S_df:
27285 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
27288 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
27291 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
27294 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
27297 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
27300 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
27302 case OPC_ASUB_S_df:
27303 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
27306 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
27309 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
27312 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
27315 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
27318 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
27321 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
27323 case OPC_ASUB_U_df:
27324 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
27327 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
27330 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
27333 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
27336 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
27338 case OPC_AVER_S_df:
27339 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
27342 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
27345 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
27348 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
27351 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
27353 case OPC_AVER_U_df:
27354 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
27357 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
27360 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
27363 case OPC_DOTP_S_df:
27364 case OPC_DOTP_U_df:
27365 case OPC_DPADD_S_df:
27366 case OPC_DPADD_U_df:
27367 case OPC_DPSUB_S_df:
27368 case OPC_HADD_S_df:
27369 case OPC_DPSUB_U_df:
27370 case OPC_HADD_U_df:
27371 case OPC_HSUB_S_df:
27372 case OPC_HSUB_U_df:
27373 if (df == DF_BYTE) {
27374 generate_exception_end(ctx, EXCP_RI);
27377 switch (MASK_MSA_3R(ctx->opcode)) {
27378 case OPC_DOTP_S_df:
27379 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
27381 case OPC_DOTP_U_df:
27382 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
27384 case OPC_DPADD_S_df:
27385 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
27387 case OPC_DPADD_U_df:
27388 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
27390 case OPC_DPSUB_S_df:
27391 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
27393 case OPC_HADD_S_df:
27394 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
27396 case OPC_DPSUB_U_df:
27397 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
27399 case OPC_HADD_U_df:
27400 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
27402 case OPC_HSUB_S_df:
27403 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
27405 case OPC_HSUB_U_df:
27406 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
27411 MIPS_INVAL("MSA instruction");
27412 generate_exception_end(ctx, EXCP_RI);
27415 tcg_temp_free_i32(twd);
27416 tcg_temp_free_i32(tws);
27417 tcg_temp_free_i32(twt);
27418 tcg_temp_free_i32(tdf);
27421 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
27423 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
27424 uint8_t source = (ctx->opcode >> 11) & 0x1f;
27425 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
27426 TCGv telm = tcg_temp_new();
27427 TCGv_i32 tsr = tcg_const_i32(source);
27428 TCGv_i32 tdt = tcg_const_i32(dest);
27430 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
27432 gen_load_gpr(telm, source);
27433 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
27436 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
27437 gen_store_gpr(telm, dest);
27440 gen_helper_msa_move_v(cpu_env, tdt, tsr);
27443 MIPS_INVAL("MSA instruction");
27444 generate_exception_end(ctx, EXCP_RI);
27448 tcg_temp_free(telm);
27449 tcg_temp_free_i32(tdt);
27450 tcg_temp_free_i32(tsr);
27453 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
27456 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
27457 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27458 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27460 TCGv_i32 tws = tcg_const_i32(ws);
27461 TCGv_i32 twd = tcg_const_i32(wd);
27462 TCGv_i32 tn = tcg_const_i32(n);
27463 TCGv_i32 tdf = tcg_const_i32(df);
27465 switch (MASK_MSA_ELM(ctx->opcode)) {
27467 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
27469 case OPC_SPLATI_df:
27470 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
27473 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
27475 case OPC_COPY_S_df:
27476 case OPC_COPY_U_df:
27477 case OPC_INSERT_df:
27478 #if !defined(TARGET_MIPS64)
27479 /* Double format valid only for MIPS64 */
27480 if (df == DF_DOUBLE) {
27481 generate_exception_end(ctx, EXCP_RI);
27485 switch (MASK_MSA_ELM(ctx->opcode)) {
27486 case OPC_COPY_S_df:
27487 if (likely(wd != 0)) {
27488 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
27491 case OPC_COPY_U_df:
27492 if (likely(wd != 0)) {
27493 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
27496 case OPC_INSERT_df:
27497 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
27502 MIPS_INVAL("MSA instruction");
27503 generate_exception_end(ctx, EXCP_RI);
27505 tcg_temp_free_i32(twd);
27506 tcg_temp_free_i32(tws);
27507 tcg_temp_free_i32(tn);
27508 tcg_temp_free_i32(tdf);
27511 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
27513 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
27514 uint32_t df = 0, n = 0;
27516 if ((dfn & 0x30) == 0x00) {
27519 } else if ((dfn & 0x38) == 0x20) {
27522 } else if ((dfn & 0x3c) == 0x30) {
27525 } else if ((dfn & 0x3e) == 0x38) {
27528 } else if (dfn == 0x3E) {
27529 /* CTCMSA, CFCMSA, MOVE.V */
27530 gen_msa_elm_3e(env, ctx);
27533 generate_exception_end(ctx, EXCP_RI);
27537 gen_msa_elm_df(env, ctx, df, n);
27540 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
27542 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
27543 uint8_t df = (ctx->opcode >> 21) & 0x1;
27544 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27545 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27546 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27548 TCGv_i32 twd = tcg_const_i32(wd);
27549 TCGv_i32 tws = tcg_const_i32(ws);
27550 TCGv_i32 twt = tcg_const_i32(wt);
27551 TCGv_i32 tdf = tcg_temp_new_i32();
27553 /* adjust df value for floating-point instruction */
27554 tcg_gen_movi_i32(tdf, df + 2);
27556 switch (MASK_MSA_3RF(ctx->opcode)) {
27558 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
27561 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
27564 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
27567 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
27570 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
27573 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
27576 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
27579 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
27582 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
27585 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
27588 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
27591 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
27594 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
27597 tcg_gen_movi_i32(tdf, df + 1);
27598 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
27601 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
27604 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
27606 case OPC_MADD_Q_df:
27607 tcg_gen_movi_i32(tdf, df + 1);
27608 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
27611 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
27613 case OPC_MSUB_Q_df:
27614 tcg_gen_movi_i32(tdf, df + 1);
27615 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
27618 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
27621 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
27624 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
27627 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
27630 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
27633 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
27636 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
27639 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
27642 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
27645 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
27648 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
27651 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
27654 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
27656 case OPC_MULR_Q_df:
27657 tcg_gen_movi_i32(tdf, df + 1);
27658 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
27661 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
27663 case OPC_FMIN_A_df:
27664 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
27666 case OPC_MADDR_Q_df:
27667 tcg_gen_movi_i32(tdf, df + 1);
27668 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
27671 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
27674 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
27676 case OPC_MSUBR_Q_df:
27677 tcg_gen_movi_i32(tdf, df + 1);
27678 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
27681 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
27683 case OPC_FMAX_A_df:
27684 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
27687 MIPS_INVAL("MSA instruction");
27688 generate_exception_end(ctx, EXCP_RI);
27692 tcg_temp_free_i32(twd);
27693 tcg_temp_free_i32(tws);
27694 tcg_temp_free_i32(twt);
27695 tcg_temp_free_i32(tdf);
27698 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
27700 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27701 (op & (0x7 << 18)))
27702 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27703 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27704 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27705 uint8_t df = (ctx->opcode >> 16) & 0x3;
27706 TCGv_i32 twd = tcg_const_i32(wd);
27707 TCGv_i32 tws = tcg_const_i32(ws);
27708 TCGv_i32 twt = tcg_const_i32(wt);
27709 TCGv_i32 tdf = tcg_const_i32(df);
27711 switch (MASK_MSA_2R(ctx->opcode)) {
27713 #if !defined(TARGET_MIPS64)
27714 /* Double format valid only for MIPS64 */
27715 if (df == DF_DOUBLE) {
27716 generate_exception_end(ctx, EXCP_RI);
27720 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
27723 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
27726 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
27729 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
27732 MIPS_INVAL("MSA instruction");
27733 generate_exception_end(ctx, EXCP_RI);
27737 tcg_temp_free_i32(twd);
27738 tcg_temp_free_i32(tws);
27739 tcg_temp_free_i32(twt);
27740 tcg_temp_free_i32(tdf);
27743 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
27745 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27746 (op & (0xf << 17)))
27747 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27748 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27749 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27750 uint8_t df = (ctx->opcode >> 16) & 0x1;
27751 TCGv_i32 twd = tcg_const_i32(wd);
27752 TCGv_i32 tws = tcg_const_i32(ws);
27753 TCGv_i32 twt = tcg_const_i32(wt);
27754 /* adjust df value for floating-point instruction */
27755 TCGv_i32 tdf = tcg_const_i32(df + 2);
27757 switch (MASK_MSA_2RF(ctx->opcode)) {
27758 case OPC_FCLASS_df:
27759 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
27761 case OPC_FTRUNC_S_df:
27762 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
27764 case OPC_FTRUNC_U_df:
27765 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
27768 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
27770 case OPC_FRSQRT_df:
27771 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
27774 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
27777 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
27780 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
27782 case OPC_FEXUPL_df:
27783 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
27785 case OPC_FEXUPR_df:
27786 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
27789 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
27792 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
27794 case OPC_FTINT_S_df:
27795 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
27797 case OPC_FTINT_U_df:
27798 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
27800 case OPC_FFINT_S_df:
27801 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
27803 case OPC_FFINT_U_df:
27804 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
27808 tcg_temp_free_i32(twd);
27809 tcg_temp_free_i32(tws);
27810 tcg_temp_free_i32(twt);
27811 tcg_temp_free_i32(tdf);
27814 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
27816 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
27817 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27818 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27819 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27820 TCGv_i32 twd = tcg_const_i32(wd);
27821 TCGv_i32 tws = tcg_const_i32(ws);
27822 TCGv_i32 twt = tcg_const_i32(wt);
27824 switch (MASK_MSA_VEC(ctx->opcode)) {
27826 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
27829 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
27832 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
27835 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
27838 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
27841 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
27844 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
27847 MIPS_INVAL("MSA instruction");
27848 generate_exception_end(ctx, EXCP_RI);
27852 tcg_temp_free_i32(twd);
27853 tcg_temp_free_i32(tws);
27854 tcg_temp_free_i32(twt);
27857 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
27859 switch (MASK_MSA_VEC(ctx->opcode)) {
27867 gen_msa_vec_v(env, ctx);
27870 gen_msa_2r(env, ctx);
27873 gen_msa_2rf(env, ctx);
27876 MIPS_INVAL("MSA instruction");
27877 generate_exception_end(ctx, EXCP_RI);
27882 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
27884 uint32_t opcode = ctx->opcode;
27885 check_insn(ctx, ASE_MSA);
27886 check_msa_access(ctx);
27888 switch (MASK_MSA_MINOR(opcode)) {
27889 case OPC_MSA_I8_00:
27890 case OPC_MSA_I8_01:
27891 case OPC_MSA_I8_02:
27892 gen_msa_i8(env, ctx);
27894 case OPC_MSA_I5_06:
27895 case OPC_MSA_I5_07:
27896 gen_msa_i5(env, ctx);
27898 case OPC_MSA_BIT_09:
27899 case OPC_MSA_BIT_0A:
27900 gen_msa_bit(env, ctx);
27902 case OPC_MSA_3R_0D:
27903 case OPC_MSA_3R_0E:
27904 case OPC_MSA_3R_0F:
27905 case OPC_MSA_3R_10:
27906 case OPC_MSA_3R_11:
27907 case OPC_MSA_3R_12:
27908 case OPC_MSA_3R_13:
27909 case OPC_MSA_3R_14:
27910 case OPC_MSA_3R_15:
27911 gen_msa_3r(env, ctx);
27914 gen_msa_elm(env, ctx);
27916 case OPC_MSA_3RF_1A:
27917 case OPC_MSA_3RF_1B:
27918 case OPC_MSA_3RF_1C:
27919 gen_msa_3rf(env, ctx);
27922 gen_msa_vec(env, ctx);
27933 int32_t s10 = sextract32(ctx->opcode, 16, 10);
27934 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
27935 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27936 uint8_t df = (ctx->opcode >> 0) & 0x3;
27938 TCGv_i32 twd = tcg_const_i32(wd);
27939 TCGv taddr = tcg_temp_new();
27940 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
27942 switch (MASK_MSA_MINOR(opcode)) {
27944 gen_helper_msa_ld_b(cpu_env, twd, taddr);
27947 gen_helper_msa_ld_h(cpu_env, twd, taddr);
27950 gen_helper_msa_ld_w(cpu_env, twd, taddr);
27953 gen_helper_msa_ld_d(cpu_env, twd, taddr);
27956 gen_helper_msa_st_b(cpu_env, twd, taddr);
27959 gen_helper_msa_st_h(cpu_env, twd, taddr);
27962 gen_helper_msa_st_w(cpu_env, twd, taddr);
27965 gen_helper_msa_st_d(cpu_env, twd, taddr);
27969 tcg_temp_free_i32(twd);
27970 tcg_temp_free(taddr);
27974 MIPS_INVAL("MSA instruction");
27975 generate_exception_end(ctx, EXCP_RI);
27981 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
27984 int rs, rt, rd, sa;
27988 /* make sure instructions are on a word boundary */
27989 if (ctx->base.pc_next & 0x3) {
27990 env->CP0_BadVAddr = ctx->base.pc_next;
27991 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
27995 /* Handle blikely not taken case */
27996 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
27997 TCGLabel *l1 = gen_new_label();
27999 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
28000 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
28001 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
28005 op = MASK_OP_MAJOR(ctx->opcode);
28006 rs = (ctx->opcode >> 21) & 0x1f;
28007 rt = (ctx->opcode >> 16) & 0x1f;
28008 rd = (ctx->opcode >> 11) & 0x1f;
28009 sa = (ctx->opcode >> 6) & 0x1f;
28010 imm = (int16_t)ctx->opcode;
28013 decode_opc_special(env, ctx);
28016 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
28017 decode_mmi(env, ctx);
28018 } else if (ctx->insn_flags & ASE_MXU) {
28019 decode_opc_mxu(env, ctx);
28021 decode_opc_special2_legacy(env, ctx);
28025 if (ctx->insn_flags & INSN_R5900) {
28026 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
28028 decode_opc_special3(env, ctx);
28032 op1 = MASK_REGIMM(ctx->opcode);
28034 case OPC_BLTZL: /* REGIMM branches */
28038 check_insn(ctx, ISA_MIPS2);
28039 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28043 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28047 if (ctx->insn_flags & ISA_MIPS32R6) {
28049 /* OPC_NAL, OPC_BAL */
28050 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
28052 generate_exception_end(ctx, EXCP_RI);
28055 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28058 case OPC_TGEI: /* REGIMM traps */
28065 check_insn(ctx, ISA_MIPS2);
28066 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28067 gen_trap(ctx, op1, rs, -1, imm);
28070 check_insn(ctx, ISA_MIPS32R6);
28071 generate_exception_end(ctx, EXCP_RI);
28074 check_insn(ctx, ISA_MIPS32R2);
28075 /* Break the TB to be able to sync copied instructions
28077 ctx->base.is_jmp = DISAS_STOP;
28079 case OPC_BPOSGE32: /* MIPS DSP branch */
28080 #if defined(TARGET_MIPS64)
28084 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
28086 #if defined(TARGET_MIPS64)
28088 check_insn(ctx, ISA_MIPS32R6);
28089 check_mips_64(ctx);
28091 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28095 check_insn(ctx, ISA_MIPS32R6);
28096 check_mips_64(ctx);
28098 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28102 default: /* Invalid */
28103 MIPS_INVAL("regimm");
28104 generate_exception_end(ctx, EXCP_RI);
28109 check_cp0_enabled(ctx);
28110 op1 = MASK_CP0(ctx->opcode);
28118 #if defined(TARGET_MIPS64)
28122 #ifndef CONFIG_USER_ONLY
28123 gen_cp0(env, ctx, op1, rt, rd);
28124 #endif /* !CONFIG_USER_ONLY */
28142 #ifndef CONFIG_USER_ONLY
28143 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
28144 #endif /* !CONFIG_USER_ONLY */
28147 #ifndef CONFIG_USER_ONLY
28150 TCGv t0 = tcg_temp_new();
28152 op2 = MASK_MFMC0(ctx->opcode);
28156 gen_helper_dmt(t0);
28157 gen_store_gpr(t0, rt);
28161 gen_helper_emt(t0);
28162 gen_store_gpr(t0, rt);
28166 gen_helper_dvpe(t0, cpu_env);
28167 gen_store_gpr(t0, rt);
28171 gen_helper_evpe(t0, cpu_env);
28172 gen_store_gpr(t0, rt);
28175 check_insn(ctx, ISA_MIPS32R6);
28177 gen_helper_dvp(t0, cpu_env);
28178 gen_store_gpr(t0, rt);
28182 check_insn(ctx, ISA_MIPS32R6);
28184 gen_helper_evp(t0, cpu_env);
28185 gen_store_gpr(t0, rt);
28189 check_insn(ctx, ISA_MIPS32R2);
28190 save_cpu_state(ctx, 1);
28191 gen_helper_di(t0, cpu_env);
28192 gen_store_gpr(t0, rt);
28193 /* Stop translation as we may have switched
28194 the execution mode. */
28195 ctx->base.is_jmp = DISAS_STOP;
28198 check_insn(ctx, ISA_MIPS32R2);
28199 save_cpu_state(ctx, 1);
28200 gen_helper_ei(t0, cpu_env);
28201 gen_store_gpr(t0, rt);
28202 /* DISAS_STOP isn't sufficient, we need to ensure we break
28203 out of translated code to check for pending interrupts */
28204 gen_save_pc(ctx->base.pc_next + 4);
28205 ctx->base.is_jmp = DISAS_EXIT;
28207 default: /* Invalid */
28208 MIPS_INVAL("mfmc0");
28209 generate_exception_end(ctx, EXCP_RI);
28214 #endif /* !CONFIG_USER_ONLY */
28217 check_insn(ctx, ISA_MIPS32R2);
28218 gen_load_srsgpr(rt, rd);
28221 check_insn(ctx, ISA_MIPS32R2);
28222 gen_store_srsgpr(rt, rd);
28226 generate_exception_end(ctx, EXCP_RI);
28230 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
28231 if (ctx->insn_flags & ISA_MIPS32R6) {
28232 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
28233 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28236 /* Arithmetic with immediate opcode */
28237 gen_arith_imm(ctx, op, rt, rs, imm);
28241 gen_arith_imm(ctx, op, rt, rs, imm);
28243 case OPC_SLTI: /* Set on less than with immediate opcode */
28245 gen_slt_imm(ctx, op, rt, rs, imm);
28247 case OPC_ANDI: /* Arithmetic with immediate opcode */
28248 case OPC_LUI: /* OPC_AUI */
28251 gen_logic_imm(ctx, op, rt, rs, imm);
28253 case OPC_J: /* Jump */
28255 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
28256 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
28259 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
28260 if (ctx->insn_flags & ISA_MIPS32R6) {
28262 generate_exception_end(ctx, EXCP_RI);
28265 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
28266 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28269 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
28272 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
28273 if (ctx->insn_flags & ISA_MIPS32R6) {
28275 generate_exception_end(ctx, EXCP_RI);
28278 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
28279 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28282 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
28285 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
28288 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
28290 check_insn(ctx, ISA_MIPS32R6);
28291 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
28292 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28295 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
28298 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
28300 check_insn(ctx, ISA_MIPS32R6);
28301 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
28302 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28307 check_insn(ctx, ISA_MIPS2);
28308 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28312 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
28314 case OPC_LL: /* Load and stores */
28315 check_insn(ctx, ISA_MIPS2);
28316 if (ctx->insn_flags & INSN_R5900) {
28317 check_insn_opc_user_only(ctx, INSN_R5900);
28322 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28330 gen_ld(ctx, op, rt, rs, imm);
28334 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28339 gen_st(ctx, op, rt, rs, imm);
28342 check_insn(ctx, ISA_MIPS2);
28343 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28344 if (ctx->insn_flags & INSN_R5900) {
28345 check_insn_opc_user_only(ctx, INSN_R5900);
28347 gen_st_cond(ctx, op, rt, rs, imm);
28350 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28351 check_cp0_enabled(ctx);
28352 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
28353 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
28354 gen_cache_operation(ctx, rt, rs, imm);
28356 /* Treat as NOP. */
28359 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28360 if (ctx->insn_flags & INSN_R5900) {
28361 /* Treat as NOP. */
28363 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
28364 /* Treat as NOP. */
28368 /* Floating point (COP1). */
28373 gen_cop1_ldst(ctx, op, rt, rs, imm);
28377 op1 = MASK_CP1(ctx->opcode);
28382 check_cp1_enabled(ctx);
28383 check_insn(ctx, ISA_MIPS32R2);
28389 check_cp1_enabled(ctx);
28390 gen_cp1(ctx, op1, rt, rd);
28392 #if defined(TARGET_MIPS64)
28395 check_cp1_enabled(ctx);
28396 check_insn(ctx, ISA_MIPS3);
28397 check_mips_64(ctx);
28398 gen_cp1(ctx, op1, rt, rd);
28401 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
28402 check_cp1_enabled(ctx);
28403 if (ctx->insn_flags & ISA_MIPS32R6) {
28405 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
28410 check_insn(ctx, ASE_MIPS3D);
28411 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
28412 (rt >> 2) & 0x7, imm << 2);
28416 check_cp1_enabled(ctx);
28417 check_insn(ctx, ISA_MIPS32R6);
28418 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
28422 check_cp1_enabled(ctx);
28423 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28425 check_insn(ctx, ASE_MIPS3D);
28428 check_cp1_enabled(ctx);
28429 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28430 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
28431 (rt >> 2) & 0x7, imm << 2);
28438 check_cp1_enabled(ctx);
28439 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
28445 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
28446 check_cp1_enabled(ctx);
28447 if (ctx->insn_flags & ISA_MIPS32R6) {
28449 case R6_OPC_CMP_AF_S:
28450 case R6_OPC_CMP_UN_S:
28451 case R6_OPC_CMP_EQ_S:
28452 case R6_OPC_CMP_UEQ_S:
28453 case R6_OPC_CMP_LT_S:
28454 case R6_OPC_CMP_ULT_S:
28455 case R6_OPC_CMP_LE_S:
28456 case R6_OPC_CMP_ULE_S:
28457 case R6_OPC_CMP_SAF_S:
28458 case R6_OPC_CMP_SUN_S:
28459 case R6_OPC_CMP_SEQ_S:
28460 case R6_OPC_CMP_SEUQ_S:
28461 case R6_OPC_CMP_SLT_S:
28462 case R6_OPC_CMP_SULT_S:
28463 case R6_OPC_CMP_SLE_S:
28464 case R6_OPC_CMP_SULE_S:
28465 case R6_OPC_CMP_OR_S:
28466 case R6_OPC_CMP_UNE_S:
28467 case R6_OPC_CMP_NE_S:
28468 case R6_OPC_CMP_SOR_S:
28469 case R6_OPC_CMP_SUNE_S:
28470 case R6_OPC_CMP_SNE_S:
28471 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
28473 case R6_OPC_CMP_AF_D:
28474 case R6_OPC_CMP_UN_D:
28475 case R6_OPC_CMP_EQ_D:
28476 case R6_OPC_CMP_UEQ_D:
28477 case R6_OPC_CMP_LT_D:
28478 case R6_OPC_CMP_ULT_D:
28479 case R6_OPC_CMP_LE_D:
28480 case R6_OPC_CMP_ULE_D:
28481 case R6_OPC_CMP_SAF_D:
28482 case R6_OPC_CMP_SUN_D:
28483 case R6_OPC_CMP_SEQ_D:
28484 case R6_OPC_CMP_SEUQ_D:
28485 case R6_OPC_CMP_SLT_D:
28486 case R6_OPC_CMP_SULT_D:
28487 case R6_OPC_CMP_SLE_D:
28488 case R6_OPC_CMP_SULE_D:
28489 case R6_OPC_CMP_OR_D:
28490 case R6_OPC_CMP_UNE_D:
28491 case R6_OPC_CMP_NE_D:
28492 case R6_OPC_CMP_SOR_D:
28493 case R6_OPC_CMP_SUNE_D:
28494 case R6_OPC_CMP_SNE_D:
28495 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
28498 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
28499 rt, rd, sa, (imm >> 8) & 0x7);
28504 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
28519 check_insn(ctx, ASE_MSA);
28520 gen_msa_branch(env, ctx, op1);
28524 generate_exception_end(ctx, EXCP_RI);
28529 /* Compact branches [R6] and COP2 [non-R6] */
28530 case OPC_BC: /* OPC_LWC2 */
28531 case OPC_BALC: /* OPC_SWC2 */
28532 if (ctx->insn_flags & ISA_MIPS32R6) {
28533 /* OPC_BC, OPC_BALC */
28534 gen_compute_compact_branch(ctx, op, 0, 0,
28535 sextract32(ctx->opcode << 2, 0, 28));
28537 /* OPC_LWC2, OPC_SWC2 */
28538 /* COP2: Not implemented. */
28539 generate_exception_err(ctx, EXCP_CpU, 2);
28542 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
28543 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
28544 if (ctx->insn_flags & ISA_MIPS32R6) {
28546 /* OPC_BEQZC, OPC_BNEZC */
28547 gen_compute_compact_branch(ctx, op, rs, 0,
28548 sextract32(ctx->opcode << 2, 0, 23));
28550 /* OPC_JIC, OPC_JIALC */
28551 gen_compute_compact_branch(ctx, op, 0, rt, imm);
28554 /* OPC_LWC2, OPC_SWC2 */
28555 /* COP2: Not implemented. */
28556 generate_exception_err(ctx, EXCP_CpU, 2);
28560 check_insn(ctx, INSN_LOONGSON2F);
28561 /* Note that these instructions use different fields. */
28562 gen_loongson_multimedia(ctx, sa, rd, rt);
28566 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28567 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
28568 check_cp1_enabled(ctx);
28569 op1 = MASK_CP3(ctx->opcode);
28573 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
28579 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28580 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
28583 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28584 /* Treat as NOP. */
28587 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
28601 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
28602 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
28606 generate_exception_end(ctx, EXCP_RI);
28610 generate_exception_err(ctx, EXCP_CpU, 1);
28614 #if defined(TARGET_MIPS64)
28615 /* MIPS64 opcodes */
28617 if (ctx->insn_flags & INSN_R5900) {
28618 check_insn_opc_user_only(ctx, INSN_R5900);
28623 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28627 check_insn(ctx, ISA_MIPS3);
28628 check_mips_64(ctx);
28629 gen_ld(ctx, op, rt, rs, imm);
28633 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28636 check_insn(ctx, ISA_MIPS3);
28637 check_mips_64(ctx);
28638 gen_st(ctx, op, rt, rs, imm);
28641 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28642 check_insn(ctx, ISA_MIPS3);
28643 if (ctx->insn_flags & INSN_R5900) {
28644 check_insn_opc_user_only(ctx, INSN_R5900);
28646 check_mips_64(ctx);
28647 gen_st_cond(ctx, op, rt, rs, imm);
28649 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
28650 if (ctx->insn_flags & ISA_MIPS32R6) {
28651 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
28652 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28655 check_insn(ctx, ISA_MIPS3);
28656 check_mips_64(ctx);
28657 gen_arith_imm(ctx, op, rt, rs, imm);
28661 check_insn(ctx, ISA_MIPS3);
28662 check_mips_64(ctx);
28663 gen_arith_imm(ctx, op, rt, rs, imm);
28666 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
28667 if (ctx->insn_flags & ISA_MIPS32R6) {
28668 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28670 MIPS_INVAL("major opcode");
28671 generate_exception_end(ctx, EXCP_RI);
28675 case OPC_DAUI: /* OPC_JALX */
28676 if (ctx->insn_flags & ISA_MIPS32R6) {
28677 #if defined(TARGET_MIPS64)
28679 check_mips_64(ctx);
28681 generate_exception(ctx, EXCP_RI);
28682 } else if (rt != 0) {
28683 TCGv t0 = tcg_temp_new();
28684 gen_load_gpr(t0, rs);
28685 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
28689 generate_exception_end(ctx, EXCP_RI);
28690 MIPS_INVAL("major opcode");
28694 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
28695 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
28696 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
28699 case OPC_MSA: /* OPC_MDMX */
28700 if (ctx->insn_flags & INSN_R5900) {
28701 gen_mmi_lq(env, ctx); /* MMI_OPC_LQ */
28703 /* MDMX: Not implemented. */
28708 check_insn(ctx, ISA_MIPS32R6);
28709 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
28711 default: /* Invalid */
28712 MIPS_INVAL("major opcode");
28713 generate_exception_end(ctx, EXCP_RI);
28718 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
28720 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28721 CPUMIPSState *env = cs->env_ptr;
28723 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
28724 ctx->saved_pc = -1;
28725 ctx->insn_flags = env->insn_flags;
28726 ctx->CP0_Config1 = env->CP0_Config1;
28727 ctx->CP0_Config2 = env->CP0_Config2;
28728 ctx->CP0_Config3 = env->CP0_Config3;
28729 ctx->CP0_Config5 = env->CP0_Config5;
28731 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
28732 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
28733 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
28734 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
28735 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
28736 ctx->PAMask = env->PAMask;
28737 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
28738 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
28739 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
28740 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
28741 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
28742 /* Restore delay slot state from the tb context. */
28743 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
28744 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
28745 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
28746 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
28747 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
28748 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
28749 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
28750 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
28751 restore_cpu_state(env, ctx);
28752 #ifdef CONFIG_USER_ONLY
28753 ctx->mem_idx = MIPS_HFLAG_UM;
28755 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
28757 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
28758 MO_UNALN : MO_ALIGN;
28760 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
28764 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
28768 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
28770 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28772 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
28776 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
28777 const CPUBreakpoint *bp)
28779 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28781 save_cpu_state(ctx, 1);
28782 ctx->base.is_jmp = DISAS_NORETURN;
28783 gen_helper_raise_exception_debug(cpu_env);
28784 /* The address covered by the breakpoint must be included in
28785 [tb->pc, tb->pc + tb->size) in order to for it to be
28786 properly cleared -- thus we increment the PC here so that
28787 the logic setting tb->size below does the right thing. */
28788 ctx->base.pc_next += 4;
28792 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
28794 CPUMIPSState *env = cs->env_ptr;
28795 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28799 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
28800 if (ctx->insn_flags & ISA_NANOMIPS32) {
28801 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28802 insn_bytes = decode_nanomips_opc(env, ctx);
28803 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
28804 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
28806 decode_opc(env, ctx);
28807 } else if (ctx->insn_flags & ASE_MICROMIPS) {
28808 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28809 insn_bytes = decode_micromips_opc(env, ctx);
28810 } else if (ctx->insn_flags & ASE_MIPS16) {
28811 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28812 insn_bytes = decode_mips16_opc(env, ctx);
28814 generate_exception_end(ctx, EXCP_RI);
28815 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
28819 if (ctx->hflags & MIPS_HFLAG_BMASK) {
28820 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
28821 MIPS_HFLAG_FBNSLOT))) {
28822 /* force to generate branch as there is neither delay nor
28826 if ((ctx->hflags & MIPS_HFLAG_M16) &&
28827 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
28828 /* Force to generate branch as microMIPS R6 doesn't restrict
28829 branches in the forbidden slot. */
28834 gen_branch(ctx, insn_bytes);
28836 ctx->base.pc_next += insn_bytes;
28838 if (ctx->base.is_jmp != DISAS_NEXT) {
28841 /* Execute a branch and its delay slot as a single instruction.
28842 This is what GDB expects and is consistent with what the
28843 hardware does (e.g. if a delay slot instruction faults, the
28844 reported PC is the PC of the branch). */
28845 if (ctx->base.singlestep_enabled &&
28846 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
28847 ctx->base.is_jmp = DISAS_TOO_MANY;
28849 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
28850 ctx->base.is_jmp = DISAS_TOO_MANY;
28854 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
28856 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28858 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
28859 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
28860 gen_helper_raise_exception_debug(cpu_env);
28862 switch (ctx->base.is_jmp) {
28864 gen_save_pc(ctx->base.pc_next);
28865 tcg_gen_lookup_and_goto_ptr();
28868 case DISAS_TOO_MANY:
28869 save_cpu_state(ctx, 0);
28870 gen_goto_tb(ctx, 0, ctx->base.pc_next);
28873 tcg_gen_exit_tb(NULL, 0);
28875 case DISAS_NORETURN:
28878 g_assert_not_reached();
28883 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
28885 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
28886 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
28889 static const TranslatorOps mips_tr_ops = {
28890 .init_disas_context = mips_tr_init_disas_context,
28891 .tb_start = mips_tr_tb_start,
28892 .insn_start = mips_tr_insn_start,
28893 .breakpoint_check = mips_tr_breakpoint_check,
28894 .translate_insn = mips_tr_translate_insn,
28895 .tb_stop = mips_tr_tb_stop,
28896 .disas_log = mips_tr_disas_log,
28899 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
28903 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
28906 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
28910 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
28912 #define printfpr(fp) \
28915 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
28916 " fd:%13g fs:%13g psu: %13g\n", \
28917 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
28918 (double)(fp)->fd, \
28919 (double)(fp)->fs[FP_ENDIAN_IDX], \
28920 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
28923 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
28924 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
28925 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
28926 " fd:%13g fs:%13g psu:%13g\n", \
28927 tmp.w[FP_ENDIAN_IDX], tmp.d, \
28929 (double)tmp.fs[FP_ENDIAN_IDX], \
28930 (double)tmp.fs[!FP_ENDIAN_IDX]); \
28935 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
28936 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
28937 get_float_exception_flags(&env->active_fpu.fp_status));
28938 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
28939 fpu_fprintf(f, "%3s: ", fregnames[i]);
28940 printfpr(&env->active_fpu.fpr[i]);
28946 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
28949 MIPSCPU *cpu = MIPS_CPU(cs);
28950 CPUMIPSState *env = &cpu->env;
28953 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
28954 " LO=0x" TARGET_FMT_lx " ds %04x "
28955 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
28956 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
28957 env->hflags, env->btarget, env->bcond);
28958 for (i = 0; i < 32; i++) {
28960 cpu_fprintf(f, "GPR%02d:", i);
28961 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
28963 cpu_fprintf(f, "\n");
28966 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
28967 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
28968 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
28970 env->CP0_Config0, env->CP0_Config1, env->lladdr);
28971 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
28972 env->CP0_Config2, env->CP0_Config3);
28973 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
28974 env->CP0_Config4, env->CP0_Config5);
28975 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
28976 fpu_dump_state(env, f, cpu_fprintf, flags);
28980 void mips_tcg_init(void)
28985 for (i = 1; i < 32; i++)
28986 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
28987 offsetof(CPUMIPSState, active_tc.gpr[i]),
28990 for (i = 0; i < 32; i++) {
28991 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
28993 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
28994 /* The scalar floating-point unit (FPU) registers are mapped on
28995 * the MSA vector registers. */
28996 fpu_f64[i] = msa_wr_d[i * 2];
28997 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
28998 msa_wr_d[i * 2 + 1] =
28999 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
29002 cpu_PC = tcg_global_mem_new(cpu_env,
29003 offsetof(CPUMIPSState, active_tc.PC), "PC");
29004 for (i = 0; i < MIPS_DSP_ACC; i++) {
29005 cpu_HI[i] = tcg_global_mem_new(cpu_env,
29006 offsetof(CPUMIPSState, active_tc.HI[i]),
29008 cpu_LO[i] = tcg_global_mem_new(cpu_env,
29009 offsetof(CPUMIPSState, active_tc.LO[i]),
29012 cpu_dspctrl = tcg_global_mem_new(cpu_env,
29013 offsetof(CPUMIPSState, active_tc.DSPControl),
29015 bcond = tcg_global_mem_new(cpu_env,
29016 offsetof(CPUMIPSState, bcond), "bcond");
29017 btarget = tcg_global_mem_new(cpu_env,
29018 offsetof(CPUMIPSState, btarget), "btarget");
29019 hflags = tcg_global_mem_new_i32(cpu_env,
29020 offsetof(CPUMIPSState, hflags), "hflags");
29022 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
29023 offsetof(CPUMIPSState, active_fpu.fcr0),
29025 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
29026 offsetof(CPUMIPSState, active_fpu.fcr31),
29029 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29030 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29031 offsetof(CPUMIPSState,
29032 active_tc.mxu_gpr[i]),
29036 mxu_CR = tcg_global_mem_new(cpu_env,
29037 offsetof(CPUMIPSState, active_tc.mxu_cr),
29038 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
29041 #include "translate_init.inc.c"
29043 void cpu_mips_realize_env(CPUMIPSState *env)
29045 env->exception_base = (int32_t)0xBFC00000;
29047 #ifndef CONFIG_USER_ONLY
29048 mmu_init(env, env->cpu_model);
29050 fpu_init(env, env->cpu_model);
29051 mvp_init(env, env->cpu_model);
29054 bool cpu_supports_cps_smp(const char *cpu_type)
29056 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29057 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
29060 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
29062 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29063 return (mcc->cpu_def->insn_flags & isa) != 0;
29066 void cpu_set_exception_base(int vp_index, target_ulong address)
29068 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
29069 vp->env.exception_base = address;
29072 void cpu_state_reset(CPUMIPSState *env)
29074 MIPSCPU *cpu = mips_env_get_cpu(env);
29075 CPUState *cs = CPU(cpu);
29077 /* Reset registers to their default values */
29078 env->CP0_PRid = env->cpu_model->CP0_PRid;
29079 env->CP0_Config0 = env->cpu_model->CP0_Config0;
29080 #ifdef TARGET_WORDS_BIGENDIAN
29081 env->CP0_Config0 |= (1 << CP0C0_BE);
29083 env->CP0_Config1 = env->cpu_model->CP0_Config1;
29084 env->CP0_Config2 = env->cpu_model->CP0_Config2;
29085 env->CP0_Config3 = env->cpu_model->CP0_Config3;
29086 env->CP0_Config4 = env->cpu_model->CP0_Config4;
29087 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
29088 env->CP0_Config5 = env->cpu_model->CP0_Config5;
29089 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
29090 env->CP0_Config6 = env->cpu_model->CP0_Config6;
29091 env->CP0_Config7 = env->cpu_model->CP0_Config7;
29092 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
29093 << env->cpu_model->CP0_LLAddr_shift;
29094 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
29095 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
29096 env->CCRes = env->cpu_model->CCRes;
29097 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
29098 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
29099 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
29100 env->current_tc = 0;
29101 env->SEGBITS = env->cpu_model->SEGBITS;
29102 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
29103 #if defined(TARGET_MIPS64)
29104 if (env->cpu_model->insn_flags & ISA_MIPS3) {
29105 env->SEGMask |= 3ULL << 62;
29108 env->PABITS = env->cpu_model->PABITS;
29109 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
29110 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
29111 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
29112 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
29113 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
29114 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
29115 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
29116 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
29117 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
29118 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
29119 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
29120 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
29121 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
29122 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
29123 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
29124 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
29125 env->msair = env->cpu_model->MSAIR;
29126 env->insn_flags = env->cpu_model->insn_flags;
29128 #if defined(CONFIG_USER_ONLY)
29129 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
29130 # ifdef TARGET_MIPS64
29131 /* Enable 64-bit register mode. */
29132 env->CP0_Status |= (1 << CP0St_PX);
29134 # ifdef TARGET_ABI_MIPSN64
29135 /* Enable 64-bit address mode. */
29136 env->CP0_Status |= (1 << CP0St_UX);
29138 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
29139 hardware registers. */
29140 env->CP0_HWREna |= 0x0000000F;
29141 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
29142 env->CP0_Status |= (1 << CP0St_CU1);
29144 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
29145 env->CP0_Status |= (1 << CP0St_MX);
29147 # if defined(TARGET_MIPS64)
29148 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
29149 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
29150 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
29151 env->CP0_Status |= (1 << CP0St_FR);
29155 if (env->hflags & MIPS_HFLAG_BMASK) {
29156 /* If the exception was raised from a delay slot,
29157 come back to the jump. */
29158 env->CP0_ErrorEPC = (env->active_tc.PC
29159 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
29161 env->CP0_ErrorEPC = env->active_tc.PC;
29163 env->active_tc.PC = env->exception_base;
29164 env->CP0_Random = env->tlb->nb_tlb - 1;
29165 env->tlb->tlb_in_use = env->tlb->nb_tlb;
29166 env->CP0_Wired = 0;
29167 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
29168 env->CP0_EBase = (cs->cpu_index & 0x3FF);
29169 if (mips_um_ksegs_enabled()) {
29170 env->CP0_EBase |= 0x40000000;
29172 env->CP0_EBase |= (int32_t)0x80000000;
29174 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
29175 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
29177 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
29179 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
29180 /* vectored interrupts not implemented, timer on int 7,
29181 no performance counters. */
29182 env->CP0_IntCtl = 0xe0000000;
29186 for (i = 0; i < 7; i++) {
29187 env->CP0_WatchLo[i] = 0;
29188 env->CP0_WatchHi[i] = 0x80000000;
29190 env->CP0_WatchLo[7] = 0;
29191 env->CP0_WatchHi[7] = 0;
29193 /* Count register increments in debug mode, EJTAG version 1 */
29194 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
29196 cpu_mips_store_count(env, 1);
29198 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
29201 /* Only TC0 on VPE 0 starts as active. */
29202 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
29203 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
29204 env->tcs[i].CP0_TCHalt = 1;
29206 env->active_tc.CP0_TCHalt = 1;
29209 if (cs->cpu_index == 0) {
29210 /* VPE0 starts up enabled. */
29211 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
29212 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
29214 /* TC0 starts up unhalted. */
29216 env->active_tc.CP0_TCHalt = 0;
29217 env->tcs[0].CP0_TCHalt = 0;
29218 /* With thread 0 active. */
29219 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
29220 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
29225 * Configure default legacy segmentation control. We use this regardless of
29226 * whether segmentation control is presented to the guest.
29228 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
29229 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
29230 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
29231 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
29232 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
29233 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
29235 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
29236 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
29237 (3 << CP0SC_C)) << 16;
29238 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
29239 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
29240 (1 << CP0SC_EU) | (2 << CP0SC_C);
29241 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
29242 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
29243 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
29244 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
29245 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
29247 if ((env->insn_flags & ISA_MIPS32R6) &&
29248 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
29249 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
29250 env->CP0_Status |= (1 << CP0St_FR);
29253 if (env->insn_flags & ISA_MIPS32R6) {
29255 env->CP0_PWSize = 0x40;
29261 env->CP0_PWField = 0x0C30C302;
29268 env->CP0_PWField = 0x02;
29271 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
29272 /* microMIPS on reset when Config3.ISA is 3 */
29273 env->hflags |= MIPS_HFLAG_M16;
29277 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
29281 compute_hflags(env);
29282 restore_fp_status(env);
29283 restore_pamask(env);
29284 cs->exception_index = EXCP_NONE;
29286 if (semihosting_get_argc()) {
29287 /* UHI interface can be used to obtain argc and argv */
29288 env->active_tc.gpr[4] = -1;
29292 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
29293 target_ulong *data)
29295 env->active_tc.PC = data[0];
29296 env->hflags &= ~MIPS_HFLAG_BMASK;
29297 env->hflags |= data[1];
29298 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
29299 case MIPS_HFLAG_BR:
29301 case MIPS_HFLAG_BC:
29302 case MIPS_HFLAG_BL:
29304 env->btarget = data[2];