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,
1403 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1404 * ============================================
1407 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1408 * instructions set. It is designed to fit the needs of signal, graphical and
1409 * video processing applications. MXU instruction set is used in Xburst family
1410 * of microprocessors by Ingenic.
1412 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1413 * the control register.
1416 * The notation used in MXU assembler mnemonics
1417 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1419 * Register operands:
1421 * XRa, XRb, XRc, XRd - MXU registers
1422 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1424 * Non-register operands:
1426 * aptn1 - 1-bit accumulate add/subtract pattern
1427 * aptn2 - 2-bit accumulate add/subtract pattern
1428 * eptn2 - 2-bit execute add/subtract pattern
1429 * optn2 - 2-bit operand pattern
1430 * optn3 - 3-bit operand pattern
1431 * sft4 - 4-bit shift amount
1432 * strd2 - 2-bit stride amount
1436 * Level of parallelism: Operand size:
1437 * S - single operation at a time 32 - word
1438 * D - two operations in parallel 16 - half word
1439 * Q - four operations in parallel 8 - byte
1443 * ADD - Add or subtract
1444 * ADDC - Add with carry-in
1446 * ASUM - Sum together then accumulate (add or subtract)
1447 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1448 * AVG - Average between 2 operands
1449 * ABD - Absolute difference
1451 * AND - Logical bitwise 'and' operation
1453 * EXTR - Extract bits
1454 * I2M - Move from GPR register to MXU register
1455 * LDD - Load data from memory to XRF
1456 * LDI - Load data from memory to XRF (and increase the address base)
1457 * LUI - Load unsigned immediate
1459 * MULU - Unsigned multiply
1460 * MADD - 64-bit operand add 32x32 product
1461 * MSUB - 64-bit operand subtract 32x32 product
1462 * MAC - Multiply and accumulate (add or subtract)
1463 * MAD - Multiply and add or subtract
1464 * MAX - Maximum between 2 operands
1465 * MIN - Minimum between 2 operands
1466 * M2I - Move from MXU register to GPR register
1467 * MOVZ - Move if zero
1468 * MOVN - Move if non-zero
1469 * NOR - Logical bitwise 'nor' operation
1470 * OR - Logical bitwise 'or' operation
1471 * STD - Store data from XRF to memory
1472 * SDI - Store data from XRF to memory (and increase the address base)
1473 * SLT - Set of less than comparison
1474 * SAD - Sum of absolute differences
1475 * SLL - Logical shift left
1476 * SLR - Logical shift right
1477 * SAR - Arithmetic shift right
1480 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1481 * XOR - Logical bitwise 'exclusive or' operation
1485 * E - Expand results
1486 * F - Fixed point multiplication
1487 * L - Low part result
1488 * R - Doing rounding
1489 * V - Variable instead of immediate
1490 * W - Combine above L and V
1493 * The list of MXU instructions grouped by functionality
1494 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1496 * Load/Store instructions Multiplication instructions
1497 * ----------------------- ---------------------------
1499 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1500 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1501 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1502 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1503 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1504 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1505 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1506 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1507 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1508 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1509 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1510 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1511 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1512 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1513 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1514 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1515 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1516 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1517 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1518 * S16SDI XRa, Rb, s10, eptn2
1519 * S8LDD XRa, Rb, s8, eptn3
1520 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1521 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1522 * S8SDI XRa, Rb, s8, eptn3
1523 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1524 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1525 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1526 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1527 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1528 * S32CPS XRa, XRb, XRc
1529 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1530 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1531 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1532 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1533 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1534 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1535 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1536 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1537 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1538 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1539 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1540 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1541 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1542 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1543 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1544 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1545 * Q8SLT XRa, XRb, XRc
1546 * Q8SLTU XRa, XRb, XRc
1547 * Q8MOVZ XRa, XRb, XRc Shift instructions
1548 * Q8MOVN XRa, XRb, XRc ------------------
1550 * D32SLL XRa, XRb, XRc, XRd, sft4
1551 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1552 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1553 * D32SARL XRa, XRb, XRc, sft4
1554 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1555 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1556 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1557 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1558 * Q16SLL XRa, XRb, XRc, XRd, sft4
1559 * Q16SLR XRa, XRb, XRc, XRd, sft4
1560 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1561 * ------------------------- Q16SLLV XRa, XRb, Rb
1562 * Q16SLRV XRa, XRb, Rb
1563 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1564 * S32ALN XRa, XRb, XRc, Rb
1565 * S32ALNI XRa, XRb, XRc, s3
1566 * S32LUI XRa, s8, optn3 Move instructions
1567 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1568 * S32EXTRV XRa, XRb, Rs, Rt
1569 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1570 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1573 * The opcode organization of MXU instructions
1574 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1576 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1577 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1578 * other bits up to the instruction level is as follows:
1583 * ┌─ 000000 ─ OPC_MXU_S32MADD
1584 * ├─ 000001 ─ OPC_MXU_S32MADDU
1585 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1588 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1589 * │ ├─ 001 ─ OPC_MXU_S32MIN
1590 * │ ├─ 010 ─ OPC_MXU_D16MAX
1591 * │ ├─ 011 ─ OPC_MXU_D16MIN
1592 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1593 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1594 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1595 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1596 * ├─ 000100 ─ OPC_MXU_S32MSUB
1597 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1598 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1599 * │ ├─ 001 ─ OPC_MXU_D16SLT
1600 * │ ├─ 010 ─ OPC_MXU_D16AVG
1601 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1602 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1603 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1604 * │ └─ 111 ─ OPC_MXU_Q8ADD
1607 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1608 * │ ├─ 010 ─ OPC_MXU_D16CPS
1609 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1610 * │ └─ 110 ─ OPC_MXU_Q16SAT
1611 * ├─ 001000 ─ OPC_MXU_D16MUL
1613 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1614 * │ └─ 01 ─ OPC_MXU_D16MULE
1615 * ├─ 001010 ─ OPC_MXU_D16MAC
1616 * ├─ 001011 ─ OPC_MXU_D16MACF
1617 * ├─ 001100 ─ OPC_MXU_D16MADL
1618 * ├─ 001101 ─ OPC_MXU_S16MAD
1619 * ├─ 001110 ─ OPC_MXU_Q16ADD
1620 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1621 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1622 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1625 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1626 * │ └─ 1 ─ OPC_MXU_S32STDR
1629 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1630 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1633 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1634 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1637 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1638 * │ └─ 1 ─ OPC_MXU_S32LDIR
1641 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1642 * │ └─ 1 ─ OPC_MXU_S32SDIR
1645 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1646 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1649 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1650 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1651 * ├─ 011000 ─ OPC_MXU_D32ADD
1653 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1654 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1655 * │ └─ 10 ─ OPC_MXU_D32ASUM
1656 * ├─ 011010 ─ <not assigned>
1658 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1659 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1660 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1663 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1664 * │ ├─ 01 ─ OPC_MXU_D8SUM
1665 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1666 * ├─ 011110 ─ <not assigned>
1667 * ├─ 011111 ─ <not assigned>
1668 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1669 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1670 * ├─ 100010 ─ OPC_MXU_S8LDD
1671 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1672 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1673 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1674 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1675 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1678 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1679 * │ ├─ 001 ─ OPC_MXU_S32ALN
1680 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1681 * │ ├─ 011 ─ OPC_MXU_S32LUI
1682 * │ ├─ 100 ─ OPC_MXU_S32NOR
1683 * │ ├─ 101 ─ OPC_MXU_S32AND
1684 * │ ├─ 110 ─ OPC_MXU_S32OR
1685 * │ └─ 111 ─ OPC_MXU_S32XOR
1688 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1689 * │ ├─ 001 ─ OPC_MXU_LXH
1690 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1691 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1692 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1693 * ├─ 101100 ─ OPC_MXU_S16LDI
1694 * ├─ 101101 ─ OPC_MXU_S16SDI
1695 * ├─ 101110 ─ OPC_MXU_S32M2I
1696 * ├─ 101111 ─ OPC_MXU_S32I2M
1697 * ├─ 110000 ─ OPC_MXU_D32SLL
1698 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1699 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1700 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1701 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1702 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1703 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1704 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1706 * ├─ 110111 ─ OPC_MXU_Q16SAR
1708 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1709 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1712 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1713 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1714 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1715 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1716 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1717 * │ └─ 101 ─ OPC_MXU_S32MOVN
1720 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1721 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1722 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1723 * ├─ 111100 ─ OPC_MXU_Q8MADL
1724 * ├─ 111101 ─ OPC_MXU_S32SFL
1725 * ├─ 111110 ─ OPC_MXU_Q8SAD
1726 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1731 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1732 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1736 OPC_MXU_S32MADD = 0x00,
1737 OPC_MXU_S32MADDU = 0x01,
1738 OPC__MXU_MUL = 0x02,
1739 OPC_MXU__POOL00 = 0x03,
1740 OPC_MXU_S32MSUB = 0x04,
1741 OPC_MXU_S32MSUBU = 0x05,
1742 OPC_MXU__POOL01 = 0x06,
1743 OPC_MXU__POOL02 = 0x07,
1744 OPC_MXU_D16MUL = 0x08,
1745 OPC_MXU__POOL03 = 0x09,
1746 OPC_MXU_D16MAC = 0x0A,
1747 OPC_MXU_D16MACF = 0x0B,
1748 OPC_MXU_D16MADL = 0x0C,
1749 OPC_MXU_S16MAD = 0x0D,
1750 OPC_MXU_Q16ADD = 0x0E,
1751 OPC_MXU_D16MACE = 0x0F,
1752 OPC_MXU__POOL04 = 0x10,
1753 OPC_MXU__POOL05 = 0x11,
1754 OPC_MXU__POOL06 = 0x12,
1755 OPC_MXU__POOL07 = 0x13,
1756 OPC_MXU__POOL08 = 0x14,
1757 OPC_MXU__POOL09 = 0x15,
1758 OPC_MXU__POOL10 = 0x16,
1759 OPC_MXU__POOL11 = 0x17,
1760 OPC_MXU_D32ADD = 0x18,
1761 OPC_MXU__POOL12 = 0x19,
1762 /* not assigned 0x1A */
1763 OPC_MXU__POOL13 = 0x1B,
1764 OPC_MXU__POOL14 = 0x1C,
1765 OPC_MXU_Q8ACCE = 0x1D,
1766 /* not assigned 0x1E */
1767 /* not assigned 0x1F */
1768 /* not assigned 0x20 */
1769 /* not assigned 0x21 */
1770 OPC_MXU_S8LDD = 0x22,
1771 OPC_MXU_S8STD = 0x23,
1772 OPC_MXU_S8LDI = 0x24,
1773 OPC_MXU_S8SDI = 0x25,
1774 OPC_MXU__POOL15 = 0x26,
1775 OPC_MXU__POOL16 = 0x27,
1776 OPC_MXU__POOL17 = 0x28,
1777 /* not assigned 0x29 */
1778 OPC_MXU_S16LDD = 0x2A,
1779 OPC_MXU_S16STD = 0x2B,
1780 OPC_MXU_S16LDI = 0x2C,
1781 OPC_MXU_S16SDI = 0x2D,
1782 OPC_MXU_S32M2I = 0x2E,
1783 OPC_MXU_S32I2M = 0x2F,
1784 OPC_MXU_D32SLL = 0x30,
1785 OPC_MXU_D32SLR = 0x31,
1786 OPC_MXU_D32SARL = 0x32,
1787 OPC_MXU_D32SAR = 0x33,
1788 OPC_MXU_Q16SLL = 0x34,
1789 OPC_MXU_Q16SLR = 0x35,
1790 OPC_MXU__POOL18 = 0x36,
1791 OPC_MXU_Q16SAR = 0x37,
1792 OPC_MXU__POOL19 = 0x38,
1793 OPC_MXU__POOL20 = 0x39,
1794 OPC_MXU__POOL21 = 0x3A,
1795 OPC_MXU_Q16SCOP = 0x3B,
1796 OPC_MXU_Q8MADL = 0x3C,
1797 OPC_MXU_S32SFL = 0x3D,
1798 OPC_MXU_Q8SAD = 0x3E,
1799 /* not assigned 0x3F */
1807 OPC_MXU_S32MAX = 0x00,
1808 OPC_MXU_S32MIN = 0x01,
1809 OPC_MXU_D16MAX = 0x02,
1810 OPC_MXU_D16MIN = 0x03,
1811 OPC_MXU_Q8MAX = 0x04,
1812 OPC_MXU_Q8MIN = 0x05,
1813 OPC_MXU_Q8SLT = 0x06,
1814 OPC_MXU_Q8SLTU = 0x07,
1821 OPC_MXU_S32SLT = 0x00,
1822 OPC_MXU_D16SLT = 0x01,
1823 OPC_MXU_D16AVG = 0x02,
1824 OPC_MXU_D16AVGR = 0x03,
1825 OPC_MXU_Q8AVG = 0x04,
1826 OPC_MXU_Q8AVGR = 0x05,
1827 OPC_MXU_Q8ADD = 0x07,
1834 OPC_MXU_S32CPS = 0x00,
1835 OPC_MXU_D16CPS = 0x02,
1836 OPC_MXU_Q8ABD = 0x04,
1837 OPC_MXU_Q16SAT = 0x06,
1844 OPC_MXU_D16MULF = 0x00,
1845 OPC_MXU_D16MULE = 0x01,
1852 OPC_MXU_S32LDD = 0x00,
1853 OPC_MXU_S32LDDR = 0x01,
1860 OPC_MXU_S32STD = 0x00,
1861 OPC_MXU_S32STDR = 0x01,
1868 OPC_MXU_S32LDDV = 0x00,
1869 OPC_MXU_S32LDDVR = 0x01,
1876 OPC_MXU_S32STDV = 0x00,
1877 OPC_MXU_S32STDVR = 0x01,
1884 OPC_MXU_S32LDI = 0x00,
1885 OPC_MXU_S32LDIR = 0x01,
1892 OPC_MXU_S32SDI = 0x00,
1893 OPC_MXU_S32SDIR = 0x01,
1900 OPC_MXU_S32LDIV = 0x00,
1901 OPC_MXU_S32LDIVR = 0x01,
1908 OPC_MXU_S32SDIV = 0x00,
1909 OPC_MXU_S32SDIVR = 0x01,
1916 OPC_MXU_D32ACC = 0x00,
1917 OPC_MXU_D32ACCM = 0x01,
1918 OPC_MXU_D32ASUM = 0x02,
1925 OPC_MXU_Q16ACC = 0x00,
1926 OPC_MXU_Q16ACCM = 0x01,
1927 OPC_MXU_Q16ASUM = 0x02,
1934 OPC_MXU_Q8ADDE = 0x00,
1935 OPC_MXU_D8SUM = 0x01,
1936 OPC_MXU_D8SUMC = 0x02,
1943 OPC_MXU_S32MUL = 0x00,
1944 OPC_MXU_S32MULU = 0x01,
1945 OPC_MXU_S32EXTR = 0x02,
1946 OPC_MXU_S32EXTRV = 0x03,
1953 OPC_MXU_D32SARW = 0x00,
1954 OPC_MXU_S32ALN = 0x01,
1955 OPC_MXU_S32ALNI = 0x02,
1956 OPC_MXU_S32LUI = 0x03,
1957 OPC_MXU_S32NOR = 0x04,
1958 OPC_MXU_S32AND = 0x05,
1959 OPC_MXU_S32OR = 0x06,
1960 OPC_MXU_S32XOR = 0x07,
1970 OPC_MXU_LXBU = 0x04,
1971 OPC_MXU_LXHU = 0x05,
1978 OPC_MXU_D32SLLV = 0x00,
1979 OPC_MXU_D32SLRV = 0x01,
1980 OPC_MXU_D32SARV = 0x03,
1981 OPC_MXU_Q16SLLV = 0x04,
1982 OPC_MXU_Q16SLRV = 0x05,
1983 OPC_MXU_Q16SARV = 0x07,
1990 OPC_MXU_Q8MUL = 0x00,
1991 OPC_MXU_Q8MULSU = 0x01,
1998 OPC_MXU_Q8MOVZ = 0x00,
1999 OPC_MXU_Q8MOVN = 0x01,
2000 OPC_MXU_D16MOVZ = 0x02,
2001 OPC_MXU_D16MOVN = 0x03,
2002 OPC_MXU_S32MOVZ = 0x04,
2003 OPC_MXU_S32MOVN = 0x05,
2010 OPC_MXU_Q8MAC = 0x00,
2011 OPC_MXU_Q8MACSU = 0x01,
2015 * Overview of the TX79-specific instruction set
2016 * =============================================
2018 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2019 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2020 * instructions and certain multimedia instructions (MMIs). These MMIs
2021 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2022 * or sixteen 8-bit paths.
2026 * The Toshiba TX System RISC TX79 Core Architecture manual,
2027 * https://wiki.qemu.org/File:C790.pdf
2029 * Three-Operand Multiply and Multiply-Add (4 instructions)
2030 * --------------------------------------------------------
2031 * MADD [rd,] rs, rt Multiply/Add
2032 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2033 * MULT [rd,] rs, rt Multiply (3-operand)
2034 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2036 * Multiply Instructions for Pipeline 1 (10 instructions)
2037 * ------------------------------------------------------
2038 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2039 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2040 * DIV1 rs, rt Divide Pipeline 1
2041 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2042 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2043 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2044 * MFHI1 rd Move From HI1 Register
2045 * MFLO1 rd Move From LO1 Register
2046 * MTHI1 rs Move To HI1 Register
2047 * MTLO1 rs Move To LO1 Register
2049 * Arithmetic (19 instructions)
2050 * ----------------------------
2051 * PADDB rd, rs, rt Parallel Add Byte
2052 * PSUBB rd, rs, rt Parallel Subtract Byte
2053 * PADDH rd, rs, rt Parallel Add Halfword
2054 * PSUBH rd, rs, rt Parallel Subtract Halfword
2055 * PADDW rd, rs, rt Parallel Add Word
2056 * PSUBW rd, rs, rt Parallel Subtract Word
2057 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2058 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2059 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2060 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2061 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2062 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2063 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2064 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2065 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2066 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2067 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2068 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2069 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2071 * Min/Max (4 instructions)
2072 * ------------------------
2073 * PMAXH rd, rs, rt Parallel Maximum Halfword
2074 * PMINH rd, rs, rt Parallel Minimum Halfword
2075 * PMAXW rd, rs, rt Parallel Maximum Word
2076 * PMINW rd, rs, rt Parallel Minimum Word
2078 * Absolute (2 instructions)
2079 * -------------------------
2080 * PABSH rd, rt Parallel Absolute Halfword
2081 * PABSW rd, rt Parallel Absolute Word
2083 * Logical (4 instructions)
2084 * ------------------------
2085 * PAND rd, rs, rt Parallel AND
2086 * POR rd, rs, rt Parallel OR
2087 * PXOR rd, rs, rt Parallel XOR
2088 * PNOR rd, rs, rt Parallel NOR
2090 * Shift (9 instructions)
2091 * ----------------------
2092 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2093 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2094 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2095 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2096 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2097 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2098 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2099 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2100 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2102 * Compare (6 instructions)
2103 * ------------------------
2104 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2105 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2106 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2107 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2108 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2109 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2111 * LZC (1 instruction)
2112 * -------------------
2113 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2115 * Quadword Load and Store (2 instructions)
2116 * ----------------------------------------
2117 * LQ rt, offset(base) Load Quadword
2118 * SQ rt, offset(base) Store Quadword
2120 * Multiply and Divide (19 instructions)
2121 * -------------------------------------
2122 * PMULTW rd, rs, rt Parallel Multiply Word
2123 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2124 * PDIVW rs, rt Parallel Divide Word
2125 * PDIVUW rs, rt Parallel Divide Unsigned Word
2126 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2127 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2128 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2129 * PMULTH rd, rs, rt Parallel Multiply Halfword
2130 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2131 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2132 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2133 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2134 * PDIVBW rs, rt Parallel Divide Broadcast Word
2135 * PMFHI rd Parallel Move From HI Register
2136 * PMFLO rd Parallel Move From LO Register
2137 * PMTHI rs Parallel Move To HI Register
2138 * PMTLO rs Parallel Move To LO Register
2139 * PMFHL rd Parallel Move From HI/LO Register
2140 * PMTHL rs Parallel Move To HI/LO Register
2142 * Pack/Extend (11 instructions)
2143 * -----------------------------
2144 * PPAC5 rd, rt Parallel Pack to 5 bits
2145 * PPACB rd, rs, rt Parallel Pack to Byte
2146 * PPACH rd, rs, rt Parallel Pack to Halfword
2147 * PPACW rd, rs, rt Parallel Pack to Word
2148 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2149 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2150 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2151 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2152 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2153 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2154 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2156 * Others (16 instructions)
2157 * ------------------------
2158 * PCPYH rd, rt Parallel Copy Halfword
2159 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2160 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2161 * PREVH rd, rt Parallel Reverse Halfword
2162 * PINTH rd, rs, rt Parallel Interleave Halfword
2163 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2164 * PEXEH rd, rt Parallel Exchange Even Halfword
2165 * PEXCH rd, rt Parallel Exchange Center Halfword
2166 * PEXEW rd, rt Parallel Exchange Even Word
2167 * PEXCW rd, rt Parallel Exchange Center Word
2168 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2169 * MFSA rd Move from Shift Amount Register
2170 * MTSA rs Move to Shift Amount Register
2171 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2172 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2173 * PROT3W rd, rt Parallel Rotate 3 Words
2175 * MMI (MultiMedia Instruction) encodings
2176 * ======================================
2178 * MMI instructions encoding table keys:
2180 * * This code is reserved for future use. An attempt to execute it
2181 * causes a Reserved Instruction exception.
2182 * % This code indicates an instruction class. The instruction word
2183 * must be further decoded by examining additional tables that show
2184 * the values for other instruction fields.
2185 * # This code is reserved for the unsupported instructions DMULT,
2186 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2187 * to execute it causes a Reserved Instruction exception.
2189 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2192 * +--------+----------------------------------------+
2194 * +--------+----------------------------------------+
2196 * opcode bits 28..26
2197 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2198 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2199 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2200 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2201 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2202 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2203 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2204 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2205 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2206 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2207 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2211 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2212 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */
2213 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
2217 * MMI instructions with opcode field = MMI:
2220 * +--------+-------------------------------+--------+
2221 * | MMI | |function|
2222 * +--------+-------------------------------+--------+
2224 * function bits 2..0
2225 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2226 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2227 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2228 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2229 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2230 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2231 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2232 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2233 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2234 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2235 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2238 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2240 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2241 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2242 MMI_OPC_PLZCW = 0x04 | MMI_OPC_CLASS_MMI,
2243 MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2244 MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2245 MMI_OPC_MFHI1 = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2246 MMI_OPC_MTHI1 = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2247 MMI_OPC_MFLO1 = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2248 MMI_OPC_MTLO1 = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2249 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2250 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2251 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
2252 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2253 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
2254 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
2255 MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2256 MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2257 MMI_OPC_PMFHL = 0x30 | MMI_OPC_CLASS_MMI,
2258 MMI_OPC_PMTHL = 0x31 | MMI_OPC_CLASS_MMI,
2259 MMI_OPC_PSLLH = 0x34 | MMI_OPC_CLASS_MMI,
2260 MMI_OPC_PSRLH = 0x36 | MMI_OPC_CLASS_MMI,
2261 MMI_OPC_PSRAH = 0x37 | MMI_OPC_CLASS_MMI,
2262 MMI_OPC_PSLLW = 0x3C | MMI_OPC_CLASS_MMI,
2263 MMI_OPC_PSRLW = 0x3E | MMI_OPC_CLASS_MMI,
2264 MMI_OPC_PSRAW = 0x3F | MMI_OPC_CLASS_MMI,
2268 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2271 * +--------+----------------------+--------+--------+
2272 * | MMI | |function| MMI0 |
2273 * +--------+----------------------+--------+--------+
2275 * function bits 7..6
2276 * bits | 0 | 1 | 2 | 3
2277 * 10..8 | 00 | 01 | 10 | 11
2278 * -------+-------+-------+-------+-------
2279 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2280 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2281 * 2 010 | PADDB | PSUBB | PCGTB | *
2282 * 3 011 | * | * | * | *
2283 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2284 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2285 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2286 * 7 111 | * | * | PEXT5 | PPAC5
2289 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2291 MMI_OPC_0_PADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2292 MMI_OPC_0_PSUBW = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2293 MMI_OPC_0_PCGTW = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2294 MMI_OPC_0_PMAXW = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2295 MMI_OPC_0_PADDH = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2296 MMI_OPC_0_PSUBH = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2297 MMI_OPC_0_PCGTH = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2298 MMI_OPC_0_PMAXH = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2299 MMI_OPC_0_PADDB = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2300 MMI_OPC_0_PSUBB = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2301 MMI_OPC_0_PCGTB = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2302 MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2303 MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2304 MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2305 MMI_OPC_0_PPACW = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2306 MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2307 MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2308 MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2309 MMI_OPC_0_PPACH = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2310 MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2311 MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2312 MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2313 MMI_OPC_0_PPACB = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2314 MMI_OPC_0_PEXT5 = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2315 MMI_OPC_0_PPAC5 = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2319 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2322 * +--------+----------------------+--------+--------+
2323 * | MMI | |function| MMI1 |
2324 * +--------+----------------------+--------+--------+
2326 * function bits 7..6
2327 * bits | 0 | 1 | 2 | 3
2328 * 10..8 | 00 | 01 | 10 | 11
2329 * -------+-------+-------+-------+-------
2330 * 0 000 | * | PABSW | PCEQW | PMINW
2331 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2332 * 2 010 | * | * | PCEQB | *
2333 * 3 011 | * | * | * | *
2334 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2335 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2336 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2337 * 7 111 | * | * | * | *
2340 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2342 MMI_OPC_1_PABSW = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2343 MMI_OPC_1_PCEQW = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2344 MMI_OPC_1_PMINW = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2345 MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2346 MMI_OPC_1_PABSH = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2347 MMI_OPC_1_PCEQH = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2348 MMI_OPC_1_PMINH = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2349 MMI_OPC_1_PCEQB = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2350 MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2351 MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2352 MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2353 MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2354 MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2355 MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2356 MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2357 MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2358 MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2359 MMI_OPC_1_QFSRV = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2363 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2366 * +--------+----------------------+--------+--------+
2367 * | MMI | |function| MMI2 |
2368 * +--------+----------------------+--------+--------+
2370 * function bits 7..6
2371 * bits | 0 | 1 | 2 | 3
2372 * 10..8 | 00 | 01 | 10 | 11
2373 * -------+-------+-------+-------+-------
2374 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2375 * 1 001 | PMSUBW| * | * | *
2376 * 2 010 | PMFHI | PMFLO | PINTH | *
2377 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2378 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2379 * 5 101 | PMSUBH| PHMSBH| * | *
2380 * 6 110 | * | * | PEXEH | PREVH
2381 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2384 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2386 MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2387 MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2388 MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2389 MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2390 MMI_OPC_2_PMFHI = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2391 MMI_OPC_2_PMFLO = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2392 MMI_OPC_2_PINTH = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2393 MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2394 MMI_OPC_2_PDIVW = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2395 MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2396 MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2397 MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2398 MMI_OPC_2_PAND = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2399 MMI_OPC_2_PXOR = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2400 MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2401 MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2402 MMI_OPC_2_PEXEH = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2403 MMI_OPC_2_PREVH = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2404 MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2405 MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2406 MMI_OPC_2_PEXEW = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2407 MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2411 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2414 * +--------+----------------------+--------+--------+
2415 * | MMI | |function| MMI3 |
2416 * +--------+----------------------+--------+--------+
2418 * function bits 7..6
2419 * bits | 0 | 1 | 2 | 3
2420 * 10..8 | 00 | 01 | 10 | 11
2421 * -------+-------+-------+-------+-------
2422 * 0 000 |PMADDUW| * | * | PSRAVW
2423 * 1 001 | * | * | * | *
2424 * 2 010 | PMTHI | PMTLO | PINTEH| *
2425 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2426 * 4 100 | * | * | POR | PNOR
2427 * 5 101 | * | * | * | *
2428 * 6 110 | * | * | PEXCH | PCPYH
2429 * 7 111 | * | * | PEXCW | *
2432 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2434 MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2435 MMI_OPC_3_PSRAVW = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2436 MMI_OPC_3_PMTHI = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2437 MMI_OPC_3_PMTLO = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2438 MMI_OPC_3_PINTEH = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2439 MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2440 MMI_OPC_3_PDIVUW = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2441 MMI_OPC_3_PCPYUD = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2442 MMI_OPC_3_POR = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2443 MMI_OPC_3_PNOR = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2444 MMI_OPC_3_PEXCH = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2445 MMI_OPC_3_PCPYH = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2446 MMI_OPC_3_PEXCW = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2449 /* global register indices */
2450 static TCGv cpu_gpr[32], cpu_PC;
2451 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2452 static TCGv cpu_dspctrl, btarget, bcond;
2453 static TCGv cpu_lladdr, cpu_llval;
2454 static TCGv_i32 hflags;
2455 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2456 static TCGv_i64 fpu_f64[32];
2457 static TCGv_i64 msa_wr_d[64];
2459 #if defined(TARGET_MIPS64)
2460 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2461 static TCGv_i64 cpu_mmr[32];
2464 #if !defined(TARGET_MIPS64)
2466 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2470 #include "exec/gen-icount.h"
2472 #define gen_helper_0e0i(name, arg) do { \
2473 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2474 gen_helper_##name(cpu_env, helper_tmp); \
2475 tcg_temp_free_i32(helper_tmp); \
2478 #define gen_helper_0e1i(name, arg1, arg2) do { \
2479 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2480 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2481 tcg_temp_free_i32(helper_tmp); \
2484 #define gen_helper_1e0i(name, ret, arg1) do { \
2485 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2486 gen_helper_##name(ret, cpu_env, helper_tmp); \
2487 tcg_temp_free_i32(helper_tmp); \
2490 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2491 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2492 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2493 tcg_temp_free_i32(helper_tmp); \
2496 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2497 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2498 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2499 tcg_temp_free_i32(helper_tmp); \
2502 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2503 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2504 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2505 tcg_temp_free_i32(helper_tmp); \
2508 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2509 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2510 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2511 tcg_temp_free_i32(helper_tmp); \
2514 typedef struct DisasContext {
2515 DisasContextBase base;
2516 target_ulong saved_pc;
2517 target_ulong page_start;
2519 uint64_t insn_flags;
2520 int32_t CP0_Config1;
2521 int32_t CP0_Config2;
2522 int32_t CP0_Config3;
2523 int32_t CP0_Config5;
2524 /* Routine used to access memory */
2526 TCGMemOp default_tcg_memop_mask;
2527 uint32_t hflags, saved_hflags;
2528 target_ulong btarget;
2539 int CP0_LLAddr_shift;
2549 #define DISAS_STOP DISAS_TARGET_0
2550 #define DISAS_EXIT DISAS_TARGET_1
2552 static const char * const regnames[] = {
2553 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2554 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2555 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2556 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2559 static const char * const regnames_HI[] = {
2560 "HI0", "HI1", "HI2", "HI3",
2563 static const char * const regnames_LO[] = {
2564 "LO0", "LO1", "LO2", "LO3",
2567 static const char * const fregnames[] = {
2568 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2569 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2570 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2571 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2574 static const char * const msaregnames[] = {
2575 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2576 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2577 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2578 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2579 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2580 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2581 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2582 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2583 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2584 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2585 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2586 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2587 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2588 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2589 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2590 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2593 #if !defined(TARGET_MIPS64)
2594 static const char * const mxuregnames[] = {
2595 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2596 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2600 #define LOG_DISAS(...) \
2602 if (MIPS_DEBUG_DISAS) { \
2603 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2607 #define MIPS_INVAL(op) \
2609 if (MIPS_DEBUG_DISAS) { \
2610 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2611 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2612 ctx->base.pc_next, ctx->opcode, op, \
2613 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2614 ((ctx->opcode >> 16) & 0x1F)); \
2618 /* General purpose registers moves. */
2619 static inline void gen_load_gpr (TCGv t, int reg)
2622 tcg_gen_movi_tl(t, 0);
2624 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2627 static inline void gen_store_gpr (TCGv t, int reg)
2630 tcg_gen_mov_tl(cpu_gpr[reg], t);
2633 /* Moves to/from shadow registers. */
2634 static inline void gen_load_srsgpr (int from, int to)
2636 TCGv t0 = tcg_temp_new();
2639 tcg_gen_movi_tl(t0, 0);
2641 TCGv_i32 t2 = tcg_temp_new_i32();
2642 TCGv_ptr addr = tcg_temp_new_ptr();
2644 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2645 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2646 tcg_gen_andi_i32(t2, t2, 0xf);
2647 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2648 tcg_gen_ext_i32_ptr(addr, t2);
2649 tcg_gen_add_ptr(addr, cpu_env, addr);
2651 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2652 tcg_temp_free_ptr(addr);
2653 tcg_temp_free_i32(t2);
2655 gen_store_gpr(t0, to);
2659 static inline void gen_store_srsgpr (int from, int to)
2662 TCGv t0 = tcg_temp_new();
2663 TCGv_i32 t2 = tcg_temp_new_i32();
2664 TCGv_ptr addr = tcg_temp_new_ptr();
2666 gen_load_gpr(t0, from);
2667 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2668 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2669 tcg_gen_andi_i32(t2, t2, 0xf);
2670 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2671 tcg_gen_ext_i32_ptr(addr, t2);
2672 tcg_gen_add_ptr(addr, cpu_env, addr);
2674 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2675 tcg_temp_free_ptr(addr);
2676 tcg_temp_free_i32(t2);
2681 #if !defined(TARGET_MIPS64)
2682 /* MXU General purpose registers moves. */
2683 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2686 tcg_gen_movi_tl(t, 0);
2687 } else if (reg <= 15) {
2688 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2692 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2694 if (reg > 0 && reg <= 15) {
2695 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2699 /* MXU control register moves. */
2700 static inline void gen_load_mxu_cr(TCGv t)
2702 tcg_gen_mov_tl(t, mxu_CR);
2705 static inline void gen_store_mxu_cr(TCGv t)
2707 /* TODO: Add handling of RW rules for MXU_CR. */
2708 tcg_gen_mov_tl(mxu_CR, t);
2714 static inline void gen_save_pc(target_ulong pc)
2716 tcg_gen_movi_tl(cpu_PC, pc);
2719 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2721 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2722 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2723 gen_save_pc(ctx->base.pc_next);
2724 ctx->saved_pc = ctx->base.pc_next;
2726 if (ctx->hflags != ctx->saved_hflags) {
2727 tcg_gen_movi_i32(hflags, ctx->hflags);
2728 ctx->saved_hflags = ctx->hflags;
2729 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2735 tcg_gen_movi_tl(btarget, ctx->btarget);
2741 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2743 ctx->saved_hflags = ctx->hflags;
2744 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2750 ctx->btarget = env->btarget;
2755 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2757 TCGv_i32 texcp = tcg_const_i32(excp);
2758 TCGv_i32 terr = tcg_const_i32(err);
2759 save_cpu_state(ctx, 1);
2760 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2761 tcg_temp_free_i32(terr);
2762 tcg_temp_free_i32(texcp);
2763 ctx->base.is_jmp = DISAS_NORETURN;
2766 static inline void generate_exception(DisasContext *ctx, int excp)
2768 gen_helper_0e0i(raise_exception, excp);
2771 static inline void generate_exception_end(DisasContext *ctx, int excp)
2773 generate_exception_err(ctx, excp, 0);
2776 /* Floating point register moves. */
2777 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2779 if (ctx->hflags & MIPS_HFLAG_FRE) {
2780 generate_exception(ctx, EXCP_RI);
2782 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2785 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2788 if (ctx->hflags & MIPS_HFLAG_FRE) {
2789 generate_exception(ctx, EXCP_RI);
2791 t64 = tcg_temp_new_i64();
2792 tcg_gen_extu_i32_i64(t64, t);
2793 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2794 tcg_temp_free_i64(t64);
2797 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2799 if (ctx->hflags & MIPS_HFLAG_F64) {
2800 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2802 gen_load_fpr32(ctx, t, reg | 1);
2806 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2808 if (ctx->hflags & MIPS_HFLAG_F64) {
2809 TCGv_i64 t64 = tcg_temp_new_i64();
2810 tcg_gen_extu_i32_i64(t64, t);
2811 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2812 tcg_temp_free_i64(t64);
2814 gen_store_fpr32(ctx, t, reg | 1);
2818 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2820 if (ctx->hflags & MIPS_HFLAG_F64) {
2821 tcg_gen_mov_i64(t, fpu_f64[reg]);
2823 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2827 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2829 if (ctx->hflags & MIPS_HFLAG_F64) {
2830 tcg_gen_mov_i64(fpu_f64[reg], t);
2833 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2834 t0 = tcg_temp_new_i64();
2835 tcg_gen_shri_i64(t0, t, 32);
2836 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2837 tcg_temp_free_i64(t0);
2841 static inline int get_fp_bit (int cc)
2849 /* Addresses computation */
2850 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2852 tcg_gen_add_tl(ret, arg0, arg1);
2854 #if defined(TARGET_MIPS64)
2855 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2856 tcg_gen_ext32s_i64(ret, ret);
2861 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2864 tcg_gen_addi_tl(ret, base, ofs);
2866 #if defined(TARGET_MIPS64)
2867 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2868 tcg_gen_ext32s_i64(ret, ret);
2873 /* Addresses computation (translation time) */
2874 static target_long addr_add(DisasContext *ctx, target_long base,
2877 target_long sum = base + offset;
2879 #if defined(TARGET_MIPS64)
2880 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2887 /* Sign-extract the low 32-bits to a target_long. */
2888 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2890 #if defined(TARGET_MIPS64)
2891 tcg_gen_ext32s_i64(ret, arg);
2893 tcg_gen_extrl_i64_i32(ret, arg);
2897 /* Sign-extract the high 32-bits to a target_long. */
2898 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2900 #if defined(TARGET_MIPS64)
2901 tcg_gen_sari_i64(ret, arg, 32);
2903 tcg_gen_extrh_i64_i32(ret, arg);
2907 static inline void check_cp0_enabled(DisasContext *ctx)
2909 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2910 generate_exception_err(ctx, EXCP_CpU, 0);
2913 static inline void check_cp1_enabled(DisasContext *ctx)
2915 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2916 generate_exception_err(ctx, EXCP_CpU, 1);
2919 /* Verify that the processor is running with COP1X instructions enabled.
2920 This is associated with the nabla symbol in the MIPS32 and MIPS64
2923 static inline void check_cop1x(DisasContext *ctx)
2925 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2926 generate_exception_end(ctx, EXCP_RI);
2929 /* Verify that the processor is running with 64-bit floating-point
2930 operations enabled. */
2932 static inline void check_cp1_64bitmode(DisasContext *ctx)
2934 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2935 generate_exception_end(ctx, EXCP_RI);
2939 * Verify if floating point register is valid; an operation is not defined
2940 * if bit 0 of any register specification is set and the FR bit in the
2941 * Status register equals zero, since the register numbers specify an
2942 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2943 * in the Status register equals one, both even and odd register numbers
2944 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2946 * Multiple 64 bit wide registers can be checked by calling
2947 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2949 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2951 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2952 generate_exception_end(ctx, EXCP_RI);
2955 /* Verify that the processor is running with DSP instructions enabled.
2956 This is enabled by CP0 Status register MX(24) bit.
2959 static inline void check_dsp(DisasContext *ctx)
2961 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2962 if (ctx->insn_flags & ASE_DSP) {
2963 generate_exception_end(ctx, EXCP_DSPDIS);
2965 generate_exception_end(ctx, EXCP_RI);
2970 static inline void check_dsp_r2(DisasContext *ctx)
2972 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2973 if (ctx->insn_flags & ASE_DSP) {
2974 generate_exception_end(ctx, EXCP_DSPDIS);
2976 generate_exception_end(ctx, EXCP_RI);
2981 static inline void check_dsp_r3(DisasContext *ctx)
2983 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2984 if (ctx->insn_flags & ASE_DSP) {
2985 generate_exception_end(ctx, EXCP_DSPDIS);
2987 generate_exception_end(ctx, EXCP_RI);
2992 /* This code generates a "reserved instruction" exception if the
2993 CPU does not support the instruction set corresponding to flags. */
2994 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2996 if (unlikely(!(ctx->insn_flags & flags))) {
2997 generate_exception_end(ctx, EXCP_RI);
3001 /* This code generates a "reserved instruction" exception if the
3002 CPU has corresponding flag set which indicates that the instruction
3003 has been removed. */
3004 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3006 if (unlikely(ctx->insn_flags & flags)) {
3007 generate_exception_end(ctx, EXCP_RI);
3012 * The Linux kernel traps certain reserved instruction exceptions to
3013 * emulate the corresponding instructions. QEMU is the kernel in user
3014 * mode, so those traps are emulated by accepting the instructions.
3016 * A reserved instruction exception is generated for flagged CPUs if
3017 * QEMU runs in system mode.
3019 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3021 #ifndef CONFIG_USER_ONLY
3022 check_insn_opc_removed(ctx, flags);
3026 /* This code generates a "reserved instruction" exception if the
3027 CPU does not support 64-bit paired-single (PS) floating point data type */
3028 static inline void check_ps(DisasContext *ctx)
3030 if (unlikely(!ctx->ps)) {
3031 generate_exception(ctx, EXCP_RI);
3033 check_cp1_64bitmode(ctx);
3036 #ifdef TARGET_MIPS64
3037 /* This code generates a "reserved instruction" exception if 64-bit
3038 instructions are not enabled. */
3039 static inline void check_mips_64(DisasContext *ctx)
3041 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
3042 generate_exception_end(ctx, EXCP_RI);
3046 #ifndef CONFIG_USER_ONLY
3047 static inline void check_mvh(DisasContext *ctx)
3049 if (unlikely(!ctx->mvh)) {
3050 generate_exception(ctx, EXCP_RI);
3056 * This code generates a "reserved instruction" exception if the
3057 * Config5 XNP bit is set.
3059 static inline void check_xnp(DisasContext *ctx)
3061 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3062 generate_exception_end(ctx, EXCP_RI);
3066 #ifndef CONFIG_USER_ONLY
3068 * This code generates a "reserved instruction" exception if the
3069 * Config3 PW bit is NOT set.
3071 static inline void check_pw(DisasContext *ctx)
3073 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3074 generate_exception_end(ctx, EXCP_RI);
3080 * This code generates a "reserved instruction" exception if the
3081 * Config3 MT bit is NOT set.
3083 static inline void check_mt(DisasContext *ctx)
3085 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3086 generate_exception_end(ctx, EXCP_RI);
3090 #ifndef CONFIG_USER_ONLY
3092 * This code generates a "coprocessor unusable" exception if CP0 is not
3093 * available, and, if that is not the case, generates a "reserved instruction"
3094 * exception if the Config5 MT bit is NOT set. This is needed for availability
3095 * control of some of MT ASE instructions.
3097 static inline void check_cp0_mt(DisasContext *ctx)
3099 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3100 generate_exception_err(ctx, EXCP_CpU, 0);
3102 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3103 generate_exception_err(ctx, EXCP_RI, 0);
3110 * This code generates a "reserved instruction" exception if the
3111 * Config5 NMS bit is set.
3113 static inline void check_nms(DisasContext *ctx)
3115 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3116 generate_exception_end(ctx, EXCP_RI);
3121 * This code generates a "reserved instruction" exception if the
3122 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3123 * Config2 TL, and Config5 L2C are unset.
3125 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3127 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3128 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3129 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3130 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3131 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3132 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3134 generate_exception_end(ctx, EXCP_RI);
3139 * This code generates a "reserved instruction" exception if the
3140 * Config5 EVA bit is NOT set.
3142 static inline void check_eva(DisasContext *ctx)
3144 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3145 generate_exception_end(ctx, EXCP_RI);
3150 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3151 calling interface for 32 and 64-bit FPRs. No sense in changing
3152 all callers for gen_load_fpr32 when we need the CTX parameter for
3154 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3155 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3156 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3157 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3158 int ft, int fs, int cc) \
3160 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3161 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3170 check_cp1_registers(ctx, fs | ft); \
3178 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3179 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3181 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3182 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3183 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3184 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3185 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3186 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3187 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3188 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3189 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3190 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3191 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3192 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3193 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3194 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3195 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3196 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
3199 tcg_temp_free_i##bits (fp0); \
3200 tcg_temp_free_i##bits (fp1); \
3203 FOP_CONDS(, 0, d, FMT_D, 64)
3204 FOP_CONDS(abs, 1, d, FMT_D, 64)
3205 FOP_CONDS(, 0, s, FMT_S, 32)
3206 FOP_CONDS(abs, 1, s, FMT_S, 32)
3207 FOP_CONDS(, 0, ps, FMT_PS, 64)
3208 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3211 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3212 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3213 int ft, int fs, int fd) \
3215 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3216 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3217 if (ifmt == FMT_D) { \
3218 check_cp1_registers(ctx, fs | ft | fd); \
3220 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3221 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3224 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3227 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3230 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3233 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3236 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3239 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3242 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3245 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3248 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3251 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3254 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3257 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3260 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3263 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3266 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3269 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3272 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3275 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3278 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3281 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3284 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3287 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3293 tcg_temp_free_i ## bits (fp0); \
3294 tcg_temp_free_i ## bits (fp1); \
3297 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3298 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3300 #undef gen_ldcmp_fpr32
3301 #undef gen_ldcmp_fpr64
3303 /* load/store instructions. */
3304 #ifdef CONFIG_USER_ONLY
3305 #define OP_LD_ATOMIC(insn,fname) \
3306 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3307 DisasContext *ctx) \
3309 TCGv t0 = tcg_temp_new(); \
3310 tcg_gen_mov_tl(t0, arg1); \
3311 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3312 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3313 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3314 tcg_temp_free(t0); \
3317 #define OP_LD_ATOMIC(insn,fname) \
3318 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3319 DisasContext *ctx) \
3321 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3324 OP_LD_ATOMIC(ll,ld32s);
3325 #if defined(TARGET_MIPS64)
3326 OP_LD_ATOMIC(lld,ld64);
3330 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3331 int base, int offset)
3334 tcg_gen_movi_tl(addr, offset);
3335 } else if (offset == 0) {
3336 gen_load_gpr(addr, base);
3338 tcg_gen_movi_tl(addr, offset);
3339 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3343 static target_ulong pc_relative_pc (DisasContext *ctx)
3345 target_ulong pc = ctx->base.pc_next;
3347 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3348 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3353 pc &= ~(target_ulong)3;
3358 static void gen_ld(DisasContext *ctx, uint32_t opc,
3359 int rt, int base, int offset)
3362 int mem_idx = ctx->mem_idx;
3364 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3365 /* Loongson CPU uses a load to zero register for prefetch.
3366 We emulate it as a NOP. On other CPU we must perform the
3367 actual memory access. */
3371 t0 = tcg_temp_new();
3372 gen_base_offset_addr(ctx, t0, base, offset);
3375 #if defined(TARGET_MIPS64)
3377 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3378 ctx->default_tcg_memop_mask);
3379 gen_store_gpr(t0, rt);
3382 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3383 ctx->default_tcg_memop_mask);
3384 gen_store_gpr(t0, rt);
3388 op_ld_lld(t0, t0, mem_idx, ctx);
3389 gen_store_gpr(t0, rt);
3392 t1 = tcg_temp_new();
3393 /* Do a byte access to possibly trigger a page
3394 fault with the unaligned address. */
3395 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3396 tcg_gen_andi_tl(t1, t0, 7);
3397 #ifndef TARGET_WORDS_BIGENDIAN
3398 tcg_gen_xori_tl(t1, t1, 7);
3400 tcg_gen_shli_tl(t1, t1, 3);
3401 tcg_gen_andi_tl(t0, t0, ~7);
3402 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3403 tcg_gen_shl_tl(t0, t0, t1);
3404 t2 = tcg_const_tl(-1);
3405 tcg_gen_shl_tl(t2, t2, t1);
3406 gen_load_gpr(t1, rt);
3407 tcg_gen_andc_tl(t1, t1, t2);
3409 tcg_gen_or_tl(t0, t0, t1);
3411 gen_store_gpr(t0, rt);
3414 t1 = tcg_temp_new();
3415 /* Do a byte access to possibly trigger a page
3416 fault with the unaligned address. */
3417 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3418 tcg_gen_andi_tl(t1, t0, 7);
3419 #ifdef TARGET_WORDS_BIGENDIAN
3420 tcg_gen_xori_tl(t1, t1, 7);
3422 tcg_gen_shli_tl(t1, t1, 3);
3423 tcg_gen_andi_tl(t0, t0, ~7);
3424 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3425 tcg_gen_shr_tl(t0, t0, t1);
3426 tcg_gen_xori_tl(t1, t1, 63);
3427 t2 = tcg_const_tl(0xfffffffffffffffeull);
3428 tcg_gen_shl_tl(t2, t2, t1);
3429 gen_load_gpr(t1, rt);
3430 tcg_gen_and_tl(t1, t1, t2);
3432 tcg_gen_or_tl(t0, t0, t1);
3434 gen_store_gpr(t0, rt);
3437 t1 = tcg_const_tl(pc_relative_pc(ctx));
3438 gen_op_addr_add(ctx, t0, t0, t1);
3440 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3441 gen_store_gpr(t0, rt);
3445 t1 = tcg_const_tl(pc_relative_pc(ctx));
3446 gen_op_addr_add(ctx, t0, t0, t1);
3448 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3449 gen_store_gpr(t0, rt);
3452 mem_idx = MIPS_HFLAG_UM;
3455 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3456 ctx->default_tcg_memop_mask);
3457 gen_store_gpr(t0, rt);
3460 mem_idx = MIPS_HFLAG_UM;
3463 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3464 ctx->default_tcg_memop_mask);
3465 gen_store_gpr(t0, rt);
3468 mem_idx = MIPS_HFLAG_UM;
3471 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3472 ctx->default_tcg_memop_mask);
3473 gen_store_gpr(t0, rt);
3476 mem_idx = MIPS_HFLAG_UM;
3479 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3480 gen_store_gpr(t0, rt);
3483 mem_idx = MIPS_HFLAG_UM;
3486 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3487 gen_store_gpr(t0, rt);
3490 mem_idx = MIPS_HFLAG_UM;
3493 t1 = tcg_temp_new();
3494 /* Do a byte access to possibly trigger a page
3495 fault with the unaligned address. */
3496 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3497 tcg_gen_andi_tl(t1, t0, 3);
3498 #ifndef TARGET_WORDS_BIGENDIAN
3499 tcg_gen_xori_tl(t1, t1, 3);
3501 tcg_gen_shli_tl(t1, t1, 3);
3502 tcg_gen_andi_tl(t0, t0, ~3);
3503 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3504 tcg_gen_shl_tl(t0, t0, t1);
3505 t2 = tcg_const_tl(-1);
3506 tcg_gen_shl_tl(t2, t2, t1);
3507 gen_load_gpr(t1, rt);
3508 tcg_gen_andc_tl(t1, t1, t2);
3510 tcg_gen_or_tl(t0, t0, t1);
3512 tcg_gen_ext32s_tl(t0, t0);
3513 gen_store_gpr(t0, rt);
3516 mem_idx = MIPS_HFLAG_UM;
3519 t1 = tcg_temp_new();
3520 /* Do a byte access to possibly trigger a page
3521 fault with the unaligned address. */
3522 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3523 tcg_gen_andi_tl(t1, t0, 3);
3524 #ifdef TARGET_WORDS_BIGENDIAN
3525 tcg_gen_xori_tl(t1, t1, 3);
3527 tcg_gen_shli_tl(t1, t1, 3);
3528 tcg_gen_andi_tl(t0, t0, ~3);
3529 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3530 tcg_gen_shr_tl(t0, t0, t1);
3531 tcg_gen_xori_tl(t1, t1, 31);
3532 t2 = tcg_const_tl(0xfffffffeull);
3533 tcg_gen_shl_tl(t2, t2, t1);
3534 gen_load_gpr(t1, rt);
3535 tcg_gen_and_tl(t1, t1, t2);
3537 tcg_gen_or_tl(t0, t0, t1);
3539 tcg_gen_ext32s_tl(t0, t0);
3540 gen_store_gpr(t0, rt);
3543 mem_idx = MIPS_HFLAG_UM;
3547 op_ld_ll(t0, t0, mem_idx, ctx);
3548 gen_store_gpr(t0, rt);
3554 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3555 uint32_t reg1, uint32_t reg2)
3557 TCGv taddr = tcg_temp_new();
3558 TCGv_i64 tval = tcg_temp_new_i64();
3559 TCGv tmp1 = tcg_temp_new();
3560 TCGv tmp2 = tcg_temp_new();
3562 gen_base_offset_addr(ctx, taddr, base, offset);
3563 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3564 #ifdef TARGET_WORDS_BIGENDIAN
3565 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3567 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3569 gen_store_gpr(tmp1, reg1);
3570 tcg_temp_free(tmp1);
3571 gen_store_gpr(tmp2, reg2);
3572 tcg_temp_free(tmp2);
3573 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3574 tcg_temp_free_i64(tval);
3575 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3576 tcg_temp_free(taddr);
3580 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3581 int base, int offset)
3583 TCGv t0 = tcg_temp_new();
3584 TCGv t1 = tcg_temp_new();
3585 int mem_idx = ctx->mem_idx;
3587 gen_base_offset_addr(ctx, t0, base, offset);
3588 gen_load_gpr(t1, rt);
3590 #if defined(TARGET_MIPS64)
3592 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3593 ctx->default_tcg_memop_mask);
3596 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3599 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3603 mem_idx = MIPS_HFLAG_UM;
3606 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3607 ctx->default_tcg_memop_mask);
3610 mem_idx = MIPS_HFLAG_UM;
3613 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3614 ctx->default_tcg_memop_mask);
3617 mem_idx = MIPS_HFLAG_UM;
3620 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3623 mem_idx = MIPS_HFLAG_UM;
3626 gen_helper_0e2i(swl, t1, t0, mem_idx);
3629 mem_idx = MIPS_HFLAG_UM;
3632 gen_helper_0e2i(swr, t1, t0, mem_idx);
3640 /* Store conditional */
3641 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3642 TCGMemOp tcg_mo, bool eva)
3645 TCGLabel *l1 = gen_new_label();
3646 TCGLabel *done = gen_new_label();
3648 t0 = tcg_temp_new();
3649 addr = tcg_temp_new();
3650 /* compare the address against that of the preceeding LL */
3651 gen_base_offset_addr(ctx, addr, base, offset);
3652 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3653 tcg_temp_free(addr);
3654 tcg_gen_movi_tl(t0, 0);
3655 gen_store_gpr(t0, rt);
3659 /* generate cmpxchg */
3660 val = tcg_temp_new();
3661 gen_load_gpr(val, rt);
3662 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3663 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3664 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3665 gen_store_gpr(t0, rt);
3668 gen_set_label(done);
3673 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3674 uint32_t reg1, uint32_t reg2, bool eva)
3676 TCGv taddr = tcg_temp_local_new();
3677 TCGv lladdr = tcg_temp_local_new();
3678 TCGv_i64 tval = tcg_temp_new_i64();
3679 TCGv_i64 llval = tcg_temp_new_i64();
3680 TCGv_i64 val = tcg_temp_new_i64();
3681 TCGv tmp1 = tcg_temp_new();
3682 TCGv tmp2 = tcg_temp_new();
3683 TCGLabel *lab_fail = gen_new_label();
3684 TCGLabel *lab_done = gen_new_label();
3686 gen_base_offset_addr(ctx, taddr, base, offset);
3688 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3689 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3691 gen_load_gpr(tmp1, reg1);
3692 gen_load_gpr(tmp2, reg2);
3694 #ifdef TARGET_WORDS_BIGENDIAN
3695 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3697 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3700 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3701 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3702 eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3704 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3706 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3708 gen_set_label(lab_fail);
3711 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3713 gen_set_label(lab_done);
3714 tcg_gen_movi_tl(lladdr, -1);
3715 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3718 /* Load and store */
3719 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3722 /* Don't do NOP if destination is zero: we must perform the actual
3727 TCGv_i32 fp0 = tcg_temp_new_i32();
3728 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3729 ctx->default_tcg_memop_mask);
3730 gen_store_fpr32(ctx, fp0, ft);
3731 tcg_temp_free_i32(fp0);
3736 TCGv_i32 fp0 = tcg_temp_new_i32();
3737 gen_load_fpr32(ctx, fp0, ft);
3738 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3739 ctx->default_tcg_memop_mask);
3740 tcg_temp_free_i32(fp0);
3745 TCGv_i64 fp0 = tcg_temp_new_i64();
3746 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3747 ctx->default_tcg_memop_mask);
3748 gen_store_fpr64(ctx, fp0, ft);
3749 tcg_temp_free_i64(fp0);
3754 TCGv_i64 fp0 = tcg_temp_new_i64();
3755 gen_load_fpr64(ctx, fp0, ft);
3756 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3757 ctx->default_tcg_memop_mask);
3758 tcg_temp_free_i64(fp0);
3762 MIPS_INVAL("flt_ldst");
3763 generate_exception_end(ctx, EXCP_RI);
3768 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3769 int rs, int16_t imm)
3771 TCGv t0 = tcg_temp_new();
3773 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3774 check_cp1_enabled(ctx);
3778 check_insn(ctx, ISA_MIPS2);
3781 gen_base_offset_addr(ctx, t0, rs, imm);
3782 gen_flt_ldst(ctx, op, rt, t0);
3785 generate_exception_err(ctx, EXCP_CpU, 1);
3790 /* Arithmetic with immediate operand */
3791 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3792 int rt, int rs, int imm)
3794 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3796 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3797 /* If no destination, treat it as a NOP.
3798 For addi, we must generate the overflow exception when needed. */
3804 TCGv t0 = tcg_temp_local_new();
3805 TCGv t1 = tcg_temp_new();
3806 TCGv t2 = tcg_temp_new();
3807 TCGLabel *l1 = gen_new_label();
3809 gen_load_gpr(t1, rs);
3810 tcg_gen_addi_tl(t0, t1, uimm);
3811 tcg_gen_ext32s_tl(t0, t0);
3813 tcg_gen_xori_tl(t1, t1, ~uimm);
3814 tcg_gen_xori_tl(t2, t0, uimm);
3815 tcg_gen_and_tl(t1, t1, t2);
3817 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3819 /* operands of same sign, result different sign */
3820 generate_exception(ctx, EXCP_OVERFLOW);
3822 tcg_gen_ext32s_tl(t0, t0);
3823 gen_store_gpr(t0, rt);
3829 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3830 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3832 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3835 #if defined(TARGET_MIPS64)
3838 TCGv t0 = tcg_temp_local_new();
3839 TCGv t1 = tcg_temp_new();
3840 TCGv t2 = tcg_temp_new();
3841 TCGLabel *l1 = gen_new_label();
3843 gen_load_gpr(t1, rs);
3844 tcg_gen_addi_tl(t0, t1, uimm);
3846 tcg_gen_xori_tl(t1, t1, ~uimm);
3847 tcg_gen_xori_tl(t2, t0, uimm);
3848 tcg_gen_and_tl(t1, t1, t2);
3850 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3852 /* operands of same sign, result different sign */
3853 generate_exception(ctx, EXCP_OVERFLOW);
3855 gen_store_gpr(t0, rt);
3861 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3863 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3870 /* Logic with immediate operand */
3871 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3872 int rt, int rs, int16_t imm)
3877 /* If no destination, treat it as a NOP. */
3880 uimm = (uint16_t)imm;
3883 if (likely(rs != 0))
3884 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3886 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3890 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3892 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3895 if (likely(rs != 0))
3896 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3898 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3901 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3903 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3904 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3906 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3915 /* Set on less than with immediate operand */
3916 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3917 int rt, int rs, int16_t imm)
3919 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3923 /* If no destination, treat it as a NOP. */
3926 t0 = tcg_temp_new();
3927 gen_load_gpr(t0, rs);
3930 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3933 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3939 /* Shifts with immediate operand */
3940 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3941 int rt, int rs, int16_t imm)
3943 target_ulong uimm = ((uint16_t)imm) & 0x1f;
3947 /* If no destination, treat it as a NOP. */
3951 t0 = tcg_temp_new();
3952 gen_load_gpr(t0, rs);
3955 tcg_gen_shli_tl(t0, t0, uimm);
3956 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3959 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3963 tcg_gen_ext32u_tl(t0, t0);
3964 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3966 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3971 TCGv_i32 t1 = tcg_temp_new_i32();
3973 tcg_gen_trunc_tl_i32(t1, t0);
3974 tcg_gen_rotri_i32(t1, t1, uimm);
3975 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3976 tcg_temp_free_i32(t1);
3978 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3981 #if defined(TARGET_MIPS64)
3983 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3986 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3989 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3993 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3995 tcg_gen_mov_tl(cpu_gpr[rt], t0);
3999 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4002 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4005 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4008 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4016 static void gen_arith(DisasContext *ctx, uint32_t opc,
4017 int rd, int rs, int rt)
4019 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4020 && opc != OPC_DADD && opc != OPC_DSUB) {
4021 /* If no destination, treat it as a NOP.
4022 For add & sub, we must generate the overflow exception when needed. */
4029 TCGv t0 = tcg_temp_local_new();
4030 TCGv t1 = tcg_temp_new();
4031 TCGv t2 = tcg_temp_new();
4032 TCGLabel *l1 = gen_new_label();
4034 gen_load_gpr(t1, rs);
4035 gen_load_gpr(t2, rt);
4036 tcg_gen_add_tl(t0, t1, t2);
4037 tcg_gen_ext32s_tl(t0, t0);
4038 tcg_gen_xor_tl(t1, t1, t2);
4039 tcg_gen_xor_tl(t2, t0, t2);
4040 tcg_gen_andc_tl(t1, t2, t1);
4042 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4044 /* operands of same sign, result different sign */
4045 generate_exception(ctx, EXCP_OVERFLOW);
4047 gen_store_gpr(t0, rd);
4052 if (rs != 0 && rt != 0) {
4053 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4054 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4055 } else if (rs == 0 && rt != 0) {
4056 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4057 } else if (rs != 0 && rt == 0) {
4058 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4060 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4065 TCGv t0 = tcg_temp_local_new();
4066 TCGv t1 = tcg_temp_new();
4067 TCGv t2 = tcg_temp_new();
4068 TCGLabel *l1 = gen_new_label();
4070 gen_load_gpr(t1, rs);
4071 gen_load_gpr(t2, rt);
4072 tcg_gen_sub_tl(t0, t1, t2);
4073 tcg_gen_ext32s_tl(t0, t0);
4074 tcg_gen_xor_tl(t2, t1, t2);
4075 tcg_gen_xor_tl(t1, t0, t1);
4076 tcg_gen_and_tl(t1, t1, t2);
4078 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4080 /* operands of different sign, first operand and result different sign */
4081 generate_exception(ctx, EXCP_OVERFLOW);
4083 gen_store_gpr(t0, rd);
4088 if (rs != 0 && rt != 0) {
4089 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4090 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4091 } else if (rs == 0 && rt != 0) {
4092 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4093 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4094 } else if (rs != 0 && rt == 0) {
4095 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4097 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4100 #if defined(TARGET_MIPS64)
4103 TCGv t0 = tcg_temp_local_new();
4104 TCGv t1 = tcg_temp_new();
4105 TCGv t2 = tcg_temp_new();
4106 TCGLabel *l1 = gen_new_label();
4108 gen_load_gpr(t1, rs);
4109 gen_load_gpr(t2, rt);
4110 tcg_gen_add_tl(t0, t1, t2);
4111 tcg_gen_xor_tl(t1, t1, t2);
4112 tcg_gen_xor_tl(t2, t0, t2);
4113 tcg_gen_andc_tl(t1, t2, t1);
4115 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4117 /* operands of same sign, result different sign */
4118 generate_exception(ctx, EXCP_OVERFLOW);
4120 gen_store_gpr(t0, rd);
4125 if (rs != 0 && rt != 0) {
4126 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4127 } else if (rs == 0 && rt != 0) {
4128 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4129 } else if (rs != 0 && rt == 0) {
4130 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4132 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4137 TCGv t0 = tcg_temp_local_new();
4138 TCGv t1 = tcg_temp_new();
4139 TCGv t2 = tcg_temp_new();
4140 TCGLabel *l1 = gen_new_label();
4142 gen_load_gpr(t1, rs);
4143 gen_load_gpr(t2, rt);
4144 tcg_gen_sub_tl(t0, t1, t2);
4145 tcg_gen_xor_tl(t2, t1, t2);
4146 tcg_gen_xor_tl(t1, t0, t1);
4147 tcg_gen_and_tl(t1, t1, t2);
4149 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4151 /* operands of different sign, first operand and result different sign */
4152 generate_exception(ctx, EXCP_OVERFLOW);
4154 gen_store_gpr(t0, rd);
4159 if (rs != 0 && rt != 0) {
4160 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4161 } else if (rs == 0 && rt != 0) {
4162 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4163 } else if (rs != 0 && rt == 0) {
4164 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4166 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4171 if (likely(rs != 0 && rt != 0)) {
4172 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4173 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4175 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4181 /* Conditional move */
4182 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4183 int rd, int rs, int rt)
4188 /* If no destination, treat it as a NOP. */
4192 t0 = tcg_temp_new();
4193 gen_load_gpr(t0, rt);
4194 t1 = tcg_const_tl(0);
4195 t2 = tcg_temp_new();
4196 gen_load_gpr(t2, rs);
4199 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4202 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4205 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4208 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4217 static void gen_logic(DisasContext *ctx, uint32_t opc,
4218 int rd, int rs, int rt)
4221 /* If no destination, treat it as a NOP. */
4227 if (likely(rs != 0 && rt != 0)) {
4228 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4230 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4234 if (rs != 0 && rt != 0) {
4235 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4236 } else if (rs == 0 && rt != 0) {
4237 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4238 } else if (rs != 0 && rt == 0) {
4239 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4241 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4245 if (likely(rs != 0 && rt != 0)) {
4246 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4247 } else if (rs == 0 && rt != 0) {
4248 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4249 } else if (rs != 0 && rt == 0) {
4250 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4252 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4256 if (likely(rs != 0 && rt != 0)) {
4257 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4258 } else if (rs == 0 && rt != 0) {
4259 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4260 } else if (rs != 0 && rt == 0) {
4261 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4263 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4269 /* Set on lower than */
4270 static void gen_slt(DisasContext *ctx, uint32_t opc,
4271 int rd, int rs, int rt)
4276 /* If no destination, treat it as a NOP. */
4280 t0 = tcg_temp_new();
4281 t1 = tcg_temp_new();
4282 gen_load_gpr(t0, rs);
4283 gen_load_gpr(t1, rt);
4286 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4289 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4297 static void gen_shift(DisasContext *ctx, uint32_t opc,
4298 int rd, int rs, int rt)
4303 /* If no destination, treat it as a NOP.
4304 For add & sub, we must generate the overflow exception when needed. */
4308 t0 = tcg_temp_new();
4309 t1 = tcg_temp_new();
4310 gen_load_gpr(t0, rs);
4311 gen_load_gpr(t1, rt);
4314 tcg_gen_andi_tl(t0, t0, 0x1f);
4315 tcg_gen_shl_tl(t0, t1, t0);
4316 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4319 tcg_gen_andi_tl(t0, t0, 0x1f);
4320 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4323 tcg_gen_ext32u_tl(t1, t1);
4324 tcg_gen_andi_tl(t0, t0, 0x1f);
4325 tcg_gen_shr_tl(t0, t1, t0);
4326 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4330 TCGv_i32 t2 = tcg_temp_new_i32();
4331 TCGv_i32 t3 = tcg_temp_new_i32();
4333 tcg_gen_trunc_tl_i32(t2, t0);
4334 tcg_gen_trunc_tl_i32(t3, t1);
4335 tcg_gen_andi_i32(t2, t2, 0x1f);
4336 tcg_gen_rotr_i32(t2, t3, t2);
4337 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4338 tcg_temp_free_i32(t2);
4339 tcg_temp_free_i32(t3);
4342 #if defined(TARGET_MIPS64)
4344 tcg_gen_andi_tl(t0, t0, 0x3f);
4345 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4348 tcg_gen_andi_tl(t0, t0, 0x3f);
4349 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4352 tcg_gen_andi_tl(t0, t0, 0x3f);
4353 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4356 tcg_gen_andi_tl(t0, t0, 0x3f);
4357 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4365 #if defined(TARGET_MIPS64)
4366 /* Copy GPR to and from TX79 HI1/LO1 register. */
4367 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4369 if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4376 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4379 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4383 tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4385 tcg_gen_movi_tl(cpu_HI[1], 0);
4390 tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4392 tcg_gen_movi_tl(cpu_LO[1], 0);
4396 MIPS_INVAL("mfthilo1 TX79");
4397 generate_exception_end(ctx, EXCP_RI);
4403 /* Arithmetic on HI/LO registers */
4404 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4406 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4417 #if defined(TARGET_MIPS64)
4419 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4423 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4427 #if defined(TARGET_MIPS64)
4429 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4433 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4438 #if defined(TARGET_MIPS64)
4440 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4444 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4447 tcg_gen_movi_tl(cpu_HI[acc], 0);
4452 #if defined(TARGET_MIPS64)
4454 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4458 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4461 tcg_gen_movi_tl(cpu_LO[acc], 0);
4467 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4470 TCGv t0 = tcg_const_tl(addr);
4471 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4472 gen_store_gpr(t0, reg);
4476 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4482 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4485 offset = sextract32(ctx->opcode << 2, 0, 21);
4486 addr = addr_add(ctx, pc, offset);
4487 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4491 offset = sextract32(ctx->opcode << 2, 0, 21);
4492 addr = addr_add(ctx, pc, offset);
4493 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4495 #if defined(TARGET_MIPS64)
4498 offset = sextract32(ctx->opcode << 2, 0, 21);
4499 addr = addr_add(ctx, pc, offset);
4500 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4504 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4507 offset = sextract32(ctx->opcode, 0, 16) << 16;
4508 addr = addr_add(ctx, pc, offset);
4509 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4514 offset = sextract32(ctx->opcode, 0, 16) << 16;
4515 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4516 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4519 #if defined(TARGET_MIPS64)
4520 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4521 case R6_OPC_LDPC + (1 << 16):
4522 case R6_OPC_LDPC + (2 << 16):
4523 case R6_OPC_LDPC + (3 << 16):
4525 offset = sextract32(ctx->opcode << 3, 0, 21);
4526 addr = addr_add(ctx, (pc & ~0x7), offset);
4527 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4531 MIPS_INVAL("OPC_PCREL");
4532 generate_exception_end(ctx, EXCP_RI);
4539 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4548 t0 = tcg_temp_new();
4549 t1 = tcg_temp_new();
4551 gen_load_gpr(t0, rs);
4552 gen_load_gpr(t1, rt);
4557 TCGv t2 = tcg_temp_new();
4558 TCGv t3 = tcg_temp_new();
4559 tcg_gen_ext32s_tl(t0, t0);
4560 tcg_gen_ext32s_tl(t1, t1);
4561 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4562 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4563 tcg_gen_and_tl(t2, t2, t3);
4564 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4565 tcg_gen_or_tl(t2, t2, t3);
4566 tcg_gen_movi_tl(t3, 0);
4567 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4568 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4569 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4576 TCGv t2 = tcg_temp_new();
4577 TCGv t3 = tcg_temp_new();
4578 tcg_gen_ext32s_tl(t0, t0);
4579 tcg_gen_ext32s_tl(t1, t1);
4580 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4581 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4582 tcg_gen_and_tl(t2, t2, t3);
4583 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4584 tcg_gen_or_tl(t2, t2, t3);
4585 tcg_gen_movi_tl(t3, 0);
4586 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4587 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4588 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4595 TCGv t2 = tcg_const_tl(0);
4596 TCGv t3 = tcg_const_tl(1);
4597 tcg_gen_ext32u_tl(t0, t0);
4598 tcg_gen_ext32u_tl(t1, t1);
4599 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4600 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4601 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4608 TCGv t2 = tcg_const_tl(0);
4609 TCGv t3 = tcg_const_tl(1);
4610 tcg_gen_ext32u_tl(t0, t0);
4611 tcg_gen_ext32u_tl(t1, t1);
4612 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4613 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4614 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4621 TCGv_i32 t2 = tcg_temp_new_i32();
4622 TCGv_i32 t3 = tcg_temp_new_i32();
4623 tcg_gen_trunc_tl_i32(t2, t0);
4624 tcg_gen_trunc_tl_i32(t3, t1);
4625 tcg_gen_mul_i32(t2, t2, t3);
4626 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4627 tcg_temp_free_i32(t2);
4628 tcg_temp_free_i32(t3);
4633 TCGv_i32 t2 = tcg_temp_new_i32();
4634 TCGv_i32 t3 = tcg_temp_new_i32();
4635 tcg_gen_trunc_tl_i32(t2, t0);
4636 tcg_gen_trunc_tl_i32(t3, t1);
4637 tcg_gen_muls2_i32(t2, t3, t2, t3);
4638 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4639 tcg_temp_free_i32(t2);
4640 tcg_temp_free_i32(t3);
4645 TCGv_i32 t2 = tcg_temp_new_i32();
4646 TCGv_i32 t3 = tcg_temp_new_i32();
4647 tcg_gen_trunc_tl_i32(t2, t0);
4648 tcg_gen_trunc_tl_i32(t3, t1);
4649 tcg_gen_mul_i32(t2, t2, t3);
4650 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4651 tcg_temp_free_i32(t2);
4652 tcg_temp_free_i32(t3);
4657 TCGv_i32 t2 = tcg_temp_new_i32();
4658 TCGv_i32 t3 = tcg_temp_new_i32();
4659 tcg_gen_trunc_tl_i32(t2, t0);
4660 tcg_gen_trunc_tl_i32(t3, t1);
4661 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4662 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4663 tcg_temp_free_i32(t2);
4664 tcg_temp_free_i32(t3);
4667 #if defined(TARGET_MIPS64)
4670 TCGv t2 = tcg_temp_new();
4671 TCGv t3 = tcg_temp_new();
4672 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4673 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4674 tcg_gen_and_tl(t2, t2, t3);
4675 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4676 tcg_gen_or_tl(t2, t2, t3);
4677 tcg_gen_movi_tl(t3, 0);
4678 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4679 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4686 TCGv t2 = tcg_temp_new();
4687 TCGv t3 = tcg_temp_new();
4688 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4689 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4690 tcg_gen_and_tl(t2, t2, t3);
4691 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4692 tcg_gen_or_tl(t2, t2, t3);
4693 tcg_gen_movi_tl(t3, 0);
4694 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4695 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4702 TCGv t2 = tcg_const_tl(0);
4703 TCGv t3 = tcg_const_tl(1);
4704 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4705 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4712 TCGv t2 = tcg_const_tl(0);
4713 TCGv t3 = tcg_const_tl(1);
4714 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4715 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4721 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4725 TCGv t2 = tcg_temp_new();
4726 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4731 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4735 TCGv t2 = tcg_temp_new();
4736 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4742 MIPS_INVAL("r6 mul/div");
4743 generate_exception_end(ctx, EXCP_RI);
4751 #if defined(TARGET_MIPS64)
4752 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4756 t0 = tcg_temp_new();
4757 t1 = tcg_temp_new();
4759 gen_load_gpr(t0, rs);
4760 gen_load_gpr(t1, rt);
4765 TCGv t2 = tcg_temp_new();
4766 TCGv t3 = tcg_temp_new();
4767 tcg_gen_ext32s_tl(t0, t0);
4768 tcg_gen_ext32s_tl(t1, t1);
4769 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4770 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4771 tcg_gen_and_tl(t2, t2, t3);
4772 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4773 tcg_gen_or_tl(t2, t2, t3);
4774 tcg_gen_movi_tl(t3, 0);
4775 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4776 tcg_gen_div_tl(cpu_LO[1], t0, t1);
4777 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4778 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4779 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4786 TCGv t2 = tcg_const_tl(0);
4787 TCGv t3 = tcg_const_tl(1);
4788 tcg_gen_ext32u_tl(t0, t0);
4789 tcg_gen_ext32u_tl(t1, t1);
4790 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4791 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4792 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4793 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4794 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4800 MIPS_INVAL("div1 TX79");
4801 generate_exception_end(ctx, EXCP_RI);
4810 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4811 int acc, int rs, int rt)
4815 t0 = tcg_temp_new();
4816 t1 = tcg_temp_new();
4818 gen_load_gpr(t0, rs);
4819 gen_load_gpr(t1, rt);
4828 TCGv t2 = tcg_temp_new();
4829 TCGv t3 = tcg_temp_new();
4830 tcg_gen_ext32s_tl(t0, t0);
4831 tcg_gen_ext32s_tl(t1, t1);
4832 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4833 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4834 tcg_gen_and_tl(t2, t2, t3);
4835 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4836 tcg_gen_or_tl(t2, t2, t3);
4837 tcg_gen_movi_tl(t3, 0);
4838 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4839 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4840 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4841 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4842 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4849 TCGv t2 = tcg_const_tl(0);
4850 TCGv t3 = tcg_const_tl(1);
4851 tcg_gen_ext32u_tl(t0, t0);
4852 tcg_gen_ext32u_tl(t1, t1);
4853 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4854 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4855 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4856 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4857 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4864 TCGv_i32 t2 = tcg_temp_new_i32();
4865 TCGv_i32 t3 = tcg_temp_new_i32();
4866 tcg_gen_trunc_tl_i32(t2, t0);
4867 tcg_gen_trunc_tl_i32(t3, t1);
4868 tcg_gen_muls2_i32(t2, t3, t2, t3);
4869 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4870 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4871 tcg_temp_free_i32(t2);
4872 tcg_temp_free_i32(t3);
4877 TCGv_i32 t2 = tcg_temp_new_i32();
4878 TCGv_i32 t3 = tcg_temp_new_i32();
4879 tcg_gen_trunc_tl_i32(t2, t0);
4880 tcg_gen_trunc_tl_i32(t3, t1);
4881 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4882 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4883 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4884 tcg_temp_free_i32(t2);
4885 tcg_temp_free_i32(t3);
4888 #if defined(TARGET_MIPS64)
4891 TCGv t2 = tcg_temp_new();
4892 TCGv t3 = tcg_temp_new();
4893 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4894 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4895 tcg_gen_and_tl(t2, t2, t3);
4896 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4897 tcg_gen_or_tl(t2, t2, t3);
4898 tcg_gen_movi_tl(t3, 0);
4899 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4900 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4901 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4908 TCGv t2 = tcg_const_tl(0);
4909 TCGv t3 = tcg_const_tl(1);
4910 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4911 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4912 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4918 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4921 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4926 TCGv_i64 t2 = tcg_temp_new_i64();
4927 TCGv_i64 t3 = tcg_temp_new_i64();
4929 tcg_gen_ext_tl_i64(t2, t0);
4930 tcg_gen_ext_tl_i64(t3, t1);
4931 tcg_gen_mul_i64(t2, t2, t3);
4932 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4933 tcg_gen_add_i64(t2, t2, t3);
4934 tcg_temp_free_i64(t3);
4935 gen_move_low32(cpu_LO[acc], t2);
4936 gen_move_high32(cpu_HI[acc], t2);
4937 tcg_temp_free_i64(t2);
4942 TCGv_i64 t2 = tcg_temp_new_i64();
4943 TCGv_i64 t3 = tcg_temp_new_i64();
4945 tcg_gen_ext32u_tl(t0, t0);
4946 tcg_gen_ext32u_tl(t1, t1);
4947 tcg_gen_extu_tl_i64(t2, t0);
4948 tcg_gen_extu_tl_i64(t3, t1);
4949 tcg_gen_mul_i64(t2, t2, t3);
4950 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4951 tcg_gen_add_i64(t2, t2, t3);
4952 tcg_temp_free_i64(t3);
4953 gen_move_low32(cpu_LO[acc], t2);
4954 gen_move_high32(cpu_HI[acc], t2);
4955 tcg_temp_free_i64(t2);
4960 TCGv_i64 t2 = tcg_temp_new_i64();
4961 TCGv_i64 t3 = tcg_temp_new_i64();
4963 tcg_gen_ext_tl_i64(t2, t0);
4964 tcg_gen_ext_tl_i64(t3, t1);
4965 tcg_gen_mul_i64(t2, t2, t3);
4966 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4967 tcg_gen_sub_i64(t2, t3, t2);
4968 tcg_temp_free_i64(t3);
4969 gen_move_low32(cpu_LO[acc], t2);
4970 gen_move_high32(cpu_HI[acc], t2);
4971 tcg_temp_free_i64(t2);
4976 TCGv_i64 t2 = tcg_temp_new_i64();
4977 TCGv_i64 t3 = tcg_temp_new_i64();
4979 tcg_gen_ext32u_tl(t0, t0);
4980 tcg_gen_ext32u_tl(t1, t1);
4981 tcg_gen_extu_tl_i64(t2, t0);
4982 tcg_gen_extu_tl_i64(t3, t1);
4983 tcg_gen_mul_i64(t2, t2, t3);
4984 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4985 tcg_gen_sub_i64(t2, t3, t2);
4986 tcg_temp_free_i64(t3);
4987 gen_move_low32(cpu_LO[acc], t2);
4988 gen_move_high32(cpu_HI[acc], t2);
4989 tcg_temp_free_i64(t2);
4993 MIPS_INVAL("mul/div");
4994 generate_exception_end(ctx, EXCP_RI);
5003 * These MULT[U] and MADD[U] instructions implemented in for example
5004 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5005 * architectures are special three-operand variants with the syntax
5007 * MULT[U][1] rd, rs, rt
5011 * (rd, LO, HI) <- rs * rt
5015 * MADD[U][1] rd, rs, rt
5019 * (rd, LO, HI) <- (LO, HI) + rs * rt
5021 * where the low-order 32-bits of the result is placed into both the
5022 * GPR rd and the special register LO. The high-order 32-bits of the
5023 * result is placed into the special register HI.
5025 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5026 * which is the zero register that always reads as 0.
5028 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5029 int rd, int rs, int rt)
5031 TCGv t0 = tcg_temp_new();
5032 TCGv t1 = tcg_temp_new();
5035 gen_load_gpr(t0, rs);
5036 gen_load_gpr(t1, rt);
5044 TCGv_i32 t2 = tcg_temp_new_i32();
5045 TCGv_i32 t3 = tcg_temp_new_i32();
5046 tcg_gen_trunc_tl_i32(t2, t0);
5047 tcg_gen_trunc_tl_i32(t3, t1);
5048 tcg_gen_muls2_i32(t2, t3, t2, t3);
5050 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5052 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5053 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5054 tcg_temp_free_i32(t2);
5055 tcg_temp_free_i32(t3);
5058 case MMI_OPC_MULTU1:
5063 TCGv_i32 t2 = tcg_temp_new_i32();
5064 TCGv_i32 t3 = tcg_temp_new_i32();
5065 tcg_gen_trunc_tl_i32(t2, t0);
5066 tcg_gen_trunc_tl_i32(t3, t1);
5067 tcg_gen_mulu2_i32(t2, t3, t2, t3);
5069 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5071 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5072 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5073 tcg_temp_free_i32(t2);
5074 tcg_temp_free_i32(t3);
5082 TCGv_i64 t2 = tcg_temp_new_i64();
5083 TCGv_i64 t3 = tcg_temp_new_i64();
5085 tcg_gen_ext_tl_i64(t2, t0);
5086 tcg_gen_ext_tl_i64(t3, t1);
5087 tcg_gen_mul_i64(t2, t2, t3);
5088 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5089 tcg_gen_add_i64(t2, t2, t3);
5090 tcg_temp_free_i64(t3);
5091 gen_move_low32(cpu_LO[acc], t2);
5092 gen_move_high32(cpu_HI[acc], t2);
5094 gen_move_low32(cpu_gpr[rd], t2);
5096 tcg_temp_free_i64(t2);
5099 case MMI_OPC_MADDU1:
5104 TCGv_i64 t2 = tcg_temp_new_i64();
5105 TCGv_i64 t3 = tcg_temp_new_i64();
5107 tcg_gen_ext32u_tl(t0, t0);
5108 tcg_gen_ext32u_tl(t1, t1);
5109 tcg_gen_extu_tl_i64(t2, t0);
5110 tcg_gen_extu_tl_i64(t3, t1);
5111 tcg_gen_mul_i64(t2, t2, t3);
5112 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5113 tcg_gen_add_i64(t2, t2, t3);
5114 tcg_temp_free_i64(t3);
5115 gen_move_low32(cpu_LO[acc], t2);
5116 gen_move_high32(cpu_HI[acc], t2);
5118 gen_move_low32(cpu_gpr[rd], t2);
5120 tcg_temp_free_i64(t2);
5124 MIPS_INVAL("mul/madd TXx9");
5125 generate_exception_end(ctx, EXCP_RI);
5134 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5135 int rd, int rs, int rt)
5137 TCGv t0 = tcg_temp_new();
5138 TCGv t1 = tcg_temp_new();
5140 gen_load_gpr(t0, rs);
5141 gen_load_gpr(t1, rt);
5144 case OPC_VR54XX_MULS:
5145 gen_helper_muls(t0, cpu_env, t0, t1);
5147 case OPC_VR54XX_MULSU:
5148 gen_helper_mulsu(t0, cpu_env, t0, t1);
5150 case OPC_VR54XX_MACC:
5151 gen_helper_macc(t0, cpu_env, t0, t1);
5153 case OPC_VR54XX_MACCU:
5154 gen_helper_maccu(t0, cpu_env, t0, t1);
5156 case OPC_VR54XX_MSAC:
5157 gen_helper_msac(t0, cpu_env, t0, t1);
5159 case OPC_VR54XX_MSACU:
5160 gen_helper_msacu(t0, cpu_env, t0, t1);
5162 case OPC_VR54XX_MULHI:
5163 gen_helper_mulhi(t0, cpu_env, t0, t1);
5165 case OPC_VR54XX_MULHIU:
5166 gen_helper_mulhiu(t0, cpu_env, t0, t1);
5168 case OPC_VR54XX_MULSHI:
5169 gen_helper_mulshi(t0, cpu_env, t0, t1);
5171 case OPC_VR54XX_MULSHIU:
5172 gen_helper_mulshiu(t0, cpu_env, t0, t1);
5174 case OPC_VR54XX_MACCHI:
5175 gen_helper_macchi(t0, cpu_env, t0, t1);
5177 case OPC_VR54XX_MACCHIU:
5178 gen_helper_macchiu(t0, cpu_env, t0, t1);
5180 case OPC_VR54XX_MSACHI:
5181 gen_helper_msachi(t0, cpu_env, t0, t1);
5183 case OPC_VR54XX_MSACHIU:
5184 gen_helper_msachiu(t0, cpu_env, t0, t1);
5187 MIPS_INVAL("mul vr54xx");
5188 generate_exception_end(ctx, EXCP_RI);
5191 gen_store_gpr(t0, rd);
5198 static void gen_cl (DisasContext *ctx, uint32_t opc,
5208 gen_load_gpr(t0, rs);
5213 #if defined(TARGET_MIPS64)
5217 tcg_gen_not_tl(t0, t0);
5226 tcg_gen_ext32u_tl(t0, t0);
5227 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5228 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5230 #if defined(TARGET_MIPS64)
5235 tcg_gen_clzi_i64(t0, t0, 64);
5241 /* Godson integer instructions */
5242 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5243 int rd, int rs, int rt)
5255 case OPC_MULTU_G_2E:
5256 case OPC_MULTU_G_2F:
5257 #if defined(TARGET_MIPS64)
5258 case OPC_DMULT_G_2E:
5259 case OPC_DMULT_G_2F:
5260 case OPC_DMULTU_G_2E:
5261 case OPC_DMULTU_G_2F:
5263 t0 = tcg_temp_new();
5264 t1 = tcg_temp_new();
5267 t0 = tcg_temp_local_new();
5268 t1 = tcg_temp_local_new();
5272 gen_load_gpr(t0, rs);
5273 gen_load_gpr(t1, rt);
5278 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5279 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5281 case OPC_MULTU_G_2E:
5282 case OPC_MULTU_G_2F:
5283 tcg_gen_ext32u_tl(t0, t0);
5284 tcg_gen_ext32u_tl(t1, t1);
5285 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5286 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5291 TCGLabel *l1 = gen_new_label();
5292 TCGLabel *l2 = gen_new_label();
5293 TCGLabel *l3 = gen_new_label();
5294 tcg_gen_ext32s_tl(t0, t0);
5295 tcg_gen_ext32s_tl(t1, t1);
5296 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5297 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5300 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5301 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5302 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5305 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5306 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5313 TCGLabel *l1 = gen_new_label();
5314 TCGLabel *l2 = gen_new_label();
5315 tcg_gen_ext32u_tl(t0, t0);
5316 tcg_gen_ext32u_tl(t1, t1);
5317 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5318 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5321 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5322 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5329 TCGLabel *l1 = gen_new_label();
5330 TCGLabel *l2 = gen_new_label();
5331 TCGLabel *l3 = gen_new_label();
5332 tcg_gen_ext32u_tl(t0, t0);
5333 tcg_gen_ext32u_tl(t1, t1);
5334 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5335 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5336 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5338 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5341 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5342 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5349 TCGLabel *l1 = gen_new_label();
5350 TCGLabel *l2 = gen_new_label();
5351 tcg_gen_ext32u_tl(t0, t0);
5352 tcg_gen_ext32u_tl(t1, t1);
5353 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5354 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5357 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5358 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5362 #if defined(TARGET_MIPS64)
5363 case OPC_DMULT_G_2E:
5364 case OPC_DMULT_G_2F:
5365 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5367 case OPC_DMULTU_G_2E:
5368 case OPC_DMULTU_G_2F:
5369 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5374 TCGLabel *l1 = gen_new_label();
5375 TCGLabel *l2 = gen_new_label();
5376 TCGLabel *l3 = gen_new_label();
5377 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5378 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5381 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5382 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5383 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5386 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5390 case OPC_DDIVU_G_2E:
5391 case OPC_DDIVU_G_2F:
5393 TCGLabel *l1 = gen_new_label();
5394 TCGLabel *l2 = gen_new_label();
5395 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5396 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5399 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5406 TCGLabel *l1 = gen_new_label();
5407 TCGLabel *l2 = gen_new_label();
5408 TCGLabel *l3 = gen_new_label();
5409 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5410 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5411 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5413 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5416 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5420 case OPC_DMODU_G_2E:
5421 case OPC_DMODU_G_2F:
5423 TCGLabel *l1 = gen_new_label();
5424 TCGLabel *l2 = gen_new_label();
5425 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5426 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5429 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5440 /* Loongson multimedia instructions */
5441 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5443 uint32_t opc, shift_max;
5446 opc = MASK_LMI(ctx->opcode);
5452 t0 = tcg_temp_local_new_i64();
5453 t1 = tcg_temp_local_new_i64();
5456 t0 = tcg_temp_new_i64();
5457 t1 = tcg_temp_new_i64();
5461 check_cp1_enabled(ctx);
5462 gen_load_fpr64(ctx, t0, rs);
5463 gen_load_fpr64(ctx, t1, rt);
5465 #define LMI_HELPER(UP, LO) \
5466 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5467 #define LMI_HELPER_1(UP, LO) \
5468 case OPC_##UP: gen_helper_##LO(t0, t0); break
5469 #define LMI_DIRECT(UP, LO, OP) \
5470 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5473 LMI_HELPER(PADDSH, paddsh);
5474 LMI_HELPER(PADDUSH, paddush);
5475 LMI_HELPER(PADDH, paddh);
5476 LMI_HELPER(PADDW, paddw);
5477 LMI_HELPER(PADDSB, paddsb);
5478 LMI_HELPER(PADDUSB, paddusb);
5479 LMI_HELPER(PADDB, paddb);
5481 LMI_HELPER(PSUBSH, psubsh);
5482 LMI_HELPER(PSUBUSH, psubush);
5483 LMI_HELPER(PSUBH, psubh);
5484 LMI_HELPER(PSUBW, psubw);
5485 LMI_HELPER(PSUBSB, psubsb);
5486 LMI_HELPER(PSUBUSB, psubusb);
5487 LMI_HELPER(PSUBB, psubb);
5489 LMI_HELPER(PSHUFH, pshufh);
5490 LMI_HELPER(PACKSSWH, packsswh);
5491 LMI_HELPER(PACKSSHB, packsshb);
5492 LMI_HELPER(PACKUSHB, packushb);
5494 LMI_HELPER(PUNPCKLHW, punpcklhw);
5495 LMI_HELPER(PUNPCKHHW, punpckhhw);
5496 LMI_HELPER(PUNPCKLBH, punpcklbh);
5497 LMI_HELPER(PUNPCKHBH, punpckhbh);
5498 LMI_HELPER(PUNPCKLWD, punpcklwd);
5499 LMI_HELPER(PUNPCKHWD, punpckhwd);
5501 LMI_HELPER(PAVGH, pavgh);
5502 LMI_HELPER(PAVGB, pavgb);
5503 LMI_HELPER(PMAXSH, pmaxsh);
5504 LMI_HELPER(PMINSH, pminsh);
5505 LMI_HELPER(PMAXUB, pmaxub);
5506 LMI_HELPER(PMINUB, pminub);
5508 LMI_HELPER(PCMPEQW, pcmpeqw);
5509 LMI_HELPER(PCMPGTW, pcmpgtw);
5510 LMI_HELPER(PCMPEQH, pcmpeqh);
5511 LMI_HELPER(PCMPGTH, pcmpgth);
5512 LMI_HELPER(PCMPEQB, pcmpeqb);
5513 LMI_HELPER(PCMPGTB, pcmpgtb);
5515 LMI_HELPER(PSLLW, psllw);
5516 LMI_HELPER(PSLLH, psllh);
5517 LMI_HELPER(PSRLW, psrlw);
5518 LMI_HELPER(PSRLH, psrlh);
5519 LMI_HELPER(PSRAW, psraw);
5520 LMI_HELPER(PSRAH, psrah);
5522 LMI_HELPER(PMULLH, pmullh);
5523 LMI_HELPER(PMULHH, pmulhh);
5524 LMI_HELPER(PMULHUH, pmulhuh);
5525 LMI_HELPER(PMADDHW, pmaddhw);
5527 LMI_HELPER(PASUBUB, pasubub);
5528 LMI_HELPER_1(BIADD, biadd);
5529 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5531 LMI_DIRECT(PADDD, paddd, add);
5532 LMI_DIRECT(PSUBD, psubd, sub);
5533 LMI_DIRECT(XOR_CP2, xor, xor);
5534 LMI_DIRECT(NOR_CP2, nor, nor);
5535 LMI_DIRECT(AND_CP2, and, and);
5536 LMI_DIRECT(OR_CP2, or, or);
5539 tcg_gen_andc_i64(t0, t1, t0);
5543 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5546 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5549 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5552 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5556 tcg_gen_andi_i64(t1, t1, 3);
5557 tcg_gen_shli_i64(t1, t1, 4);
5558 tcg_gen_shr_i64(t0, t0, t1);
5559 tcg_gen_ext16u_i64(t0, t0);
5563 tcg_gen_add_i64(t0, t0, t1);
5564 tcg_gen_ext32s_i64(t0, t0);
5567 tcg_gen_sub_i64(t0, t0, t1);
5568 tcg_gen_ext32s_i64(t0, t0);
5590 /* Make sure shift count isn't TCG undefined behaviour. */
5591 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5596 tcg_gen_shl_i64(t0, t0, t1);
5600 /* Since SRA is UndefinedResult without sign-extended inputs,
5601 we can treat SRA and DSRA the same. */
5602 tcg_gen_sar_i64(t0, t0, t1);
5605 /* We want to shift in zeros for SRL; zero-extend first. */
5606 tcg_gen_ext32u_i64(t0, t0);
5609 tcg_gen_shr_i64(t0, t0, t1);
5613 if (shift_max == 32) {
5614 tcg_gen_ext32s_i64(t0, t0);
5617 /* Shifts larger than MAX produce zero. */
5618 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5619 tcg_gen_neg_i64(t1, t1);
5620 tcg_gen_and_i64(t0, t0, t1);
5626 TCGv_i64 t2 = tcg_temp_new_i64();
5627 TCGLabel *lab = gen_new_label();
5629 tcg_gen_mov_i64(t2, t0);
5630 tcg_gen_add_i64(t0, t1, t2);
5631 if (opc == OPC_ADD_CP2) {
5632 tcg_gen_ext32s_i64(t0, t0);
5634 tcg_gen_xor_i64(t1, t1, t2);
5635 tcg_gen_xor_i64(t2, t2, t0);
5636 tcg_gen_andc_i64(t1, t2, t1);
5637 tcg_temp_free_i64(t2);
5638 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5639 generate_exception(ctx, EXCP_OVERFLOW);
5647 TCGv_i64 t2 = tcg_temp_new_i64();
5648 TCGLabel *lab = gen_new_label();
5650 tcg_gen_mov_i64(t2, t0);
5651 tcg_gen_sub_i64(t0, t1, t2);
5652 if (opc == OPC_SUB_CP2) {
5653 tcg_gen_ext32s_i64(t0, t0);
5655 tcg_gen_xor_i64(t1, t1, t2);
5656 tcg_gen_xor_i64(t2, t2, t0);
5657 tcg_gen_and_i64(t1, t1, t2);
5658 tcg_temp_free_i64(t2);
5659 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5660 generate_exception(ctx, EXCP_OVERFLOW);
5666 tcg_gen_ext32u_i64(t0, t0);
5667 tcg_gen_ext32u_i64(t1, t1);
5668 tcg_gen_mul_i64(t0, t0, t1);
5677 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5678 FD field is the CC field? */
5680 MIPS_INVAL("loongson_cp2");
5681 generate_exception_end(ctx, EXCP_RI);
5688 gen_store_fpr64(ctx, t0, rd);
5690 tcg_temp_free_i64(t0);
5691 tcg_temp_free_i64(t1);
5695 static void gen_trap (DisasContext *ctx, uint32_t opc,
5696 int rs, int rt, int16_t imm)
5699 TCGv t0 = tcg_temp_new();
5700 TCGv t1 = tcg_temp_new();
5703 /* Load needed operands */
5711 /* Compare two registers */
5713 gen_load_gpr(t0, rs);
5714 gen_load_gpr(t1, rt);
5724 /* Compare register to immediate */
5725 if (rs != 0 || imm != 0) {
5726 gen_load_gpr(t0, rs);
5727 tcg_gen_movi_tl(t1, (int32_t)imm);
5734 case OPC_TEQ: /* rs == rs */
5735 case OPC_TEQI: /* r0 == 0 */
5736 case OPC_TGE: /* rs >= rs */
5737 case OPC_TGEI: /* r0 >= 0 */
5738 case OPC_TGEU: /* rs >= rs unsigned */
5739 case OPC_TGEIU: /* r0 >= 0 unsigned */
5741 generate_exception_end(ctx, EXCP_TRAP);
5743 case OPC_TLT: /* rs < rs */
5744 case OPC_TLTI: /* r0 < 0 */
5745 case OPC_TLTU: /* rs < rs unsigned */
5746 case OPC_TLTIU: /* r0 < 0 unsigned */
5747 case OPC_TNE: /* rs != rs */
5748 case OPC_TNEI: /* r0 != 0 */
5749 /* Never trap: treat as NOP. */
5753 TCGLabel *l1 = gen_new_label();
5758 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5762 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5766 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5770 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5774 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5778 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5781 generate_exception(ctx, EXCP_TRAP);
5788 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5790 if (unlikely(ctx->base.singlestep_enabled)) {
5794 #ifndef CONFIG_USER_ONLY
5795 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5801 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5803 if (use_goto_tb(ctx, dest)) {
5806 tcg_gen_exit_tb(ctx->base.tb, n);
5809 if (ctx->base.singlestep_enabled) {
5810 save_cpu_state(ctx, 0);
5811 gen_helper_raise_exception_debug(cpu_env);
5813 tcg_gen_lookup_and_goto_ptr();
5817 /* Branches (before delay slot) */
5818 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5820 int rs, int rt, int32_t offset,
5823 target_ulong btgt = -1;
5825 int bcond_compute = 0;
5826 TCGv t0 = tcg_temp_new();
5827 TCGv t1 = tcg_temp_new();
5829 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5830 #ifdef MIPS_DEBUG_DISAS
5831 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5832 TARGET_FMT_lx "\n", ctx->base.pc_next);
5834 generate_exception_end(ctx, EXCP_RI);
5838 /* Load needed operands */
5844 /* Compare two registers */
5846 gen_load_gpr(t0, rs);
5847 gen_load_gpr(t1, rt);
5850 btgt = ctx->base.pc_next + insn_bytes + offset;
5864 /* Compare to zero */
5866 gen_load_gpr(t0, rs);
5869 btgt = ctx->base.pc_next + insn_bytes + offset;
5872 #if defined(TARGET_MIPS64)
5874 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5876 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5879 btgt = ctx->base.pc_next + insn_bytes + offset;
5884 /* Jump to immediate */
5885 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5890 /* Jump to register */
5891 if (offset != 0 && offset != 16) {
5892 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5893 others are reserved. */
5894 MIPS_INVAL("jump hint");
5895 generate_exception_end(ctx, EXCP_RI);
5898 gen_load_gpr(btarget, rs);
5901 MIPS_INVAL("branch/jump");
5902 generate_exception_end(ctx, EXCP_RI);
5905 if (bcond_compute == 0) {
5906 /* No condition to be computed */
5908 case OPC_BEQ: /* rx == rx */
5909 case OPC_BEQL: /* rx == rx likely */
5910 case OPC_BGEZ: /* 0 >= 0 */
5911 case OPC_BGEZL: /* 0 >= 0 likely */
5912 case OPC_BLEZ: /* 0 <= 0 */
5913 case OPC_BLEZL: /* 0 <= 0 likely */
5915 ctx->hflags |= MIPS_HFLAG_B;
5917 case OPC_BGEZAL: /* 0 >= 0 */
5918 case OPC_BGEZALL: /* 0 >= 0 likely */
5919 /* Always take and link */
5921 ctx->hflags |= MIPS_HFLAG_B;
5923 case OPC_BNE: /* rx != rx */
5924 case OPC_BGTZ: /* 0 > 0 */
5925 case OPC_BLTZ: /* 0 < 0 */
5928 case OPC_BLTZAL: /* 0 < 0 */
5929 /* Handle as an unconditional branch to get correct delay
5932 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5933 ctx->hflags |= MIPS_HFLAG_B;
5935 case OPC_BLTZALL: /* 0 < 0 likely */
5936 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5937 /* Skip the instruction in the delay slot */
5938 ctx->base.pc_next += 4;
5940 case OPC_BNEL: /* rx != rx likely */
5941 case OPC_BGTZL: /* 0 > 0 likely */
5942 case OPC_BLTZL: /* 0 < 0 likely */
5943 /* Skip the instruction in the delay slot */
5944 ctx->base.pc_next += 4;
5947 ctx->hflags |= MIPS_HFLAG_B;
5950 ctx->hflags |= MIPS_HFLAG_BX;
5954 ctx->hflags |= MIPS_HFLAG_B;
5957 ctx->hflags |= MIPS_HFLAG_BR;
5961 ctx->hflags |= MIPS_HFLAG_BR;
5964 MIPS_INVAL("branch/jump");
5965 generate_exception_end(ctx, EXCP_RI);
5971 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5974 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5977 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5980 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5983 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5986 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5989 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5993 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5997 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6000 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6003 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6006 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6009 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6012 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6015 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6017 #if defined(TARGET_MIPS64)
6019 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6023 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6026 ctx->hflags |= MIPS_HFLAG_BC;
6029 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6032 ctx->hflags |= MIPS_HFLAG_BL;
6035 MIPS_INVAL("conditional branch/jump");
6036 generate_exception_end(ctx, EXCP_RI);
6041 ctx->btarget = btgt;
6043 switch (delayslot_size) {
6045 ctx->hflags |= MIPS_HFLAG_BDS16;
6048 ctx->hflags |= MIPS_HFLAG_BDS32;
6053 int post_delay = insn_bytes + delayslot_size;
6054 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6056 tcg_gen_movi_tl(cpu_gpr[blink],
6057 ctx->base.pc_next + post_delay + lowbit);
6061 if (insn_bytes == 2)
6062 ctx->hflags |= MIPS_HFLAG_B16;
6068 /* nanoMIPS Branches */
6069 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6071 int rs, int rt, int32_t offset)
6073 target_ulong btgt = -1;
6074 int bcond_compute = 0;
6075 TCGv t0 = tcg_temp_new();
6076 TCGv t1 = tcg_temp_new();
6078 /* Load needed operands */
6082 /* Compare two registers */
6084 gen_load_gpr(t0, rs);
6085 gen_load_gpr(t1, rt);
6088 btgt = ctx->base.pc_next + insn_bytes + offset;
6091 /* Compare to zero */
6093 gen_load_gpr(t0, rs);
6096 btgt = ctx->base.pc_next + insn_bytes + offset;
6099 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6101 btgt = ctx->base.pc_next + insn_bytes + offset;
6105 /* Jump to register */
6106 if (offset != 0 && offset != 16) {
6107 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6108 others are reserved. */
6109 MIPS_INVAL("jump hint");
6110 generate_exception_end(ctx, EXCP_RI);
6113 gen_load_gpr(btarget, rs);
6116 MIPS_INVAL("branch/jump");
6117 generate_exception_end(ctx, EXCP_RI);
6120 if (bcond_compute == 0) {
6121 /* No condition to be computed */
6123 case OPC_BEQ: /* rx == rx */
6125 ctx->hflags |= MIPS_HFLAG_B;
6127 case OPC_BGEZAL: /* 0 >= 0 */
6128 /* Always take and link */
6129 tcg_gen_movi_tl(cpu_gpr[31],
6130 ctx->base.pc_next + insn_bytes);
6131 ctx->hflags |= MIPS_HFLAG_B;
6133 case OPC_BNE: /* rx != rx */
6134 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6135 /* Skip the instruction in the delay slot */
6136 ctx->base.pc_next += 4;
6139 ctx->hflags |= MIPS_HFLAG_BR;
6143 tcg_gen_movi_tl(cpu_gpr[rt],
6144 ctx->base.pc_next + insn_bytes);
6146 ctx->hflags |= MIPS_HFLAG_BR;
6149 MIPS_INVAL("branch/jump");
6150 generate_exception_end(ctx, EXCP_RI);
6156 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6159 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6162 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6163 tcg_gen_movi_tl(cpu_gpr[31],
6164 ctx->base.pc_next + insn_bytes);
6167 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6169 ctx->hflags |= MIPS_HFLAG_BC;
6172 MIPS_INVAL("conditional branch/jump");
6173 generate_exception_end(ctx, EXCP_RI);
6178 ctx->btarget = btgt;
6181 if (insn_bytes == 2) {
6182 ctx->hflags |= MIPS_HFLAG_B16;
6189 /* special3 bitfield operations */
6190 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
6191 int rs, int lsb, int msb)
6193 TCGv t0 = tcg_temp_new();
6194 TCGv t1 = tcg_temp_new();
6196 gen_load_gpr(t1, rs);
6199 if (lsb + msb > 31) {
6203 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6205 /* The two checks together imply that lsb == 0,
6206 so this is a simple sign-extension. */
6207 tcg_gen_ext32s_tl(t0, t1);
6210 #if defined(TARGET_MIPS64)
6219 if (lsb + msb > 63) {
6222 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6229 gen_load_gpr(t0, rt);
6230 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6231 tcg_gen_ext32s_tl(t0, t0);
6233 #if defined(TARGET_MIPS64)
6244 gen_load_gpr(t0, rt);
6245 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6250 MIPS_INVAL("bitops");
6251 generate_exception_end(ctx, EXCP_RI);
6256 gen_store_gpr(t0, rt);
6261 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6266 /* If no destination, treat it as a NOP. */
6270 t0 = tcg_temp_new();
6271 gen_load_gpr(t0, rt);
6275 TCGv t1 = tcg_temp_new();
6276 TCGv t2 = tcg_const_tl(0x00FF00FF);
6278 tcg_gen_shri_tl(t1, t0, 8);
6279 tcg_gen_and_tl(t1, t1, t2);
6280 tcg_gen_and_tl(t0, t0, t2);
6281 tcg_gen_shli_tl(t0, t0, 8);
6282 tcg_gen_or_tl(t0, t0, t1);
6285 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6289 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6292 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6294 #if defined(TARGET_MIPS64)
6297 TCGv t1 = tcg_temp_new();
6298 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6300 tcg_gen_shri_tl(t1, t0, 8);
6301 tcg_gen_and_tl(t1, t1, t2);
6302 tcg_gen_and_tl(t0, t0, t2);
6303 tcg_gen_shli_tl(t0, t0, 8);
6304 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6311 TCGv t1 = tcg_temp_new();
6312 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6314 tcg_gen_shri_tl(t1, t0, 16);
6315 tcg_gen_and_tl(t1, t1, t2);
6316 tcg_gen_and_tl(t0, t0, t2);
6317 tcg_gen_shli_tl(t0, t0, 16);
6318 tcg_gen_or_tl(t0, t0, t1);
6319 tcg_gen_shri_tl(t1, t0, 32);
6320 tcg_gen_shli_tl(t0, t0, 32);
6321 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6328 MIPS_INVAL("bsfhl");
6329 generate_exception_end(ctx, EXCP_RI);
6336 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6345 t0 = tcg_temp_new();
6346 t1 = tcg_temp_new();
6347 gen_load_gpr(t0, rs);
6348 gen_load_gpr(t1, rt);
6349 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6350 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6351 if (opc == OPC_LSA) {
6352 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6361 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6369 t0 = tcg_temp_new();
6370 if (bits == 0 || bits == wordsz) {
6372 gen_load_gpr(t0, rt);
6374 gen_load_gpr(t0, rs);
6378 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6380 #if defined(TARGET_MIPS64)
6382 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6387 TCGv t1 = tcg_temp_new();
6388 gen_load_gpr(t0, rt);
6389 gen_load_gpr(t1, rs);
6393 TCGv_i64 t2 = tcg_temp_new_i64();
6394 tcg_gen_concat_tl_i64(t2, t1, t0);
6395 tcg_gen_shri_i64(t2, t2, 32 - bits);
6396 gen_move_low32(cpu_gpr[rd], t2);
6397 tcg_temp_free_i64(t2);
6400 #if defined(TARGET_MIPS64)
6402 tcg_gen_shli_tl(t0, t0, bits);
6403 tcg_gen_shri_tl(t1, t1, 64 - bits);
6404 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6414 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6417 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6420 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6423 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6426 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6433 t0 = tcg_temp_new();
6434 gen_load_gpr(t0, rt);
6437 gen_helper_bitswap(cpu_gpr[rd], t0);
6439 #if defined(TARGET_MIPS64)
6441 gen_helper_dbitswap(cpu_gpr[rd], t0);
6448 #ifndef CONFIG_USER_ONLY
6449 /* CP0 (MMU and control) */
6450 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6452 TCGv_i64 t0 = tcg_temp_new_i64();
6453 TCGv_i64 t1 = tcg_temp_new_i64();
6455 tcg_gen_ext_tl_i64(t0, arg);
6456 tcg_gen_ld_i64(t1, cpu_env, off);
6457 #if defined(TARGET_MIPS64)
6458 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6460 tcg_gen_concat32_i64(t1, t1, t0);
6462 tcg_gen_st_i64(t1, cpu_env, off);
6463 tcg_temp_free_i64(t1);
6464 tcg_temp_free_i64(t0);
6467 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6469 TCGv_i64 t0 = tcg_temp_new_i64();
6470 TCGv_i64 t1 = tcg_temp_new_i64();
6472 tcg_gen_ext_tl_i64(t0, arg);
6473 tcg_gen_ld_i64(t1, cpu_env, off);
6474 tcg_gen_concat32_i64(t1, t1, t0);
6475 tcg_gen_st_i64(t1, cpu_env, off);
6476 tcg_temp_free_i64(t1);
6477 tcg_temp_free_i64(t0);
6480 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6482 TCGv_i64 t0 = tcg_temp_new_i64();
6484 tcg_gen_ld_i64(t0, cpu_env, off);
6485 #if defined(TARGET_MIPS64)
6486 tcg_gen_shri_i64(t0, t0, 30);
6488 tcg_gen_shri_i64(t0, t0, 32);
6490 gen_move_low32(arg, t0);
6491 tcg_temp_free_i64(t0);
6494 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6496 TCGv_i64 t0 = tcg_temp_new_i64();
6498 tcg_gen_ld_i64(t0, cpu_env, off);
6499 tcg_gen_shri_i64(t0, t0, 32 + shift);
6500 gen_move_low32(arg, t0);
6501 tcg_temp_free_i64(t0);
6504 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6506 TCGv_i32 t0 = tcg_temp_new_i32();
6508 tcg_gen_ld_i32(t0, cpu_env, off);
6509 tcg_gen_ext_i32_tl(arg, t0);
6510 tcg_temp_free_i32(t0);
6513 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6515 tcg_gen_ld_tl(arg, cpu_env, off);
6516 tcg_gen_ext32s_tl(arg, arg);
6519 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6521 TCGv_i32 t0 = tcg_temp_new_i32();
6523 tcg_gen_trunc_tl_i32(t0, arg);
6524 tcg_gen_st_i32(t0, cpu_env, off);
6525 tcg_temp_free_i32(t0);
6528 #define CP0_CHECK(c) \
6531 goto cp0_unimplemented; \
6535 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6537 const char *register_name = "invalid";
6540 case CP0_REGISTER_02:
6543 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6544 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6545 register_name = "EntryLo0";
6548 goto cp0_unimplemented;
6551 case CP0_REGISTER_03:
6554 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6555 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6556 register_name = "EntryLo1";
6559 goto cp0_unimplemented;
6562 case CP0_REGISTER_09:
6565 CP0_CHECK(ctx->saar);
6566 gen_helper_mfhc0_saar(arg, cpu_env);
6567 register_name = "SAAR";
6570 goto cp0_unimplemented;
6573 case CP0_REGISTER_17:
6576 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
6577 ctx->CP0_LLAddr_shift);
6578 register_name = "LLAddr";
6581 CP0_CHECK(ctx->mrp);
6582 gen_helper_mfhc0_maar(arg, cpu_env);
6583 register_name = "MAAR";
6586 goto cp0_unimplemented;
6589 case CP0_REGISTER_28:
6595 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6596 register_name = "TagLo";
6599 goto cp0_unimplemented;
6603 goto cp0_unimplemented;
6605 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6609 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6610 register_name, reg, sel);
6611 tcg_gen_movi_tl(arg, 0);
6614 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6616 const char *register_name = "invalid";
6617 uint64_t mask = ctx->PAMask >> 36;
6620 case CP0_REGISTER_02:
6623 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6624 tcg_gen_andi_tl(arg, arg, mask);
6625 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6626 register_name = "EntryLo0";
6629 goto cp0_unimplemented;
6632 case CP0_REGISTER_03:
6635 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6636 tcg_gen_andi_tl(arg, arg, mask);
6637 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6638 register_name = "EntryLo1";
6641 goto cp0_unimplemented;
6644 case CP0_REGISTER_09:
6647 CP0_CHECK(ctx->saar);
6648 gen_helper_mthc0_saar(cpu_env, arg);
6649 register_name = "SAAR";
6652 goto cp0_unimplemented;
6654 case CP0_REGISTER_17:
6657 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6658 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6659 relevant for modern MIPS cores supporting MTHC0, therefore
6660 treating MTHC0 to LLAddr as NOP. */
6661 register_name = "LLAddr";
6664 CP0_CHECK(ctx->mrp);
6665 gen_helper_mthc0_maar(cpu_env, arg);
6666 register_name = "MAAR";
6669 goto cp0_unimplemented;
6672 case CP0_REGISTER_28:
6678 tcg_gen_andi_tl(arg, arg, mask);
6679 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6680 register_name = "TagLo";
6683 goto cp0_unimplemented;
6687 goto cp0_unimplemented;
6689 trace_mips_translate_c0("mthc0", register_name, reg, sel);
6692 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6693 register_name, reg, sel);
6696 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6698 if (ctx->insn_flags & ISA_MIPS32R6) {
6699 tcg_gen_movi_tl(arg, 0);
6701 tcg_gen_movi_tl(arg, ~0);
6705 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6707 const char *register_name = "invalid";
6710 check_insn(ctx, ISA_MIPS32);
6713 case CP0_REGISTER_00:
6716 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6717 register_name = "Index";
6720 CP0_CHECK(ctx->insn_flags & ASE_MT);
6721 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6722 register_name = "MVPControl";
6725 CP0_CHECK(ctx->insn_flags & ASE_MT);
6726 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6727 register_name = "MVPConf0";
6730 CP0_CHECK(ctx->insn_flags & ASE_MT);
6731 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6732 register_name = "MVPConf1";
6736 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6737 register_name = "VPControl";
6740 goto cp0_unimplemented;
6743 case CP0_REGISTER_01:
6746 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6747 gen_helper_mfc0_random(arg, cpu_env);
6748 register_name = "Random";
6751 CP0_CHECK(ctx->insn_flags & ASE_MT);
6752 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6753 register_name = "VPEControl";
6756 CP0_CHECK(ctx->insn_flags & ASE_MT);
6757 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6758 register_name = "VPEConf0";
6761 CP0_CHECK(ctx->insn_flags & ASE_MT);
6762 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6763 register_name = "VPEConf1";
6766 CP0_CHECK(ctx->insn_flags & ASE_MT);
6767 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6768 register_name = "YQMask";
6771 CP0_CHECK(ctx->insn_flags & ASE_MT);
6772 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6773 register_name = "VPESchedule";
6776 CP0_CHECK(ctx->insn_flags & ASE_MT);
6777 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6778 register_name = "VPEScheFBack";
6781 CP0_CHECK(ctx->insn_flags & ASE_MT);
6782 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6783 register_name = "VPEOpt";
6786 goto cp0_unimplemented;
6789 case CP0_REGISTER_02:
6793 TCGv_i64 tmp = tcg_temp_new_i64();
6794 tcg_gen_ld_i64(tmp, cpu_env,
6795 offsetof(CPUMIPSState, CP0_EntryLo0));
6796 #if defined(TARGET_MIPS64)
6798 /* Move RI/XI fields to bits 31:30 */
6799 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6800 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6803 gen_move_low32(arg, tmp);
6804 tcg_temp_free_i64(tmp);
6806 register_name = "EntryLo0";
6809 CP0_CHECK(ctx->insn_flags & ASE_MT);
6810 gen_helper_mfc0_tcstatus(arg, cpu_env);
6811 register_name = "TCStatus";
6814 CP0_CHECK(ctx->insn_flags & ASE_MT);
6815 gen_helper_mfc0_tcbind(arg, cpu_env);
6816 register_name = "TCBind";
6819 CP0_CHECK(ctx->insn_flags & ASE_MT);
6820 gen_helper_mfc0_tcrestart(arg, cpu_env);
6821 register_name = "TCRestart";
6824 CP0_CHECK(ctx->insn_flags & ASE_MT);
6825 gen_helper_mfc0_tchalt(arg, cpu_env);
6826 register_name = "TCHalt";
6829 CP0_CHECK(ctx->insn_flags & ASE_MT);
6830 gen_helper_mfc0_tccontext(arg, cpu_env);
6831 register_name = "TCContext";
6834 CP0_CHECK(ctx->insn_flags & ASE_MT);
6835 gen_helper_mfc0_tcschedule(arg, cpu_env);
6836 register_name = "TCSchedule";
6839 CP0_CHECK(ctx->insn_flags & ASE_MT);
6840 gen_helper_mfc0_tcschefback(arg, cpu_env);
6841 register_name = "TCScheFBack";
6844 goto cp0_unimplemented;
6847 case CP0_REGISTER_03:
6851 TCGv_i64 tmp = tcg_temp_new_i64();
6852 tcg_gen_ld_i64(tmp, cpu_env,
6853 offsetof(CPUMIPSState, CP0_EntryLo1));
6854 #if defined(TARGET_MIPS64)
6856 /* Move RI/XI fields to bits 31:30 */
6857 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6858 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6861 gen_move_low32(arg, tmp);
6862 tcg_temp_free_i64(tmp);
6864 register_name = "EntryLo1";
6868 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6869 register_name = "GlobalNumber";
6872 goto cp0_unimplemented;
6875 case CP0_REGISTER_04:
6878 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6879 tcg_gen_ext32s_tl(arg, arg);
6880 register_name = "Context";
6883 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6884 register_name = "ContextConfig";
6885 goto cp0_unimplemented;
6887 CP0_CHECK(ctx->ulri);
6888 tcg_gen_ld_tl(arg, cpu_env,
6889 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6890 tcg_gen_ext32s_tl(arg, arg);
6891 register_name = "UserLocal";
6894 goto cp0_unimplemented;
6897 case CP0_REGISTER_05:
6900 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6901 register_name = "PageMask";
6904 check_insn(ctx, ISA_MIPS32R2);
6905 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6906 register_name = "PageGrain";
6910 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6911 tcg_gen_ext32s_tl(arg, arg);
6912 register_name = "SegCtl0";
6916 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6917 tcg_gen_ext32s_tl(arg, arg);
6918 register_name = "SegCtl1";
6922 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6923 tcg_gen_ext32s_tl(arg, arg);
6924 register_name = "SegCtl2";
6928 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6929 register_name = "PWBase";
6933 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6934 register_name = "PWField";
6938 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6939 register_name = "PWSize";
6942 goto cp0_unimplemented;
6945 case CP0_REGISTER_06:
6948 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6949 register_name = "Wired";
6952 check_insn(ctx, ISA_MIPS32R2);
6953 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6954 register_name = "SRSConf0";
6957 check_insn(ctx, ISA_MIPS32R2);
6958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6959 register_name = "SRSConf1";
6962 check_insn(ctx, ISA_MIPS32R2);
6963 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6964 register_name = "SRSConf2";
6967 check_insn(ctx, ISA_MIPS32R2);
6968 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6969 register_name = "SRSConf3";
6972 check_insn(ctx, ISA_MIPS32R2);
6973 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6974 register_name = "SRSConf4";
6978 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6979 register_name = "PWCtl";
6982 goto cp0_unimplemented;
6985 case CP0_REGISTER_07:
6988 check_insn(ctx, ISA_MIPS32R2);
6989 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6990 register_name = "HWREna";
6993 goto cp0_unimplemented;
6996 case CP0_REGISTER_08:
6999 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7000 tcg_gen_ext32s_tl(arg, arg);
7001 register_name = "BadVAddr";
7005 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7006 register_name = "BadInstr";
7010 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7011 register_name = "BadInstrP";
7015 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7016 tcg_gen_andi_tl(arg, arg, ~0xffff);
7017 register_name = "BadInstrX";
7020 goto cp0_unimplemented;
7023 case CP0_REGISTER_09:
7026 /* Mark as an IO operation because we read the time. */
7027 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7030 gen_helper_mfc0_count(arg, cpu_env);
7031 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7034 /* Break the TB to be able to take timer interrupts immediately
7035 after reading count. DISAS_STOP isn't sufficient, we need to
7036 ensure we break completely out of translated code. */
7037 gen_save_pc(ctx->base.pc_next + 4);
7038 ctx->base.is_jmp = DISAS_EXIT;
7039 register_name = "Count";
7042 CP0_CHECK(ctx->saar);
7043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7044 register_name = "SAARI";
7047 CP0_CHECK(ctx->saar);
7048 gen_helper_mfc0_saar(arg, cpu_env);
7049 register_name = "SAAR";
7052 goto cp0_unimplemented;
7055 case CP0_REGISTER_10:
7058 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7059 tcg_gen_ext32s_tl(arg, arg);
7060 register_name = "EntryHi";
7063 goto cp0_unimplemented;
7066 case CP0_REGISTER_11:
7069 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7070 register_name = "Compare";
7072 /* 6,7 are implementation dependent */
7074 goto cp0_unimplemented;
7077 case CP0_REGISTER_12:
7080 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7081 register_name = "Status";
7084 check_insn(ctx, ISA_MIPS32R2);
7085 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7086 register_name = "IntCtl";
7089 check_insn(ctx, ISA_MIPS32R2);
7090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7091 register_name = "SRSCtl";
7094 check_insn(ctx, ISA_MIPS32R2);
7095 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7096 register_name = "SRSMap";
7099 goto cp0_unimplemented;
7102 case CP0_REGISTER_13:
7105 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7106 register_name = "Cause";
7109 goto cp0_unimplemented;
7112 case CP0_REGISTER_14:
7115 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7116 tcg_gen_ext32s_tl(arg, arg);
7117 register_name = "EPC";
7120 goto cp0_unimplemented;
7123 case CP0_REGISTER_15:
7126 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7127 register_name = "PRid";
7130 check_insn(ctx, ISA_MIPS32R2);
7131 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7132 tcg_gen_ext32s_tl(arg, arg);
7133 register_name = "EBase";
7136 check_insn(ctx, ISA_MIPS32R2);
7137 CP0_CHECK(ctx->cmgcr);
7138 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7139 tcg_gen_ext32s_tl(arg, arg);
7140 register_name = "CMGCRBase";
7143 goto cp0_unimplemented;
7146 case CP0_REGISTER_16:
7149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7150 register_name = "Config";
7153 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7154 register_name = "Config1";
7157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7158 register_name = "Config2";
7161 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7162 register_name = "Config3";
7165 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7166 register_name = "Config4";
7169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7170 register_name = "Config5";
7172 /* 6,7 are implementation dependent */
7174 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7175 register_name = "Config6";
7178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7179 register_name = "Config7";
7182 goto cp0_unimplemented;
7185 case CP0_REGISTER_17:
7188 gen_helper_mfc0_lladdr(arg, cpu_env);
7189 register_name = "LLAddr";
7192 CP0_CHECK(ctx->mrp);
7193 gen_helper_mfc0_maar(arg, cpu_env);
7194 register_name = "MAAR";
7197 CP0_CHECK(ctx->mrp);
7198 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7199 register_name = "MAARI";
7202 goto cp0_unimplemented;
7205 case CP0_REGISTER_18:
7215 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7216 gen_helper_1e0i(mfc0_watchlo, arg, sel);
7217 register_name = "WatchLo";
7220 goto cp0_unimplemented;
7223 case CP0_REGISTER_19:
7233 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7234 gen_helper_1e0i(mfc0_watchhi, arg, sel);
7235 register_name = "WatchHi";
7238 goto cp0_unimplemented;
7241 case CP0_REGISTER_20:
7244 #if defined(TARGET_MIPS64)
7245 check_insn(ctx, ISA_MIPS3);
7246 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7247 tcg_gen_ext32s_tl(arg, arg);
7248 register_name = "XContext";
7252 goto cp0_unimplemented;
7255 case CP0_REGISTER_21:
7256 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7257 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7261 register_name = "Framemask";
7264 goto cp0_unimplemented;
7267 case CP0_REGISTER_22:
7268 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7269 register_name = "'Diagnostic"; /* implementation dependent */
7271 case CP0_REGISTER_23:
7274 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7275 register_name = "Debug";
7278 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7279 register_name = "TraceControl";
7280 goto cp0_unimplemented;
7282 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7283 register_name = "TraceControl2";
7284 goto cp0_unimplemented;
7286 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7287 register_name = "UserTraceData";
7288 goto cp0_unimplemented;
7290 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7291 register_name = "TraceBPC";
7292 goto cp0_unimplemented;
7294 goto cp0_unimplemented;
7297 case CP0_REGISTER_24:
7301 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7302 tcg_gen_ext32s_tl(arg, arg);
7303 register_name = "DEPC";
7306 goto cp0_unimplemented;
7309 case CP0_REGISTER_25:
7312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7313 register_name = "Performance0";
7316 // gen_helper_mfc0_performance1(arg);
7317 register_name = "Performance1";
7318 goto cp0_unimplemented;
7320 // gen_helper_mfc0_performance2(arg);
7321 register_name = "Performance2";
7322 goto cp0_unimplemented;
7324 // gen_helper_mfc0_performance3(arg);
7325 register_name = "Performance3";
7326 goto cp0_unimplemented;
7328 // gen_helper_mfc0_performance4(arg);
7329 register_name = "Performance4";
7330 goto cp0_unimplemented;
7332 // gen_helper_mfc0_performance5(arg);
7333 register_name = "Performance5";
7334 goto cp0_unimplemented;
7336 // gen_helper_mfc0_performance6(arg);
7337 register_name = "Performance6";
7338 goto cp0_unimplemented;
7340 // gen_helper_mfc0_performance7(arg);
7341 register_name = "Performance7";
7342 goto cp0_unimplemented;
7344 goto cp0_unimplemented;
7347 case CP0_REGISTER_26:
7350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7351 register_name = "ErrCtl";
7354 goto cp0_unimplemented;
7357 case CP0_REGISTER_27:
7363 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7364 register_name = "CacheErr";
7367 goto cp0_unimplemented;
7370 case CP0_REGISTER_28:
7377 TCGv_i64 tmp = tcg_temp_new_i64();
7378 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7379 gen_move_low32(arg, tmp);
7380 tcg_temp_free_i64(tmp);
7382 register_name = "TagLo";
7388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7389 register_name = "DataLo";
7392 goto cp0_unimplemented;
7395 case CP0_REGISTER_29:
7401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7402 register_name = "TagHi";
7408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7409 register_name = "DataHi";
7412 goto cp0_unimplemented;
7415 case CP0_REGISTER_30:
7418 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7419 tcg_gen_ext32s_tl(arg, arg);
7420 register_name = "ErrorEPC";
7423 goto cp0_unimplemented;
7426 case CP0_REGISTER_31:
7430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7431 register_name = "DESAVE";
7439 CP0_CHECK(ctx->kscrexist & (1 << sel));
7440 tcg_gen_ld_tl(arg, cpu_env,
7441 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7442 tcg_gen_ext32s_tl(arg, arg);
7443 register_name = "KScratch";
7446 goto cp0_unimplemented;
7450 goto cp0_unimplemented;
7452 trace_mips_translate_c0("mfc0", register_name, reg, sel);
7456 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7457 register_name, reg, sel);
7458 gen_mfc0_unimplemented(ctx, arg);
7461 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7463 const char *register_name = "invalid";
7466 check_insn(ctx, ISA_MIPS32);
7468 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7473 case CP0_REGISTER_00:
7476 gen_helper_mtc0_index(cpu_env, arg);
7477 register_name = "Index";
7480 CP0_CHECK(ctx->insn_flags & ASE_MT);
7481 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7482 register_name = "MVPControl";
7485 CP0_CHECK(ctx->insn_flags & ASE_MT);
7487 register_name = "MVPConf0";
7490 CP0_CHECK(ctx->insn_flags & ASE_MT);
7492 register_name = "MVPConf1";
7497 register_name = "VPControl";
7500 goto cp0_unimplemented;
7503 case CP0_REGISTER_01:
7507 register_name = "Random";
7510 CP0_CHECK(ctx->insn_flags & ASE_MT);
7511 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7512 register_name = "VPEControl";
7515 CP0_CHECK(ctx->insn_flags & ASE_MT);
7516 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7517 register_name = "VPEConf0";
7520 CP0_CHECK(ctx->insn_flags & ASE_MT);
7521 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7522 register_name = "VPEConf1";
7525 CP0_CHECK(ctx->insn_flags & ASE_MT);
7526 gen_helper_mtc0_yqmask(cpu_env, arg);
7527 register_name = "YQMask";
7530 CP0_CHECK(ctx->insn_flags & ASE_MT);
7531 tcg_gen_st_tl(arg, cpu_env,
7532 offsetof(CPUMIPSState, CP0_VPESchedule));
7533 register_name = "VPESchedule";
7536 CP0_CHECK(ctx->insn_flags & ASE_MT);
7537 tcg_gen_st_tl(arg, cpu_env,
7538 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7539 register_name = "VPEScheFBack";
7542 CP0_CHECK(ctx->insn_flags & ASE_MT);
7543 gen_helper_mtc0_vpeopt(cpu_env, arg);
7544 register_name = "VPEOpt";
7547 goto cp0_unimplemented;
7550 case CP0_REGISTER_02:
7553 gen_helper_mtc0_entrylo0(cpu_env, arg);
7554 register_name = "EntryLo0";
7557 CP0_CHECK(ctx->insn_flags & ASE_MT);
7558 gen_helper_mtc0_tcstatus(cpu_env, arg);
7559 register_name = "TCStatus";
7562 CP0_CHECK(ctx->insn_flags & ASE_MT);
7563 gen_helper_mtc0_tcbind(cpu_env, arg);
7564 register_name = "TCBind";
7567 CP0_CHECK(ctx->insn_flags & ASE_MT);
7568 gen_helper_mtc0_tcrestart(cpu_env, arg);
7569 register_name = "TCRestart";
7572 CP0_CHECK(ctx->insn_flags & ASE_MT);
7573 gen_helper_mtc0_tchalt(cpu_env, arg);
7574 register_name = "TCHalt";
7577 CP0_CHECK(ctx->insn_flags & ASE_MT);
7578 gen_helper_mtc0_tccontext(cpu_env, arg);
7579 register_name = "TCContext";
7582 CP0_CHECK(ctx->insn_flags & ASE_MT);
7583 gen_helper_mtc0_tcschedule(cpu_env, arg);
7584 register_name = "TCSchedule";
7587 CP0_CHECK(ctx->insn_flags & ASE_MT);
7588 gen_helper_mtc0_tcschefback(cpu_env, arg);
7589 register_name = "TCScheFBack";
7592 goto cp0_unimplemented;
7595 case CP0_REGISTER_03:
7598 gen_helper_mtc0_entrylo1(cpu_env, arg);
7599 register_name = "EntryLo1";
7604 register_name = "GlobalNumber";
7607 goto cp0_unimplemented;
7610 case CP0_REGISTER_04:
7613 gen_helper_mtc0_context(cpu_env, arg);
7614 register_name = "Context";
7617 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7618 register_name = "ContextConfig";
7619 goto cp0_unimplemented;
7621 CP0_CHECK(ctx->ulri);
7622 tcg_gen_st_tl(arg, cpu_env,
7623 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7624 register_name = "UserLocal";
7627 goto cp0_unimplemented;
7630 case CP0_REGISTER_05:
7633 gen_helper_mtc0_pagemask(cpu_env, arg);
7634 register_name = "PageMask";
7637 check_insn(ctx, ISA_MIPS32R2);
7638 gen_helper_mtc0_pagegrain(cpu_env, arg);
7639 register_name = "PageGrain";
7640 ctx->base.is_jmp = DISAS_STOP;
7644 gen_helper_mtc0_segctl0(cpu_env, arg);
7645 register_name = "SegCtl0";
7649 gen_helper_mtc0_segctl1(cpu_env, arg);
7650 register_name = "SegCtl1";
7654 gen_helper_mtc0_segctl2(cpu_env, arg);
7655 register_name = "SegCtl2";
7659 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7660 register_name = "PWBase";
7664 gen_helper_mtc0_pwfield(cpu_env, arg);
7665 register_name = "PWField";
7669 gen_helper_mtc0_pwsize(cpu_env, arg);
7670 register_name = "PWSize";
7673 goto cp0_unimplemented;
7676 case CP0_REGISTER_06:
7679 gen_helper_mtc0_wired(cpu_env, arg);
7680 register_name = "Wired";
7683 check_insn(ctx, ISA_MIPS32R2);
7684 gen_helper_mtc0_srsconf0(cpu_env, arg);
7685 register_name = "SRSConf0";
7688 check_insn(ctx, ISA_MIPS32R2);
7689 gen_helper_mtc0_srsconf1(cpu_env, arg);
7690 register_name = "SRSConf1";
7693 check_insn(ctx, ISA_MIPS32R2);
7694 gen_helper_mtc0_srsconf2(cpu_env, arg);
7695 register_name = "SRSConf2";
7698 check_insn(ctx, ISA_MIPS32R2);
7699 gen_helper_mtc0_srsconf3(cpu_env, arg);
7700 register_name = "SRSConf3";
7703 check_insn(ctx, ISA_MIPS32R2);
7704 gen_helper_mtc0_srsconf4(cpu_env, arg);
7705 register_name = "SRSConf4";
7709 gen_helper_mtc0_pwctl(cpu_env, arg);
7710 register_name = "PWCtl";
7713 goto cp0_unimplemented;
7716 case CP0_REGISTER_07:
7719 check_insn(ctx, ISA_MIPS32R2);
7720 gen_helper_mtc0_hwrena(cpu_env, arg);
7721 ctx->base.is_jmp = DISAS_STOP;
7722 register_name = "HWREna";
7725 goto cp0_unimplemented;
7728 case CP0_REGISTER_08:
7732 register_name = "BadVAddr";
7736 register_name = "BadInstr";
7740 register_name = "BadInstrP";
7744 register_name = "BadInstrX";
7747 goto cp0_unimplemented;
7750 case CP0_REGISTER_09:
7753 gen_helper_mtc0_count(cpu_env, arg);
7754 register_name = "Count";
7757 CP0_CHECK(ctx->saar);
7758 gen_helper_mtc0_saari(cpu_env, arg);
7759 register_name = "SAARI";
7762 CP0_CHECK(ctx->saar);
7763 gen_helper_mtc0_saar(cpu_env, arg);
7764 register_name = "SAAR";
7767 goto cp0_unimplemented;
7770 case CP0_REGISTER_10:
7773 gen_helper_mtc0_entryhi(cpu_env, arg);
7774 register_name = "EntryHi";
7777 goto cp0_unimplemented;
7780 case CP0_REGISTER_11:
7783 gen_helper_mtc0_compare(cpu_env, arg);
7784 register_name = "Compare";
7786 /* 6,7 are implementation dependent */
7788 goto cp0_unimplemented;
7791 case CP0_REGISTER_12:
7794 save_cpu_state(ctx, 1);
7795 gen_helper_mtc0_status(cpu_env, arg);
7796 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7797 gen_save_pc(ctx->base.pc_next + 4);
7798 ctx->base.is_jmp = DISAS_EXIT;
7799 register_name = "Status";
7802 check_insn(ctx, ISA_MIPS32R2);
7803 gen_helper_mtc0_intctl(cpu_env, arg);
7804 /* Stop translation as we may have switched the execution mode */
7805 ctx->base.is_jmp = DISAS_STOP;
7806 register_name = "IntCtl";
7809 check_insn(ctx, ISA_MIPS32R2);
7810 gen_helper_mtc0_srsctl(cpu_env, arg);
7811 /* Stop translation as we may have switched the execution mode */
7812 ctx->base.is_jmp = DISAS_STOP;
7813 register_name = "SRSCtl";
7816 check_insn(ctx, ISA_MIPS32R2);
7817 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7818 /* Stop translation as we may have switched the execution mode */
7819 ctx->base.is_jmp = DISAS_STOP;
7820 register_name = "SRSMap";
7823 goto cp0_unimplemented;
7826 case CP0_REGISTER_13:
7829 save_cpu_state(ctx, 1);
7830 gen_helper_mtc0_cause(cpu_env, arg);
7831 /* Stop translation as we may have triggered an interrupt.
7832 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7833 * translated code to check for pending interrupts. */
7834 gen_save_pc(ctx->base.pc_next + 4);
7835 ctx->base.is_jmp = DISAS_EXIT;
7836 register_name = "Cause";
7839 goto cp0_unimplemented;
7842 case CP0_REGISTER_14:
7845 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7846 register_name = "EPC";
7849 goto cp0_unimplemented;
7852 case CP0_REGISTER_15:
7856 register_name = "PRid";
7859 check_insn(ctx, ISA_MIPS32R2);
7860 gen_helper_mtc0_ebase(cpu_env, arg);
7861 register_name = "EBase";
7864 goto cp0_unimplemented;
7867 case CP0_REGISTER_16:
7870 gen_helper_mtc0_config0(cpu_env, arg);
7871 register_name = "Config";
7872 /* Stop translation as we may have switched the execution mode */
7873 ctx->base.is_jmp = DISAS_STOP;
7876 /* ignored, read only */
7877 register_name = "Config1";
7880 gen_helper_mtc0_config2(cpu_env, arg);
7881 register_name = "Config2";
7882 /* Stop translation as we may have switched the execution mode */
7883 ctx->base.is_jmp = DISAS_STOP;
7886 gen_helper_mtc0_config3(cpu_env, arg);
7887 register_name = "Config3";
7888 /* Stop translation as we may have switched the execution mode */
7889 ctx->base.is_jmp = DISAS_STOP;
7892 gen_helper_mtc0_config4(cpu_env, arg);
7893 register_name = "Config4";
7894 ctx->base.is_jmp = DISAS_STOP;
7897 gen_helper_mtc0_config5(cpu_env, arg);
7898 register_name = "Config5";
7899 /* Stop translation as we may have switched the execution mode */
7900 ctx->base.is_jmp = DISAS_STOP;
7902 /* 6,7 are implementation dependent */
7905 register_name = "Config6";
7909 register_name = "Config7";
7912 register_name = "Invalid config selector";
7913 goto cp0_unimplemented;
7916 case CP0_REGISTER_17:
7919 gen_helper_mtc0_lladdr(cpu_env, arg);
7920 register_name = "LLAddr";
7923 CP0_CHECK(ctx->mrp);
7924 gen_helper_mtc0_maar(cpu_env, arg);
7925 register_name = "MAAR";
7928 CP0_CHECK(ctx->mrp);
7929 gen_helper_mtc0_maari(cpu_env, arg);
7930 register_name = "MAARI";
7933 goto cp0_unimplemented;
7936 case CP0_REGISTER_18:
7946 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7947 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7948 register_name = "WatchLo";
7951 goto cp0_unimplemented;
7954 case CP0_REGISTER_19:
7964 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7965 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7966 register_name = "WatchHi";
7969 goto cp0_unimplemented;
7972 case CP0_REGISTER_20:
7975 #if defined(TARGET_MIPS64)
7976 check_insn(ctx, ISA_MIPS3);
7977 gen_helper_mtc0_xcontext(cpu_env, arg);
7978 register_name = "XContext";
7982 goto cp0_unimplemented;
7985 case CP0_REGISTER_21:
7986 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7987 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7990 gen_helper_mtc0_framemask(cpu_env, arg);
7991 register_name = "Framemask";
7994 goto cp0_unimplemented;
7997 case CP0_REGISTER_22:
7999 register_name = "Diagnostic"; /* implementation dependent */
8001 case CP0_REGISTER_23:
8004 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8005 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8006 gen_save_pc(ctx->base.pc_next + 4);
8007 ctx->base.is_jmp = DISAS_EXIT;
8008 register_name = "Debug";
8011 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8012 register_name = "TraceControl";
8013 /* Stop translation as we may have switched the execution mode */
8014 ctx->base.is_jmp = DISAS_STOP;
8015 goto cp0_unimplemented;
8017 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8018 register_name = "TraceControl2";
8019 /* Stop translation as we may have switched the execution mode */
8020 ctx->base.is_jmp = DISAS_STOP;
8021 goto cp0_unimplemented;
8023 /* Stop translation as we may have switched the execution mode */
8024 ctx->base.is_jmp = DISAS_STOP;
8025 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8026 register_name = "UserTraceData";
8027 /* Stop translation as we may have switched the execution mode */
8028 ctx->base.is_jmp = DISAS_STOP;
8029 goto cp0_unimplemented;
8031 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8032 /* Stop translation as we may have switched the execution mode */
8033 ctx->base.is_jmp = DISAS_STOP;
8034 register_name = "TraceBPC";
8035 goto cp0_unimplemented;
8037 goto cp0_unimplemented;
8040 case CP0_REGISTER_24:
8044 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8045 register_name = "DEPC";
8048 goto cp0_unimplemented;
8051 case CP0_REGISTER_25:
8054 gen_helper_mtc0_performance0(cpu_env, arg);
8055 register_name = "Performance0";
8058 // gen_helper_mtc0_performance1(arg);
8059 register_name = "Performance1";
8060 goto cp0_unimplemented;
8062 // gen_helper_mtc0_performance2(arg);
8063 register_name = "Performance2";
8064 goto cp0_unimplemented;
8066 // gen_helper_mtc0_performance3(arg);
8067 register_name = "Performance3";
8068 goto cp0_unimplemented;
8070 // gen_helper_mtc0_performance4(arg);
8071 register_name = "Performance4";
8072 goto cp0_unimplemented;
8074 // gen_helper_mtc0_performance5(arg);
8075 register_name = "Performance5";
8076 goto cp0_unimplemented;
8078 // gen_helper_mtc0_performance6(arg);
8079 register_name = "Performance6";
8080 goto cp0_unimplemented;
8082 // gen_helper_mtc0_performance7(arg);
8083 register_name = "Performance7";
8084 goto cp0_unimplemented;
8086 goto cp0_unimplemented;
8089 case CP0_REGISTER_26:
8092 gen_helper_mtc0_errctl(cpu_env, arg);
8093 ctx->base.is_jmp = DISAS_STOP;
8094 register_name = "ErrCtl";
8097 goto cp0_unimplemented;
8100 case CP0_REGISTER_27:
8107 register_name = "CacheErr";
8110 goto cp0_unimplemented;
8113 case CP0_REGISTER_28:
8119 gen_helper_mtc0_taglo(cpu_env, arg);
8120 register_name = "TagLo";
8126 gen_helper_mtc0_datalo(cpu_env, arg);
8127 register_name = "DataLo";
8130 goto cp0_unimplemented;
8133 case CP0_REGISTER_29:
8139 gen_helper_mtc0_taghi(cpu_env, arg);
8140 register_name = "TagHi";
8146 gen_helper_mtc0_datahi(cpu_env, arg);
8147 register_name = "DataHi";
8150 register_name = "invalid sel";
8151 goto cp0_unimplemented;
8154 case CP0_REGISTER_30:
8157 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8158 register_name = "ErrorEPC";
8161 goto cp0_unimplemented;
8164 case CP0_REGISTER_31:
8168 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8169 register_name = "DESAVE";
8177 CP0_CHECK(ctx->kscrexist & (1 << sel));
8178 tcg_gen_st_tl(arg, cpu_env,
8179 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8180 register_name = "KScratch";
8183 goto cp0_unimplemented;
8187 goto cp0_unimplemented;
8189 trace_mips_translate_c0("mtc0", register_name, reg, sel);
8191 /* For simplicity assume that all writes can cause interrupts. */
8192 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8194 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8195 * translated code to check for pending interrupts. */
8196 gen_save_pc(ctx->base.pc_next + 4);
8197 ctx->base.is_jmp = DISAS_EXIT;
8202 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8203 register_name, reg, sel);
8206 #if defined(TARGET_MIPS64)
8207 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8209 const char *register_name = "invalid";
8212 check_insn(ctx, ISA_MIPS64);
8215 case CP0_REGISTER_00:
8218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8219 register_name = "Index";
8222 CP0_CHECK(ctx->insn_flags & ASE_MT);
8223 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8224 register_name = "MVPControl";
8227 CP0_CHECK(ctx->insn_flags & ASE_MT);
8228 gen_helper_mfc0_mvpconf0(arg, cpu_env);
8229 register_name = "MVPConf0";
8232 CP0_CHECK(ctx->insn_flags & ASE_MT);
8233 gen_helper_mfc0_mvpconf1(arg, cpu_env);
8234 register_name = "MVPConf1";
8238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8239 register_name = "VPControl";
8242 goto cp0_unimplemented;
8245 case CP0_REGISTER_01:
8248 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8249 gen_helper_mfc0_random(arg, cpu_env);
8250 register_name = "Random";
8253 CP0_CHECK(ctx->insn_flags & ASE_MT);
8254 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8255 register_name = "VPEControl";
8258 CP0_CHECK(ctx->insn_flags & ASE_MT);
8259 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8260 register_name = "VPEConf0";
8263 CP0_CHECK(ctx->insn_flags & ASE_MT);
8264 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8265 register_name = "VPEConf1";
8268 CP0_CHECK(ctx->insn_flags & ASE_MT);
8269 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8270 register_name = "YQMask";
8273 CP0_CHECK(ctx->insn_flags & ASE_MT);
8274 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8275 register_name = "VPESchedule";
8278 CP0_CHECK(ctx->insn_flags & ASE_MT);
8279 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8280 register_name = "VPEScheFBack";
8283 CP0_CHECK(ctx->insn_flags & ASE_MT);
8284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8285 register_name = "VPEOpt";
8288 goto cp0_unimplemented;
8291 case CP0_REGISTER_02:
8294 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8295 register_name = "EntryLo0";
8298 CP0_CHECK(ctx->insn_flags & ASE_MT);
8299 gen_helper_mfc0_tcstatus(arg, cpu_env);
8300 register_name = "TCStatus";
8303 CP0_CHECK(ctx->insn_flags & ASE_MT);
8304 gen_helper_mfc0_tcbind(arg, cpu_env);
8305 register_name = "TCBind";
8308 CP0_CHECK(ctx->insn_flags & ASE_MT);
8309 gen_helper_dmfc0_tcrestart(arg, cpu_env);
8310 register_name = "TCRestart";
8313 CP0_CHECK(ctx->insn_flags & ASE_MT);
8314 gen_helper_dmfc0_tchalt(arg, cpu_env);
8315 register_name = "TCHalt";
8318 CP0_CHECK(ctx->insn_flags & ASE_MT);
8319 gen_helper_dmfc0_tccontext(arg, cpu_env);
8320 register_name = "TCContext";
8323 CP0_CHECK(ctx->insn_flags & ASE_MT);
8324 gen_helper_dmfc0_tcschedule(arg, cpu_env);
8325 register_name = "TCSchedule";
8328 CP0_CHECK(ctx->insn_flags & ASE_MT);
8329 gen_helper_dmfc0_tcschefback(arg, cpu_env);
8330 register_name = "TCScheFBack";
8333 goto cp0_unimplemented;
8336 case CP0_REGISTER_03:
8339 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8340 register_name = "EntryLo1";
8344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8345 register_name = "GlobalNumber";
8348 goto cp0_unimplemented;
8351 case CP0_REGISTER_04:
8354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8355 register_name = "Context";
8358 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8359 register_name = "ContextConfig";
8360 goto cp0_unimplemented;
8362 CP0_CHECK(ctx->ulri);
8363 tcg_gen_ld_tl(arg, cpu_env,
8364 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8365 register_name = "UserLocal";
8368 goto cp0_unimplemented;
8371 case CP0_REGISTER_05:
8374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8375 register_name = "PageMask";
8378 check_insn(ctx, ISA_MIPS32R2);
8379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8380 register_name = "PageGrain";
8384 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8385 register_name = "SegCtl0";
8389 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8390 register_name = "SegCtl1";
8394 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8395 register_name = "SegCtl2";
8399 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8400 register_name = "PWBase";
8404 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8405 register_name = "PWField";
8409 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8410 register_name = "PWSize";
8413 goto cp0_unimplemented;
8416 case CP0_REGISTER_06:
8419 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8420 register_name = "Wired";
8423 check_insn(ctx, ISA_MIPS32R2);
8424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8425 register_name = "SRSConf0";
8428 check_insn(ctx, ISA_MIPS32R2);
8429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8430 register_name = "SRSConf1";
8433 check_insn(ctx, ISA_MIPS32R2);
8434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8435 register_name = "SRSConf2";
8438 check_insn(ctx, ISA_MIPS32R2);
8439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8440 register_name = "SRSConf3";
8443 check_insn(ctx, ISA_MIPS32R2);
8444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8445 register_name = "SRSConf4";
8449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8450 register_name = "PWCtl";
8453 goto cp0_unimplemented;
8456 case CP0_REGISTER_07:
8459 check_insn(ctx, ISA_MIPS32R2);
8460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8461 register_name = "HWREna";
8464 goto cp0_unimplemented;
8467 case CP0_REGISTER_08:
8470 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8471 register_name = "BadVAddr";
8475 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8476 register_name = "BadInstr";
8480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8481 register_name = "BadInstrP";
8485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8486 tcg_gen_andi_tl(arg, arg, ~0xffff);
8487 register_name = "BadInstrX";
8490 goto cp0_unimplemented;
8493 case CP0_REGISTER_09:
8496 /* Mark as an IO operation because we read the time. */
8497 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8500 gen_helper_mfc0_count(arg, cpu_env);
8501 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8504 /* Break the TB to be able to take timer interrupts immediately
8505 after reading count. DISAS_STOP isn't sufficient, we need to
8506 ensure we break completely out of translated code. */
8507 gen_save_pc(ctx->base.pc_next + 4);
8508 ctx->base.is_jmp = DISAS_EXIT;
8509 register_name = "Count";
8512 CP0_CHECK(ctx->saar);
8513 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8514 register_name = "SAARI";
8517 CP0_CHECK(ctx->saar);
8518 gen_helper_dmfc0_saar(arg, cpu_env);
8519 register_name = "SAAR";
8522 goto cp0_unimplemented;
8525 case CP0_REGISTER_10:
8528 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8529 register_name = "EntryHi";
8532 goto cp0_unimplemented;
8535 case CP0_REGISTER_11:
8538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8539 register_name = "Compare";
8541 /* 6,7 are implementation dependent */
8543 goto cp0_unimplemented;
8546 case CP0_REGISTER_12:
8549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8550 register_name = "Status";
8553 check_insn(ctx, ISA_MIPS32R2);
8554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8555 register_name = "IntCtl";
8558 check_insn(ctx, ISA_MIPS32R2);
8559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8560 register_name = "SRSCtl";
8563 check_insn(ctx, ISA_MIPS32R2);
8564 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8565 register_name = "SRSMap";
8568 goto cp0_unimplemented;
8571 case CP0_REGISTER_13:
8574 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8575 register_name = "Cause";
8578 goto cp0_unimplemented;
8581 case CP0_REGISTER_14:
8584 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8585 register_name = "EPC";
8588 goto cp0_unimplemented;
8591 case CP0_REGISTER_15:
8594 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8595 register_name = "PRid";
8598 check_insn(ctx, ISA_MIPS32R2);
8599 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8600 register_name = "EBase";
8603 check_insn(ctx, ISA_MIPS32R2);
8604 CP0_CHECK(ctx->cmgcr);
8605 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8606 register_name = "CMGCRBase";
8609 goto cp0_unimplemented;
8612 case CP0_REGISTER_16:
8615 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8616 register_name = "Config";
8619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8620 register_name = "Config1";
8623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8624 register_name = "Config2";
8627 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8628 register_name = "Config3";
8631 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8632 register_name = "Config4";
8635 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8636 register_name = "Config5";
8638 /* 6,7 are implementation dependent */
8640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8641 register_name = "Config6";
8644 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8645 register_name = "Config7";
8648 goto cp0_unimplemented;
8651 case CP0_REGISTER_17:
8654 gen_helper_dmfc0_lladdr(arg, cpu_env);
8655 register_name = "LLAddr";
8658 CP0_CHECK(ctx->mrp);
8659 gen_helper_dmfc0_maar(arg, cpu_env);
8660 register_name = "MAAR";
8663 CP0_CHECK(ctx->mrp);
8664 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8665 register_name = "MAARI";
8668 goto cp0_unimplemented;
8671 case CP0_REGISTER_18:
8681 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8682 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8683 register_name = "WatchLo";
8686 goto cp0_unimplemented;
8689 case CP0_REGISTER_19:
8699 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8700 gen_helper_1e0i(mfc0_watchhi, arg, sel);
8701 register_name = "WatchHi";
8704 goto cp0_unimplemented;
8707 case CP0_REGISTER_20:
8710 check_insn(ctx, ISA_MIPS3);
8711 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8712 register_name = "XContext";
8715 goto cp0_unimplemented;
8718 case CP0_REGISTER_21:
8719 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8720 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8723 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8724 register_name = "Framemask";
8727 goto cp0_unimplemented;
8730 case CP0_REGISTER_22:
8731 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8732 register_name = "'Diagnostic"; /* implementation dependent */
8734 case CP0_REGISTER_23:
8737 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8738 register_name = "Debug";
8741 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8742 register_name = "TraceControl";
8743 goto cp0_unimplemented;
8745 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8746 register_name = "TraceControl2";
8747 goto cp0_unimplemented;
8749 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8750 register_name = "UserTraceData";
8751 goto cp0_unimplemented;
8753 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8754 register_name = "TraceBPC";
8755 goto cp0_unimplemented;
8757 goto cp0_unimplemented;
8760 case CP0_REGISTER_24:
8764 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8765 register_name = "DEPC";
8768 goto cp0_unimplemented;
8771 case CP0_REGISTER_25:
8774 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8775 register_name = "Performance0";
8778 // gen_helper_dmfc0_performance1(arg);
8779 register_name = "Performance1";
8780 goto cp0_unimplemented;
8782 // gen_helper_dmfc0_performance2(arg);
8783 register_name = "Performance2";
8784 goto cp0_unimplemented;
8786 // gen_helper_dmfc0_performance3(arg);
8787 register_name = "Performance3";
8788 goto cp0_unimplemented;
8790 // gen_helper_dmfc0_performance4(arg);
8791 register_name = "Performance4";
8792 goto cp0_unimplemented;
8794 // gen_helper_dmfc0_performance5(arg);
8795 register_name = "Performance5";
8796 goto cp0_unimplemented;
8798 // gen_helper_dmfc0_performance6(arg);
8799 register_name = "Performance6";
8800 goto cp0_unimplemented;
8802 // gen_helper_dmfc0_performance7(arg);
8803 register_name = "Performance7";
8804 goto cp0_unimplemented;
8806 goto cp0_unimplemented;
8809 case CP0_REGISTER_26:
8812 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8813 register_name = "ErrCtl";
8816 goto cp0_unimplemented;
8819 case CP0_REGISTER_27:
8826 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8827 register_name = "CacheErr";
8830 goto cp0_unimplemented;
8833 case CP0_REGISTER_28:
8839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8840 register_name = "TagLo";
8846 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8847 register_name = "DataLo";
8850 goto cp0_unimplemented;
8853 case CP0_REGISTER_29:
8859 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8860 register_name = "TagHi";
8866 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8867 register_name = "DataHi";
8870 goto cp0_unimplemented;
8873 case CP0_REGISTER_30:
8876 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8877 register_name = "ErrorEPC";
8880 goto cp0_unimplemented;
8883 case CP0_REGISTER_31:
8887 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8888 register_name = "DESAVE";
8896 CP0_CHECK(ctx->kscrexist & (1 << sel));
8897 tcg_gen_ld_tl(arg, cpu_env,
8898 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8899 register_name = "KScratch";
8902 goto cp0_unimplemented;
8906 goto cp0_unimplemented;
8908 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
8912 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
8913 register_name, reg, sel);
8914 gen_mfc0_unimplemented(ctx, arg);
8917 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8919 const char *register_name = "invalid";
8922 check_insn(ctx, ISA_MIPS64);
8924 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8929 case CP0_REGISTER_00:
8932 gen_helper_mtc0_index(cpu_env, arg);
8933 register_name = "Index";
8936 CP0_CHECK(ctx->insn_flags & ASE_MT);
8937 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8938 register_name = "MVPControl";
8941 CP0_CHECK(ctx->insn_flags & ASE_MT);
8943 register_name = "MVPConf0";
8946 CP0_CHECK(ctx->insn_flags & ASE_MT);
8948 register_name = "MVPConf1";
8953 register_name = "VPControl";
8956 goto cp0_unimplemented;
8959 case CP0_REGISTER_01:
8963 register_name = "Random";
8966 CP0_CHECK(ctx->insn_flags & ASE_MT);
8967 gen_helper_mtc0_vpecontrol(cpu_env, arg);
8968 register_name = "VPEControl";
8971 CP0_CHECK(ctx->insn_flags & ASE_MT);
8972 gen_helper_mtc0_vpeconf0(cpu_env, arg);
8973 register_name = "VPEConf0";
8976 CP0_CHECK(ctx->insn_flags & ASE_MT);
8977 gen_helper_mtc0_vpeconf1(cpu_env, arg);
8978 register_name = "VPEConf1";
8981 CP0_CHECK(ctx->insn_flags & ASE_MT);
8982 gen_helper_mtc0_yqmask(cpu_env, arg);
8983 register_name = "YQMask";
8986 CP0_CHECK(ctx->insn_flags & ASE_MT);
8987 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8988 register_name = "VPESchedule";
8991 CP0_CHECK(ctx->insn_flags & ASE_MT);
8992 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8993 register_name = "VPEScheFBack";
8996 CP0_CHECK(ctx->insn_flags & ASE_MT);
8997 gen_helper_mtc0_vpeopt(cpu_env, arg);
8998 register_name = "VPEOpt";
9001 goto cp0_unimplemented;
9004 case CP0_REGISTER_02:
9007 gen_helper_dmtc0_entrylo0(cpu_env, arg);
9008 register_name = "EntryLo0";
9011 CP0_CHECK(ctx->insn_flags & ASE_MT);
9012 gen_helper_mtc0_tcstatus(cpu_env, arg);
9013 register_name = "TCStatus";
9016 CP0_CHECK(ctx->insn_flags & ASE_MT);
9017 gen_helper_mtc0_tcbind(cpu_env, arg);
9018 register_name = "TCBind";
9021 CP0_CHECK(ctx->insn_flags & ASE_MT);
9022 gen_helper_mtc0_tcrestart(cpu_env, arg);
9023 register_name = "TCRestart";
9026 CP0_CHECK(ctx->insn_flags & ASE_MT);
9027 gen_helper_mtc0_tchalt(cpu_env, arg);
9028 register_name = "TCHalt";
9031 CP0_CHECK(ctx->insn_flags & ASE_MT);
9032 gen_helper_mtc0_tccontext(cpu_env, arg);
9033 register_name = "TCContext";
9036 CP0_CHECK(ctx->insn_flags & ASE_MT);
9037 gen_helper_mtc0_tcschedule(cpu_env, arg);
9038 register_name = "TCSchedule";
9041 CP0_CHECK(ctx->insn_flags & ASE_MT);
9042 gen_helper_mtc0_tcschefback(cpu_env, arg);
9043 register_name = "TCScheFBack";
9046 goto cp0_unimplemented;
9049 case CP0_REGISTER_03:
9052 gen_helper_dmtc0_entrylo1(cpu_env, arg);
9053 register_name = "EntryLo1";
9058 register_name = "GlobalNumber";
9061 goto cp0_unimplemented;
9064 case CP0_REGISTER_04:
9067 gen_helper_mtc0_context(cpu_env, arg);
9068 register_name = "Context";
9071 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
9072 register_name = "ContextConfig";
9073 goto cp0_unimplemented;
9075 CP0_CHECK(ctx->ulri);
9076 tcg_gen_st_tl(arg, cpu_env,
9077 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9078 register_name = "UserLocal";
9081 goto cp0_unimplemented;
9084 case CP0_REGISTER_05:
9087 gen_helper_mtc0_pagemask(cpu_env, arg);
9088 register_name = "PageMask";
9091 check_insn(ctx, ISA_MIPS32R2);
9092 gen_helper_mtc0_pagegrain(cpu_env, arg);
9093 register_name = "PageGrain";
9097 gen_helper_mtc0_segctl0(cpu_env, arg);
9098 register_name = "SegCtl0";
9102 gen_helper_mtc0_segctl1(cpu_env, arg);
9103 register_name = "SegCtl1";
9107 gen_helper_mtc0_segctl2(cpu_env, arg);
9108 register_name = "SegCtl2";
9112 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9113 register_name = "PWBase";
9117 gen_helper_mtc0_pwfield(cpu_env, arg);
9118 register_name = "PWField";
9122 gen_helper_mtc0_pwsize(cpu_env, arg);
9123 register_name = "PWSize";
9126 goto cp0_unimplemented;
9129 case CP0_REGISTER_06:
9132 gen_helper_mtc0_wired(cpu_env, arg);
9133 register_name = "Wired";
9136 check_insn(ctx, ISA_MIPS32R2);
9137 gen_helper_mtc0_srsconf0(cpu_env, arg);
9138 register_name = "SRSConf0";
9141 check_insn(ctx, ISA_MIPS32R2);
9142 gen_helper_mtc0_srsconf1(cpu_env, arg);
9143 register_name = "SRSConf1";
9146 check_insn(ctx, ISA_MIPS32R2);
9147 gen_helper_mtc0_srsconf2(cpu_env, arg);
9148 register_name = "SRSConf2";
9151 check_insn(ctx, ISA_MIPS32R2);
9152 gen_helper_mtc0_srsconf3(cpu_env, arg);
9153 register_name = "SRSConf3";
9156 check_insn(ctx, ISA_MIPS32R2);
9157 gen_helper_mtc0_srsconf4(cpu_env, arg);
9158 register_name = "SRSConf4";
9162 gen_helper_mtc0_pwctl(cpu_env, arg);
9163 register_name = "PWCtl";
9166 goto cp0_unimplemented;
9169 case CP0_REGISTER_07:
9172 check_insn(ctx, ISA_MIPS32R2);
9173 gen_helper_mtc0_hwrena(cpu_env, arg);
9174 ctx->base.is_jmp = DISAS_STOP;
9175 register_name = "HWREna";
9178 goto cp0_unimplemented;
9181 case CP0_REGISTER_08:
9185 register_name = "BadVAddr";
9189 register_name = "BadInstr";
9193 register_name = "BadInstrP";
9197 register_name = "BadInstrX";
9200 goto cp0_unimplemented;
9203 case CP0_REGISTER_09:
9206 gen_helper_mtc0_count(cpu_env, arg);
9207 register_name = "Count";
9210 CP0_CHECK(ctx->saar);
9211 gen_helper_mtc0_saari(cpu_env, arg);
9212 register_name = "SAARI";
9215 CP0_CHECK(ctx->saar);
9216 gen_helper_mtc0_saar(cpu_env, arg);
9217 register_name = "SAAR";
9220 goto cp0_unimplemented;
9222 /* Stop translation as we may have switched the execution mode */
9223 ctx->base.is_jmp = DISAS_STOP;
9225 case CP0_REGISTER_10:
9228 gen_helper_mtc0_entryhi(cpu_env, arg);
9229 register_name = "EntryHi";
9232 goto cp0_unimplemented;
9235 case CP0_REGISTER_11:
9238 gen_helper_mtc0_compare(cpu_env, arg);
9239 register_name = "Compare";
9241 /* 6,7 are implementation dependent */
9243 goto cp0_unimplemented;
9245 /* Stop translation as we may have switched the execution mode */
9246 ctx->base.is_jmp = DISAS_STOP;
9248 case CP0_REGISTER_12:
9251 save_cpu_state(ctx, 1);
9252 gen_helper_mtc0_status(cpu_env, arg);
9253 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9254 gen_save_pc(ctx->base.pc_next + 4);
9255 ctx->base.is_jmp = DISAS_EXIT;
9256 register_name = "Status";
9259 check_insn(ctx, ISA_MIPS32R2);
9260 gen_helper_mtc0_intctl(cpu_env, arg);
9261 /* Stop translation as we may have switched the execution mode */
9262 ctx->base.is_jmp = DISAS_STOP;
9263 register_name = "IntCtl";
9266 check_insn(ctx, ISA_MIPS32R2);
9267 gen_helper_mtc0_srsctl(cpu_env, arg);
9268 /* Stop translation as we may have switched the execution mode */
9269 ctx->base.is_jmp = DISAS_STOP;
9270 register_name = "SRSCtl";
9273 check_insn(ctx, ISA_MIPS32R2);
9274 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9275 /* Stop translation as we may have switched the execution mode */
9276 ctx->base.is_jmp = DISAS_STOP;
9277 register_name = "SRSMap";
9280 goto cp0_unimplemented;
9283 case CP0_REGISTER_13:
9286 save_cpu_state(ctx, 1);
9287 gen_helper_mtc0_cause(cpu_env, arg);
9288 /* Stop translation as we may have triggered an interrupt.
9289 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9290 * translated code to check for pending interrupts. */
9291 gen_save_pc(ctx->base.pc_next + 4);
9292 ctx->base.is_jmp = DISAS_EXIT;
9293 register_name = "Cause";
9296 goto cp0_unimplemented;
9299 case CP0_REGISTER_14:
9302 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9303 register_name = "EPC";
9306 goto cp0_unimplemented;
9309 case CP0_REGISTER_15:
9313 register_name = "PRid";
9316 check_insn(ctx, ISA_MIPS32R2);
9317 gen_helper_mtc0_ebase(cpu_env, arg);
9318 register_name = "EBase";
9321 goto cp0_unimplemented;
9324 case CP0_REGISTER_16:
9327 gen_helper_mtc0_config0(cpu_env, arg);
9328 register_name = "Config";
9329 /* Stop translation as we may have switched the execution mode */
9330 ctx->base.is_jmp = DISAS_STOP;
9333 /* ignored, read only */
9334 register_name = "Config1";
9337 gen_helper_mtc0_config2(cpu_env, arg);
9338 register_name = "Config2";
9339 /* Stop translation as we may have switched the execution mode */
9340 ctx->base.is_jmp = DISAS_STOP;
9343 gen_helper_mtc0_config3(cpu_env, arg);
9344 register_name = "Config3";
9345 /* Stop translation as we may have switched the execution mode */
9346 ctx->base.is_jmp = DISAS_STOP;
9349 /* currently ignored */
9350 register_name = "Config4";
9353 gen_helper_mtc0_config5(cpu_env, arg);
9354 register_name = "Config5";
9355 /* Stop translation as we may have switched the execution mode */
9356 ctx->base.is_jmp = DISAS_STOP;
9358 /* 6,7 are implementation dependent */
9360 register_name = "Invalid config selector";
9361 goto cp0_unimplemented;
9364 case CP0_REGISTER_17:
9367 gen_helper_mtc0_lladdr(cpu_env, arg);
9368 register_name = "LLAddr";
9371 CP0_CHECK(ctx->mrp);
9372 gen_helper_mtc0_maar(cpu_env, arg);
9373 register_name = "MAAR";
9376 CP0_CHECK(ctx->mrp);
9377 gen_helper_mtc0_maari(cpu_env, arg);
9378 register_name = "MAARI";
9381 goto cp0_unimplemented;
9384 case CP0_REGISTER_18:
9394 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9395 gen_helper_0e1i(mtc0_watchlo, arg, sel);
9396 register_name = "WatchLo";
9399 goto cp0_unimplemented;
9402 case CP0_REGISTER_19:
9412 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9413 gen_helper_0e1i(mtc0_watchhi, arg, sel);
9414 register_name = "WatchHi";
9417 goto cp0_unimplemented;
9420 case CP0_REGISTER_20:
9423 check_insn(ctx, ISA_MIPS3);
9424 gen_helper_mtc0_xcontext(cpu_env, arg);
9425 register_name = "XContext";
9428 goto cp0_unimplemented;
9431 case CP0_REGISTER_21:
9432 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9433 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9436 gen_helper_mtc0_framemask(cpu_env, arg);
9437 register_name = "Framemask";
9440 goto cp0_unimplemented;
9443 case CP0_REGISTER_22:
9445 register_name = "Diagnostic"; /* implementation dependent */
9447 case CP0_REGISTER_23:
9450 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9451 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9452 gen_save_pc(ctx->base.pc_next + 4);
9453 ctx->base.is_jmp = DISAS_EXIT;
9454 register_name = "Debug";
9457 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9458 /* Stop translation as we may have switched the execution mode */
9459 ctx->base.is_jmp = DISAS_STOP;
9460 register_name = "TraceControl";
9461 goto cp0_unimplemented;
9463 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9464 /* Stop translation as we may have switched the execution mode */
9465 ctx->base.is_jmp = DISAS_STOP;
9466 register_name = "TraceControl2";
9467 goto cp0_unimplemented;
9469 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9470 /* Stop translation as we may have switched the execution mode */
9471 ctx->base.is_jmp = DISAS_STOP;
9472 register_name = "UserTraceData";
9473 goto cp0_unimplemented;
9475 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9476 /* Stop translation as we may have switched the execution mode */
9477 ctx->base.is_jmp = DISAS_STOP;
9478 register_name = "TraceBPC";
9479 goto cp0_unimplemented;
9481 goto cp0_unimplemented;
9484 case CP0_REGISTER_24:
9488 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9489 register_name = "DEPC";
9492 goto cp0_unimplemented;
9495 case CP0_REGISTER_25:
9498 gen_helper_mtc0_performance0(cpu_env, arg);
9499 register_name = "Performance0";
9502 // gen_helper_mtc0_performance1(cpu_env, arg);
9503 register_name = "Performance1";
9504 goto cp0_unimplemented;
9506 // gen_helper_mtc0_performance2(cpu_env, arg);
9507 register_name = "Performance2";
9508 goto cp0_unimplemented;
9510 // gen_helper_mtc0_performance3(cpu_env, arg);
9511 register_name = "Performance3";
9512 goto cp0_unimplemented;
9514 // gen_helper_mtc0_performance4(cpu_env, arg);
9515 register_name = "Performance4";
9516 goto cp0_unimplemented;
9518 // gen_helper_mtc0_performance5(cpu_env, arg);
9519 register_name = "Performance5";
9520 goto cp0_unimplemented;
9522 // gen_helper_mtc0_performance6(cpu_env, arg);
9523 register_name = "Performance6";
9524 goto cp0_unimplemented;
9526 // gen_helper_mtc0_performance7(cpu_env, arg);
9527 register_name = "Performance7";
9528 goto cp0_unimplemented;
9530 goto cp0_unimplemented;
9533 case CP0_REGISTER_26:
9536 gen_helper_mtc0_errctl(cpu_env, arg);
9537 ctx->base.is_jmp = DISAS_STOP;
9538 register_name = "ErrCtl";
9541 goto cp0_unimplemented;
9544 case CP0_REGISTER_27:
9551 register_name = "CacheErr";
9554 goto cp0_unimplemented;
9557 case CP0_REGISTER_28:
9563 gen_helper_mtc0_taglo(cpu_env, arg);
9564 register_name = "TagLo";
9570 gen_helper_mtc0_datalo(cpu_env, arg);
9571 register_name = "DataLo";
9574 goto cp0_unimplemented;
9577 case CP0_REGISTER_29:
9583 gen_helper_mtc0_taghi(cpu_env, arg);
9584 register_name = "TagHi";
9590 gen_helper_mtc0_datahi(cpu_env, arg);
9591 register_name = "DataHi";
9594 register_name = "invalid sel";
9595 goto cp0_unimplemented;
9598 case CP0_REGISTER_30:
9601 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9602 register_name = "ErrorEPC";
9605 goto cp0_unimplemented;
9608 case CP0_REGISTER_31:
9612 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9613 register_name = "DESAVE";
9621 CP0_CHECK(ctx->kscrexist & (1 << sel));
9622 tcg_gen_st_tl(arg, cpu_env,
9623 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9624 register_name = "KScratch";
9627 goto cp0_unimplemented;
9631 goto cp0_unimplemented;
9633 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9635 /* For simplicity assume that all writes can cause interrupts. */
9636 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9638 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9639 * translated code to check for pending interrupts. */
9640 gen_save_pc(ctx->base.pc_next + 4);
9641 ctx->base.is_jmp = DISAS_EXIT;
9646 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9647 register_name, reg, sel);
9649 #endif /* TARGET_MIPS64 */
9651 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9652 int u, int sel, int h)
9654 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9655 TCGv t0 = tcg_temp_local_new();
9657 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9658 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9659 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9660 tcg_gen_movi_tl(t0, -1);
9661 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9662 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9663 tcg_gen_movi_tl(t0, -1);
9669 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9672 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9682 gen_helper_mftc0_tcstatus(t0, cpu_env);
9685 gen_helper_mftc0_tcbind(t0, cpu_env);
9688 gen_helper_mftc0_tcrestart(t0, cpu_env);
9691 gen_helper_mftc0_tchalt(t0, cpu_env);
9694 gen_helper_mftc0_tccontext(t0, cpu_env);
9697 gen_helper_mftc0_tcschedule(t0, cpu_env);
9700 gen_helper_mftc0_tcschefback(t0, cpu_env);
9703 gen_mfc0(ctx, t0, rt, sel);
9710 gen_helper_mftc0_entryhi(t0, cpu_env);
9713 gen_mfc0(ctx, t0, rt, sel);
9719 gen_helper_mftc0_status(t0, cpu_env);
9722 gen_mfc0(ctx, t0, rt, sel);
9728 gen_helper_mftc0_cause(t0, cpu_env);
9738 gen_helper_mftc0_epc(t0, cpu_env);
9748 gen_helper_mftc0_ebase(t0, cpu_env);
9765 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9775 gen_helper_mftc0_debug(t0, cpu_env);
9778 gen_mfc0(ctx, t0, rt, sel);
9783 gen_mfc0(ctx, t0, rt, sel);
9785 } else switch (sel) {
9786 /* GPR registers. */
9788 gen_helper_1e0i(mftgpr, t0, rt);
9790 /* Auxiliary CPU registers */
9794 gen_helper_1e0i(mftlo, t0, 0);
9797 gen_helper_1e0i(mfthi, t0, 0);
9800 gen_helper_1e0i(mftacx, t0, 0);
9803 gen_helper_1e0i(mftlo, t0, 1);
9806 gen_helper_1e0i(mfthi, t0, 1);
9809 gen_helper_1e0i(mftacx, t0, 1);
9812 gen_helper_1e0i(mftlo, t0, 2);
9815 gen_helper_1e0i(mfthi, t0, 2);
9818 gen_helper_1e0i(mftacx, t0, 2);
9821 gen_helper_1e0i(mftlo, t0, 3);
9824 gen_helper_1e0i(mfthi, t0, 3);
9827 gen_helper_1e0i(mftacx, t0, 3);
9830 gen_helper_mftdsp(t0, cpu_env);
9836 /* Floating point (COP1). */
9838 /* XXX: For now we support only a single FPU context. */
9840 TCGv_i32 fp0 = tcg_temp_new_i32();
9842 gen_load_fpr32(ctx, fp0, rt);
9843 tcg_gen_ext_i32_tl(t0, fp0);
9844 tcg_temp_free_i32(fp0);
9846 TCGv_i32 fp0 = tcg_temp_new_i32();
9848 gen_load_fpr32h(ctx, fp0, rt);
9849 tcg_gen_ext_i32_tl(t0, fp0);
9850 tcg_temp_free_i32(fp0);
9854 /* XXX: For now we support only a single FPU context. */
9855 gen_helper_1e0i(cfc1, t0, rt);
9857 /* COP2: Not implemented. */
9864 trace_mips_translate_tr("mftr", rt, u, sel, h);
9865 gen_store_gpr(t0, rd);
9871 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9872 generate_exception_end(ctx, EXCP_RI);
9875 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9876 int u, int sel, int h)
9878 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9879 TCGv t0 = tcg_temp_local_new();
9881 gen_load_gpr(t0, rt);
9882 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9883 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9884 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9886 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9887 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9894 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9897 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9907 gen_helper_mttc0_tcstatus(cpu_env, t0);
9910 gen_helper_mttc0_tcbind(cpu_env, t0);
9913 gen_helper_mttc0_tcrestart(cpu_env, t0);
9916 gen_helper_mttc0_tchalt(cpu_env, t0);
9919 gen_helper_mttc0_tccontext(cpu_env, t0);
9922 gen_helper_mttc0_tcschedule(cpu_env, t0);
9925 gen_helper_mttc0_tcschefback(cpu_env, t0);
9928 gen_mtc0(ctx, t0, rd, sel);
9935 gen_helper_mttc0_entryhi(cpu_env, t0);
9938 gen_mtc0(ctx, t0, rd, sel);
9944 gen_helper_mttc0_status(cpu_env, t0);
9947 gen_mtc0(ctx, t0, rd, sel);
9953 gen_helper_mttc0_cause(cpu_env, t0);
9963 gen_helper_mttc0_ebase(cpu_env, t0);
9973 gen_helper_mttc0_debug(cpu_env, t0);
9976 gen_mtc0(ctx, t0, rd, sel);
9981 gen_mtc0(ctx, t0, rd, sel);
9983 } else switch (sel) {
9984 /* GPR registers. */
9986 gen_helper_0e1i(mttgpr, t0, rd);
9988 /* Auxiliary CPU registers */
9992 gen_helper_0e1i(mttlo, t0, 0);
9995 gen_helper_0e1i(mtthi, t0, 0);
9998 gen_helper_0e1i(mttacx, t0, 0);
10001 gen_helper_0e1i(mttlo, t0, 1);
10004 gen_helper_0e1i(mtthi, t0, 1);
10007 gen_helper_0e1i(mttacx, t0, 1);
10010 gen_helper_0e1i(mttlo, t0, 2);
10013 gen_helper_0e1i(mtthi, t0, 2);
10016 gen_helper_0e1i(mttacx, t0, 2);
10019 gen_helper_0e1i(mttlo, t0, 3);
10022 gen_helper_0e1i(mtthi, t0, 3);
10025 gen_helper_0e1i(mttacx, t0, 3);
10028 gen_helper_mttdsp(cpu_env, t0);
10034 /* Floating point (COP1). */
10036 /* XXX: For now we support only a single FPU context. */
10038 TCGv_i32 fp0 = tcg_temp_new_i32();
10040 tcg_gen_trunc_tl_i32(fp0, t0);
10041 gen_store_fpr32(ctx, fp0, rd);
10042 tcg_temp_free_i32(fp0);
10044 TCGv_i32 fp0 = tcg_temp_new_i32();
10046 tcg_gen_trunc_tl_i32(fp0, t0);
10047 gen_store_fpr32h(ctx, fp0, rd);
10048 tcg_temp_free_i32(fp0);
10052 /* XXX: For now we support only a single FPU context. */
10054 TCGv_i32 fs_tmp = tcg_const_i32(rd);
10056 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10057 tcg_temp_free_i32(fs_tmp);
10059 /* Stop translation as we may have changed hflags */
10060 ctx->base.is_jmp = DISAS_STOP;
10062 /* COP2: Not implemented. */
10069 trace_mips_translate_tr("mttr", rd, u, sel, h);
10075 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10076 generate_exception_end(ctx, EXCP_RI);
10079 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
10081 const char *opn = "ldst";
10083 check_cp0_enabled(ctx);
10087 /* Treat as NOP. */
10090 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10095 TCGv t0 = tcg_temp_new();
10097 gen_load_gpr(t0, rt);
10098 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10103 #if defined(TARGET_MIPS64)
10105 check_insn(ctx, ISA_MIPS3);
10107 /* Treat as NOP. */
10110 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10114 check_insn(ctx, ISA_MIPS3);
10116 TCGv t0 = tcg_temp_new();
10118 gen_load_gpr(t0, rt);
10119 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10128 /* Treat as NOP. */
10131 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10137 TCGv t0 = tcg_temp_new();
10138 gen_load_gpr(t0, rt);
10139 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10145 check_cp0_enabled(ctx);
10147 /* Treat as NOP. */
10150 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10151 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10155 check_cp0_enabled(ctx);
10156 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10157 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10162 if (!env->tlb->helper_tlbwi)
10164 gen_helper_tlbwi(cpu_env);
10168 if (ctx->ie >= 2) {
10169 if (!env->tlb->helper_tlbinv) {
10172 gen_helper_tlbinv(cpu_env);
10173 } /* treat as nop if TLBINV not supported */
10177 if (ctx->ie >= 2) {
10178 if (!env->tlb->helper_tlbinvf) {
10181 gen_helper_tlbinvf(cpu_env);
10182 } /* treat as nop if TLBINV not supported */
10186 if (!env->tlb->helper_tlbwr)
10188 gen_helper_tlbwr(cpu_env);
10192 if (!env->tlb->helper_tlbp)
10194 gen_helper_tlbp(cpu_env);
10198 if (!env->tlb->helper_tlbr)
10200 gen_helper_tlbr(cpu_env);
10202 case OPC_ERET: /* OPC_ERETNC */
10203 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10204 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10207 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10208 if (ctx->opcode & (1 << bit_shift)) {
10211 check_insn(ctx, ISA_MIPS32R5);
10212 gen_helper_eretnc(cpu_env);
10216 check_insn(ctx, ISA_MIPS2);
10217 gen_helper_eret(cpu_env);
10219 ctx->base.is_jmp = DISAS_EXIT;
10224 check_insn(ctx, ISA_MIPS32);
10225 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10226 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10229 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10231 generate_exception_end(ctx, EXCP_RI);
10233 gen_helper_deret(cpu_env);
10234 ctx->base.is_jmp = DISAS_EXIT;
10239 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10240 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10241 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10244 /* If we get an exception, we want to restart at next instruction */
10245 ctx->base.pc_next += 4;
10246 save_cpu_state(ctx, 1);
10247 ctx->base.pc_next -= 4;
10248 gen_helper_wait(cpu_env);
10249 ctx->base.is_jmp = DISAS_NORETURN;
10254 generate_exception_end(ctx, EXCP_RI);
10257 (void)opn; /* avoid a compiler warning */
10259 #endif /* !CONFIG_USER_ONLY */
10261 /* CP1 Branches (before delay slot) */
10262 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10263 int32_t cc, int32_t offset)
10265 target_ulong btarget;
10266 TCGv_i32 t0 = tcg_temp_new_i32();
10268 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10269 generate_exception_end(ctx, EXCP_RI);
10274 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10276 btarget = ctx->base.pc_next + 4 + offset;
10280 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10281 tcg_gen_not_i32(t0, t0);
10282 tcg_gen_andi_i32(t0, t0, 1);
10283 tcg_gen_extu_i32_tl(bcond, t0);
10286 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10287 tcg_gen_not_i32(t0, t0);
10288 tcg_gen_andi_i32(t0, t0, 1);
10289 tcg_gen_extu_i32_tl(bcond, t0);
10292 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10293 tcg_gen_andi_i32(t0, t0, 1);
10294 tcg_gen_extu_i32_tl(bcond, t0);
10297 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10298 tcg_gen_andi_i32(t0, t0, 1);
10299 tcg_gen_extu_i32_tl(bcond, t0);
10301 ctx->hflags |= MIPS_HFLAG_BL;
10305 TCGv_i32 t1 = tcg_temp_new_i32();
10306 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10307 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10308 tcg_gen_nand_i32(t0, t0, t1);
10309 tcg_temp_free_i32(t1);
10310 tcg_gen_andi_i32(t0, t0, 1);
10311 tcg_gen_extu_i32_tl(bcond, t0);
10316 TCGv_i32 t1 = tcg_temp_new_i32();
10317 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10318 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10319 tcg_gen_or_i32(t0, t0, t1);
10320 tcg_temp_free_i32(t1);
10321 tcg_gen_andi_i32(t0, t0, 1);
10322 tcg_gen_extu_i32_tl(bcond, t0);
10327 TCGv_i32 t1 = tcg_temp_new_i32();
10328 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10329 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10330 tcg_gen_and_i32(t0, t0, t1);
10331 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10332 tcg_gen_and_i32(t0, t0, t1);
10333 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10334 tcg_gen_nand_i32(t0, t0, t1);
10335 tcg_temp_free_i32(t1);
10336 tcg_gen_andi_i32(t0, t0, 1);
10337 tcg_gen_extu_i32_tl(bcond, t0);
10342 TCGv_i32 t1 = tcg_temp_new_i32();
10343 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10344 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10345 tcg_gen_or_i32(t0, t0, t1);
10346 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10347 tcg_gen_or_i32(t0, t0, t1);
10348 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10349 tcg_gen_or_i32(t0, t0, t1);
10350 tcg_temp_free_i32(t1);
10351 tcg_gen_andi_i32(t0, t0, 1);
10352 tcg_gen_extu_i32_tl(bcond, t0);
10355 ctx->hflags |= MIPS_HFLAG_BC;
10358 MIPS_INVAL("cp1 cond branch");
10359 generate_exception_end(ctx, EXCP_RI);
10362 ctx->btarget = btarget;
10363 ctx->hflags |= MIPS_HFLAG_BDS32;
10365 tcg_temp_free_i32(t0);
10368 /* R6 CP1 Branches */
10369 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10370 int32_t ft, int32_t offset,
10371 int delayslot_size)
10373 target_ulong btarget;
10374 TCGv_i64 t0 = tcg_temp_new_i64();
10376 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10377 #ifdef MIPS_DEBUG_DISAS
10378 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10379 "\n", ctx->base.pc_next);
10381 generate_exception_end(ctx, EXCP_RI);
10385 gen_load_fpr64(ctx, t0, ft);
10386 tcg_gen_andi_i64(t0, t0, 1);
10388 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10392 tcg_gen_xori_i64(t0, t0, 1);
10393 ctx->hflags |= MIPS_HFLAG_BC;
10396 /* t0 already set */
10397 ctx->hflags |= MIPS_HFLAG_BC;
10400 MIPS_INVAL("cp1 cond branch");
10401 generate_exception_end(ctx, EXCP_RI);
10405 tcg_gen_trunc_i64_tl(bcond, t0);
10407 ctx->btarget = btarget;
10409 switch (delayslot_size) {
10411 ctx->hflags |= MIPS_HFLAG_BDS16;
10414 ctx->hflags |= MIPS_HFLAG_BDS32;
10419 tcg_temp_free_i64(t0);
10422 /* Coprocessor 1 (FPU) */
10424 #define FOP(func, fmt) (((fmt) << 21) | (func))
10427 OPC_ADD_S = FOP(0, FMT_S),
10428 OPC_SUB_S = FOP(1, FMT_S),
10429 OPC_MUL_S = FOP(2, FMT_S),
10430 OPC_DIV_S = FOP(3, FMT_S),
10431 OPC_SQRT_S = FOP(4, FMT_S),
10432 OPC_ABS_S = FOP(5, FMT_S),
10433 OPC_MOV_S = FOP(6, FMT_S),
10434 OPC_NEG_S = FOP(7, FMT_S),
10435 OPC_ROUND_L_S = FOP(8, FMT_S),
10436 OPC_TRUNC_L_S = FOP(9, FMT_S),
10437 OPC_CEIL_L_S = FOP(10, FMT_S),
10438 OPC_FLOOR_L_S = FOP(11, FMT_S),
10439 OPC_ROUND_W_S = FOP(12, FMT_S),
10440 OPC_TRUNC_W_S = FOP(13, FMT_S),
10441 OPC_CEIL_W_S = FOP(14, FMT_S),
10442 OPC_FLOOR_W_S = FOP(15, FMT_S),
10443 OPC_SEL_S = FOP(16, FMT_S),
10444 OPC_MOVCF_S = FOP(17, FMT_S),
10445 OPC_MOVZ_S = FOP(18, FMT_S),
10446 OPC_MOVN_S = FOP(19, FMT_S),
10447 OPC_SELEQZ_S = FOP(20, FMT_S),
10448 OPC_RECIP_S = FOP(21, FMT_S),
10449 OPC_RSQRT_S = FOP(22, FMT_S),
10450 OPC_SELNEZ_S = FOP(23, FMT_S),
10451 OPC_MADDF_S = FOP(24, FMT_S),
10452 OPC_MSUBF_S = FOP(25, FMT_S),
10453 OPC_RINT_S = FOP(26, FMT_S),
10454 OPC_CLASS_S = FOP(27, FMT_S),
10455 OPC_MIN_S = FOP(28, FMT_S),
10456 OPC_RECIP2_S = FOP(28, FMT_S),
10457 OPC_MINA_S = FOP(29, FMT_S),
10458 OPC_RECIP1_S = FOP(29, FMT_S),
10459 OPC_MAX_S = FOP(30, FMT_S),
10460 OPC_RSQRT1_S = FOP(30, FMT_S),
10461 OPC_MAXA_S = FOP(31, FMT_S),
10462 OPC_RSQRT2_S = FOP(31, FMT_S),
10463 OPC_CVT_D_S = FOP(33, FMT_S),
10464 OPC_CVT_W_S = FOP(36, FMT_S),
10465 OPC_CVT_L_S = FOP(37, FMT_S),
10466 OPC_CVT_PS_S = FOP(38, FMT_S),
10467 OPC_CMP_F_S = FOP (48, FMT_S),
10468 OPC_CMP_UN_S = FOP (49, FMT_S),
10469 OPC_CMP_EQ_S = FOP (50, FMT_S),
10470 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10471 OPC_CMP_OLT_S = FOP (52, FMT_S),
10472 OPC_CMP_ULT_S = FOP (53, FMT_S),
10473 OPC_CMP_OLE_S = FOP (54, FMT_S),
10474 OPC_CMP_ULE_S = FOP (55, FMT_S),
10475 OPC_CMP_SF_S = FOP (56, FMT_S),
10476 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10477 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10478 OPC_CMP_NGL_S = FOP (59, FMT_S),
10479 OPC_CMP_LT_S = FOP (60, FMT_S),
10480 OPC_CMP_NGE_S = FOP (61, FMT_S),
10481 OPC_CMP_LE_S = FOP (62, FMT_S),
10482 OPC_CMP_NGT_S = FOP (63, FMT_S),
10484 OPC_ADD_D = FOP(0, FMT_D),
10485 OPC_SUB_D = FOP(1, FMT_D),
10486 OPC_MUL_D = FOP(2, FMT_D),
10487 OPC_DIV_D = FOP(3, FMT_D),
10488 OPC_SQRT_D = FOP(4, FMT_D),
10489 OPC_ABS_D = FOP(5, FMT_D),
10490 OPC_MOV_D = FOP(6, FMT_D),
10491 OPC_NEG_D = FOP(7, FMT_D),
10492 OPC_ROUND_L_D = FOP(8, FMT_D),
10493 OPC_TRUNC_L_D = FOP(9, FMT_D),
10494 OPC_CEIL_L_D = FOP(10, FMT_D),
10495 OPC_FLOOR_L_D = FOP(11, FMT_D),
10496 OPC_ROUND_W_D = FOP(12, FMT_D),
10497 OPC_TRUNC_W_D = FOP(13, FMT_D),
10498 OPC_CEIL_W_D = FOP(14, FMT_D),
10499 OPC_FLOOR_W_D = FOP(15, FMT_D),
10500 OPC_SEL_D = FOP(16, FMT_D),
10501 OPC_MOVCF_D = FOP(17, FMT_D),
10502 OPC_MOVZ_D = FOP(18, FMT_D),
10503 OPC_MOVN_D = FOP(19, FMT_D),
10504 OPC_SELEQZ_D = FOP(20, FMT_D),
10505 OPC_RECIP_D = FOP(21, FMT_D),
10506 OPC_RSQRT_D = FOP(22, FMT_D),
10507 OPC_SELNEZ_D = FOP(23, FMT_D),
10508 OPC_MADDF_D = FOP(24, FMT_D),
10509 OPC_MSUBF_D = FOP(25, FMT_D),
10510 OPC_RINT_D = FOP(26, FMT_D),
10511 OPC_CLASS_D = FOP(27, FMT_D),
10512 OPC_MIN_D = FOP(28, FMT_D),
10513 OPC_RECIP2_D = FOP(28, FMT_D),
10514 OPC_MINA_D = FOP(29, FMT_D),
10515 OPC_RECIP1_D = FOP(29, FMT_D),
10516 OPC_MAX_D = FOP(30, FMT_D),
10517 OPC_RSQRT1_D = FOP(30, FMT_D),
10518 OPC_MAXA_D = FOP(31, FMT_D),
10519 OPC_RSQRT2_D = FOP(31, FMT_D),
10520 OPC_CVT_S_D = FOP(32, FMT_D),
10521 OPC_CVT_W_D = FOP(36, FMT_D),
10522 OPC_CVT_L_D = FOP(37, FMT_D),
10523 OPC_CMP_F_D = FOP (48, FMT_D),
10524 OPC_CMP_UN_D = FOP (49, FMT_D),
10525 OPC_CMP_EQ_D = FOP (50, FMT_D),
10526 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10527 OPC_CMP_OLT_D = FOP (52, FMT_D),
10528 OPC_CMP_ULT_D = FOP (53, FMT_D),
10529 OPC_CMP_OLE_D = FOP (54, FMT_D),
10530 OPC_CMP_ULE_D = FOP (55, FMT_D),
10531 OPC_CMP_SF_D = FOP (56, FMT_D),
10532 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10533 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10534 OPC_CMP_NGL_D = FOP (59, FMT_D),
10535 OPC_CMP_LT_D = FOP (60, FMT_D),
10536 OPC_CMP_NGE_D = FOP (61, FMT_D),
10537 OPC_CMP_LE_D = FOP (62, FMT_D),
10538 OPC_CMP_NGT_D = FOP (63, FMT_D),
10540 OPC_CVT_S_W = FOP(32, FMT_W),
10541 OPC_CVT_D_W = FOP(33, FMT_W),
10542 OPC_CVT_S_L = FOP(32, FMT_L),
10543 OPC_CVT_D_L = FOP(33, FMT_L),
10544 OPC_CVT_PS_PW = FOP(38, FMT_W),
10546 OPC_ADD_PS = FOP(0, FMT_PS),
10547 OPC_SUB_PS = FOP(1, FMT_PS),
10548 OPC_MUL_PS = FOP(2, FMT_PS),
10549 OPC_DIV_PS = FOP(3, FMT_PS),
10550 OPC_ABS_PS = FOP(5, FMT_PS),
10551 OPC_MOV_PS = FOP(6, FMT_PS),
10552 OPC_NEG_PS = FOP(7, FMT_PS),
10553 OPC_MOVCF_PS = FOP(17, FMT_PS),
10554 OPC_MOVZ_PS = FOP(18, FMT_PS),
10555 OPC_MOVN_PS = FOP(19, FMT_PS),
10556 OPC_ADDR_PS = FOP(24, FMT_PS),
10557 OPC_MULR_PS = FOP(26, FMT_PS),
10558 OPC_RECIP2_PS = FOP(28, FMT_PS),
10559 OPC_RECIP1_PS = FOP(29, FMT_PS),
10560 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10561 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10563 OPC_CVT_S_PU = FOP(32, FMT_PS),
10564 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10565 OPC_CVT_S_PL = FOP(40, FMT_PS),
10566 OPC_PLL_PS = FOP(44, FMT_PS),
10567 OPC_PLU_PS = FOP(45, FMT_PS),
10568 OPC_PUL_PS = FOP(46, FMT_PS),
10569 OPC_PUU_PS = FOP(47, FMT_PS),
10570 OPC_CMP_F_PS = FOP (48, FMT_PS),
10571 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10572 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10573 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10574 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10575 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10576 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10577 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10578 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10579 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10580 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10581 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10582 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10583 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10584 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10585 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10589 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10590 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10591 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10592 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10593 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10594 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10595 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10596 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10597 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10598 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10599 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10600 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10601 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10602 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10603 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10604 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10605 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10606 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10607 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10608 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10609 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10610 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10612 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10613 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10614 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10615 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10616 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10617 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10618 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10619 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10620 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10621 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10622 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10623 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10624 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10625 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10626 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10627 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10628 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10629 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10630 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10631 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10632 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10633 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10635 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10637 TCGv t0 = tcg_temp_new();
10642 TCGv_i32 fp0 = tcg_temp_new_i32();
10644 gen_load_fpr32(ctx, fp0, fs);
10645 tcg_gen_ext_i32_tl(t0, fp0);
10646 tcg_temp_free_i32(fp0);
10648 gen_store_gpr(t0, rt);
10651 gen_load_gpr(t0, rt);
10653 TCGv_i32 fp0 = tcg_temp_new_i32();
10655 tcg_gen_trunc_tl_i32(fp0, t0);
10656 gen_store_fpr32(ctx, fp0, fs);
10657 tcg_temp_free_i32(fp0);
10661 gen_helper_1e0i(cfc1, t0, fs);
10662 gen_store_gpr(t0, rt);
10665 gen_load_gpr(t0, rt);
10666 save_cpu_state(ctx, 0);
10668 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10670 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10671 tcg_temp_free_i32(fs_tmp);
10673 /* Stop translation as we may have changed hflags */
10674 ctx->base.is_jmp = DISAS_STOP;
10676 #if defined(TARGET_MIPS64)
10678 gen_load_fpr64(ctx, t0, fs);
10679 gen_store_gpr(t0, rt);
10682 gen_load_gpr(t0, rt);
10683 gen_store_fpr64(ctx, t0, fs);
10688 TCGv_i32 fp0 = tcg_temp_new_i32();
10690 gen_load_fpr32h(ctx, fp0, fs);
10691 tcg_gen_ext_i32_tl(t0, fp0);
10692 tcg_temp_free_i32(fp0);
10694 gen_store_gpr(t0, rt);
10697 gen_load_gpr(t0, rt);
10699 TCGv_i32 fp0 = tcg_temp_new_i32();
10701 tcg_gen_trunc_tl_i32(fp0, t0);
10702 gen_store_fpr32h(ctx, fp0, fs);
10703 tcg_temp_free_i32(fp0);
10707 MIPS_INVAL("cp1 move");
10708 generate_exception_end(ctx, EXCP_RI);
10716 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10723 /* Treat as NOP. */
10728 cond = TCG_COND_EQ;
10730 cond = TCG_COND_NE;
10732 l1 = gen_new_label();
10733 t0 = tcg_temp_new_i32();
10734 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10735 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10736 tcg_temp_free_i32(t0);
10738 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10740 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10745 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10749 TCGv_i32 t0 = tcg_temp_new_i32();
10750 TCGLabel *l1 = gen_new_label();
10753 cond = TCG_COND_EQ;
10755 cond = TCG_COND_NE;
10757 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10758 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10759 gen_load_fpr32(ctx, t0, fs);
10760 gen_store_fpr32(ctx, t0, fd);
10762 tcg_temp_free_i32(t0);
10765 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10768 TCGv_i32 t0 = tcg_temp_new_i32();
10770 TCGLabel *l1 = gen_new_label();
10773 cond = TCG_COND_EQ;
10775 cond = TCG_COND_NE;
10777 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10778 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10779 tcg_temp_free_i32(t0);
10780 fp0 = tcg_temp_new_i64();
10781 gen_load_fpr64(ctx, fp0, fs);
10782 gen_store_fpr64(ctx, fp0, fd);
10783 tcg_temp_free_i64(fp0);
10787 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10791 TCGv_i32 t0 = tcg_temp_new_i32();
10792 TCGLabel *l1 = gen_new_label();
10793 TCGLabel *l2 = gen_new_label();
10796 cond = TCG_COND_EQ;
10798 cond = TCG_COND_NE;
10800 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10801 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10802 gen_load_fpr32(ctx, t0, fs);
10803 gen_store_fpr32(ctx, t0, fd);
10806 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10807 tcg_gen_brcondi_i32(cond, t0, 0, l2);
10808 gen_load_fpr32h(ctx, t0, fs);
10809 gen_store_fpr32h(ctx, t0, fd);
10810 tcg_temp_free_i32(t0);
10814 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10817 TCGv_i32 t1 = tcg_const_i32(0);
10818 TCGv_i32 fp0 = tcg_temp_new_i32();
10819 TCGv_i32 fp1 = tcg_temp_new_i32();
10820 TCGv_i32 fp2 = tcg_temp_new_i32();
10821 gen_load_fpr32(ctx, fp0, fd);
10822 gen_load_fpr32(ctx, fp1, ft);
10823 gen_load_fpr32(ctx, fp2, fs);
10827 tcg_gen_andi_i32(fp0, fp0, 1);
10828 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10831 tcg_gen_andi_i32(fp1, fp1, 1);
10832 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10835 tcg_gen_andi_i32(fp1, fp1, 1);
10836 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10839 MIPS_INVAL("gen_sel_s");
10840 generate_exception_end(ctx, EXCP_RI);
10844 gen_store_fpr32(ctx, fp0, fd);
10845 tcg_temp_free_i32(fp2);
10846 tcg_temp_free_i32(fp1);
10847 tcg_temp_free_i32(fp0);
10848 tcg_temp_free_i32(t1);
10851 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10854 TCGv_i64 t1 = tcg_const_i64(0);
10855 TCGv_i64 fp0 = tcg_temp_new_i64();
10856 TCGv_i64 fp1 = tcg_temp_new_i64();
10857 TCGv_i64 fp2 = tcg_temp_new_i64();
10858 gen_load_fpr64(ctx, fp0, fd);
10859 gen_load_fpr64(ctx, fp1, ft);
10860 gen_load_fpr64(ctx, fp2, fs);
10864 tcg_gen_andi_i64(fp0, fp0, 1);
10865 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10868 tcg_gen_andi_i64(fp1, fp1, 1);
10869 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10872 tcg_gen_andi_i64(fp1, fp1, 1);
10873 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10876 MIPS_INVAL("gen_sel_d");
10877 generate_exception_end(ctx, EXCP_RI);
10881 gen_store_fpr64(ctx, fp0, fd);
10882 tcg_temp_free_i64(fp2);
10883 tcg_temp_free_i64(fp1);
10884 tcg_temp_free_i64(fp0);
10885 tcg_temp_free_i64(t1);
10888 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10889 int ft, int fs, int fd, int cc)
10891 uint32_t func = ctx->opcode & 0x3f;
10895 TCGv_i32 fp0 = tcg_temp_new_i32();
10896 TCGv_i32 fp1 = tcg_temp_new_i32();
10898 gen_load_fpr32(ctx, fp0, fs);
10899 gen_load_fpr32(ctx, fp1, ft);
10900 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10901 tcg_temp_free_i32(fp1);
10902 gen_store_fpr32(ctx, fp0, fd);
10903 tcg_temp_free_i32(fp0);
10908 TCGv_i32 fp0 = tcg_temp_new_i32();
10909 TCGv_i32 fp1 = tcg_temp_new_i32();
10911 gen_load_fpr32(ctx, fp0, fs);
10912 gen_load_fpr32(ctx, fp1, ft);
10913 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10914 tcg_temp_free_i32(fp1);
10915 gen_store_fpr32(ctx, fp0, fd);
10916 tcg_temp_free_i32(fp0);
10921 TCGv_i32 fp0 = tcg_temp_new_i32();
10922 TCGv_i32 fp1 = tcg_temp_new_i32();
10924 gen_load_fpr32(ctx, fp0, fs);
10925 gen_load_fpr32(ctx, fp1, ft);
10926 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10927 tcg_temp_free_i32(fp1);
10928 gen_store_fpr32(ctx, fp0, fd);
10929 tcg_temp_free_i32(fp0);
10934 TCGv_i32 fp0 = tcg_temp_new_i32();
10935 TCGv_i32 fp1 = tcg_temp_new_i32();
10937 gen_load_fpr32(ctx, fp0, fs);
10938 gen_load_fpr32(ctx, fp1, ft);
10939 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10940 tcg_temp_free_i32(fp1);
10941 gen_store_fpr32(ctx, fp0, fd);
10942 tcg_temp_free_i32(fp0);
10947 TCGv_i32 fp0 = tcg_temp_new_i32();
10949 gen_load_fpr32(ctx, fp0, fs);
10950 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10951 gen_store_fpr32(ctx, fp0, fd);
10952 tcg_temp_free_i32(fp0);
10957 TCGv_i32 fp0 = tcg_temp_new_i32();
10959 gen_load_fpr32(ctx, fp0, fs);
10960 if (ctx->abs2008) {
10961 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10963 gen_helper_float_abs_s(fp0, fp0);
10965 gen_store_fpr32(ctx, fp0, fd);
10966 tcg_temp_free_i32(fp0);
10971 TCGv_i32 fp0 = tcg_temp_new_i32();
10973 gen_load_fpr32(ctx, fp0, fs);
10974 gen_store_fpr32(ctx, fp0, fd);
10975 tcg_temp_free_i32(fp0);
10980 TCGv_i32 fp0 = tcg_temp_new_i32();
10982 gen_load_fpr32(ctx, fp0, fs);
10983 if (ctx->abs2008) {
10984 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10986 gen_helper_float_chs_s(fp0, fp0);
10988 gen_store_fpr32(ctx, fp0, fd);
10989 tcg_temp_free_i32(fp0);
10992 case OPC_ROUND_L_S:
10993 check_cp1_64bitmode(ctx);
10995 TCGv_i32 fp32 = tcg_temp_new_i32();
10996 TCGv_i64 fp64 = tcg_temp_new_i64();
10998 gen_load_fpr32(ctx, fp32, fs);
10999 if (ctx->nan2008) {
11000 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11002 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11004 tcg_temp_free_i32(fp32);
11005 gen_store_fpr64(ctx, fp64, fd);
11006 tcg_temp_free_i64(fp64);
11009 case OPC_TRUNC_L_S:
11010 check_cp1_64bitmode(ctx);
11012 TCGv_i32 fp32 = tcg_temp_new_i32();
11013 TCGv_i64 fp64 = tcg_temp_new_i64();
11015 gen_load_fpr32(ctx, fp32, fs);
11016 if (ctx->nan2008) {
11017 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11019 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11021 tcg_temp_free_i32(fp32);
11022 gen_store_fpr64(ctx, fp64, fd);
11023 tcg_temp_free_i64(fp64);
11027 check_cp1_64bitmode(ctx);
11029 TCGv_i32 fp32 = tcg_temp_new_i32();
11030 TCGv_i64 fp64 = tcg_temp_new_i64();
11032 gen_load_fpr32(ctx, fp32, fs);
11033 if (ctx->nan2008) {
11034 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11036 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11038 tcg_temp_free_i32(fp32);
11039 gen_store_fpr64(ctx, fp64, fd);
11040 tcg_temp_free_i64(fp64);
11043 case OPC_FLOOR_L_S:
11044 check_cp1_64bitmode(ctx);
11046 TCGv_i32 fp32 = tcg_temp_new_i32();
11047 TCGv_i64 fp64 = tcg_temp_new_i64();
11049 gen_load_fpr32(ctx, fp32, fs);
11050 if (ctx->nan2008) {
11051 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11053 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11055 tcg_temp_free_i32(fp32);
11056 gen_store_fpr64(ctx, fp64, fd);
11057 tcg_temp_free_i64(fp64);
11060 case OPC_ROUND_W_S:
11062 TCGv_i32 fp0 = tcg_temp_new_i32();
11064 gen_load_fpr32(ctx, fp0, fs);
11065 if (ctx->nan2008) {
11066 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11068 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11070 gen_store_fpr32(ctx, fp0, fd);
11071 tcg_temp_free_i32(fp0);
11074 case OPC_TRUNC_W_S:
11076 TCGv_i32 fp0 = tcg_temp_new_i32();
11078 gen_load_fpr32(ctx, fp0, fs);
11079 if (ctx->nan2008) {
11080 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11082 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11084 gen_store_fpr32(ctx, fp0, fd);
11085 tcg_temp_free_i32(fp0);
11090 TCGv_i32 fp0 = tcg_temp_new_i32();
11092 gen_load_fpr32(ctx, fp0, fs);
11093 if (ctx->nan2008) {
11094 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11096 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11098 gen_store_fpr32(ctx, fp0, fd);
11099 tcg_temp_free_i32(fp0);
11102 case OPC_FLOOR_W_S:
11104 TCGv_i32 fp0 = tcg_temp_new_i32();
11106 gen_load_fpr32(ctx, fp0, fs);
11107 if (ctx->nan2008) {
11108 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11110 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11112 gen_store_fpr32(ctx, fp0, fd);
11113 tcg_temp_free_i32(fp0);
11117 check_insn(ctx, ISA_MIPS32R6);
11118 gen_sel_s(ctx, op1, fd, ft, fs);
11121 check_insn(ctx, ISA_MIPS32R6);
11122 gen_sel_s(ctx, op1, fd, ft, fs);
11125 check_insn(ctx, ISA_MIPS32R6);
11126 gen_sel_s(ctx, op1, fd, ft, fs);
11129 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11130 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11133 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11135 TCGLabel *l1 = gen_new_label();
11139 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11141 fp0 = tcg_temp_new_i32();
11142 gen_load_fpr32(ctx, fp0, fs);
11143 gen_store_fpr32(ctx, fp0, fd);
11144 tcg_temp_free_i32(fp0);
11149 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11151 TCGLabel *l1 = gen_new_label();
11155 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11156 fp0 = tcg_temp_new_i32();
11157 gen_load_fpr32(ctx, fp0, fs);
11158 gen_store_fpr32(ctx, fp0, fd);
11159 tcg_temp_free_i32(fp0);
11166 TCGv_i32 fp0 = tcg_temp_new_i32();
11168 gen_load_fpr32(ctx, fp0, fs);
11169 gen_helper_float_recip_s(fp0, cpu_env, fp0);
11170 gen_store_fpr32(ctx, fp0, fd);
11171 tcg_temp_free_i32(fp0);
11176 TCGv_i32 fp0 = tcg_temp_new_i32();
11178 gen_load_fpr32(ctx, fp0, fs);
11179 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11180 gen_store_fpr32(ctx, fp0, fd);
11181 tcg_temp_free_i32(fp0);
11185 check_insn(ctx, ISA_MIPS32R6);
11187 TCGv_i32 fp0 = tcg_temp_new_i32();
11188 TCGv_i32 fp1 = tcg_temp_new_i32();
11189 TCGv_i32 fp2 = tcg_temp_new_i32();
11190 gen_load_fpr32(ctx, fp0, fs);
11191 gen_load_fpr32(ctx, fp1, ft);
11192 gen_load_fpr32(ctx, fp2, fd);
11193 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11194 gen_store_fpr32(ctx, fp2, fd);
11195 tcg_temp_free_i32(fp2);
11196 tcg_temp_free_i32(fp1);
11197 tcg_temp_free_i32(fp0);
11201 check_insn(ctx, ISA_MIPS32R6);
11203 TCGv_i32 fp0 = tcg_temp_new_i32();
11204 TCGv_i32 fp1 = tcg_temp_new_i32();
11205 TCGv_i32 fp2 = tcg_temp_new_i32();
11206 gen_load_fpr32(ctx, fp0, fs);
11207 gen_load_fpr32(ctx, fp1, ft);
11208 gen_load_fpr32(ctx, fp2, fd);
11209 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11210 gen_store_fpr32(ctx, fp2, fd);
11211 tcg_temp_free_i32(fp2);
11212 tcg_temp_free_i32(fp1);
11213 tcg_temp_free_i32(fp0);
11217 check_insn(ctx, ISA_MIPS32R6);
11219 TCGv_i32 fp0 = tcg_temp_new_i32();
11220 gen_load_fpr32(ctx, fp0, fs);
11221 gen_helper_float_rint_s(fp0, cpu_env, fp0);
11222 gen_store_fpr32(ctx, fp0, fd);
11223 tcg_temp_free_i32(fp0);
11227 check_insn(ctx, ISA_MIPS32R6);
11229 TCGv_i32 fp0 = tcg_temp_new_i32();
11230 gen_load_fpr32(ctx, fp0, fs);
11231 gen_helper_float_class_s(fp0, cpu_env, fp0);
11232 gen_store_fpr32(ctx, fp0, fd);
11233 tcg_temp_free_i32(fp0);
11236 case OPC_MIN_S: /* OPC_RECIP2_S */
11237 if (ctx->insn_flags & ISA_MIPS32R6) {
11239 TCGv_i32 fp0 = tcg_temp_new_i32();
11240 TCGv_i32 fp1 = tcg_temp_new_i32();
11241 TCGv_i32 fp2 = tcg_temp_new_i32();
11242 gen_load_fpr32(ctx, fp0, fs);
11243 gen_load_fpr32(ctx, fp1, ft);
11244 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11245 gen_store_fpr32(ctx, fp2, fd);
11246 tcg_temp_free_i32(fp2);
11247 tcg_temp_free_i32(fp1);
11248 tcg_temp_free_i32(fp0);
11251 check_cp1_64bitmode(ctx);
11253 TCGv_i32 fp0 = tcg_temp_new_i32();
11254 TCGv_i32 fp1 = tcg_temp_new_i32();
11256 gen_load_fpr32(ctx, fp0, fs);
11257 gen_load_fpr32(ctx, fp1, ft);
11258 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11259 tcg_temp_free_i32(fp1);
11260 gen_store_fpr32(ctx, fp0, fd);
11261 tcg_temp_free_i32(fp0);
11265 case OPC_MINA_S: /* OPC_RECIP1_S */
11266 if (ctx->insn_flags & ISA_MIPS32R6) {
11268 TCGv_i32 fp0 = tcg_temp_new_i32();
11269 TCGv_i32 fp1 = tcg_temp_new_i32();
11270 TCGv_i32 fp2 = tcg_temp_new_i32();
11271 gen_load_fpr32(ctx, fp0, fs);
11272 gen_load_fpr32(ctx, fp1, ft);
11273 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11274 gen_store_fpr32(ctx, fp2, fd);
11275 tcg_temp_free_i32(fp2);
11276 tcg_temp_free_i32(fp1);
11277 tcg_temp_free_i32(fp0);
11280 check_cp1_64bitmode(ctx);
11282 TCGv_i32 fp0 = tcg_temp_new_i32();
11284 gen_load_fpr32(ctx, fp0, fs);
11285 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11286 gen_store_fpr32(ctx, fp0, fd);
11287 tcg_temp_free_i32(fp0);
11291 case OPC_MAX_S: /* OPC_RSQRT1_S */
11292 if (ctx->insn_flags & ISA_MIPS32R6) {
11294 TCGv_i32 fp0 = tcg_temp_new_i32();
11295 TCGv_i32 fp1 = tcg_temp_new_i32();
11296 gen_load_fpr32(ctx, fp0, fs);
11297 gen_load_fpr32(ctx, fp1, ft);
11298 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11299 gen_store_fpr32(ctx, fp1, fd);
11300 tcg_temp_free_i32(fp1);
11301 tcg_temp_free_i32(fp0);
11304 check_cp1_64bitmode(ctx);
11306 TCGv_i32 fp0 = tcg_temp_new_i32();
11308 gen_load_fpr32(ctx, fp0, fs);
11309 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11310 gen_store_fpr32(ctx, fp0, fd);
11311 tcg_temp_free_i32(fp0);
11315 case OPC_MAXA_S: /* OPC_RSQRT2_S */
11316 if (ctx->insn_flags & ISA_MIPS32R6) {
11318 TCGv_i32 fp0 = tcg_temp_new_i32();
11319 TCGv_i32 fp1 = tcg_temp_new_i32();
11320 gen_load_fpr32(ctx, fp0, fs);
11321 gen_load_fpr32(ctx, fp1, ft);
11322 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11323 gen_store_fpr32(ctx, fp1, fd);
11324 tcg_temp_free_i32(fp1);
11325 tcg_temp_free_i32(fp0);
11328 check_cp1_64bitmode(ctx);
11330 TCGv_i32 fp0 = tcg_temp_new_i32();
11331 TCGv_i32 fp1 = tcg_temp_new_i32();
11333 gen_load_fpr32(ctx, fp0, fs);
11334 gen_load_fpr32(ctx, fp1, ft);
11335 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11336 tcg_temp_free_i32(fp1);
11337 gen_store_fpr32(ctx, fp0, fd);
11338 tcg_temp_free_i32(fp0);
11343 check_cp1_registers(ctx, fd);
11345 TCGv_i32 fp32 = tcg_temp_new_i32();
11346 TCGv_i64 fp64 = tcg_temp_new_i64();
11348 gen_load_fpr32(ctx, fp32, fs);
11349 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11350 tcg_temp_free_i32(fp32);
11351 gen_store_fpr64(ctx, fp64, fd);
11352 tcg_temp_free_i64(fp64);
11357 TCGv_i32 fp0 = tcg_temp_new_i32();
11359 gen_load_fpr32(ctx, fp0, fs);
11360 if (ctx->nan2008) {
11361 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11363 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11365 gen_store_fpr32(ctx, fp0, fd);
11366 tcg_temp_free_i32(fp0);
11370 check_cp1_64bitmode(ctx);
11372 TCGv_i32 fp32 = tcg_temp_new_i32();
11373 TCGv_i64 fp64 = tcg_temp_new_i64();
11375 gen_load_fpr32(ctx, fp32, fs);
11376 if (ctx->nan2008) {
11377 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11379 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11381 tcg_temp_free_i32(fp32);
11382 gen_store_fpr64(ctx, fp64, fd);
11383 tcg_temp_free_i64(fp64);
11389 TCGv_i64 fp64 = tcg_temp_new_i64();
11390 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11391 TCGv_i32 fp32_1 = tcg_temp_new_i32();
11393 gen_load_fpr32(ctx, fp32_0, fs);
11394 gen_load_fpr32(ctx, fp32_1, ft);
11395 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11396 tcg_temp_free_i32(fp32_1);
11397 tcg_temp_free_i32(fp32_0);
11398 gen_store_fpr64(ctx, fp64, fd);
11399 tcg_temp_free_i64(fp64);
11405 case OPC_CMP_UEQ_S:
11406 case OPC_CMP_OLT_S:
11407 case OPC_CMP_ULT_S:
11408 case OPC_CMP_OLE_S:
11409 case OPC_CMP_ULE_S:
11411 case OPC_CMP_NGLE_S:
11412 case OPC_CMP_SEQ_S:
11413 case OPC_CMP_NGL_S:
11415 case OPC_CMP_NGE_S:
11417 case OPC_CMP_NGT_S:
11418 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11419 if (ctx->opcode & (1 << 6)) {
11420 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11422 gen_cmp_s(ctx, func-48, ft, fs, cc);
11426 check_cp1_registers(ctx, fs | ft | fd);
11428 TCGv_i64 fp0 = tcg_temp_new_i64();
11429 TCGv_i64 fp1 = tcg_temp_new_i64();
11431 gen_load_fpr64(ctx, fp0, fs);
11432 gen_load_fpr64(ctx, fp1, ft);
11433 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11434 tcg_temp_free_i64(fp1);
11435 gen_store_fpr64(ctx, fp0, fd);
11436 tcg_temp_free_i64(fp0);
11440 check_cp1_registers(ctx, fs | ft | fd);
11442 TCGv_i64 fp0 = tcg_temp_new_i64();
11443 TCGv_i64 fp1 = tcg_temp_new_i64();
11445 gen_load_fpr64(ctx, fp0, fs);
11446 gen_load_fpr64(ctx, fp1, ft);
11447 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11448 tcg_temp_free_i64(fp1);
11449 gen_store_fpr64(ctx, fp0, fd);
11450 tcg_temp_free_i64(fp0);
11454 check_cp1_registers(ctx, fs | ft | fd);
11456 TCGv_i64 fp0 = tcg_temp_new_i64();
11457 TCGv_i64 fp1 = tcg_temp_new_i64();
11459 gen_load_fpr64(ctx, fp0, fs);
11460 gen_load_fpr64(ctx, fp1, ft);
11461 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11462 tcg_temp_free_i64(fp1);
11463 gen_store_fpr64(ctx, fp0, fd);
11464 tcg_temp_free_i64(fp0);
11468 check_cp1_registers(ctx, fs | ft | fd);
11470 TCGv_i64 fp0 = tcg_temp_new_i64();
11471 TCGv_i64 fp1 = tcg_temp_new_i64();
11473 gen_load_fpr64(ctx, fp0, fs);
11474 gen_load_fpr64(ctx, fp1, ft);
11475 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11476 tcg_temp_free_i64(fp1);
11477 gen_store_fpr64(ctx, fp0, fd);
11478 tcg_temp_free_i64(fp0);
11482 check_cp1_registers(ctx, fs | fd);
11484 TCGv_i64 fp0 = tcg_temp_new_i64();
11486 gen_load_fpr64(ctx, fp0, fs);
11487 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11488 gen_store_fpr64(ctx, fp0, fd);
11489 tcg_temp_free_i64(fp0);
11493 check_cp1_registers(ctx, fs | fd);
11495 TCGv_i64 fp0 = tcg_temp_new_i64();
11497 gen_load_fpr64(ctx, fp0, fs);
11498 if (ctx->abs2008) {
11499 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11501 gen_helper_float_abs_d(fp0, fp0);
11503 gen_store_fpr64(ctx, fp0, fd);
11504 tcg_temp_free_i64(fp0);
11508 check_cp1_registers(ctx, fs | fd);
11510 TCGv_i64 fp0 = tcg_temp_new_i64();
11512 gen_load_fpr64(ctx, fp0, fs);
11513 gen_store_fpr64(ctx, fp0, fd);
11514 tcg_temp_free_i64(fp0);
11518 check_cp1_registers(ctx, fs | fd);
11520 TCGv_i64 fp0 = tcg_temp_new_i64();
11522 gen_load_fpr64(ctx, fp0, fs);
11523 if (ctx->abs2008) {
11524 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11526 gen_helper_float_chs_d(fp0, fp0);
11528 gen_store_fpr64(ctx, fp0, fd);
11529 tcg_temp_free_i64(fp0);
11532 case OPC_ROUND_L_D:
11533 check_cp1_64bitmode(ctx);
11535 TCGv_i64 fp0 = tcg_temp_new_i64();
11537 gen_load_fpr64(ctx, fp0, fs);
11538 if (ctx->nan2008) {
11539 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11541 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11543 gen_store_fpr64(ctx, fp0, fd);
11544 tcg_temp_free_i64(fp0);
11547 case OPC_TRUNC_L_D:
11548 check_cp1_64bitmode(ctx);
11550 TCGv_i64 fp0 = tcg_temp_new_i64();
11552 gen_load_fpr64(ctx, fp0, fs);
11553 if (ctx->nan2008) {
11554 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11556 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11558 gen_store_fpr64(ctx, fp0, fd);
11559 tcg_temp_free_i64(fp0);
11563 check_cp1_64bitmode(ctx);
11565 TCGv_i64 fp0 = tcg_temp_new_i64();
11567 gen_load_fpr64(ctx, fp0, fs);
11568 if (ctx->nan2008) {
11569 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11571 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11573 gen_store_fpr64(ctx, fp0, fd);
11574 tcg_temp_free_i64(fp0);
11577 case OPC_FLOOR_L_D:
11578 check_cp1_64bitmode(ctx);
11580 TCGv_i64 fp0 = tcg_temp_new_i64();
11582 gen_load_fpr64(ctx, fp0, fs);
11583 if (ctx->nan2008) {
11584 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11586 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11588 gen_store_fpr64(ctx, fp0, fd);
11589 tcg_temp_free_i64(fp0);
11592 case OPC_ROUND_W_D:
11593 check_cp1_registers(ctx, fs);
11595 TCGv_i32 fp32 = tcg_temp_new_i32();
11596 TCGv_i64 fp64 = tcg_temp_new_i64();
11598 gen_load_fpr64(ctx, fp64, fs);
11599 if (ctx->nan2008) {
11600 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11602 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11604 tcg_temp_free_i64(fp64);
11605 gen_store_fpr32(ctx, fp32, fd);
11606 tcg_temp_free_i32(fp32);
11609 case OPC_TRUNC_W_D:
11610 check_cp1_registers(ctx, fs);
11612 TCGv_i32 fp32 = tcg_temp_new_i32();
11613 TCGv_i64 fp64 = tcg_temp_new_i64();
11615 gen_load_fpr64(ctx, fp64, fs);
11616 if (ctx->nan2008) {
11617 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11619 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11621 tcg_temp_free_i64(fp64);
11622 gen_store_fpr32(ctx, fp32, fd);
11623 tcg_temp_free_i32(fp32);
11627 check_cp1_registers(ctx, fs);
11629 TCGv_i32 fp32 = tcg_temp_new_i32();
11630 TCGv_i64 fp64 = tcg_temp_new_i64();
11632 gen_load_fpr64(ctx, fp64, fs);
11633 if (ctx->nan2008) {
11634 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11636 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11638 tcg_temp_free_i64(fp64);
11639 gen_store_fpr32(ctx, fp32, fd);
11640 tcg_temp_free_i32(fp32);
11643 case OPC_FLOOR_W_D:
11644 check_cp1_registers(ctx, fs);
11646 TCGv_i32 fp32 = tcg_temp_new_i32();
11647 TCGv_i64 fp64 = tcg_temp_new_i64();
11649 gen_load_fpr64(ctx, fp64, fs);
11650 if (ctx->nan2008) {
11651 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11653 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11655 tcg_temp_free_i64(fp64);
11656 gen_store_fpr32(ctx, fp32, fd);
11657 tcg_temp_free_i32(fp32);
11661 check_insn(ctx, ISA_MIPS32R6);
11662 gen_sel_d(ctx, op1, fd, ft, fs);
11665 check_insn(ctx, ISA_MIPS32R6);
11666 gen_sel_d(ctx, op1, fd, ft, fs);
11669 check_insn(ctx, ISA_MIPS32R6);
11670 gen_sel_d(ctx, op1, fd, ft, fs);
11673 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11674 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11677 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11679 TCGLabel *l1 = gen_new_label();
11683 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11685 fp0 = tcg_temp_new_i64();
11686 gen_load_fpr64(ctx, fp0, fs);
11687 gen_store_fpr64(ctx, fp0, fd);
11688 tcg_temp_free_i64(fp0);
11693 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11695 TCGLabel *l1 = gen_new_label();
11699 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11700 fp0 = tcg_temp_new_i64();
11701 gen_load_fpr64(ctx, fp0, fs);
11702 gen_store_fpr64(ctx, fp0, fd);
11703 tcg_temp_free_i64(fp0);
11709 check_cp1_registers(ctx, fs | fd);
11711 TCGv_i64 fp0 = tcg_temp_new_i64();
11713 gen_load_fpr64(ctx, fp0, fs);
11714 gen_helper_float_recip_d(fp0, cpu_env, fp0);
11715 gen_store_fpr64(ctx, fp0, fd);
11716 tcg_temp_free_i64(fp0);
11720 check_cp1_registers(ctx, fs | fd);
11722 TCGv_i64 fp0 = tcg_temp_new_i64();
11724 gen_load_fpr64(ctx, fp0, fs);
11725 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11726 gen_store_fpr64(ctx, fp0, fd);
11727 tcg_temp_free_i64(fp0);
11731 check_insn(ctx, ISA_MIPS32R6);
11733 TCGv_i64 fp0 = tcg_temp_new_i64();
11734 TCGv_i64 fp1 = tcg_temp_new_i64();
11735 TCGv_i64 fp2 = tcg_temp_new_i64();
11736 gen_load_fpr64(ctx, fp0, fs);
11737 gen_load_fpr64(ctx, fp1, ft);
11738 gen_load_fpr64(ctx, fp2, fd);
11739 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11740 gen_store_fpr64(ctx, fp2, fd);
11741 tcg_temp_free_i64(fp2);
11742 tcg_temp_free_i64(fp1);
11743 tcg_temp_free_i64(fp0);
11747 check_insn(ctx, ISA_MIPS32R6);
11749 TCGv_i64 fp0 = tcg_temp_new_i64();
11750 TCGv_i64 fp1 = tcg_temp_new_i64();
11751 TCGv_i64 fp2 = tcg_temp_new_i64();
11752 gen_load_fpr64(ctx, fp0, fs);
11753 gen_load_fpr64(ctx, fp1, ft);
11754 gen_load_fpr64(ctx, fp2, fd);
11755 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11756 gen_store_fpr64(ctx, fp2, fd);
11757 tcg_temp_free_i64(fp2);
11758 tcg_temp_free_i64(fp1);
11759 tcg_temp_free_i64(fp0);
11763 check_insn(ctx, ISA_MIPS32R6);
11765 TCGv_i64 fp0 = tcg_temp_new_i64();
11766 gen_load_fpr64(ctx, fp0, fs);
11767 gen_helper_float_rint_d(fp0, cpu_env, fp0);
11768 gen_store_fpr64(ctx, fp0, fd);
11769 tcg_temp_free_i64(fp0);
11773 check_insn(ctx, ISA_MIPS32R6);
11775 TCGv_i64 fp0 = tcg_temp_new_i64();
11776 gen_load_fpr64(ctx, fp0, fs);
11777 gen_helper_float_class_d(fp0, cpu_env, fp0);
11778 gen_store_fpr64(ctx, fp0, fd);
11779 tcg_temp_free_i64(fp0);
11782 case OPC_MIN_D: /* OPC_RECIP2_D */
11783 if (ctx->insn_flags & ISA_MIPS32R6) {
11785 TCGv_i64 fp0 = tcg_temp_new_i64();
11786 TCGv_i64 fp1 = tcg_temp_new_i64();
11787 gen_load_fpr64(ctx, fp0, fs);
11788 gen_load_fpr64(ctx, fp1, ft);
11789 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11790 gen_store_fpr64(ctx, fp1, fd);
11791 tcg_temp_free_i64(fp1);
11792 tcg_temp_free_i64(fp0);
11795 check_cp1_64bitmode(ctx);
11797 TCGv_i64 fp0 = tcg_temp_new_i64();
11798 TCGv_i64 fp1 = tcg_temp_new_i64();
11800 gen_load_fpr64(ctx, fp0, fs);
11801 gen_load_fpr64(ctx, fp1, ft);
11802 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11803 tcg_temp_free_i64(fp1);
11804 gen_store_fpr64(ctx, fp0, fd);
11805 tcg_temp_free_i64(fp0);
11809 case OPC_MINA_D: /* OPC_RECIP1_D */
11810 if (ctx->insn_flags & ISA_MIPS32R6) {
11812 TCGv_i64 fp0 = tcg_temp_new_i64();
11813 TCGv_i64 fp1 = tcg_temp_new_i64();
11814 gen_load_fpr64(ctx, fp0, fs);
11815 gen_load_fpr64(ctx, fp1, ft);
11816 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11817 gen_store_fpr64(ctx, fp1, fd);
11818 tcg_temp_free_i64(fp1);
11819 tcg_temp_free_i64(fp0);
11822 check_cp1_64bitmode(ctx);
11824 TCGv_i64 fp0 = tcg_temp_new_i64();
11826 gen_load_fpr64(ctx, fp0, fs);
11827 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11828 gen_store_fpr64(ctx, fp0, fd);
11829 tcg_temp_free_i64(fp0);
11833 case OPC_MAX_D: /* OPC_RSQRT1_D */
11834 if (ctx->insn_flags & ISA_MIPS32R6) {
11836 TCGv_i64 fp0 = tcg_temp_new_i64();
11837 TCGv_i64 fp1 = tcg_temp_new_i64();
11838 gen_load_fpr64(ctx, fp0, fs);
11839 gen_load_fpr64(ctx, fp1, ft);
11840 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11841 gen_store_fpr64(ctx, fp1, fd);
11842 tcg_temp_free_i64(fp1);
11843 tcg_temp_free_i64(fp0);
11846 check_cp1_64bitmode(ctx);
11848 TCGv_i64 fp0 = tcg_temp_new_i64();
11850 gen_load_fpr64(ctx, fp0, fs);
11851 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11852 gen_store_fpr64(ctx, fp0, fd);
11853 tcg_temp_free_i64(fp0);
11857 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11858 if (ctx->insn_flags & ISA_MIPS32R6) {
11860 TCGv_i64 fp0 = tcg_temp_new_i64();
11861 TCGv_i64 fp1 = tcg_temp_new_i64();
11862 gen_load_fpr64(ctx, fp0, fs);
11863 gen_load_fpr64(ctx, fp1, ft);
11864 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11865 gen_store_fpr64(ctx, fp1, fd);
11866 tcg_temp_free_i64(fp1);
11867 tcg_temp_free_i64(fp0);
11870 check_cp1_64bitmode(ctx);
11872 TCGv_i64 fp0 = tcg_temp_new_i64();
11873 TCGv_i64 fp1 = tcg_temp_new_i64();
11875 gen_load_fpr64(ctx, fp0, fs);
11876 gen_load_fpr64(ctx, fp1, ft);
11877 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11878 tcg_temp_free_i64(fp1);
11879 gen_store_fpr64(ctx, fp0, fd);
11880 tcg_temp_free_i64(fp0);
11887 case OPC_CMP_UEQ_D:
11888 case OPC_CMP_OLT_D:
11889 case OPC_CMP_ULT_D:
11890 case OPC_CMP_OLE_D:
11891 case OPC_CMP_ULE_D:
11893 case OPC_CMP_NGLE_D:
11894 case OPC_CMP_SEQ_D:
11895 case OPC_CMP_NGL_D:
11897 case OPC_CMP_NGE_D:
11899 case OPC_CMP_NGT_D:
11900 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11901 if (ctx->opcode & (1 << 6)) {
11902 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11904 gen_cmp_d(ctx, func-48, ft, fs, cc);
11908 check_cp1_registers(ctx, fs);
11910 TCGv_i32 fp32 = tcg_temp_new_i32();
11911 TCGv_i64 fp64 = tcg_temp_new_i64();
11913 gen_load_fpr64(ctx, fp64, fs);
11914 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11915 tcg_temp_free_i64(fp64);
11916 gen_store_fpr32(ctx, fp32, fd);
11917 tcg_temp_free_i32(fp32);
11921 check_cp1_registers(ctx, fs);
11923 TCGv_i32 fp32 = tcg_temp_new_i32();
11924 TCGv_i64 fp64 = tcg_temp_new_i64();
11926 gen_load_fpr64(ctx, fp64, fs);
11927 if (ctx->nan2008) {
11928 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11930 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11932 tcg_temp_free_i64(fp64);
11933 gen_store_fpr32(ctx, fp32, fd);
11934 tcg_temp_free_i32(fp32);
11938 check_cp1_64bitmode(ctx);
11940 TCGv_i64 fp0 = tcg_temp_new_i64();
11942 gen_load_fpr64(ctx, fp0, fs);
11943 if (ctx->nan2008) {
11944 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11946 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11948 gen_store_fpr64(ctx, fp0, fd);
11949 tcg_temp_free_i64(fp0);
11954 TCGv_i32 fp0 = tcg_temp_new_i32();
11956 gen_load_fpr32(ctx, fp0, fs);
11957 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11958 gen_store_fpr32(ctx, fp0, fd);
11959 tcg_temp_free_i32(fp0);
11963 check_cp1_registers(ctx, fd);
11965 TCGv_i32 fp32 = tcg_temp_new_i32();
11966 TCGv_i64 fp64 = tcg_temp_new_i64();
11968 gen_load_fpr32(ctx, fp32, fs);
11969 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11970 tcg_temp_free_i32(fp32);
11971 gen_store_fpr64(ctx, fp64, fd);
11972 tcg_temp_free_i64(fp64);
11976 check_cp1_64bitmode(ctx);
11978 TCGv_i32 fp32 = tcg_temp_new_i32();
11979 TCGv_i64 fp64 = tcg_temp_new_i64();
11981 gen_load_fpr64(ctx, fp64, fs);
11982 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11983 tcg_temp_free_i64(fp64);
11984 gen_store_fpr32(ctx, fp32, fd);
11985 tcg_temp_free_i32(fp32);
11989 check_cp1_64bitmode(ctx);
11991 TCGv_i64 fp0 = tcg_temp_new_i64();
11993 gen_load_fpr64(ctx, fp0, fs);
11994 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11995 gen_store_fpr64(ctx, fp0, fd);
11996 tcg_temp_free_i64(fp0);
11999 case OPC_CVT_PS_PW:
12002 TCGv_i64 fp0 = tcg_temp_new_i64();
12004 gen_load_fpr64(ctx, fp0, fs);
12005 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12006 gen_store_fpr64(ctx, fp0, fd);
12007 tcg_temp_free_i64(fp0);
12013 TCGv_i64 fp0 = tcg_temp_new_i64();
12014 TCGv_i64 fp1 = tcg_temp_new_i64();
12016 gen_load_fpr64(ctx, fp0, fs);
12017 gen_load_fpr64(ctx, fp1, ft);
12018 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12019 tcg_temp_free_i64(fp1);
12020 gen_store_fpr64(ctx, fp0, fd);
12021 tcg_temp_free_i64(fp0);
12027 TCGv_i64 fp0 = tcg_temp_new_i64();
12028 TCGv_i64 fp1 = tcg_temp_new_i64();
12030 gen_load_fpr64(ctx, fp0, fs);
12031 gen_load_fpr64(ctx, fp1, ft);
12032 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12033 tcg_temp_free_i64(fp1);
12034 gen_store_fpr64(ctx, fp0, fd);
12035 tcg_temp_free_i64(fp0);
12041 TCGv_i64 fp0 = tcg_temp_new_i64();
12042 TCGv_i64 fp1 = tcg_temp_new_i64();
12044 gen_load_fpr64(ctx, fp0, fs);
12045 gen_load_fpr64(ctx, fp1, ft);
12046 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12047 tcg_temp_free_i64(fp1);
12048 gen_store_fpr64(ctx, fp0, fd);
12049 tcg_temp_free_i64(fp0);
12055 TCGv_i64 fp0 = tcg_temp_new_i64();
12057 gen_load_fpr64(ctx, fp0, fs);
12058 gen_helper_float_abs_ps(fp0, fp0);
12059 gen_store_fpr64(ctx, fp0, fd);
12060 tcg_temp_free_i64(fp0);
12066 TCGv_i64 fp0 = tcg_temp_new_i64();
12068 gen_load_fpr64(ctx, fp0, fs);
12069 gen_store_fpr64(ctx, fp0, fd);
12070 tcg_temp_free_i64(fp0);
12076 TCGv_i64 fp0 = tcg_temp_new_i64();
12078 gen_load_fpr64(ctx, fp0, fs);
12079 gen_helper_float_chs_ps(fp0, fp0);
12080 gen_store_fpr64(ctx, fp0, fd);
12081 tcg_temp_free_i64(fp0);
12086 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12091 TCGLabel *l1 = gen_new_label();
12095 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12096 fp0 = tcg_temp_new_i64();
12097 gen_load_fpr64(ctx, fp0, fs);
12098 gen_store_fpr64(ctx, fp0, fd);
12099 tcg_temp_free_i64(fp0);
12106 TCGLabel *l1 = gen_new_label();
12110 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12111 fp0 = tcg_temp_new_i64();
12112 gen_load_fpr64(ctx, fp0, fs);
12113 gen_store_fpr64(ctx, fp0, fd);
12114 tcg_temp_free_i64(fp0);
12122 TCGv_i64 fp0 = tcg_temp_new_i64();
12123 TCGv_i64 fp1 = tcg_temp_new_i64();
12125 gen_load_fpr64(ctx, fp0, ft);
12126 gen_load_fpr64(ctx, fp1, fs);
12127 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12128 tcg_temp_free_i64(fp1);
12129 gen_store_fpr64(ctx, fp0, fd);
12130 tcg_temp_free_i64(fp0);
12136 TCGv_i64 fp0 = tcg_temp_new_i64();
12137 TCGv_i64 fp1 = tcg_temp_new_i64();
12139 gen_load_fpr64(ctx, fp0, ft);
12140 gen_load_fpr64(ctx, fp1, fs);
12141 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12142 tcg_temp_free_i64(fp1);
12143 gen_store_fpr64(ctx, fp0, fd);
12144 tcg_temp_free_i64(fp0);
12147 case OPC_RECIP2_PS:
12150 TCGv_i64 fp0 = tcg_temp_new_i64();
12151 TCGv_i64 fp1 = tcg_temp_new_i64();
12153 gen_load_fpr64(ctx, fp0, fs);
12154 gen_load_fpr64(ctx, fp1, ft);
12155 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12156 tcg_temp_free_i64(fp1);
12157 gen_store_fpr64(ctx, fp0, fd);
12158 tcg_temp_free_i64(fp0);
12161 case OPC_RECIP1_PS:
12164 TCGv_i64 fp0 = tcg_temp_new_i64();
12166 gen_load_fpr64(ctx, fp0, fs);
12167 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12168 gen_store_fpr64(ctx, fp0, fd);
12169 tcg_temp_free_i64(fp0);
12172 case OPC_RSQRT1_PS:
12175 TCGv_i64 fp0 = tcg_temp_new_i64();
12177 gen_load_fpr64(ctx, fp0, fs);
12178 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12179 gen_store_fpr64(ctx, fp0, fd);
12180 tcg_temp_free_i64(fp0);
12183 case OPC_RSQRT2_PS:
12186 TCGv_i64 fp0 = tcg_temp_new_i64();
12187 TCGv_i64 fp1 = tcg_temp_new_i64();
12189 gen_load_fpr64(ctx, fp0, fs);
12190 gen_load_fpr64(ctx, fp1, ft);
12191 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12192 tcg_temp_free_i64(fp1);
12193 gen_store_fpr64(ctx, fp0, fd);
12194 tcg_temp_free_i64(fp0);
12198 check_cp1_64bitmode(ctx);
12200 TCGv_i32 fp0 = tcg_temp_new_i32();
12202 gen_load_fpr32h(ctx, fp0, fs);
12203 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12204 gen_store_fpr32(ctx, fp0, fd);
12205 tcg_temp_free_i32(fp0);
12208 case OPC_CVT_PW_PS:
12211 TCGv_i64 fp0 = tcg_temp_new_i64();
12213 gen_load_fpr64(ctx, fp0, fs);
12214 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12215 gen_store_fpr64(ctx, fp0, fd);
12216 tcg_temp_free_i64(fp0);
12220 check_cp1_64bitmode(ctx);
12222 TCGv_i32 fp0 = tcg_temp_new_i32();
12224 gen_load_fpr32(ctx, fp0, fs);
12225 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12226 gen_store_fpr32(ctx, fp0, fd);
12227 tcg_temp_free_i32(fp0);
12233 TCGv_i32 fp0 = tcg_temp_new_i32();
12234 TCGv_i32 fp1 = tcg_temp_new_i32();
12236 gen_load_fpr32(ctx, fp0, fs);
12237 gen_load_fpr32(ctx, fp1, ft);
12238 gen_store_fpr32h(ctx, fp0, fd);
12239 gen_store_fpr32(ctx, fp1, fd);
12240 tcg_temp_free_i32(fp0);
12241 tcg_temp_free_i32(fp1);
12247 TCGv_i32 fp0 = tcg_temp_new_i32();
12248 TCGv_i32 fp1 = tcg_temp_new_i32();
12250 gen_load_fpr32(ctx, fp0, fs);
12251 gen_load_fpr32h(ctx, fp1, ft);
12252 gen_store_fpr32(ctx, fp1, fd);
12253 gen_store_fpr32h(ctx, fp0, fd);
12254 tcg_temp_free_i32(fp0);
12255 tcg_temp_free_i32(fp1);
12261 TCGv_i32 fp0 = tcg_temp_new_i32();
12262 TCGv_i32 fp1 = tcg_temp_new_i32();
12264 gen_load_fpr32h(ctx, fp0, fs);
12265 gen_load_fpr32(ctx, fp1, ft);
12266 gen_store_fpr32(ctx, fp1, fd);
12267 gen_store_fpr32h(ctx, fp0, fd);
12268 tcg_temp_free_i32(fp0);
12269 tcg_temp_free_i32(fp1);
12275 TCGv_i32 fp0 = tcg_temp_new_i32();
12276 TCGv_i32 fp1 = tcg_temp_new_i32();
12278 gen_load_fpr32h(ctx, fp0, fs);
12279 gen_load_fpr32h(ctx, fp1, ft);
12280 gen_store_fpr32(ctx, fp1, fd);
12281 gen_store_fpr32h(ctx, fp0, fd);
12282 tcg_temp_free_i32(fp0);
12283 tcg_temp_free_i32(fp1);
12287 case OPC_CMP_UN_PS:
12288 case OPC_CMP_EQ_PS:
12289 case OPC_CMP_UEQ_PS:
12290 case OPC_CMP_OLT_PS:
12291 case OPC_CMP_ULT_PS:
12292 case OPC_CMP_OLE_PS:
12293 case OPC_CMP_ULE_PS:
12294 case OPC_CMP_SF_PS:
12295 case OPC_CMP_NGLE_PS:
12296 case OPC_CMP_SEQ_PS:
12297 case OPC_CMP_NGL_PS:
12298 case OPC_CMP_LT_PS:
12299 case OPC_CMP_NGE_PS:
12300 case OPC_CMP_LE_PS:
12301 case OPC_CMP_NGT_PS:
12302 if (ctx->opcode & (1 << 6)) {
12303 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12305 gen_cmp_ps(ctx, func-48, ft, fs, cc);
12309 MIPS_INVAL("farith");
12310 generate_exception_end(ctx, EXCP_RI);
12315 /* Coprocessor 3 (FPU) */
12316 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12317 int fd, int fs, int base, int index)
12319 TCGv t0 = tcg_temp_new();
12322 gen_load_gpr(t0, index);
12323 } else if (index == 0) {
12324 gen_load_gpr(t0, base);
12326 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12328 /* Don't do NOP if destination is zero: we must perform the actual
12334 TCGv_i32 fp0 = tcg_temp_new_i32();
12336 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12337 tcg_gen_trunc_tl_i32(fp0, t0);
12338 gen_store_fpr32(ctx, fp0, fd);
12339 tcg_temp_free_i32(fp0);
12344 check_cp1_registers(ctx, fd);
12346 TCGv_i64 fp0 = tcg_temp_new_i64();
12347 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12348 gen_store_fpr64(ctx, fp0, fd);
12349 tcg_temp_free_i64(fp0);
12353 check_cp1_64bitmode(ctx);
12354 tcg_gen_andi_tl(t0, t0, ~0x7);
12356 TCGv_i64 fp0 = tcg_temp_new_i64();
12358 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12359 gen_store_fpr64(ctx, fp0, fd);
12360 tcg_temp_free_i64(fp0);
12366 TCGv_i32 fp0 = tcg_temp_new_i32();
12367 gen_load_fpr32(ctx, fp0, fs);
12368 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12369 tcg_temp_free_i32(fp0);
12374 check_cp1_registers(ctx, fs);
12376 TCGv_i64 fp0 = tcg_temp_new_i64();
12377 gen_load_fpr64(ctx, fp0, fs);
12378 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12379 tcg_temp_free_i64(fp0);
12383 check_cp1_64bitmode(ctx);
12384 tcg_gen_andi_tl(t0, t0, ~0x7);
12386 TCGv_i64 fp0 = tcg_temp_new_i64();
12387 gen_load_fpr64(ctx, fp0, fs);
12388 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12389 tcg_temp_free_i64(fp0);
12396 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12397 int fd, int fr, int fs, int ft)
12403 TCGv t0 = tcg_temp_local_new();
12404 TCGv_i32 fp = tcg_temp_new_i32();
12405 TCGv_i32 fph = tcg_temp_new_i32();
12406 TCGLabel *l1 = gen_new_label();
12407 TCGLabel *l2 = gen_new_label();
12409 gen_load_gpr(t0, fr);
12410 tcg_gen_andi_tl(t0, t0, 0x7);
12412 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12413 gen_load_fpr32(ctx, fp, fs);
12414 gen_load_fpr32h(ctx, fph, fs);
12415 gen_store_fpr32(ctx, fp, fd);
12416 gen_store_fpr32h(ctx, fph, fd);
12419 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12421 #ifdef TARGET_WORDS_BIGENDIAN
12422 gen_load_fpr32(ctx, fp, fs);
12423 gen_load_fpr32h(ctx, fph, ft);
12424 gen_store_fpr32h(ctx, fp, fd);
12425 gen_store_fpr32(ctx, fph, fd);
12427 gen_load_fpr32h(ctx, fph, fs);
12428 gen_load_fpr32(ctx, fp, ft);
12429 gen_store_fpr32(ctx, fph, fd);
12430 gen_store_fpr32h(ctx, fp, fd);
12433 tcg_temp_free_i32(fp);
12434 tcg_temp_free_i32(fph);
12440 TCGv_i32 fp0 = tcg_temp_new_i32();
12441 TCGv_i32 fp1 = tcg_temp_new_i32();
12442 TCGv_i32 fp2 = tcg_temp_new_i32();
12444 gen_load_fpr32(ctx, fp0, fs);
12445 gen_load_fpr32(ctx, fp1, ft);
12446 gen_load_fpr32(ctx, fp2, fr);
12447 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12448 tcg_temp_free_i32(fp0);
12449 tcg_temp_free_i32(fp1);
12450 gen_store_fpr32(ctx, fp2, fd);
12451 tcg_temp_free_i32(fp2);
12456 check_cp1_registers(ctx, fd | fs | ft | fr);
12458 TCGv_i64 fp0 = tcg_temp_new_i64();
12459 TCGv_i64 fp1 = tcg_temp_new_i64();
12460 TCGv_i64 fp2 = tcg_temp_new_i64();
12462 gen_load_fpr64(ctx, fp0, fs);
12463 gen_load_fpr64(ctx, fp1, ft);
12464 gen_load_fpr64(ctx, fp2, fr);
12465 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12466 tcg_temp_free_i64(fp0);
12467 tcg_temp_free_i64(fp1);
12468 gen_store_fpr64(ctx, fp2, fd);
12469 tcg_temp_free_i64(fp2);
12475 TCGv_i64 fp0 = tcg_temp_new_i64();
12476 TCGv_i64 fp1 = tcg_temp_new_i64();
12477 TCGv_i64 fp2 = tcg_temp_new_i64();
12479 gen_load_fpr64(ctx, fp0, fs);
12480 gen_load_fpr64(ctx, fp1, ft);
12481 gen_load_fpr64(ctx, fp2, fr);
12482 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12483 tcg_temp_free_i64(fp0);
12484 tcg_temp_free_i64(fp1);
12485 gen_store_fpr64(ctx, fp2, fd);
12486 tcg_temp_free_i64(fp2);
12492 TCGv_i32 fp0 = tcg_temp_new_i32();
12493 TCGv_i32 fp1 = tcg_temp_new_i32();
12494 TCGv_i32 fp2 = tcg_temp_new_i32();
12496 gen_load_fpr32(ctx, fp0, fs);
12497 gen_load_fpr32(ctx, fp1, ft);
12498 gen_load_fpr32(ctx, fp2, fr);
12499 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12500 tcg_temp_free_i32(fp0);
12501 tcg_temp_free_i32(fp1);
12502 gen_store_fpr32(ctx, fp2, fd);
12503 tcg_temp_free_i32(fp2);
12508 check_cp1_registers(ctx, fd | fs | ft | fr);
12510 TCGv_i64 fp0 = tcg_temp_new_i64();
12511 TCGv_i64 fp1 = tcg_temp_new_i64();
12512 TCGv_i64 fp2 = tcg_temp_new_i64();
12514 gen_load_fpr64(ctx, fp0, fs);
12515 gen_load_fpr64(ctx, fp1, ft);
12516 gen_load_fpr64(ctx, fp2, fr);
12517 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12518 tcg_temp_free_i64(fp0);
12519 tcg_temp_free_i64(fp1);
12520 gen_store_fpr64(ctx, fp2, fd);
12521 tcg_temp_free_i64(fp2);
12527 TCGv_i64 fp0 = tcg_temp_new_i64();
12528 TCGv_i64 fp1 = tcg_temp_new_i64();
12529 TCGv_i64 fp2 = tcg_temp_new_i64();
12531 gen_load_fpr64(ctx, fp0, fs);
12532 gen_load_fpr64(ctx, fp1, ft);
12533 gen_load_fpr64(ctx, fp2, fr);
12534 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12535 tcg_temp_free_i64(fp0);
12536 tcg_temp_free_i64(fp1);
12537 gen_store_fpr64(ctx, fp2, fd);
12538 tcg_temp_free_i64(fp2);
12544 TCGv_i32 fp0 = tcg_temp_new_i32();
12545 TCGv_i32 fp1 = tcg_temp_new_i32();
12546 TCGv_i32 fp2 = tcg_temp_new_i32();
12548 gen_load_fpr32(ctx, fp0, fs);
12549 gen_load_fpr32(ctx, fp1, ft);
12550 gen_load_fpr32(ctx, fp2, fr);
12551 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12552 tcg_temp_free_i32(fp0);
12553 tcg_temp_free_i32(fp1);
12554 gen_store_fpr32(ctx, fp2, fd);
12555 tcg_temp_free_i32(fp2);
12560 check_cp1_registers(ctx, fd | fs | ft | fr);
12562 TCGv_i64 fp0 = tcg_temp_new_i64();
12563 TCGv_i64 fp1 = tcg_temp_new_i64();
12564 TCGv_i64 fp2 = tcg_temp_new_i64();
12566 gen_load_fpr64(ctx, fp0, fs);
12567 gen_load_fpr64(ctx, fp1, ft);
12568 gen_load_fpr64(ctx, fp2, fr);
12569 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12570 tcg_temp_free_i64(fp0);
12571 tcg_temp_free_i64(fp1);
12572 gen_store_fpr64(ctx, fp2, fd);
12573 tcg_temp_free_i64(fp2);
12579 TCGv_i64 fp0 = tcg_temp_new_i64();
12580 TCGv_i64 fp1 = tcg_temp_new_i64();
12581 TCGv_i64 fp2 = tcg_temp_new_i64();
12583 gen_load_fpr64(ctx, fp0, fs);
12584 gen_load_fpr64(ctx, fp1, ft);
12585 gen_load_fpr64(ctx, fp2, fr);
12586 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12587 tcg_temp_free_i64(fp0);
12588 tcg_temp_free_i64(fp1);
12589 gen_store_fpr64(ctx, fp2, fd);
12590 tcg_temp_free_i64(fp2);
12596 TCGv_i32 fp0 = tcg_temp_new_i32();
12597 TCGv_i32 fp1 = tcg_temp_new_i32();
12598 TCGv_i32 fp2 = tcg_temp_new_i32();
12600 gen_load_fpr32(ctx, fp0, fs);
12601 gen_load_fpr32(ctx, fp1, ft);
12602 gen_load_fpr32(ctx, fp2, fr);
12603 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12604 tcg_temp_free_i32(fp0);
12605 tcg_temp_free_i32(fp1);
12606 gen_store_fpr32(ctx, fp2, fd);
12607 tcg_temp_free_i32(fp2);
12612 check_cp1_registers(ctx, fd | fs | ft | fr);
12614 TCGv_i64 fp0 = tcg_temp_new_i64();
12615 TCGv_i64 fp1 = tcg_temp_new_i64();
12616 TCGv_i64 fp2 = tcg_temp_new_i64();
12618 gen_load_fpr64(ctx, fp0, fs);
12619 gen_load_fpr64(ctx, fp1, ft);
12620 gen_load_fpr64(ctx, fp2, fr);
12621 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12622 tcg_temp_free_i64(fp0);
12623 tcg_temp_free_i64(fp1);
12624 gen_store_fpr64(ctx, fp2, fd);
12625 tcg_temp_free_i64(fp2);
12631 TCGv_i64 fp0 = tcg_temp_new_i64();
12632 TCGv_i64 fp1 = tcg_temp_new_i64();
12633 TCGv_i64 fp2 = tcg_temp_new_i64();
12635 gen_load_fpr64(ctx, fp0, fs);
12636 gen_load_fpr64(ctx, fp1, ft);
12637 gen_load_fpr64(ctx, fp2, fr);
12638 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12639 tcg_temp_free_i64(fp0);
12640 tcg_temp_free_i64(fp1);
12641 gen_store_fpr64(ctx, fp2, fd);
12642 tcg_temp_free_i64(fp2);
12646 MIPS_INVAL("flt3_arith");
12647 generate_exception_end(ctx, EXCP_RI);
12652 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12656 #if !defined(CONFIG_USER_ONLY)
12657 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12658 Therefore only check the ISA in system mode. */
12659 check_insn(ctx, ISA_MIPS32R2);
12661 t0 = tcg_temp_new();
12665 gen_helper_rdhwr_cpunum(t0, cpu_env);
12666 gen_store_gpr(t0, rt);
12669 gen_helper_rdhwr_synci_step(t0, cpu_env);
12670 gen_store_gpr(t0, rt);
12673 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12676 gen_helper_rdhwr_cc(t0, cpu_env);
12677 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12680 gen_store_gpr(t0, rt);
12681 /* Break the TB to be able to take timer interrupts immediately
12682 after reading count. DISAS_STOP isn't sufficient, we need to ensure
12683 we break completely out of translated code. */
12684 gen_save_pc(ctx->base.pc_next + 4);
12685 ctx->base.is_jmp = DISAS_EXIT;
12688 gen_helper_rdhwr_ccres(t0, cpu_env);
12689 gen_store_gpr(t0, rt);
12692 check_insn(ctx, ISA_MIPS32R6);
12694 /* Performance counter registers are not implemented other than
12695 * control register 0.
12697 generate_exception(ctx, EXCP_RI);
12699 gen_helper_rdhwr_performance(t0, cpu_env);
12700 gen_store_gpr(t0, rt);
12703 check_insn(ctx, ISA_MIPS32R6);
12704 gen_helper_rdhwr_xnp(t0, cpu_env);
12705 gen_store_gpr(t0, rt);
12708 #if defined(CONFIG_USER_ONLY)
12709 tcg_gen_ld_tl(t0, cpu_env,
12710 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12711 gen_store_gpr(t0, rt);
12714 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12715 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12716 tcg_gen_ld_tl(t0, cpu_env,
12717 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12718 gen_store_gpr(t0, rt);
12720 generate_exception_end(ctx, EXCP_RI);
12724 default: /* Invalid */
12725 MIPS_INVAL("rdhwr");
12726 generate_exception_end(ctx, EXCP_RI);
12732 static inline void clear_branch_hflags(DisasContext *ctx)
12734 ctx->hflags &= ~MIPS_HFLAG_BMASK;
12735 if (ctx->base.is_jmp == DISAS_NEXT) {
12736 save_cpu_state(ctx, 0);
12738 /* it is not safe to save ctx->hflags as hflags may be changed
12739 in execution time by the instruction in delay / forbidden slot. */
12740 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12744 static void gen_branch(DisasContext *ctx, int insn_bytes)
12746 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12747 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12748 /* Branches completion */
12749 clear_branch_hflags(ctx);
12750 ctx->base.is_jmp = DISAS_NORETURN;
12751 /* FIXME: Need to clear can_do_io. */
12752 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12753 case MIPS_HFLAG_FBNSLOT:
12754 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12757 /* unconditional branch */
12758 if (proc_hflags & MIPS_HFLAG_BX) {
12759 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12761 gen_goto_tb(ctx, 0, ctx->btarget);
12763 case MIPS_HFLAG_BL:
12764 /* blikely taken case */
12765 gen_goto_tb(ctx, 0, ctx->btarget);
12767 case MIPS_HFLAG_BC:
12768 /* Conditional branch */
12770 TCGLabel *l1 = gen_new_label();
12772 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12773 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12775 gen_goto_tb(ctx, 0, ctx->btarget);
12778 case MIPS_HFLAG_BR:
12779 /* unconditional branch to register */
12780 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12781 TCGv t0 = tcg_temp_new();
12782 TCGv_i32 t1 = tcg_temp_new_i32();
12784 tcg_gen_andi_tl(t0, btarget, 0x1);
12785 tcg_gen_trunc_tl_i32(t1, t0);
12787 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12788 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12789 tcg_gen_or_i32(hflags, hflags, t1);
12790 tcg_temp_free_i32(t1);
12792 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12794 tcg_gen_mov_tl(cpu_PC, btarget);
12796 if (ctx->base.singlestep_enabled) {
12797 save_cpu_state(ctx, 0);
12798 gen_helper_raise_exception_debug(cpu_env);
12800 tcg_gen_lookup_and_goto_ptr();
12803 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12809 /* Compact Branches */
12810 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12811 int rs, int rt, int32_t offset)
12813 int bcond_compute = 0;
12814 TCGv t0 = tcg_temp_new();
12815 TCGv t1 = tcg_temp_new();
12816 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12818 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12819 #ifdef MIPS_DEBUG_DISAS
12820 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12821 "\n", ctx->base.pc_next);
12823 generate_exception_end(ctx, EXCP_RI);
12827 /* Load needed operands and calculate btarget */
12829 /* compact branch */
12830 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12831 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12832 gen_load_gpr(t0, rs);
12833 gen_load_gpr(t1, rt);
12835 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12836 if (rs <= rt && rs == 0) {
12837 /* OPC_BEQZALC, OPC_BNEZALC */
12838 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12841 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12842 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12843 gen_load_gpr(t0, rs);
12844 gen_load_gpr(t1, rt);
12846 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12848 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12849 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12850 if (rs == 0 || rs == rt) {
12851 /* OPC_BLEZALC, OPC_BGEZALC */
12852 /* OPC_BGTZALC, OPC_BLTZALC */
12853 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12855 gen_load_gpr(t0, rs);
12856 gen_load_gpr(t1, rt);
12858 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12862 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12867 /* OPC_BEQZC, OPC_BNEZC */
12868 gen_load_gpr(t0, rs);
12870 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12872 /* OPC_JIC, OPC_JIALC */
12873 TCGv tbase = tcg_temp_new();
12874 TCGv toffset = tcg_temp_new();
12876 gen_load_gpr(tbase, rt);
12877 tcg_gen_movi_tl(toffset, offset);
12878 gen_op_addr_add(ctx, btarget, tbase, toffset);
12879 tcg_temp_free(tbase);
12880 tcg_temp_free(toffset);
12884 MIPS_INVAL("Compact branch/jump");
12885 generate_exception_end(ctx, EXCP_RI);
12889 if (bcond_compute == 0) {
12890 /* Uncoditional compact branch */
12893 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12896 ctx->hflags |= MIPS_HFLAG_BR;
12899 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12902 ctx->hflags |= MIPS_HFLAG_B;
12905 MIPS_INVAL("Compact branch/jump");
12906 generate_exception_end(ctx, EXCP_RI);
12910 /* Generating branch here as compact branches don't have delay slot */
12911 gen_branch(ctx, 4);
12913 /* Conditional compact branch */
12914 TCGLabel *fs = gen_new_label();
12915 save_cpu_state(ctx, 0);
12918 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12919 if (rs == 0 && rt != 0) {
12921 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12922 } else if (rs != 0 && rt != 0 && rs == rt) {
12924 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12927 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12930 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12931 if (rs == 0 && rt != 0) {
12933 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12934 } else if (rs != 0 && rt != 0 && rs == rt) {
12936 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12939 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12942 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12943 if (rs == 0 && rt != 0) {
12945 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12946 } else if (rs != 0 && rt != 0 && rs == rt) {
12948 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12951 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12954 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12955 if (rs == 0 && rt != 0) {
12957 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12958 } else if (rs != 0 && rt != 0 && rs == rt) {
12960 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12963 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12966 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12967 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12969 /* OPC_BOVC, OPC_BNVC */
12970 TCGv t2 = tcg_temp_new();
12971 TCGv t3 = tcg_temp_new();
12972 TCGv t4 = tcg_temp_new();
12973 TCGv input_overflow = tcg_temp_new();
12975 gen_load_gpr(t0, rs);
12976 gen_load_gpr(t1, rt);
12977 tcg_gen_ext32s_tl(t2, t0);
12978 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12979 tcg_gen_ext32s_tl(t3, t1);
12980 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12981 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12983 tcg_gen_add_tl(t4, t2, t3);
12984 tcg_gen_ext32s_tl(t4, t4);
12985 tcg_gen_xor_tl(t2, t2, t3);
12986 tcg_gen_xor_tl(t3, t4, t3);
12987 tcg_gen_andc_tl(t2, t3, t2);
12988 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12989 tcg_gen_or_tl(t4, t4, input_overflow);
12990 if (opc == OPC_BOVC) {
12992 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12995 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12997 tcg_temp_free(input_overflow);
13001 } else if (rs < rt && rs == 0) {
13002 /* OPC_BEQZALC, OPC_BNEZALC */
13003 if (opc == OPC_BEQZALC) {
13005 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13008 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13011 /* OPC_BEQC, OPC_BNEC */
13012 if (opc == OPC_BEQC) {
13014 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13017 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13022 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13025 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13028 MIPS_INVAL("Compact conditional branch/jump");
13029 generate_exception_end(ctx, EXCP_RI);
13033 /* Generating branch here as compact branches don't have delay slot */
13034 gen_goto_tb(ctx, 1, ctx->btarget);
13037 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13045 /* ISA extensions (ASEs) */
13046 /* MIPS16 extension to MIPS32 */
13048 /* MIPS16 major opcodes */
13050 M16_OPC_ADDIUSP = 0x00,
13051 M16_OPC_ADDIUPC = 0x01,
13053 M16_OPC_JAL = 0x03,
13054 M16_OPC_BEQZ = 0x04,
13055 M16_OPC_BNEQZ = 0x05,
13056 M16_OPC_SHIFT = 0x06,
13058 M16_OPC_RRIA = 0x08,
13059 M16_OPC_ADDIU8 = 0x09,
13060 M16_OPC_SLTI = 0x0a,
13061 M16_OPC_SLTIU = 0x0b,
13064 M16_OPC_CMPI = 0x0e,
13068 M16_OPC_LWSP = 0x12,
13070 M16_OPC_LBU = 0x14,
13071 M16_OPC_LHU = 0x15,
13072 M16_OPC_LWPC = 0x16,
13073 M16_OPC_LWU = 0x17,
13076 M16_OPC_SWSP = 0x1a,
13078 M16_OPC_RRR = 0x1c,
13080 M16_OPC_EXTEND = 0x1e,
13084 /* I8 funct field */
13103 /* RR funct field */
13137 /* I64 funct field */
13145 I64_DADDIUPC = 0x6,
13149 /* RR ry field for CNVT */
13151 RR_RY_CNVT_ZEB = 0x0,
13152 RR_RY_CNVT_ZEH = 0x1,
13153 RR_RY_CNVT_ZEW = 0x2,
13154 RR_RY_CNVT_SEB = 0x4,
13155 RR_RY_CNVT_SEH = 0x5,
13156 RR_RY_CNVT_SEW = 0x6,
13159 static int xlat (int r)
13161 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13166 static void gen_mips16_save (DisasContext *ctx,
13167 int xsregs, int aregs,
13168 int do_ra, int do_s0, int do_s1,
13171 TCGv t0 = tcg_temp_new();
13172 TCGv t1 = tcg_temp_new();
13173 TCGv t2 = tcg_temp_new();
13203 generate_exception_end(ctx, EXCP_RI);
13209 gen_base_offset_addr(ctx, t0, 29, 12);
13210 gen_load_gpr(t1, 7);
13211 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13214 gen_base_offset_addr(ctx, t0, 29, 8);
13215 gen_load_gpr(t1, 6);
13216 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13219 gen_base_offset_addr(ctx, t0, 29, 4);
13220 gen_load_gpr(t1, 5);
13221 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13224 gen_base_offset_addr(ctx, t0, 29, 0);
13225 gen_load_gpr(t1, 4);
13226 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13229 gen_load_gpr(t0, 29);
13231 #define DECR_AND_STORE(reg) do { \
13232 tcg_gen_movi_tl(t2, -4); \
13233 gen_op_addr_add(ctx, t0, t0, t2); \
13234 gen_load_gpr(t1, reg); \
13235 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13239 DECR_AND_STORE(31);
13244 DECR_AND_STORE(30);
13247 DECR_AND_STORE(23);
13250 DECR_AND_STORE(22);
13253 DECR_AND_STORE(21);
13256 DECR_AND_STORE(20);
13259 DECR_AND_STORE(19);
13262 DECR_AND_STORE(18);
13266 DECR_AND_STORE(17);
13269 DECR_AND_STORE(16);
13299 generate_exception_end(ctx, EXCP_RI);
13315 #undef DECR_AND_STORE
13317 tcg_gen_movi_tl(t2, -framesize);
13318 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13324 static void gen_mips16_restore (DisasContext *ctx,
13325 int xsregs, int aregs,
13326 int do_ra, int do_s0, int do_s1,
13330 TCGv t0 = tcg_temp_new();
13331 TCGv t1 = tcg_temp_new();
13332 TCGv t2 = tcg_temp_new();
13334 tcg_gen_movi_tl(t2, framesize);
13335 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13337 #define DECR_AND_LOAD(reg) do { \
13338 tcg_gen_movi_tl(t2, -4); \
13339 gen_op_addr_add(ctx, t0, t0, t2); \
13340 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13341 gen_store_gpr(t1, reg); \
13405 generate_exception_end(ctx, EXCP_RI);
13421 #undef DECR_AND_LOAD
13423 tcg_gen_movi_tl(t2, framesize);
13424 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13430 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13431 int is_64_bit, int extended)
13435 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13436 generate_exception_end(ctx, EXCP_RI);
13440 t0 = tcg_temp_new();
13442 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13443 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13445 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13451 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13454 TCGv_i32 t0 = tcg_const_i32(op);
13455 TCGv t1 = tcg_temp_new();
13456 gen_base_offset_addr(ctx, t1, base, offset);
13457 gen_helper_cache(cpu_env, t1, t0);
13460 #if defined(TARGET_MIPS64)
13461 static void decode_i64_mips16 (DisasContext *ctx,
13462 int ry, int funct, int16_t offset,
13467 check_insn(ctx, ISA_MIPS3);
13468 check_mips_64(ctx);
13469 offset = extended ? offset : offset << 3;
13470 gen_ld(ctx, OPC_LD, ry, 29, offset);
13473 check_insn(ctx, ISA_MIPS3);
13474 check_mips_64(ctx);
13475 offset = extended ? offset : offset << 3;
13476 gen_st(ctx, OPC_SD, ry, 29, offset);
13479 check_insn(ctx, ISA_MIPS3);
13480 check_mips_64(ctx);
13481 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13482 gen_st(ctx, OPC_SD, 31, 29, offset);
13485 check_insn(ctx, ISA_MIPS3);
13486 check_mips_64(ctx);
13487 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13488 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13491 check_insn(ctx, ISA_MIPS3);
13492 check_mips_64(ctx);
13493 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13494 generate_exception_end(ctx, EXCP_RI);
13496 offset = extended ? offset : offset << 3;
13497 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13501 check_insn(ctx, ISA_MIPS3);
13502 check_mips_64(ctx);
13503 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13504 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13507 check_insn(ctx, ISA_MIPS3);
13508 check_mips_64(ctx);
13509 offset = extended ? offset : offset << 2;
13510 gen_addiupc(ctx, ry, offset, 1, extended);
13513 check_insn(ctx, ISA_MIPS3);
13514 check_mips_64(ctx);
13515 offset = extended ? offset : offset << 2;
13516 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13522 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13524 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13525 int op, rx, ry, funct, sa;
13526 int16_t imm, offset;
13528 ctx->opcode = (ctx->opcode << 16) | extend;
13529 op = (ctx->opcode >> 11) & 0x1f;
13530 sa = (ctx->opcode >> 22) & 0x1f;
13531 funct = (ctx->opcode >> 8) & 0x7;
13532 rx = xlat((ctx->opcode >> 8) & 0x7);
13533 ry = xlat((ctx->opcode >> 5) & 0x7);
13534 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13535 | ((ctx->opcode >> 21) & 0x3f) << 5
13536 | (ctx->opcode & 0x1f));
13538 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13541 case M16_OPC_ADDIUSP:
13542 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13544 case M16_OPC_ADDIUPC:
13545 gen_addiupc(ctx, rx, imm, 0, 1);
13548 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13549 /* No delay slot, so just process as a normal instruction */
13552 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13553 /* No delay slot, so just process as a normal instruction */
13555 case M16_OPC_BNEQZ:
13556 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13557 /* No delay slot, so just process as a normal instruction */
13559 case M16_OPC_SHIFT:
13560 switch (ctx->opcode & 0x3) {
13562 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13565 #if defined(TARGET_MIPS64)
13566 check_mips_64(ctx);
13567 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13569 generate_exception_end(ctx, EXCP_RI);
13573 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13576 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13580 #if defined(TARGET_MIPS64)
13582 check_insn(ctx, ISA_MIPS3);
13583 check_mips_64(ctx);
13584 gen_ld(ctx, OPC_LD, ry, rx, offset);
13588 imm = ctx->opcode & 0xf;
13589 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13590 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13591 imm = (int16_t) (imm << 1) >> 1;
13592 if ((ctx->opcode >> 4) & 0x1) {
13593 #if defined(TARGET_MIPS64)
13594 check_mips_64(ctx);
13595 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13597 generate_exception_end(ctx, EXCP_RI);
13600 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13603 case M16_OPC_ADDIU8:
13604 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13607 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13609 case M16_OPC_SLTIU:
13610 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13615 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13618 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13621 gen_st(ctx, OPC_SW, 31, 29, imm);
13624 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13627 check_insn(ctx, ISA_MIPS32);
13629 int xsregs = (ctx->opcode >> 24) & 0x7;
13630 int aregs = (ctx->opcode >> 16) & 0xf;
13631 int do_ra = (ctx->opcode >> 6) & 0x1;
13632 int do_s0 = (ctx->opcode >> 5) & 0x1;
13633 int do_s1 = (ctx->opcode >> 4) & 0x1;
13634 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13635 | (ctx->opcode & 0xf)) << 3;
13637 if (ctx->opcode & (1 << 7)) {
13638 gen_mips16_save(ctx, xsregs, aregs,
13639 do_ra, do_s0, do_s1,
13642 gen_mips16_restore(ctx, xsregs, aregs,
13643 do_ra, do_s0, do_s1,
13649 generate_exception_end(ctx, EXCP_RI);
13654 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13657 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13659 #if defined(TARGET_MIPS64)
13661 check_insn(ctx, ISA_MIPS3);
13662 check_mips_64(ctx);
13663 gen_st(ctx, OPC_SD, ry, rx, offset);
13667 gen_ld(ctx, OPC_LB, ry, rx, offset);
13670 gen_ld(ctx, OPC_LH, ry, rx, offset);
13673 gen_ld(ctx, OPC_LW, rx, 29, offset);
13676 gen_ld(ctx, OPC_LW, ry, rx, offset);
13679 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13682 gen_ld(ctx, OPC_LHU, ry, rx, offset);
13685 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13687 #if defined(TARGET_MIPS64)
13689 check_insn(ctx, ISA_MIPS3);
13690 check_mips_64(ctx);
13691 gen_ld(ctx, OPC_LWU, ry, rx, offset);
13695 gen_st(ctx, OPC_SB, ry, rx, offset);
13698 gen_st(ctx, OPC_SH, ry, rx, offset);
13701 gen_st(ctx, OPC_SW, rx, 29, offset);
13704 gen_st(ctx, OPC_SW, ry, rx, offset);
13706 #if defined(TARGET_MIPS64)
13708 decode_i64_mips16(ctx, ry, funct, offset, 1);
13712 generate_exception_end(ctx, EXCP_RI);
13719 static inline bool is_uhi(int sdbbp_code)
13721 #ifdef CONFIG_USER_ONLY
13724 return semihosting_enabled() && sdbbp_code == 1;
13728 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13732 int op, cnvt_op, op1, offset;
13736 op = (ctx->opcode >> 11) & 0x1f;
13737 sa = (ctx->opcode >> 2) & 0x7;
13738 sa = sa == 0 ? 8 : sa;
13739 rx = xlat((ctx->opcode >> 8) & 0x7);
13740 cnvt_op = (ctx->opcode >> 5) & 0x7;
13741 ry = xlat((ctx->opcode >> 5) & 0x7);
13742 op1 = offset = ctx->opcode & 0x1f;
13747 case M16_OPC_ADDIUSP:
13749 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13751 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13754 case M16_OPC_ADDIUPC:
13755 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13758 offset = (ctx->opcode & 0x7ff) << 1;
13759 offset = (int16_t)(offset << 4) >> 4;
13760 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13761 /* No delay slot, so just process as a normal instruction */
13764 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13765 offset = (((ctx->opcode & 0x1f) << 21)
13766 | ((ctx->opcode >> 5) & 0x1f) << 16
13768 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13769 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13773 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13774 ((int8_t)ctx->opcode) << 1, 0);
13775 /* No delay slot, so just process as a normal instruction */
13777 case M16_OPC_BNEQZ:
13778 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13779 ((int8_t)ctx->opcode) << 1, 0);
13780 /* No delay slot, so just process as a normal instruction */
13782 case M16_OPC_SHIFT:
13783 switch (ctx->opcode & 0x3) {
13785 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13788 #if defined(TARGET_MIPS64)
13789 check_insn(ctx, ISA_MIPS3);
13790 check_mips_64(ctx);
13791 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13793 generate_exception_end(ctx, EXCP_RI);
13797 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13800 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13804 #if defined(TARGET_MIPS64)
13806 check_insn(ctx, ISA_MIPS3);
13807 check_mips_64(ctx);
13808 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13813 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13815 if ((ctx->opcode >> 4) & 1) {
13816 #if defined(TARGET_MIPS64)
13817 check_insn(ctx, ISA_MIPS3);
13818 check_mips_64(ctx);
13819 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13821 generate_exception_end(ctx, EXCP_RI);
13824 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13828 case M16_OPC_ADDIU8:
13830 int16_t imm = (int8_t) ctx->opcode;
13832 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13837 int16_t imm = (uint8_t) ctx->opcode;
13838 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13841 case M16_OPC_SLTIU:
13843 int16_t imm = (uint8_t) ctx->opcode;
13844 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13851 funct = (ctx->opcode >> 8) & 0x7;
13854 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13855 ((int8_t)ctx->opcode) << 1, 0);
13858 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13859 ((int8_t)ctx->opcode) << 1, 0);
13862 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13865 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13866 ((int8_t)ctx->opcode) << 3);
13869 check_insn(ctx, ISA_MIPS32);
13871 int do_ra = ctx->opcode & (1 << 6);
13872 int do_s0 = ctx->opcode & (1 << 5);
13873 int do_s1 = ctx->opcode & (1 << 4);
13874 int framesize = ctx->opcode & 0xf;
13876 if (framesize == 0) {
13879 framesize = framesize << 3;
13882 if (ctx->opcode & (1 << 7)) {
13883 gen_mips16_save(ctx, 0, 0,
13884 do_ra, do_s0, do_s1, framesize);
13886 gen_mips16_restore(ctx, 0, 0,
13887 do_ra, do_s0, do_s1, framesize);
13893 int rz = xlat(ctx->opcode & 0x7);
13895 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13896 ((ctx->opcode >> 5) & 0x7);
13897 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13901 reg32 = ctx->opcode & 0x1f;
13902 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13905 generate_exception_end(ctx, EXCP_RI);
13912 int16_t imm = (uint8_t) ctx->opcode;
13914 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13919 int16_t imm = (uint8_t) ctx->opcode;
13920 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13923 #if defined(TARGET_MIPS64)
13925 check_insn(ctx, ISA_MIPS3);
13926 check_mips_64(ctx);
13927 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13931 gen_ld(ctx, OPC_LB, ry, rx, offset);
13934 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13937 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13940 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13943 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13946 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13949 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13951 #if defined (TARGET_MIPS64)
13953 check_insn(ctx, ISA_MIPS3);
13954 check_mips_64(ctx);
13955 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13959 gen_st(ctx, OPC_SB, ry, rx, offset);
13962 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13965 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13968 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13972 int rz = xlat((ctx->opcode >> 2) & 0x7);
13975 switch (ctx->opcode & 0x3) {
13977 mips32_op = OPC_ADDU;
13980 mips32_op = OPC_SUBU;
13982 #if defined(TARGET_MIPS64)
13984 mips32_op = OPC_DADDU;
13985 check_insn(ctx, ISA_MIPS3);
13986 check_mips_64(ctx);
13989 mips32_op = OPC_DSUBU;
13990 check_insn(ctx, ISA_MIPS3);
13991 check_mips_64(ctx);
13995 generate_exception_end(ctx, EXCP_RI);
13999 gen_arith(ctx, mips32_op, rz, rx, ry);
14008 int nd = (ctx->opcode >> 7) & 0x1;
14009 int link = (ctx->opcode >> 6) & 0x1;
14010 int ra = (ctx->opcode >> 5) & 0x1;
14013 check_insn(ctx, ISA_MIPS32);
14022 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14027 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14028 gen_helper_do_semihosting(cpu_env);
14030 /* XXX: not clear which exception should be raised
14031 * when in debug mode...
14033 check_insn(ctx, ISA_MIPS32);
14034 generate_exception_end(ctx, EXCP_DBp);
14038 gen_slt(ctx, OPC_SLT, 24, rx, ry);
14041 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14044 generate_exception_end(ctx, EXCP_BREAK);
14047 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14050 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14053 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14055 #if defined (TARGET_MIPS64)
14057 check_insn(ctx, ISA_MIPS3);
14058 check_mips_64(ctx);
14059 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14063 gen_logic(ctx, OPC_XOR, 24, rx, ry);
14066 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14069 gen_logic(ctx, OPC_AND, rx, rx, ry);
14072 gen_logic(ctx, OPC_OR, rx, rx, ry);
14075 gen_logic(ctx, OPC_XOR, rx, rx, ry);
14078 gen_logic(ctx, OPC_NOR, rx, ry, 0);
14081 gen_HILO(ctx, OPC_MFHI, 0, rx);
14084 check_insn(ctx, ISA_MIPS32);
14086 case RR_RY_CNVT_ZEB:
14087 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14089 case RR_RY_CNVT_ZEH:
14090 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14092 case RR_RY_CNVT_SEB:
14093 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14095 case RR_RY_CNVT_SEH:
14096 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14098 #if defined (TARGET_MIPS64)
14099 case RR_RY_CNVT_ZEW:
14100 check_insn(ctx, ISA_MIPS64);
14101 check_mips_64(ctx);
14102 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14104 case RR_RY_CNVT_SEW:
14105 check_insn(ctx, ISA_MIPS64);
14106 check_mips_64(ctx);
14107 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14111 generate_exception_end(ctx, EXCP_RI);
14116 gen_HILO(ctx, OPC_MFLO, 0, rx);
14118 #if defined (TARGET_MIPS64)
14120 check_insn(ctx, ISA_MIPS3);
14121 check_mips_64(ctx);
14122 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14125 check_insn(ctx, ISA_MIPS3);
14126 check_mips_64(ctx);
14127 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14130 check_insn(ctx, ISA_MIPS3);
14131 check_mips_64(ctx);
14132 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14135 check_insn(ctx, ISA_MIPS3);
14136 check_mips_64(ctx);
14137 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14141 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14144 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14147 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14150 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14152 #if defined (TARGET_MIPS64)
14154 check_insn(ctx, ISA_MIPS3);
14155 check_mips_64(ctx);
14156 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14159 check_insn(ctx, ISA_MIPS3);
14160 check_mips_64(ctx);
14161 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14164 check_insn(ctx, ISA_MIPS3);
14165 check_mips_64(ctx);
14166 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14169 check_insn(ctx, ISA_MIPS3);
14170 check_mips_64(ctx);
14171 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14175 generate_exception_end(ctx, EXCP_RI);
14179 case M16_OPC_EXTEND:
14180 decode_extended_mips16_opc(env, ctx);
14183 #if defined(TARGET_MIPS64)
14185 funct = (ctx->opcode >> 8) & 0x7;
14186 decode_i64_mips16(ctx, ry, funct, offset, 0);
14190 generate_exception_end(ctx, EXCP_RI);
14197 /* microMIPS extension to MIPS32/MIPS64 */
14200 * microMIPS32/microMIPS64 major opcodes
14202 * 1. MIPS Architecture for Programmers Volume II-B:
14203 * The microMIPS32 Instruction Set (Revision 3.05)
14205 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14207 * 2. MIPS Architecture For Programmers Volume II-A:
14208 * The MIPS64 Instruction Set (Revision 3.51)
14238 POOL32S = 0x16, /* MIPS64 */
14239 DADDIU32 = 0x17, /* MIPS64 */
14268 /* 0x29 is reserved */
14281 /* 0x31 is reserved */
14294 SD32 = 0x36, /* MIPS64 */
14295 LD32 = 0x37, /* MIPS64 */
14297 /* 0x39 is reserved */
14313 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14335 /* POOL32A encoding of minor opcode field */
14338 /* These opcodes are distinguished only by bits 9..6; those bits are
14339 * what are recorded below. */
14376 /* The following can be distinguished by their lower 6 bits. */
14386 /* POOL32AXF encoding of minor opcode field extension */
14389 * 1. MIPS Architecture for Programmers Volume II-B:
14390 * The microMIPS32 Instruction Set (Revision 3.05)
14392 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14394 * 2. MIPS Architecture for Programmers VolumeIV-e:
14395 * The MIPS DSP Application-Specific Extension
14396 * to the microMIPS32 Architecture (Revision 2.34)
14398 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14413 /* begin of microMIPS32 DSP */
14415 /* bits 13..12 for 0x01 */
14421 /* bits 13..12 for 0x2a */
14427 /* bits 13..12 for 0x32 */
14431 /* end of microMIPS32 DSP */
14433 /* bits 15..12 for 0x2c */
14450 /* bits 15..12 for 0x34 */
14458 /* bits 15..12 for 0x3c */
14460 JR = 0x0, /* alias */
14468 /* bits 15..12 for 0x05 */
14472 /* bits 15..12 for 0x0d */
14484 /* bits 15..12 for 0x15 */
14490 /* bits 15..12 for 0x1d */
14494 /* bits 15..12 for 0x2d */
14499 /* bits 15..12 for 0x35 */
14506 /* POOL32B encoding of minor opcode field (bits 15..12) */
14522 /* POOL32C encoding of minor opcode field (bits 15..12) */
14543 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14556 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14569 /* POOL32F encoding of minor opcode field (bits 5..0) */
14572 /* These are the bit 7..6 values */
14581 /* These are the bit 8..6 values */
14606 MOVZ_FMT_05 = 0x05,
14640 CABS_COND_FMT = 0x1c, /* MIPS3D */
14647 /* POOL32Fxf encoding of minor opcode extension field */
14685 /* POOL32I encoding of minor opcode field (bits 25..21) */
14715 /* These overlap and are distinguished by bit16 of the instruction */
14724 /* POOL16A encoding of minor opcode field */
14731 /* POOL16B encoding of minor opcode field */
14738 /* POOL16C encoding of minor opcode field */
14758 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14782 /* POOL16D encoding of minor opcode field */
14789 /* POOL16E encoding of minor opcode field */
14796 static int mmreg (int r)
14798 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14803 /* Used for 16-bit store instructions. */
14804 static int mmreg2 (int r)
14806 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14811 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14812 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14813 #define uMIPS_RS2(op) uMIPS_RS(op)
14814 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14815 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14816 #define uMIPS_RS5(op) (op & 0x1f)
14818 /* Signed immediate */
14819 #define SIMM(op, start, width) \
14820 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14823 /* Zero-extended immediate */
14824 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14826 static void gen_addiur1sp(DisasContext *ctx)
14828 int rd = mmreg(uMIPS_RD(ctx->opcode));
14830 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14833 static void gen_addiur2(DisasContext *ctx)
14835 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14836 int rd = mmreg(uMIPS_RD(ctx->opcode));
14837 int rs = mmreg(uMIPS_RS(ctx->opcode));
14839 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14842 static void gen_addiusp(DisasContext *ctx)
14844 int encoded = ZIMM(ctx->opcode, 1, 9);
14847 if (encoded <= 1) {
14848 decoded = 256 + encoded;
14849 } else if (encoded <= 255) {
14851 } else if (encoded <= 509) {
14852 decoded = encoded - 512;
14854 decoded = encoded - 768;
14857 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14860 static void gen_addius5(DisasContext *ctx)
14862 int imm = SIMM(ctx->opcode, 1, 4);
14863 int rd = (ctx->opcode >> 5) & 0x1f;
14865 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14868 static void gen_andi16(DisasContext *ctx)
14870 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14871 31, 32, 63, 64, 255, 32768, 65535 };
14872 int rd = mmreg(uMIPS_RD(ctx->opcode));
14873 int rs = mmreg(uMIPS_RS(ctx->opcode));
14874 int encoded = ZIMM(ctx->opcode, 0, 4);
14876 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14879 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14880 int base, int16_t offset)
14885 if (ctx->hflags & MIPS_HFLAG_BMASK) {
14886 generate_exception_end(ctx, EXCP_RI);
14890 t0 = tcg_temp_new();
14892 gen_base_offset_addr(ctx, t0, base, offset);
14894 t1 = tcg_const_tl(reglist);
14895 t2 = tcg_const_i32(ctx->mem_idx);
14897 save_cpu_state(ctx, 1);
14900 gen_helper_lwm(cpu_env, t0, t1, t2);
14903 gen_helper_swm(cpu_env, t0, t1, t2);
14905 #ifdef TARGET_MIPS64
14907 gen_helper_ldm(cpu_env, t0, t1, t2);
14910 gen_helper_sdm(cpu_env, t0, t1, t2);
14916 tcg_temp_free_i32(t2);
14920 static void gen_pool16c_insn(DisasContext *ctx)
14922 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14923 int rs = mmreg(ctx->opcode & 0x7);
14925 switch (((ctx->opcode) >> 4) & 0x3f) {
14930 gen_logic(ctx, OPC_NOR, rd, rs, 0);
14936 gen_logic(ctx, OPC_XOR, rd, rd, rs);
14942 gen_logic(ctx, OPC_AND, rd, rd, rs);
14948 gen_logic(ctx, OPC_OR, rd, rd, rs);
14955 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14956 int offset = ZIMM(ctx->opcode, 0, 4);
14958 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14967 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14968 int offset = ZIMM(ctx->opcode, 0, 4);
14970 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14977 int reg = ctx->opcode & 0x1f;
14979 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14985 int reg = ctx->opcode & 0x1f;
14986 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14987 /* Let normal delay slot handling in our caller take us
14988 to the branch target. */
14993 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14994 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14998 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14999 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15003 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15007 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15010 generate_exception_end(ctx, EXCP_BREAK);
15013 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15014 gen_helper_do_semihosting(cpu_env);
15016 /* XXX: not clear which exception should be raised
15017 * when in debug mode...
15019 check_insn(ctx, ISA_MIPS32);
15020 generate_exception_end(ctx, EXCP_DBp);
15023 case JRADDIUSP + 0:
15024 case JRADDIUSP + 1:
15026 int imm = ZIMM(ctx->opcode, 0, 5);
15027 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15028 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15029 /* Let normal delay slot handling in our caller take us
15030 to the branch target. */
15034 generate_exception_end(ctx, EXCP_RI);
15039 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15042 int rd, rs, re, rt;
15043 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15044 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15045 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15046 rd = rd_enc[enc_dest];
15047 re = re_enc[enc_dest];
15048 rs = rs_rt_enc[enc_rs];
15049 rt = rs_rt_enc[enc_rt];
15051 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15053 tcg_gen_movi_tl(cpu_gpr[rd], 0);
15056 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15058 tcg_gen_movi_tl(cpu_gpr[re], 0);
15062 static void gen_pool16c_r6_insn(DisasContext *ctx)
15064 int rt = mmreg((ctx->opcode >> 7) & 0x7);
15065 int rs = mmreg((ctx->opcode >> 4) & 0x7);
15067 switch (ctx->opcode & 0xf) {
15069 gen_logic(ctx, OPC_NOR, rt, rs, 0);
15072 gen_logic(ctx, OPC_AND, rt, rt, rs);
15076 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15077 int offset = extract32(ctx->opcode, 4, 4);
15078 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15081 case R6_JRC16: /* JRCADDIUSP */
15082 if ((ctx->opcode >> 4) & 1) {
15084 int imm = extract32(ctx->opcode, 5, 5);
15085 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15086 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15089 rs = extract32(ctx->opcode, 5, 5);
15090 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15102 int enc_dest = uMIPS_RD(ctx->opcode);
15103 int enc_rt = uMIPS_RS2(ctx->opcode);
15104 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15105 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15109 gen_logic(ctx, OPC_XOR, rt, rt, rs);
15112 gen_logic(ctx, OPC_OR, rt, rt, rs);
15116 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15117 int offset = extract32(ctx->opcode, 4, 4);
15118 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15121 case JALRC16: /* BREAK16, SDBBP16 */
15122 switch (ctx->opcode & 0x3f) {
15124 case JALRC16 + 0x20:
15126 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15131 generate_exception(ctx, EXCP_BREAK);
15135 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15136 gen_helper_do_semihosting(cpu_env);
15138 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15139 generate_exception(ctx, EXCP_RI);
15141 generate_exception(ctx, EXCP_DBp);
15148 generate_exception(ctx, EXCP_RI);
15153 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15155 TCGv t0 = tcg_temp_new();
15156 TCGv t1 = tcg_temp_new();
15158 gen_load_gpr(t0, base);
15161 gen_load_gpr(t1, index);
15162 tcg_gen_shli_tl(t1, t1, 2);
15163 gen_op_addr_add(ctx, t0, t1, t0);
15166 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15167 gen_store_gpr(t1, rd);
15173 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15174 int base, int16_t offset)
15178 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15179 generate_exception_end(ctx, EXCP_RI);
15183 t0 = tcg_temp_new();
15184 t1 = tcg_temp_new();
15186 gen_base_offset_addr(ctx, t0, base, offset);
15191 generate_exception_end(ctx, EXCP_RI);
15194 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15195 gen_store_gpr(t1, rd);
15196 tcg_gen_movi_tl(t1, 4);
15197 gen_op_addr_add(ctx, t0, t0, t1);
15198 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15199 gen_store_gpr(t1, rd+1);
15202 gen_load_gpr(t1, rd);
15203 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15204 tcg_gen_movi_tl(t1, 4);
15205 gen_op_addr_add(ctx, t0, t0, t1);
15206 gen_load_gpr(t1, rd+1);
15207 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15209 #ifdef TARGET_MIPS64
15212 generate_exception_end(ctx, EXCP_RI);
15215 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15216 gen_store_gpr(t1, rd);
15217 tcg_gen_movi_tl(t1, 8);
15218 gen_op_addr_add(ctx, t0, t0, t1);
15219 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15220 gen_store_gpr(t1, rd+1);
15223 gen_load_gpr(t1, rd);
15224 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15225 tcg_gen_movi_tl(t1, 8);
15226 gen_op_addr_add(ctx, t0, t0, t1);
15227 gen_load_gpr(t1, rd+1);
15228 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15236 static void gen_sync(int stype)
15238 TCGBar tcg_mo = TCG_BAR_SC;
15241 case 0x4: /* SYNC_WMB */
15242 tcg_mo |= TCG_MO_ST_ST;
15244 case 0x10: /* SYNC_MB */
15245 tcg_mo |= TCG_MO_ALL;
15247 case 0x11: /* SYNC_ACQUIRE */
15248 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15250 case 0x12: /* SYNC_RELEASE */
15251 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15253 case 0x13: /* SYNC_RMB */
15254 tcg_mo |= TCG_MO_LD_LD;
15257 tcg_mo |= TCG_MO_ALL;
15261 tcg_gen_mb(tcg_mo);
15264 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15266 int extension = (ctx->opcode >> 6) & 0x3f;
15267 int minor = (ctx->opcode >> 12) & 0xf;
15268 uint32_t mips32_op;
15270 switch (extension) {
15272 mips32_op = OPC_TEQ;
15275 mips32_op = OPC_TGE;
15278 mips32_op = OPC_TGEU;
15281 mips32_op = OPC_TLT;
15284 mips32_op = OPC_TLTU;
15287 mips32_op = OPC_TNE;
15289 gen_trap(ctx, mips32_op, rs, rt, -1);
15291 #ifndef CONFIG_USER_ONLY
15294 check_cp0_enabled(ctx);
15296 /* Treat as NOP. */
15299 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15303 check_cp0_enabled(ctx);
15305 TCGv t0 = tcg_temp_new();
15307 gen_load_gpr(t0, rt);
15308 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15314 switch (minor & 3) {
15316 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15319 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15322 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15325 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15328 goto pool32axf_invalid;
15332 switch (minor & 3) {
15334 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15337 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15340 goto pool32axf_invalid;
15346 check_insn(ctx, ISA_MIPS32R6);
15347 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15350 gen_bshfl(ctx, OPC_SEB, rs, rt);
15353 gen_bshfl(ctx, OPC_SEH, rs, rt);
15356 mips32_op = OPC_CLO;
15359 mips32_op = OPC_CLZ;
15361 check_insn(ctx, ISA_MIPS32);
15362 gen_cl(ctx, mips32_op, rt, rs);
15365 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15366 gen_rdhwr(ctx, rt, rs, 0);
15369 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15372 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15373 mips32_op = OPC_MULT;
15376 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15377 mips32_op = OPC_MULTU;
15380 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15381 mips32_op = OPC_DIV;
15384 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15385 mips32_op = OPC_DIVU;
15388 check_insn(ctx, ISA_MIPS32);
15389 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15392 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15393 mips32_op = OPC_MADD;
15396 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15397 mips32_op = OPC_MADDU;
15400 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15401 mips32_op = OPC_MSUB;
15404 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15405 mips32_op = OPC_MSUBU;
15407 check_insn(ctx, ISA_MIPS32);
15408 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15411 goto pool32axf_invalid;
15422 generate_exception_err(ctx, EXCP_CpU, 2);
15425 goto pool32axf_invalid;
15430 case JALR: /* JALRC */
15431 case JALR_HB: /* JALRC_HB */
15432 if (ctx->insn_flags & ISA_MIPS32R6) {
15433 /* JALRC, JALRC_HB */
15434 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15436 /* JALR, JALR_HB */
15437 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15438 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15443 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15444 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15445 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15448 goto pool32axf_invalid;
15454 check_cp0_enabled(ctx);
15455 check_insn(ctx, ISA_MIPS32R2);
15456 gen_load_srsgpr(rs, rt);
15459 check_cp0_enabled(ctx);
15460 check_insn(ctx, ISA_MIPS32R2);
15461 gen_store_srsgpr(rs, rt);
15464 goto pool32axf_invalid;
15467 #ifndef CONFIG_USER_ONLY
15471 mips32_op = OPC_TLBP;
15474 mips32_op = OPC_TLBR;
15477 mips32_op = OPC_TLBWI;
15480 mips32_op = OPC_TLBWR;
15483 mips32_op = OPC_TLBINV;
15486 mips32_op = OPC_TLBINVF;
15489 mips32_op = OPC_WAIT;
15492 mips32_op = OPC_DERET;
15495 mips32_op = OPC_ERET;
15497 gen_cp0(env, ctx, mips32_op, rt, rs);
15500 goto pool32axf_invalid;
15506 check_cp0_enabled(ctx);
15508 TCGv t0 = tcg_temp_new();
15510 save_cpu_state(ctx, 1);
15511 gen_helper_di(t0, cpu_env);
15512 gen_store_gpr(t0, rs);
15513 /* Stop translation as we may have switched the execution mode */
15514 ctx->base.is_jmp = DISAS_STOP;
15519 check_cp0_enabled(ctx);
15521 TCGv t0 = tcg_temp_new();
15523 save_cpu_state(ctx, 1);
15524 gen_helper_ei(t0, cpu_env);
15525 gen_store_gpr(t0, rs);
15526 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15527 of translated code to check for pending interrupts. */
15528 gen_save_pc(ctx->base.pc_next + 4);
15529 ctx->base.is_jmp = DISAS_EXIT;
15534 goto pool32axf_invalid;
15541 gen_sync(extract32(ctx->opcode, 16, 5));
15544 generate_exception_end(ctx, EXCP_SYSCALL);
15547 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15548 gen_helper_do_semihosting(cpu_env);
15550 check_insn(ctx, ISA_MIPS32);
15551 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15552 generate_exception_end(ctx, EXCP_RI);
15554 generate_exception_end(ctx, EXCP_DBp);
15559 goto pool32axf_invalid;
15563 switch (minor & 3) {
15565 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15568 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15571 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15574 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15577 goto pool32axf_invalid;
15581 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15584 gen_HILO(ctx, OPC_MFHI, 0, rs);
15587 gen_HILO(ctx, OPC_MFLO, 0, rs);
15590 gen_HILO(ctx, OPC_MTHI, 0, rs);
15593 gen_HILO(ctx, OPC_MTLO, 0, rs);
15596 goto pool32axf_invalid;
15601 MIPS_INVAL("pool32axf");
15602 generate_exception_end(ctx, EXCP_RI);
15607 /* Values for microMIPS fmt field. Variable-width, depending on which
15608 formats the instruction supports. */
15627 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15629 int extension = (ctx->opcode >> 6) & 0x3ff;
15630 uint32_t mips32_op;
15632 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15633 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15634 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15636 switch (extension) {
15637 case FLOAT_1BIT_FMT(CFC1, 0):
15638 mips32_op = OPC_CFC1;
15640 case FLOAT_1BIT_FMT(CTC1, 0):
15641 mips32_op = OPC_CTC1;
15643 case FLOAT_1BIT_FMT(MFC1, 0):
15644 mips32_op = OPC_MFC1;
15646 case FLOAT_1BIT_FMT(MTC1, 0):
15647 mips32_op = OPC_MTC1;
15649 case FLOAT_1BIT_FMT(MFHC1, 0):
15650 mips32_op = OPC_MFHC1;
15652 case FLOAT_1BIT_FMT(MTHC1, 0):
15653 mips32_op = OPC_MTHC1;
15655 gen_cp1(ctx, mips32_op, rt, rs);
15658 /* Reciprocal square root */
15659 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15660 mips32_op = OPC_RSQRT_S;
15662 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15663 mips32_op = OPC_RSQRT_D;
15667 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15668 mips32_op = OPC_SQRT_S;
15670 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15671 mips32_op = OPC_SQRT_D;
15675 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15676 mips32_op = OPC_RECIP_S;
15678 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15679 mips32_op = OPC_RECIP_D;
15683 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15684 mips32_op = OPC_FLOOR_L_S;
15686 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15687 mips32_op = OPC_FLOOR_L_D;
15689 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15690 mips32_op = OPC_FLOOR_W_S;
15692 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15693 mips32_op = OPC_FLOOR_W_D;
15697 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15698 mips32_op = OPC_CEIL_L_S;
15700 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15701 mips32_op = OPC_CEIL_L_D;
15703 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15704 mips32_op = OPC_CEIL_W_S;
15706 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15707 mips32_op = OPC_CEIL_W_D;
15711 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15712 mips32_op = OPC_TRUNC_L_S;
15714 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15715 mips32_op = OPC_TRUNC_L_D;
15717 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15718 mips32_op = OPC_TRUNC_W_S;
15720 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15721 mips32_op = OPC_TRUNC_W_D;
15725 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15726 mips32_op = OPC_ROUND_L_S;
15728 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15729 mips32_op = OPC_ROUND_L_D;
15731 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15732 mips32_op = OPC_ROUND_W_S;
15734 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15735 mips32_op = OPC_ROUND_W_D;
15738 /* Integer to floating-point conversion */
15739 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15740 mips32_op = OPC_CVT_L_S;
15742 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15743 mips32_op = OPC_CVT_L_D;
15745 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15746 mips32_op = OPC_CVT_W_S;
15748 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15749 mips32_op = OPC_CVT_W_D;
15752 /* Paired-foo conversions */
15753 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15754 mips32_op = OPC_CVT_S_PL;
15756 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15757 mips32_op = OPC_CVT_S_PU;
15759 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15760 mips32_op = OPC_CVT_PW_PS;
15762 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15763 mips32_op = OPC_CVT_PS_PW;
15766 /* Floating-point moves */
15767 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15768 mips32_op = OPC_MOV_S;
15770 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15771 mips32_op = OPC_MOV_D;
15773 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15774 mips32_op = OPC_MOV_PS;
15777 /* Absolute value */
15778 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15779 mips32_op = OPC_ABS_S;
15781 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15782 mips32_op = OPC_ABS_D;
15784 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15785 mips32_op = OPC_ABS_PS;
15789 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15790 mips32_op = OPC_NEG_S;
15792 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15793 mips32_op = OPC_NEG_D;
15795 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15796 mips32_op = OPC_NEG_PS;
15799 /* Reciprocal square root step */
15800 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15801 mips32_op = OPC_RSQRT1_S;
15803 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15804 mips32_op = OPC_RSQRT1_D;
15806 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15807 mips32_op = OPC_RSQRT1_PS;
15810 /* Reciprocal step */
15811 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15812 mips32_op = OPC_RECIP1_S;
15814 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15815 mips32_op = OPC_RECIP1_S;
15817 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15818 mips32_op = OPC_RECIP1_PS;
15821 /* Conversions from double */
15822 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15823 mips32_op = OPC_CVT_D_S;
15825 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15826 mips32_op = OPC_CVT_D_W;
15828 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15829 mips32_op = OPC_CVT_D_L;
15832 /* Conversions from single */
15833 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15834 mips32_op = OPC_CVT_S_D;
15836 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15837 mips32_op = OPC_CVT_S_W;
15839 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15840 mips32_op = OPC_CVT_S_L;
15842 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15845 /* Conditional moves on floating-point codes */
15846 case COND_FLOAT_MOV(MOVT, 0):
15847 case COND_FLOAT_MOV(MOVT, 1):
15848 case COND_FLOAT_MOV(MOVT, 2):
15849 case COND_FLOAT_MOV(MOVT, 3):
15850 case COND_FLOAT_MOV(MOVT, 4):
15851 case COND_FLOAT_MOV(MOVT, 5):
15852 case COND_FLOAT_MOV(MOVT, 6):
15853 case COND_FLOAT_MOV(MOVT, 7):
15854 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15855 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15857 case COND_FLOAT_MOV(MOVF, 0):
15858 case COND_FLOAT_MOV(MOVF, 1):
15859 case COND_FLOAT_MOV(MOVF, 2):
15860 case COND_FLOAT_MOV(MOVF, 3):
15861 case COND_FLOAT_MOV(MOVF, 4):
15862 case COND_FLOAT_MOV(MOVF, 5):
15863 case COND_FLOAT_MOV(MOVF, 6):
15864 case COND_FLOAT_MOV(MOVF, 7):
15865 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15866 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15869 MIPS_INVAL("pool32fxf");
15870 generate_exception_end(ctx, EXCP_RI);
15875 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15879 int rt, rs, rd, rr;
15881 uint32_t op, minor, minor2, mips32_op;
15882 uint32_t cond, fmt, cc;
15884 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15885 ctx->opcode = (ctx->opcode << 16) | insn;
15887 rt = (ctx->opcode >> 21) & 0x1f;
15888 rs = (ctx->opcode >> 16) & 0x1f;
15889 rd = (ctx->opcode >> 11) & 0x1f;
15890 rr = (ctx->opcode >> 6) & 0x1f;
15891 imm = (int16_t) ctx->opcode;
15893 op = (ctx->opcode >> 26) & 0x3f;
15896 minor = ctx->opcode & 0x3f;
15899 minor = (ctx->opcode >> 6) & 0xf;
15902 mips32_op = OPC_SLL;
15905 mips32_op = OPC_SRA;
15908 mips32_op = OPC_SRL;
15911 mips32_op = OPC_ROTR;
15913 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15916 check_insn(ctx, ISA_MIPS32R6);
15917 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15920 check_insn(ctx, ISA_MIPS32R6);
15921 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15924 check_insn(ctx, ISA_MIPS32R6);
15925 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15928 goto pool32a_invalid;
15932 minor = (ctx->opcode >> 6) & 0xf;
15936 mips32_op = OPC_ADD;
15939 mips32_op = OPC_ADDU;
15942 mips32_op = OPC_SUB;
15945 mips32_op = OPC_SUBU;
15948 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15949 mips32_op = OPC_MUL;
15951 gen_arith(ctx, mips32_op, rd, rs, rt);
15955 mips32_op = OPC_SLLV;
15958 mips32_op = OPC_SRLV;
15961 mips32_op = OPC_SRAV;
15964 mips32_op = OPC_ROTRV;
15966 gen_shift(ctx, mips32_op, rd, rs, rt);
15968 /* Logical operations */
15970 mips32_op = OPC_AND;
15973 mips32_op = OPC_OR;
15976 mips32_op = OPC_NOR;
15979 mips32_op = OPC_XOR;
15981 gen_logic(ctx, mips32_op, rd, rs, rt);
15983 /* Set less than */
15985 mips32_op = OPC_SLT;
15988 mips32_op = OPC_SLTU;
15990 gen_slt(ctx, mips32_op, rd, rs, rt);
15993 goto pool32a_invalid;
15997 minor = (ctx->opcode >> 6) & 0xf;
15999 /* Conditional moves */
16000 case MOVN: /* MUL */
16001 if (ctx->insn_flags & ISA_MIPS32R6) {
16003 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16006 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16009 case MOVZ: /* MUH */
16010 if (ctx->insn_flags & ISA_MIPS32R6) {
16012 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16015 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16019 check_insn(ctx, ISA_MIPS32R6);
16020 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16023 check_insn(ctx, ISA_MIPS32R6);
16024 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16026 case LWXS: /* DIV */
16027 if (ctx->insn_flags & ISA_MIPS32R6) {
16029 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16032 gen_ldxs(ctx, rs, rt, rd);
16036 check_insn(ctx, ISA_MIPS32R6);
16037 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16040 check_insn(ctx, ISA_MIPS32R6);
16041 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16044 check_insn(ctx, ISA_MIPS32R6);
16045 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16048 goto pool32a_invalid;
16052 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16055 check_insn(ctx, ISA_MIPS32R6);
16056 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16057 extract32(ctx->opcode, 9, 2));
16060 check_insn(ctx, ISA_MIPS32R6);
16061 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16064 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16067 gen_pool32axf(env, ctx, rt, rs);
16070 generate_exception_end(ctx, EXCP_BREAK);
16073 check_insn(ctx, ISA_MIPS32R6);
16074 generate_exception_end(ctx, EXCP_RI);
16078 MIPS_INVAL("pool32a");
16079 generate_exception_end(ctx, EXCP_RI);
16084 minor = (ctx->opcode >> 12) & 0xf;
16087 check_cp0_enabled(ctx);
16088 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16089 gen_cache_operation(ctx, rt, rs, imm);
16094 /* COP2: Not implemented. */
16095 generate_exception_err(ctx, EXCP_CpU, 2);
16097 #ifdef TARGET_MIPS64
16100 check_insn(ctx, ISA_MIPS3);
16101 check_mips_64(ctx);
16106 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16108 #ifdef TARGET_MIPS64
16111 check_insn(ctx, ISA_MIPS3);
16112 check_mips_64(ctx);
16117 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16120 MIPS_INVAL("pool32b");
16121 generate_exception_end(ctx, EXCP_RI);
16126 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16127 minor = ctx->opcode & 0x3f;
16128 check_cp1_enabled(ctx);
16131 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16132 mips32_op = OPC_ALNV_PS;
16135 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16136 mips32_op = OPC_MADD_S;
16139 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16140 mips32_op = OPC_MADD_D;
16143 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16144 mips32_op = OPC_MADD_PS;
16147 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16148 mips32_op = OPC_MSUB_S;
16151 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16152 mips32_op = OPC_MSUB_D;
16155 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16156 mips32_op = OPC_MSUB_PS;
16159 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16160 mips32_op = OPC_NMADD_S;
16163 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16164 mips32_op = OPC_NMADD_D;
16167 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16168 mips32_op = OPC_NMADD_PS;
16171 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16172 mips32_op = OPC_NMSUB_S;
16175 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16176 mips32_op = OPC_NMSUB_D;
16179 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16180 mips32_op = OPC_NMSUB_PS;
16182 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16184 case CABS_COND_FMT:
16185 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16186 cond = (ctx->opcode >> 6) & 0xf;
16187 cc = (ctx->opcode >> 13) & 0x7;
16188 fmt = (ctx->opcode >> 10) & 0x3;
16191 gen_cmpabs_s(ctx, cond, rt, rs, cc);
16194 gen_cmpabs_d(ctx, cond, rt, rs, cc);
16197 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16200 goto pool32f_invalid;
16204 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16205 cond = (ctx->opcode >> 6) & 0xf;
16206 cc = (ctx->opcode >> 13) & 0x7;
16207 fmt = (ctx->opcode >> 10) & 0x3;
16210 gen_cmp_s(ctx, cond, rt, rs, cc);
16213 gen_cmp_d(ctx, cond, rt, rs, cc);
16216 gen_cmp_ps(ctx, cond, rt, rs, cc);
16219 goto pool32f_invalid;
16223 check_insn(ctx, ISA_MIPS32R6);
16224 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16227 check_insn(ctx, ISA_MIPS32R6);
16228 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16231 gen_pool32fxf(ctx, rt, rs);
16235 switch ((ctx->opcode >> 6) & 0x7) {
16237 mips32_op = OPC_PLL_PS;
16240 mips32_op = OPC_PLU_PS;
16243 mips32_op = OPC_PUL_PS;
16246 mips32_op = OPC_PUU_PS;
16249 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16250 mips32_op = OPC_CVT_PS_S;
16252 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16255 goto pool32f_invalid;
16259 check_insn(ctx, ISA_MIPS32R6);
16260 switch ((ctx->opcode >> 9) & 0x3) {
16262 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16265 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16268 goto pool32f_invalid;
16273 switch ((ctx->opcode >> 6) & 0x7) {
16275 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16276 mips32_op = OPC_LWXC1;
16279 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16280 mips32_op = OPC_SWXC1;
16283 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16284 mips32_op = OPC_LDXC1;
16287 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16288 mips32_op = OPC_SDXC1;
16291 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16292 mips32_op = OPC_LUXC1;
16295 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16296 mips32_op = OPC_SUXC1;
16298 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16301 goto pool32f_invalid;
16305 check_insn(ctx, ISA_MIPS32R6);
16306 switch ((ctx->opcode >> 9) & 0x3) {
16308 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16311 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16314 goto pool32f_invalid;
16319 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16320 fmt = (ctx->opcode >> 9) & 0x3;
16321 switch ((ctx->opcode >> 6) & 0x7) {
16325 mips32_op = OPC_RSQRT2_S;
16328 mips32_op = OPC_RSQRT2_D;
16331 mips32_op = OPC_RSQRT2_PS;
16334 goto pool32f_invalid;
16340 mips32_op = OPC_RECIP2_S;
16343 mips32_op = OPC_RECIP2_D;
16346 mips32_op = OPC_RECIP2_PS;
16349 goto pool32f_invalid;
16353 mips32_op = OPC_ADDR_PS;
16356 mips32_op = OPC_MULR_PS;
16358 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16361 goto pool32f_invalid;
16365 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16366 cc = (ctx->opcode >> 13) & 0x7;
16367 fmt = (ctx->opcode >> 9) & 0x3;
16368 switch ((ctx->opcode >> 6) & 0x7) {
16369 case MOVF_FMT: /* RINT_FMT */
16370 if (ctx->insn_flags & ISA_MIPS32R6) {
16374 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16377 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16380 goto pool32f_invalid;
16386 gen_movcf_s(ctx, rs, rt, cc, 0);
16389 gen_movcf_d(ctx, rs, rt, cc, 0);
16393 gen_movcf_ps(ctx, rs, rt, cc, 0);
16396 goto pool32f_invalid;
16400 case MOVT_FMT: /* CLASS_FMT */
16401 if (ctx->insn_flags & ISA_MIPS32R6) {
16405 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16408 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16411 goto pool32f_invalid;
16417 gen_movcf_s(ctx, rs, rt, cc, 1);
16420 gen_movcf_d(ctx, rs, rt, cc, 1);
16424 gen_movcf_ps(ctx, rs, rt, cc, 1);
16427 goto pool32f_invalid;
16432 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16435 goto pool32f_invalid;
16438 #define FINSN_3ARG_SDPS(prfx) \
16439 switch ((ctx->opcode >> 8) & 0x3) { \
16441 mips32_op = OPC_##prfx##_S; \
16444 mips32_op = OPC_##prfx##_D; \
16446 case FMT_SDPS_PS: \
16448 mips32_op = OPC_##prfx##_PS; \
16451 goto pool32f_invalid; \
16454 check_insn(ctx, ISA_MIPS32R6);
16455 switch ((ctx->opcode >> 9) & 0x3) {
16457 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16460 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16463 goto pool32f_invalid;
16467 check_insn(ctx, ISA_MIPS32R6);
16468 switch ((ctx->opcode >> 9) & 0x3) {
16470 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16473 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16476 goto pool32f_invalid;
16480 /* regular FP ops */
16481 switch ((ctx->opcode >> 6) & 0x3) {
16483 FINSN_3ARG_SDPS(ADD);
16486 FINSN_3ARG_SDPS(SUB);
16489 FINSN_3ARG_SDPS(MUL);
16492 fmt = (ctx->opcode >> 8) & 0x3;
16494 mips32_op = OPC_DIV_D;
16495 } else if (fmt == 0) {
16496 mips32_op = OPC_DIV_S;
16498 goto pool32f_invalid;
16502 goto pool32f_invalid;
16507 switch ((ctx->opcode >> 6) & 0x7) {
16508 case MOVN_FMT: /* SELEQZ_FMT */
16509 if (ctx->insn_flags & ISA_MIPS32R6) {
16511 switch ((ctx->opcode >> 9) & 0x3) {
16513 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16516 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16519 goto pool32f_invalid;
16523 FINSN_3ARG_SDPS(MOVN);
16527 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16528 FINSN_3ARG_SDPS(MOVN);
16530 case MOVZ_FMT: /* SELNEZ_FMT */
16531 if (ctx->insn_flags & ISA_MIPS32R6) {
16533 switch ((ctx->opcode >> 9) & 0x3) {
16535 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16538 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16541 goto pool32f_invalid;
16545 FINSN_3ARG_SDPS(MOVZ);
16549 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16550 FINSN_3ARG_SDPS(MOVZ);
16553 check_insn(ctx, ISA_MIPS32R6);
16554 switch ((ctx->opcode >> 9) & 0x3) {
16556 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16559 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16562 goto pool32f_invalid;
16566 check_insn(ctx, ISA_MIPS32R6);
16567 switch ((ctx->opcode >> 9) & 0x3) {
16569 mips32_op = OPC_MADDF_S;
16572 mips32_op = OPC_MADDF_D;
16575 goto pool32f_invalid;
16579 check_insn(ctx, ISA_MIPS32R6);
16580 switch ((ctx->opcode >> 9) & 0x3) {
16582 mips32_op = OPC_MSUBF_S;
16585 mips32_op = OPC_MSUBF_D;
16588 goto pool32f_invalid;
16592 goto pool32f_invalid;
16596 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16600 MIPS_INVAL("pool32f");
16601 generate_exception_end(ctx, EXCP_RI);
16605 generate_exception_err(ctx, EXCP_CpU, 1);
16609 minor = (ctx->opcode >> 21) & 0x1f;
16612 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16613 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16616 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16617 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16618 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16621 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16622 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16623 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16626 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16627 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16630 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16631 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16632 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16635 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16636 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16637 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16640 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16641 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16644 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16645 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16649 case TLTI: /* BC1EQZC */
16650 if (ctx->insn_flags & ISA_MIPS32R6) {
16652 check_cp1_enabled(ctx);
16653 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16656 mips32_op = OPC_TLTI;
16660 case TGEI: /* BC1NEZC */
16661 if (ctx->insn_flags & ISA_MIPS32R6) {
16663 check_cp1_enabled(ctx);
16664 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16667 mips32_op = OPC_TGEI;
16672 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16673 mips32_op = OPC_TLTIU;
16676 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16677 mips32_op = OPC_TGEIU;
16679 case TNEI: /* SYNCI */
16680 if (ctx->insn_flags & ISA_MIPS32R6) {
16682 /* Break the TB to be able to sync copied instructions
16684 ctx->base.is_jmp = DISAS_STOP;
16687 mips32_op = OPC_TNEI;
16692 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16693 mips32_op = OPC_TEQI;
16695 gen_trap(ctx, mips32_op, rs, -1, imm);
16700 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16701 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16702 4, rs, 0, imm << 1, 0);
16703 /* Compact branches don't have a delay slot, so just let
16704 the normal delay slot handling take us to the branch
16708 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16709 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16712 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16713 /* Break the TB to be able to sync copied instructions
16715 ctx->base.is_jmp = DISAS_STOP;
16719 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16720 /* COP2: Not implemented. */
16721 generate_exception_err(ctx, EXCP_CpU, 2);
16724 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16725 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16728 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16729 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16732 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16733 mips32_op = OPC_BC1FANY4;
16736 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16737 mips32_op = OPC_BC1TANY4;
16740 check_insn(ctx, ASE_MIPS3D);
16743 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16744 check_cp1_enabled(ctx);
16745 gen_compute_branch1(ctx, mips32_op,
16746 (ctx->opcode >> 18) & 0x7, imm << 1);
16748 generate_exception_err(ctx, EXCP_CpU, 1);
16753 /* MIPS DSP: not implemented */
16756 MIPS_INVAL("pool32i");
16757 generate_exception_end(ctx, EXCP_RI);
16762 minor = (ctx->opcode >> 12) & 0xf;
16763 offset = sextract32(ctx->opcode, 0,
16764 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16767 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16768 mips32_op = OPC_LWL;
16771 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16772 mips32_op = OPC_SWL;
16775 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16776 mips32_op = OPC_LWR;
16779 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16780 mips32_op = OPC_SWR;
16782 #if defined(TARGET_MIPS64)
16784 check_insn(ctx, ISA_MIPS3);
16785 check_mips_64(ctx);
16786 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16787 mips32_op = OPC_LDL;
16790 check_insn(ctx, ISA_MIPS3);
16791 check_mips_64(ctx);
16792 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16793 mips32_op = OPC_SDL;
16796 check_insn(ctx, ISA_MIPS3);
16797 check_mips_64(ctx);
16798 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16799 mips32_op = OPC_LDR;
16802 check_insn(ctx, ISA_MIPS3);
16803 check_mips_64(ctx);
16804 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16805 mips32_op = OPC_SDR;
16808 check_insn(ctx, ISA_MIPS3);
16809 check_mips_64(ctx);
16810 mips32_op = OPC_LWU;
16813 check_insn(ctx, ISA_MIPS3);
16814 check_mips_64(ctx);
16815 mips32_op = OPC_LLD;
16819 mips32_op = OPC_LL;
16822 gen_ld(ctx, mips32_op, rt, rs, offset);
16825 gen_st(ctx, mips32_op, rt, rs, offset);
16828 gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
16830 #if defined(TARGET_MIPS64)
16832 check_insn(ctx, ISA_MIPS3);
16833 check_mips_64(ctx);
16834 gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
16839 MIPS_INVAL("pool32c ld-eva");
16840 generate_exception_end(ctx, EXCP_RI);
16843 check_cp0_enabled(ctx);
16845 minor2 = (ctx->opcode >> 9) & 0x7;
16846 offset = sextract32(ctx->opcode, 0, 9);
16849 mips32_op = OPC_LBUE;
16852 mips32_op = OPC_LHUE;
16855 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16856 mips32_op = OPC_LWLE;
16859 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16860 mips32_op = OPC_LWRE;
16863 mips32_op = OPC_LBE;
16866 mips32_op = OPC_LHE;
16869 mips32_op = OPC_LLE;
16872 mips32_op = OPC_LWE;
16878 MIPS_INVAL("pool32c st-eva");
16879 generate_exception_end(ctx, EXCP_RI);
16882 check_cp0_enabled(ctx);
16884 minor2 = (ctx->opcode >> 9) & 0x7;
16885 offset = sextract32(ctx->opcode, 0, 9);
16888 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16889 mips32_op = OPC_SWLE;
16892 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16893 mips32_op = OPC_SWRE;
16896 /* Treat as no-op */
16897 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16898 /* hint codes 24-31 are reserved and signal RI */
16899 generate_exception(ctx, EXCP_RI);
16903 /* Treat as no-op */
16904 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16905 gen_cache_operation(ctx, rt, rs, offset);
16909 mips32_op = OPC_SBE;
16912 mips32_op = OPC_SHE;
16915 gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
16918 mips32_op = OPC_SWE;
16923 /* Treat as no-op */
16924 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16925 /* hint codes 24-31 are reserved and signal RI */
16926 generate_exception(ctx, EXCP_RI);
16930 MIPS_INVAL("pool32c");
16931 generate_exception_end(ctx, EXCP_RI);
16935 case ADDI32: /* AUI, LUI */
16936 if (ctx->insn_flags & ISA_MIPS32R6) {
16938 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16941 mips32_op = OPC_ADDI;
16946 mips32_op = OPC_ADDIU;
16948 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16951 /* Logical operations */
16953 mips32_op = OPC_ORI;
16956 mips32_op = OPC_XORI;
16959 mips32_op = OPC_ANDI;
16961 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16964 /* Set less than immediate */
16966 mips32_op = OPC_SLTI;
16969 mips32_op = OPC_SLTIU;
16971 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16974 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16975 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16976 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16977 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16979 case JALS32: /* BOVC, BEQC, BEQZALC */
16980 if (ctx->insn_flags & ISA_MIPS32R6) {
16983 mips32_op = OPC_BOVC;
16984 } else if (rs < rt && rs == 0) {
16986 mips32_op = OPC_BEQZALC;
16989 mips32_op = OPC_BEQC;
16991 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16994 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16995 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16996 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16999 case BEQ32: /* BC */
17000 if (ctx->insn_flags & ISA_MIPS32R6) {
17002 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17003 sextract32(ctx->opcode << 1, 0, 27));
17006 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17009 case BNE32: /* BALC */
17010 if (ctx->insn_flags & ISA_MIPS32R6) {
17012 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17013 sextract32(ctx->opcode << 1, 0, 27));
17016 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17019 case J32: /* BGTZC, BLTZC, BLTC */
17020 if (ctx->insn_flags & ISA_MIPS32R6) {
17021 if (rs == 0 && rt != 0) {
17023 mips32_op = OPC_BGTZC;
17024 } else if (rs != 0 && rt != 0 && rs == rt) {
17026 mips32_op = OPC_BLTZC;
17029 mips32_op = OPC_BLTC;
17031 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17034 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17035 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17038 case JAL32: /* BLEZC, BGEZC, BGEC */
17039 if (ctx->insn_flags & ISA_MIPS32R6) {
17040 if (rs == 0 && rt != 0) {
17042 mips32_op = OPC_BLEZC;
17043 } else if (rs != 0 && rt != 0 && rs == rt) {
17045 mips32_op = OPC_BGEZC;
17048 mips32_op = OPC_BGEC;
17050 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17053 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17054 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17055 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17058 /* Floating point (COP1) */
17060 mips32_op = OPC_LWC1;
17063 mips32_op = OPC_LDC1;
17066 mips32_op = OPC_SWC1;
17069 mips32_op = OPC_SDC1;
17071 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17073 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17074 if (ctx->insn_flags & ISA_MIPS32R6) {
17075 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17076 switch ((ctx->opcode >> 16) & 0x1f) {
17085 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17088 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17091 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17101 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17104 generate_exception(ctx, EXCP_RI);
17109 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17110 offset = SIMM(ctx->opcode, 0, 23) << 2;
17112 gen_addiupc(ctx, reg, offset, 0, 0);
17115 case BNVC: /* BNEC, BNEZALC */
17116 check_insn(ctx, ISA_MIPS32R6);
17119 mips32_op = OPC_BNVC;
17120 } else if (rs < rt && rs == 0) {
17122 mips32_op = OPC_BNEZALC;
17125 mips32_op = OPC_BNEC;
17127 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17129 case R6_BNEZC: /* JIALC */
17130 check_insn(ctx, ISA_MIPS32R6);
17133 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17134 sextract32(ctx->opcode << 1, 0, 22));
17137 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17140 case R6_BEQZC: /* JIC */
17141 check_insn(ctx, ISA_MIPS32R6);
17144 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17145 sextract32(ctx->opcode << 1, 0, 22));
17148 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17151 case BLEZALC: /* BGEZALC, BGEUC */
17152 check_insn(ctx, ISA_MIPS32R6);
17153 if (rs == 0 && rt != 0) {
17155 mips32_op = OPC_BLEZALC;
17156 } else if (rs != 0 && rt != 0 && rs == rt) {
17158 mips32_op = OPC_BGEZALC;
17161 mips32_op = OPC_BGEUC;
17163 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17165 case BGTZALC: /* BLTZALC, BLTUC */
17166 check_insn(ctx, ISA_MIPS32R6);
17167 if (rs == 0 && rt != 0) {
17169 mips32_op = OPC_BGTZALC;
17170 } else if (rs != 0 && rt != 0 && rs == rt) {
17172 mips32_op = OPC_BLTZALC;
17175 mips32_op = OPC_BLTUC;
17177 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17179 /* Loads and stores */
17181 mips32_op = OPC_LB;
17184 mips32_op = OPC_LBU;
17187 mips32_op = OPC_LH;
17190 mips32_op = OPC_LHU;
17193 mips32_op = OPC_LW;
17195 #ifdef TARGET_MIPS64
17197 check_insn(ctx, ISA_MIPS3);
17198 check_mips_64(ctx);
17199 mips32_op = OPC_LD;
17202 check_insn(ctx, ISA_MIPS3);
17203 check_mips_64(ctx);
17204 mips32_op = OPC_SD;
17208 mips32_op = OPC_SB;
17211 mips32_op = OPC_SH;
17214 mips32_op = OPC_SW;
17217 gen_ld(ctx, mips32_op, rt, rs, imm);
17220 gen_st(ctx, mips32_op, rt, rs, imm);
17223 generate_exception_end(ctx, EXCP_RI);
17228 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
17232 /* make sure instructions are on a halfword boundary */
17233 if (ctx->base.pc_next & 0x1) {
17234 env->CP0_BadVAddr = ctx->base.pc_next;
17235 generate_exception_end(ctx, EXCP_AdEL);
17239 op = (ctx->opcode >> 10) & 0x3f;
17240 /* Enforce properly-sized instructions in a delay slot */
17241 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17242 switch (op & 0x7) { /* MSB-3..MSB-5 */
17244 /* POOL32A, POOL32B, POOL32I, POOL32C */
17246 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17248 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17250 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17252 /* LB32, LH32, LWC132, LDC132, LW32 */
17253 if (ctx->hflags & MIPS_HFLAG_BDS16) {
17254 generate_exception_end(ctx, EXCP_RI);
17259 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17261 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17263 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17264 if (ctx->hflags & MIPS_HFLAG_BDS32) {
17265 generate_exception_end(ctx, EXCP_RI);
17275 int rd = mmreg(uMIPS_RD(ctx->opcode));
17276 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17277 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17280 switch (ctx->opcode & 0x1) {
17288 if (ctx->insn_flags & ISA_MIPS32R6) {
17289 /* In the Release 6 the register number location in
17290 * the instruction encoding has changed.
17292 gen_arith(ctx, opc, rs1, rd, rs2);
17294 gen_arith(ctx, opc, rd, rs1, rs2);
17300 int rd = mmreg(uMIPS_RD(ctx->opcode));
17301 int rs = mmreg(uMIPS_RS(ctx->opcode));
17302 int amount = (ctx->opcode >> 1) & 0x7;
17304 amount = amount == 0 ? 8 : amount;
17306 switch (ctx->opcode & 0x1) {
17315 gen_shift_imm(ctx, opc, rd, rs, amount);
17319 if (ctx->insn_flags & ISA_MIPS32R6) {
17320 gen_pool16c_r6_insn(ctx);
17322 gen_pool16c_insn(ctx);
17327 int rd = mmreg(uMIPS_RD(ctx->opcode));
17328 int rb = 28; /* GP */
17329 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17331 gen_ld(ctx, OPC_LW, rd, rb, offset);
17335 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17336 if (ctx->opcode & 1) {
17337 generate_exception_end(ctx, EXCP_RI);
17340 int enc_dest = uMIPS_RD(ctx->opcode);
17341 int enc_rt = uMIPS_RS2(ctx->opcode);
17342 int enc_rs = uMIPS_RS1(ctx->opcode);
17343 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17348 int rd = mmreg(uMIPS_RD(ctx->opcode));
17349 int rb = mmreg(uMIPS_RS(ctx->opcode));
17350 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17351 offset = (offset == 0xf ? -1 : offset);
17353 gen_ld(ctx, OPC_LBU, rd, rb, offset);
17358 int rd = mmreg(uMIPS_RD(ctx->opcode));
17359 int rb = mmreg(uMIPS_RS(ctx->opcode));
17360 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17362 gen_ld(ctx, OPC_LHU, rd, rb, offset);
17367 int rd = (ctx->opcode >> 5) & 0x1f;
17368 int rb = 29; /* SP */
17369 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17371 gen_ld(ctx, OPC_LW, rd, rb, offset);
17376 int rd = mmreg(uMIPS_RD(ctx->opcode));
17377 int rb = mmreg(uMIPS_RS(ctx->opcode));
17378 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17380 gen_ld(ctx, OPC_LW, rd, rb, offset);
17385 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17386 int rb = mmreg(uMIPS_RS(ctx->opcode));
17387 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17389 gen_st(ctx, OPC_SB, rd, rb, offset);
17394 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17395 int rb = mmreg(uMIPS_RS(ctx->opcode));
17396 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17398 gen_st(ctx, OPC_SH, rd, rb, offset);
17403 int rd = (ctx->opcode >> 5) & 0x1f;
17404 int rb = 29; /* SP */
17405 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17407 gen_st(ctx, OPC_SW, rd, rb, offset);
17412 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17413 int rb = mmreg(uMIPS_RS(ctx->opcode));
17414 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17416 gen_st(ctx, OPC_SW, rd, rb, offset);
17421 int rd = uMIPS_RD5(ctx->opcode);
17422 int rs = uMIPS_RS5(ctx->opcode);
17424 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17431 switch (ctx->opcode & 0x1) {
17441 switch (ctx->opcode & 0x1) {
17446 gen_addiur1sp(ctx);
17450 case B16: /* BC16 */
17451 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17452 sextract32(ctx->opcode, 0, 10) << 1,
17453 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17455 case BNEZ16: /* BNEZC16 */
17456 case BEQZ16: /* BEQZC16 */
17457 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17458 mmreg(uMIPS_RD(ctx->opcode)),
17459 0, sextract32(ctx->opcode, 0, 7) << 1,
17460 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17465 int reg = mmreg(uMIPS_RD(ctx->opcode));
17466 int imm = ZIMM(ctx->opcode, 0, 7);
17468 imm = (imm == 0x7f ? -1 : imm);
17469 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17475 generate_exception_end(ctx, EXCP_RI);
17478 decode_micromips32_opc(env, ctx);
17491 /* MAJOR, P16, and P32 pools opcodes */
17495 NM_MOVE_BALC = 0x02,
17503 NM_P16_SHIFT = 0x0c,
17521 NM_P_LS_U12 = 0x21,
17531 NM_P16_ADDU = 0x2c,
17545 NM_MOVEPREV = 0x3f,
17548 /* POOL32A instruction pool */
17550 NM_POOL32A0 = 0x00,
17551 NM_SPECIAL2 = 0x01,
17554 NM_POOL32A5 = 0x05,
17555 NM_POOL32A7 = 0x07,
17558 /* P.GP.W instruction pool */
17560 NM_ADDIUGP_W = 0x00,
17565 /* P48I instruction pool */
17569 NM_ADDIUGP48 = 0x02,
17570 NM_ADDIUPC48 = 0x03,
17575 /* P.U12 instruction pool */
17584 NM_ADDIUNEG = 0x08,
17591 /* POOL32F instruction pool */
17593 NM_POOL32F_0 = 0x00,
17594 NM_POOL32F_3 = 0x03,
17595 NM_POOL32F_5 = 0x05,
17598 /* POOL32S instruction pool */
17600 NM_POOL32S_0 = 0x00,
17601 NM_POOL32S_4 = 0x04,
17604 /* P.LUI instruction pool */
17610 /* P.GP.BH instruction pool */
17615 NM_ADDIUGP_B = 0x03,
17618 NM_P_GP_CP1 = 0x06,
17621 /* P.LS.U12 instruction pool */
17626 NM_P_PREFU12 = 0x03,
17639 /* P.LS.S9 instruction pool */
17645 NM_P_LS_UAWM = 0x05,
17648 /* P.BAL instruction pool */
17654 /* P.J instruction pool */
17657 NM_JALRC_HB = 0x01,
17658 NM_P_BALRSC = 0x08,
17661 /* P.BR1 instruction pool */
17669 /* P.BR2 instruction pool */
17676 /* P.BRI instruction pool */
17688 /* P16.SHIFT instruction pool */
17694 /* POOL16C instruction pool */
17696 NM_POOL16C_0 = 0x00,
17700 /* P16.A1 instruction pool */
17702 NM_ADDIUR1SP = 0x01,
17705 /* P16.A2 instruction pool */
17708 NM_P_ADDIURS5 = 0x01,
17711 /* P16.ADDU instruction pool */
17717 /* P16.SR instruction pool */
17720 NM_RESTORE_JRC16 = 0x01,
17723 /* P16.4X4 instruction pool */
17729 /* P16.LB instruction pool */
17736 /* P16.LH instruction pool */
17743 /* P.RI instruction pool */
17746 NM_P_SYSCALL = 0x01,
17751 /* POOL32A0 instruction pool */
17786 NM_D_E_MT_VPE = 0x56,
17794 /* CRC32 instruction pool */
17804 /* POOL32A5 instruction pool */
17806 NM_CMP_EQ_PH = 0x00,
17807 NM_CMP_LT_PH = 0x08,
17808 NM_CMP_LE_PH = 0x10,
17809 NM_CMPGU_EQ_QB = 0x18,
17810 NM_CMPGU_LT_QB = 0x20,
17811 NM_CMPGU_LE_QB = 0x28,
17812 NM_CMPGDU_EQ_QB = 0x30,
17813 NM_CMPGDU_LT_QB = 0x38,
17814 NM_CMPGDU_LE_QB = 0x40,
17815 NM_CMPU_EQ_QB = 0x48,
17816 NM_CMPU_LT_QB = 0x50,
17817 NM_CMPU_LE_QB = 0x58,
17818 NM_ADDQ_S_W = 0x60,
17819 NM_SUBQ_S_W = 0x68,
17823 NM_ADDQ_S_PH = 0x01,
17824 NM_ADDQH_R_PH = 0x09,
17825 NM_ADDQH_R_W = 0x11,
17826 NM_ADDU_S_QB = 0x19,
17827 NM_ADDU_S_PH = 0x21,
17828 NM_ADDUH_R_QB = 0x29,
17829 NM_SHRAV_R_PH = 0x31,
17830 NM_SHRAV_R_QB = 0x39,
17831 NM_SUBQ_S_PH = 0x41,
17832 NM_SUBQH_R_PH = 0x49,
17833 NM_SUBQH_R_W = 0x51,
17834 NM_SUBU_S_QB = 0x59,
17835 NM_SUBU_S_PH = 0x61,
17836 NM_SUBUH_R_QB = 0x69,
17837 NM_SHLLV_S_PH = 0x71,
17838 NM_PRECR_SRA_R_PH_W = 0x79,
17840 NM_MULEU_S_PH_QBL = 0x12,
17841 NM_MULEU_S_PH_QBR = 0x1a,
17842 NM_MULQ_RS_PH = 0x22,
17843 NM_MULQ_S_PH = 0x2a,
17844 NM_MULQ_RS_W = 0x32,
17845 NM_MULQ_S_W = 0x3a,
17848 NM_SHRAV_R_W = 0x5a,
17849 NM_SHRLV_PH = 0x62,
17850 NM_SHRLV_QB = 0x6a,
17851 NM_SHLLV_QB = 0x72,
17852 NM_SHLLV_S_W = 0x7a,
17856 NM_MULEQ_S_W_PHL = 0x04,
17857 NM_MULEQ_S_W_PHR = 0x0c,
17859 NM_MUL_S_PH = 0x05,
17860 NM_PRECR_QB_PH = 0x0d,
17861 NM_PRECRQ_QB_PH = 0x15,
17862 NM_PRECRQ_PH_W = 0x1d,
17863 NM_PRECRQ_RS_PH_W = 0x25,
17864 NM_PRECRQU_S_QB_PH = 0x2d,
17865 NM_PACKRL_PH = 0x35,
17869 NM_SHRA_R_W = 0x5e,
17870 NM_SHRA_R_PH = 0x66,
17871 NM_SHLL_S_PH = 0x76,
17872 NM_SHLL_S_W = 0x7e,
17877 /* POOL32A7 instruction pool */
17882 NM_POOL32AXF = 0x07,
17885 /* P.SR instruction pool */
17891 /* P.SHIFT instruction pool */
17899 /* P.ROTX instruction pool */
17904 /* P.INS instruction pool */
17909 /* P.EXT instruction pool */
17914 /* POOL32F_0 (fmt) instruction pool */
17919 NM_SELEQZ_S = 0x07,
17920 NM_SELEQZ_D = 0x47,
17924 NM_SELNEZ_S = 0x0f,
17925 NM_SELNEZ_D = 0x4f,
17940 /* POOL32F_3 instruction pool */
17944 NM_MINA_FMT = 0x04,
17945 NM_MAXA_FMT = 0x05,
17946 NM_POOL32FXF = 0x07,
17949 /* POOL32F_5 instruction pool */
17951 NM_CMP_CONDN_S = 0x00,
17952 NM_CMP_CONDN_D = 0x02,
17955 /* P.GP.LH instruction pool */
17961 /* P.GP.SH instruction pool */
17966 /* P.GP.CP1 instruction pool */
17974 /* P.LS.S0 instruction pool */
17991 NM_P_PREFS9 = 0x03,
17997 /* P.LS.S1 instruction pool */
17999 NM_ASET_ACLR = 0x02,
18007 /* P.LS.E0 instruction pool */
18023 /* P.PREFE instruction pool */
18029 /* P.LLE instruction pool */
18035 /* P.SCE instruction pool */
18041 /* P.LS.WM instruction pool */
18047 /* P.LS.UAWM instruction pool */
18053 /* P.BR3A instruction pool */
18059 NM_BPOSGE32C = 0x04,
18062 /* P16.RI instruction pool */
18064 NM_P16_SYSCALL = 0x01,
18069 /* POOL16C_0 instruction pool */
18071 NM_POOL16C_00 = 0x00,
18074 /* P16.JRC instruction pool */
18080 /* P.SYSCALL instruction pool */
18086 /* P.TRAP instruction pool */
18092 /* P.CMOVE instruction pool */
18098 /* POOL32Axf instruction pool */
18100 NM_POOL32AXF_1 = 0x01,
18101 NM_POOL32AXF_2 = 0x02,
18102 NM_POOL32AXF_4 = 0x04,
18103 NM_POOL32AXF_5 = 0x05,
18104 NM_POOL32AXF_7 = 0x07,
18107 /* POOL32Axf_1 instruction pool */
18109 NM_POOL32AXF_1_0 = 0x00,
18110 NM_POOL32AXF_1_1 = 0x01,
18111 NM_POOL32AXF_1_3 = 0x03,
18112 NM_POOL32AXF_1_4 = 0x04,
18113 NM_POOL32AXF_1_5 = 0x05,
18114 NM_POOL32AXF_1_7 = 0x07,
18117 /* POOL32Axf_2 instruction pool */
18119 NM_POOL32AXF_2_0_7 = 0x00,
18120 NM_POOL32AXF_2_8_15 = 0x01,
18121 NM_POOL32AXF_2_16_23 = 0x02,
18122 NM_POOL32AXF_2_24_31 = 0x03,
18125 /* POOL32Axf_7 instruction pool */
18127 NM_SHRA_R_QB = 0x0,
18132 /* POOL32Axf_1_0 instruction pool */
18140 /* POOL32Axf_1_1 instruction pool */
18146 /* POOL32Axf_1_3 instruction pool */
18154 /* POOL32Axf_1_4 instruction pool */
18160 /* POOL32Axf_1_5 instruction pool */
18162 NM_MAQ_S_W_PHR = 0x0,
18163 NM_MAQ_S_W_PHL = 0x1,
18164 NM_MAQ_SA_W_PHR = 0x2,
18165 NM_MAQ_SA_W_PHL = 0x3,
18168 /* POOL32Axf_1_7 instruction pool */
18172 NM_EXTR_RS_W = 0x2,
18176 /* POOL32Axf_2_0_7 instruction pool */
18179 NM_DPAQ_S_W_PH = 0x1,
18181 NM_DPSQ_S_W_PH = 0x3,
18188 /* POOL32Axf_2_8_15 instruction pool */
18190 NM_DPAX_W_PH = 0x0,
18191 NM_DPAQ_SA_L_W = 0x1,
18192 NM_DPSX_W_PH = 0x2,
18193 NM_DPSQ_SA_L_W = 0x3,
18196 NM_EXTRV_R_W = 0x7,
18199 /* POOL32Axf_2_16_23 instruction pool */
18201 NM_DPAU_H_QBL = 0x0,
18202 NM_DPAQX_S_W_PH = 0x1,
18203 NM_DPSU_H_QBL = 0x2,
18204 NM_DPSQX_S_W_PH = 0x3,
18207 NM_MULSA_W_PH = 0x6,
18208 NM_EXTRV_RS_W = 0x7,
18211 /* POOL32Axf_2_24_31 instruction pool */
18213 NM_DPAU_H_QBR = 0x0,
18214 NM_DPAQX_SA_W_PH = 0x1,
18215 NM_DPSU_H_QBR = 0x2,
18216 NM_DPSQX_SA_W_PH = 0x3,
18219 NM_MULSAQ_S_W_PH = 0x6,
18220 NM_EXTRV_S_H = 0x7,
18223 /* POOL32Axf_{4, 5} instruction pool */
18242 /* nanoMIPS DSP instructions */
18243 NM_ABSQ_S_QB = 0x00,
18244 NM_ABSQ_S_PH = 0x08,
18245 NM_ABSQ_S_W = 0x10,
18246 NM_PRECEQ_W_PHL = 0x28,
18247 NM_PRECEQ_W_PHR = 0x30,
18248 NM_PRECEQU_PH_QBL = 0x38,
18249 NM_PRECEQU_PH_QBR = 0x48,
18250 NM_PRECEU_PH_QBL = 0x58,
18251 NM_PRECEU_PH_QBR = 0x68,
18252 NM_PRECEQU_PH_QBLA = 0x39,
18253 NM_PRECEQU_PH_QBRA = 0x49,
18254 NM_PRECEU_PH_QBLA = 0x59,
18255 NM_PRECEU_PH_QBRA = 0x69,
18256 NM_REPLV_PH = 0x01,
18257 NM_REPLV_QB = 0x09,
18260 NM_RADDU_W_QB = 0x78,
18266 /* PP.SR instruction pool */
18270 NM_RESTORE_JRC = 0x03,
18273 /* P.SR.F instruction pool */
18276 NM_RESTOREF = 0x01,
18279 /* P16.SYSCALL instruction pool */
18281 NM_SYSCALL16 = 0x00,
18282 NM_HYPCALL16 = 0x01,
18285 /* POOL16C_00 instruction pool */
18293 /* PP.LSX and PP.LSXS instruction pool */
18331 /* ERETx instruction pool */
18337 /* POOL32FxF_{0, 1} insturction pool */
18346 NM_CVT_S_PL = 0x84,
18347 NM_CVT_S_PU = 0xa4,
18349 NM_CVT_L_S = 0x004,
18350 NM_CVT_L_D = 0x104,
18351 NM_CVT_W_S = 0x024,
18352 NM_CVT_W_D = 0x124,
18354 NM_RSQRT_S = 0x008,
18355 NM_RSQRT_D = 0x108,
18360 NM_RECIP_S = 0x048,
18361 NM_RECIP_D = 0x148,
18363 NM_FLOOR_L_S = 0x00c,
18364 NM_FLOOR_L_D = 0x10c,
18366 NM_FLOOR_W_S = 0x02c,
18367 NM_FLOOR_W_D = 0x12c,
18369 NM_CEIL_L_S = 0x04c,
18370 NM_CEIL_L_D = 0x14c,
18371 NM_CEIL_W_S = 0x06c,
18372 NM_CEIL_W_D = 0x16c,
18373 NM_TRUNC_L_S = 0x08c,
18374 NM_TRUNC_L_D = 0x18c,
18375 NM_TRUNC_W_S = 0x0ac,
18376 NM_TRUNC_W_D = 0x1ac,
18377 NM_ROUND_L_S = 0x0cc,
18378 NM_ROUND_L_D = 0x1cc,
18379 NM_ROUND_W_S = 0x0ec,
18380 NM_ROUND_W_D = 0x1ec,
18388 NM_CVT_D_S = 0x04d,
18389 NM_CVT_D_W = 0x0cd,
18390 NM_CVT_D_L = 0x14d,
18391 NM_CVT_S_D = 0x06d,
18392 NM_CVT_S_W = 0x0ed,
18393 NM_CVT_S_L = 0x16d,
18396 /* P.LL instruction pool */
18402 /* P.SC instruction pool */
18408 /* P.DVP instruction pool */
18417 * nanoMIPS decoding engine
18422 /* extraction utilities */
18424 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18425 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18426 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18427 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18428 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18430 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18431 static inline int decode_gpr_gpr3(int r)
18433 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18435 return map[r & 0x7];
18438 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18439 static inline int decode_gpr_gpr3_src_store(int r)
18441 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18443 return map[r & 0x7];
18446 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18447 static inline int decode_gpr_gpr4(int r)
18449 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18450 16, 17, 18, 19, 20, 21, 22, 23 };
18452 return map[r & 0xf];
18455 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18456 static inline int decode_gpr_gpr4_zero(int r)
18458 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18459 16, 17, 18, 19, 20, 21, 22, 23 };
18461 return map[r & 0xf];
18465 static void gen_adjust_sp(DisasContext *ctx, int u)
18467 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18470 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18471 uint8_t gp, uint16_t u)
18474 TCGv va = tcg_temp_new();
18475 TCGv t0 = tcg_temp_new();
18477 while (counter != count) {
18478 bool use_gp = gp && (counter == count - 1);
18479 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18480 int this_offset = -((counter + 1) << 2);
18481 gen_base_offset_addr(ctx, va, 29, this_offset);
18482 gen_load_gpr(t0, this_rt);
18483 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18484 (MO_TEUL | ctx->default_tcg_memop_mask));
18488 /* adjust stack pointer */
18489 gen_adjust_sp(ctx, -u);
18495 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18496 uint8_t gp, uint16_t u)
18499 TCGv va = tcg_temp_new();
18500 TCGv t0 = tcg_temp_new();
18502 while (counter != count) {
18503 bool use_gp = gp && (counter == count - 1);
18504 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18505 int this_offset = u - ((counter + 1) << 2);
18506 gen_base_offset_addr(ctx, va, 29, this_offset);
18507 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18508 ctx->default_tcg_memop_mask);
18509 tcg_gen_ext32s_tl(t0, t0);
18510 gen_store_gpr(t0, this_rt);
18514 /* adjust stack pointer */
18515 gen_adjust_sp(ctx, u);
18521 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18523 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18524 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
18526 switch (extract32(ctx->opcode, 2, 2)) {
18528 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18531 gen_logic(ctx, OPC_AND, rt, rt, rs);
18534 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18537 gen_logic(ctx, OPC_OR, rt, rt, rs);
18542 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18544 int rt = extract32(ctx->opcode, 21, 5);
18545 int rs = extract32(ctx->opcode, 16, 5);
18546 int rd = extract32(ctx->opcode, 11, 5);
18548 switch (extract32(ctx->opcode, 3, 7)) {
18550 switch (extract32(ctx->opcode, 10, 1)) {
18553 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18557 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18563 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18567 gen_bshfl(ctx, OPC_SEB, rs, rt);
18570 gen_bshfl(ctx, OPC_SEH, rs, rt);
18573 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18576 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18579 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18582 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18585 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18588 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18592 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18595 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18598 switch (extract32(ctx->opcode, 10, 1)) {
18600 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18603 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18608 gen_logic(ctx, OPC_AND, rd, rs, rt);
18611 gen_logic(ctx, OPC_OR, rd, rs, rt);
18614 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18617 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18620 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18625 #ifndef CONFIG_USER_ONLY
18626 TCGv t0 = tcg_temp_new();
18627 switch (extract32(ctx->opcode, 10, 1)) {
18630 check_cp0_enabled(ctx);
18631 gen_helper_dvp(t0, cpu_env);
18632 gen_store_gpr(t0, rt);
18637 check_cp0_enabled(ctx);
18638 gen_helper_evp(t0, cpu_env);
18639 gen_store_gpr(t0, rt);
18646 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18651 TCGv t0 = tcg_temp_new();
18652 TCGv t1 = tcg_temp_new();
18653 TCGv t2 = tcg_temp_new();
18655 gen_load_gpr(t1, rs);
18656 gen_load_gpr(t2, rt);
18657 tcg_gen_add_tl(t0, t1, t2);
18658 tcg_gen_ext32s_tl(t0, t0);
18659 tcg_gen_xor_tl(t1, t1, t2);
18660 tcg_gen_xor_tl(t2, t0, t2);
18661 tcg_gen_andc_tl(t1, t2, t1);
18663 /* operands of same sign, result different sign */
18664 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18665 gen_store_gpr(t0, rd);
18673 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18676 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18679 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18682 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18685 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18688 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18691 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18694 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18696 #ifndef CONFIG_USER_ONLY
18698 check_cp0_enabled(ctx);
18700 /* Treat as NOP. */
18703 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18706 check_cp0_enabled(ctx);
18708 TCGv t0 = tcg_temp_new();
18710 gen_load_gpr(t0, rt);
18711 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18715 case NM_D_E_MT_VPE:
18717 uint8_t sc = extract32(ctx->opcode, 10, 1);
18718 TCGv t0 = tcg_temp_new();
18725 gen_helper_dmt(t0);
18726 gen_store_gpr(t0, rt);
18727 } else if (rs == 0) {
18730 gen_helper_dvpe(t0, cpu_env);
18731 gen_store_gpr(t0, rt);
18733 generate_exception_end(ctx, EXCP_RI);
18740 gen_helper_emt(t0);
18741 gen_store_gpr(t0, rt);
18742 } else if (rs == 0) {
18745 gen_helper_evpe(t0, cpu_env);
18746 gen_store_gpr(t0, rt);
18748 generate_exception_end(ctx, EXCP_RI);
18759 TCGv t0 = tcg_temp_new();
18760 TCGv t1 = tcg_temp_new();
18762 gen_load_gpr(t0, rt);
18763 gen_load_gpr(t1, rs);
18764 gen_helper_fork(t0, t1);
18771 check_cp0_enabled(ctx);
18773 /* Treat as NOP. */
18776 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18777 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18781 check_cp0_enabled(ctx);
18782 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18783 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18788 TCGv t0 = tcg_temp_new();
18790 gen_load_gpr(t0, rs);
18791 gen_helper_yield(t0, cpu_env, t0);
18792 gen_store_gpr(t0, rt);
18798 generate_exception_end(ctx, EXCP_RI);
18804 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18805 int ret, int v1, int v2)
18811 t0 = tcg_temp_new_i32();
18813 v0_t = tcg_temp_new();
18814 v1_t = tcg_temp_new();
18816 tcg_gen_movi_i32(t0, v2 >> 3);
18818 gen_load_gpr(v0_t, ret);
18819 gen_load_gpr(v1_t, v1);
18822 case NM_MAQ_S_W_PHR:
18824 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18826 case NM_MAQ_S_W_PHL:
18828 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18830 case NM_MAQ_SA_W_PHR:
18832 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18834 case NM_MAQ_SA_W_PHL:
18836 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18839 generate_exception_end(ctx, EXCP_RI);
18843 tcg_temp_free_i32(t0);
18845 tcg_temp_free(v0_t);
18846 tcg_temp_free(v1_t);
18850 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18851 int ret, int v1, int v2)
18854 TCGv t0 = tcg_temp_new();
18855 TCGv t1 = tcg_temp_new();
18856 TCGv v0_t = tcg_temp_new();
18858 gen_load_gpr(v0_t, v1);
18861 case NM_POOL32AXF_1_0:
18863 switch (extract32(ctx->opcode, 12, 2)) {
18865 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18868 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18871 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18874 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18878 case NM_POOL32AXF_1_1:
18880 switch (extract32(ctx->opcode, 12, 2)) {
18882 tcg_gen_movi_tl(t0, v2);
18883 gen_helper_mthlip(t0, v0_t, cpu_env);
18886 tcg_gen_movi_tl(t0, v2 >> 3);
18887 gen_helper_shilo(t0, v0_t, cpu_env);
18890 generate_exception_end(ctx, EXCP_RI);
18894 case NM_POOL32AXF_1_3:
18896 imm = extract32(ctx->opcode, 14, 7);
18897 switch (extract32(ctx->opcode, 12, 2)) {
18899 tcg_gen_movi_tl(t0, imm);
18900 gen_helper_rddsp(t0, t0, cpu_env);
18901 gen_store_gpr(t0, ret);
18904 gen_load_gpr(t0, ret);
18905 tcg_gen_movi_tl(t1, imm);
18906 gen_helper_wrdsp(t0, t1, cpu_env);
18909 tcg_gen_movi_tl(t0, v2 >> 3);
18910 tcg_gen_movi_tl(t1, v1);
18911 gen_helper_extp(t0, t0, t1, cpu_env);
18912 gen_store_gpr(t0, ret);
18915 tcg_gen_movi_tl(t0, v2 >> 3);
18916 tcg_gen_movi_tl(t1, v1);
18917 gen_helper_extpdp(t0, t0, t1, cpu_env);
18918 gen_store_gpr(t0, ret);
18922 case NM_POOL32AXF_1_4:
18924 tcg_gen_movi_tl(t0, v2 >> 2);
18925 switch (extract32(ctx->opcode, 12, 1)) {
18927 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18928 gen_store_gpr(t0, ret);
18931 gen_helper_shrl_qb(t0, t0, v0_t);
18932 gen_store_gpr(t0, ret);
18936 case NM_POOL32AXF_1_5:
18937 opc = extract32(ctx->opcode, 12, 2);
18938 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18940 case NM_POOL32AXF_1_7:
18942 tcg_gen_movi_tl(t0, v2 >> 3);
18943 tcg_gen_movi_tl(t1, v1);
18944 switch (extract32(ctx->opcode, 12, 2)) {
18946 gen_helper_extr_w(t0, t0, t1, cpu_env);
18947 gen_store_gpr(t0, ret);
18950 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18951 gen_store_gpr(t0, ret);
18954 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18955 gen_store_gpr(t0, ret);
18958 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18959 gen_store_gpr(t0, ret);
18964 generate_exception_end(ctx, EXCP_RI);
18970 tcg_temp_free(v0_t);
18973 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18974 TCGv v0, TCGv v1, int rd)
18978 t0 = tcg_temp_new_i32();
18980 tcg_gen_movi_i32(t0, rd >> 3);
18983 case NM_POOL32AXF_2_0_7:
18984 switch (extract32(ctx->opcode, 9, 3)) {
18987 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18989 case NM_DPAQ_S_W_PH:
18991 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18995 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18997 case NM_DPSQ_S_W_PH:
18999 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19002 generate_exception_end(ctx, EXCP_RI);
19006 case NM_POOL32AXF_2_8_15:
19007 switch (extract32(ctx->opcode, 9, 3)) {
19010 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19012 case NM_DPAQ_SA_L_W:
19014 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19018 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19020 case NM_DPSQ_SA_L_W:
19022 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19025 generate_exception_end(ctx, EXCP_RI);
19029 case NM_POOL32AXF_2_16_23:
19030 switch (extract32(ctx->opcode, 9, 3)) {
19031 case NM_DPAU_H_QBL:
19033 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19035 case NM_DPAQX_S_W_PH:
19037 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19039 case NM_DPSU_H_QBL:
19041 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19043 case NM_DPSQX_S_W_PH:
19045 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19047 case NM_MULSA_W_PH:
19049 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19052 generate_exception_end(ctx, EXCP_RI);
19056 case NM_POOL32AXF_2_24_31:
19057 switch (extract32(ctx->opcode, 9, 3)) {
19058 case NM_DPAU_H_QBR:
19060 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19062 case NM_DPAQX_SA_W_PH:
19064 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19066 case NM_DPSU_H_QBR:
19068 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19070 case NM_DPSQX_SA_W_PH:
19072 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19074 case NM_MULSAQ_S_W_PH:
19076 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19079 generate_exception_end(ctx, EXCP_RI);
19084 generate_exception_end(ctx, EXCP_RI);
19088 tcg_temp_free_i32(t0);
19091 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19092 int rt, int rs, int rd)
19095 TCGv t0 = tcg_temp_new();
19096 TCGv t1 = tcg_temp_new();
19097 TCGv v0_t = tcg_temp_new();
19098 TCGv v1_t = tcg_temp_new();
19100 gen_load_gpr(v0_t, rt);
19101 gen_load_gpr(v1_t, rs);
19104 case NM_POOL32AXF_2_0_7:
19105 switch (extract32(ctx->opcode, 9, 3)) {
19107 case NM_DPAQ_S_W_PH:
19109 case NM_DPSQ_S_W_PH:
19110 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19115 gen_load_gpr(t0, rs);
19117 if (rd != 0 && rd != 2) {
19118 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19119 tcg_gen_ext32u_tl(t0, t0);
19120 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19121 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19123 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19129 int acc = extract32(ctx->opcode, 14, 2);
19130 TCGv_i64 t2 = tcg_temp_new_i64();
19131 TCGv_i64 t3 = tcg_temp_new_i64();
19133 gen_load_gpr(t0, rt);
19134 gen_load_gpr(t1, rs);
19135 tcg_gen_ext_tl_i64(t2, t0);
19136 tcg_gen_ext_tl_i64(t3, t1);
19137 tcg_gen_mul_i64(t2, t2, t3);
19138 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19139 tcg_gen_add_i64(t2, t2, t3);
19140 tcg_temp_free_i64(t3);
19141 gen_move_low32(cpu_LO[acc], t2);
19142 gen_move_high32(cpu_HI[acc], t2);
19143 tcg_temp_free_i64(t2);
19149 int acc = extract32(ctx->opcode, 14, 2);
19150 TCGv_i32 t2 = tcg_temp_new_i32();
19151 TCGv_i32 t3 = tcg_temp_new_i32();
19153 gen_load_gpr(t0, rs);
19154 gen_load_gpr(t1, rt);
19155 tcg_gen_trunc_tl_i32(t2, t0);
19156 tcg_gen_trunc_tl_i32(t3, t1);
19157 tcg_gen_muls2_i32(t2, t3, t2, t3);
19158 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19159 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19160 tcg_temp_free_i32(t2);
19161 tcg_temp_free_i32(t3);
19166 gen_load_gpr(v1_t, rs);
19167 tcg_gen_movi_tl(t0, rd >> 3);
19168 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19169 gen_store_gpr(t0, ret);
19173 case NM_POOL32AXF_2_8_15:
19174 switch (extract32(ctx->opcode, 9, 3)) {
19176 case NM_DPAQ_SA_L_W:
19178 case NM_DPSQ_SA_L_W:
19179 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19184 int acc = extract32(ctx->opcode, 14, 2);
19185 TCGv_i64 t2 = tcg_temp_new_i64();
19186 TCGv_i64 t3 = tcg_temp_new_i64();
19188 gen_load_gpr(t0, rs);
19189 gen_load_gpr(t1, rt);
19190 tcg_gen_ext32u_tl(t0, t0);
19191 tcg_gen_ext32u_tl(t1, t1);
19192 tcg_gen_extu_tl_i64(t2, t0);
19193 tcg_gen_extu_tl_i64(t3, t1);
19194 tcg_gen_mul_i64(t2, t2, t3);
19195 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19196 tcg_gen_add_i64(t2, t2, t3);
19197 tcg_temp_free_i64(t3);
19198 gen_move_low32(cpu_LO[acc], t2);
19199 gen_move_high32(cpu_HI[acc], t2);
19200 tcg_temp_free_i64(t2);
19206 int acc = extract32(ctx->opcode, 14, 2);
19207 TCGv_i32 t2 = tcg_temp_new_i32();
19208 TCGv_i32 t3 = tcg_temp_new_i32();
19210 gen_load_gpr(t0, rs);
19211 gen_load_gpr(t1, rt);
19212 tcg_gen_trunc_tl_i32(t2, t0);
19213 tcg_gen_trunc_tl_i32(t3, t1);
19214 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19215 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19216 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19217 tcg_temp_free_i32(t2);
19218 tcg_temp_free_i32(t3);
19223 tcg_gen_movi_tl(t0, rd >> 3);
19224 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19225 gen_store_gpr(t0, ret);
19228 generate_exception_end(ctx, EXCP_RI);
19232 case NM_POOL32AXF_2_16_23:
19233 switch (extract32(ctx->opcode, 9, 3)) {
19234 case NM_DPAU_H_QBL:
19235 case NM_DPAQX_S_W_PH:
19236 case NM_DPSU_H_QBL:
19237 case NM_DPSQX_S_W_PH:
19238 case NM_MULSA_W_PH:
19239 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19243 tcg_gen_movi_tl(t0, rd >> 3);
19244 gen_helper_extp(t0, t0, v1_t, cpu_env);
19245 gen_store_gpr(t0, ret);
19250 int acc = extract32(ctx->opcode, 14, 2);
19251 TCGv_i64 t2 = tcg_temp_new_i64();
19252 TCGv_i64 t3 = tcg_temp_new_i64();
19254 gen_load_gpr(t0, rs);
19255 gen_load_gpr(t1, rt);
19256 tcg_gen_ext_tl_i64(t2, t0);
19257 tcg_gen_ext_tl_i64(t3, t1);
19258 tcg_gen_mul_i64(t2, t2, t3);
19259 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19260 tcg_gen_sub_i64(t2, t3, t2);
19261 tcg_temp_free_i64(t3);
19262 gen_move_low32(cpu_LO[acc], t2);
19263 gen_move_high32(cpu_HI[acc], t2);
19264 tcg_temp_free_i64(t2);
19267 case NM_EXTRV_RS_W:
19269 tcg_gen_movi_tl(t0, rd >> 3);
19270 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19271 gen_store_gpr(t0, ret);
19275 case NM_POOL32AXF_2_24_31:
19276 switch (extract32(ctx->opcode, 9, 3)) {
19277 case NM_DPAU_H_QBR:
19278 case NM_DPAQX_SA_W_PH:
19279 case NM_DPSU_H_QBR:
19280 case NM_DPSQX_SA_W_PH:
19281 case NM_MULSAQ_S_W_PH:
19282 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19286 tcg_gen_movi_tl(t0, rd >> 3);
19287 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19288 gen_store_gpr(t0, ret);
19293 int acc = extract32(ctx->opcode, 14, 2);
19294 TCGv_i64 t2 = tcg_temp_new_i64();
19295 TCGv_i64 t3 = tcg_temp_new_i64();
19297 gen_load_gpr(t0, rs);
19298 gen_load_gpr(t1, rt);
19299 tcg_gen_ext32u_tl(t0, t0);
19300 tcg_gen_ext32u_tl(t1, t1);
19301 tcg_gen_extu_tl_i64(t2, t0);
19302 tcg_gen_extu_tl_i64(t3, t1);
19303 tcg_gen_mul_i64(t2, t2, t3);
19304 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19305 tcg_gen_sub_i64(t2, t3, t2);
19306 tcg_temp_free_i64(t3);
19307 gen_move_low32(cpu_LO[acc], t2);
19308 gen_move_high32(cpu_HI[acc], t2);
19309 tcg_temp_free_i64(t2);
19314 tcg_gen_movi_tl(t0, rd >> 3);
19315 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19316 gen_store_gpr(t0, ret);
19321 generate_exception_end(ctx, EXCP_RI);
19328 tcg_temp_free(v0_t);
19329 tcg_temp_free(v1_t);
19332 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19336 TCGv t0 = tcg_temp_new();
19337 TCGv v0_t = tcg_temp_new();
19339 gen_load_gpr(v0_t, rs);
19344 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19345 gen_store_gpr(v0_t, ret);
19349 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19350 gen_store_gpr(v0_t, ret);
19354 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19355 gen_store_gpr(v0_t, ret);
19357 case NM_PRECEQ_W_PHL:
19359 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19360 tcg_gen_ext32s_tl(v0_t, v0_t);
19361 gen_store_gpr(v0_t, ret);
19363 case NM_PRECEQ_W_PHR:
19365 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19366 tcg_gen_shli_tl(v0_t, v0_t, 16);
19367 tcg_gen_ext32s_tl(v0_t, v0_t);
19368 gen_store_gpr(v0_t, ret);
19370 case NM_PRECEQU_PH_QBL:
19372 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19373 gen_store_gpr(v0_t, ret);
19375 case NM_PRECEQU_PH_QBR:
19377 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19378 gen_store_gpr(v0_t, ret);
19380 case NM_PRECEQU_PH_QBLA:
19382 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19383 gen_store_gpr(v0_t, ret);
19385 case NM_PRECEQU_PH_QBRA:
19387 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19388 gen_store_gpr(v0_t, ret);
19390 case NM_PRECEU_PH_QBL:
19392 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19393 gen_store_gpr(v0_t, ret);
19395 case NM_PRECEU_PH_QBR:
19397 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19398 gen_store_gpr(v0_t, ret);
19400 case NM_PRECEU_PH_QBLA:
19402 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19403 gen_store_gpr(v0_t, ret);
19405 case NM_PRECEU_PH_QBRA:
19407 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19408 gen_store_gpr(v0_t, ret);
19412 tcg_gen_ext16u_tl(v0_t, v0_t);
19413 tcg_gen_shli_tl(t0, v0_t, 16);
19414 tcg_gen_or_tl(v0_t, v0_t, t0);
19415 tcg_gen_ext32s_tl(v0_t, v0_t);
19416 gen_store_gpr(v0_t, ret);
19420 tcg_gen_ext8u_tl(v0_t, v0_t);
19421 tcg_gen_shli_tl(t0, v0_t, 8);
19422 tcg_gen_or_tl(v0_t, v0_t, t0);
19423 tcg_gen_shli_tl(t0, v0_t, 16);
19424 tcg_gen_or_tl(v0_t, v0_t, t0);
19425 tcg_gen_ext32s_tl(v0_t, v0_t);
19426 gen_store_gpr(v0_t, ret);
19430 gen_helper_bitrev(v0_t, v0_t);
19431 gen_store_gpr(v0_t, ret);
19436 TCGv tv0 = tcg_temp_new();
19438 gen_load_gpr(tv0, rt);
19439 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19440 gen_store_gpr(v0_t, ret);
19441 tcg_temp_free(tv0);
19444 case NM_RADDU_W_QB:
19446 gen_helper_raddu_w_qb(v0_t, v0_t);
19447 gen_store_gpr(v0_t, ret);
19450 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19454 gen_cl(ctx, OPC_CLO, ret, rs);
19458 gen_cl(ctx, OPC_CLZ, ret, rs);
19461 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19464 generate_exception_end(ctx, EXCP_RI);
19468 tcg_temp_free(v0_t);
19472 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19473 int rt, int rs, int rd)
19475 TCGv t0 = tcg_temp_new();
19476 TCGv rs_t = tcg_temp_new();
19478 gen_load_gpr(rs_t, rs);
19483 tcg_gen_movi_tl(t0, rd >> 2);
19484 switch (extract32(ctx->opcode, 12, 1)) {
19487 gen_helper_shra_qb(t0, t0, rs_t);
19488 gen_store_gpr(t0, rt);
19492 gen_helper_shra_r_qb(t0, t0, rs_t);
19493 gen_store_gpr(t0, rt);
19499 tcg_gen_movi_tl(t0, rd >> 1);
19500 gen_helper_shrl_ph(t0, t0, rs_t);
19501 gen_store_gpr(t0, rt);
19507 target_long result;
19508 imm = extract32(ctx->opcode, 13, 8);
19509 result = (uint32_t)imm << 24 |
19510 (uint32_t)imm << 16 |
19511 (uint32_t)imm << 8 |
19513 result = (int32_t)result;
19514 tcg_gen_movi_tl(t0, result);
19515 gen_store_gpr(t0, rt);
19519 generate_exception_end(ctx, EXCP_RI);
19523 tcg_temp_free(rs_t);
19527 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19529 int rt = extract32(ctx->opcode, 21, 5);
19530 int rs = extract32(ctx->opcode, 16, 5);
19531 int rd = extract32(ctx->opcode, 11, 5);
19533 switch (extract32(ctx->opcode, 6, 3)) {
19534 case NM_POOL32AXF_1:
19536 int32_t op1 = extract32(ctx->opcode, 9, 3);
19537 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19540 case NM_POOL32AXF_2:
19542 int32_t op1 = extract32(ctx->opcode, 12, 2);
19543 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19546 case NM_POOL32AXF_4:
19548 int32_t op1 = extract32(ctx->opcode, 9, 7);
19549 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19552 case NM_POOL32AXF_5:
19553 switch (extract32(ctx->opcode, 9, 7)) {
19554 #ifndef CONFIG_USER_ONLY
19556 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19559 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19562 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19565 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19568 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19571 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19574 check_cp0_enabled(ctx);
19576 TCGv t0 = tcg_temp_new();
19578 save_cpu_state(ctx, 1);
19579 gen_helper_di(t0, cpu_env);
19580 gen_store_gpr(t0, rt);
19581 /* Stop translation as we may have switched the execution mode */
19582 ctx->base.is_jmp = DISAS_STOP;
19587 check_cp0_enabled(ctx);
19589 TCGv t0 = tcg_temp_new();
19591 save_cpu_state(ctx, 1);
19592 gen_helper_ei(t0, cpu_env);
19593 gen_store_gpr(t0, rt);
19594 /* Stop translation as we may have switched the execution mode */
19595 ctx->base.is_jmp = DISAS_STOP;
19600 gen_load_srsgpr(rs, rt);
19603 gen_store_srsgpr(rs, rt);
19606 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19609 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19612 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19616 generate_exception_end(ctx, EXCP_RI);
19620 case NM_POOL32AXF_7:
19622 int32_t op1 = extract32(ctx->opcode, 9, 3);
19623 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19627 generate_exception_end(ctx, EXCP_RI);
19632 /* Immediate Value Compact Branches */
19633 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19634 int rt, int32_t imm, int32_t offset)
19637 int bcond_compute = 0;
19638 TCGv t0 = tcg_temp_new();
19639 TCGv t1 = tcg_temp_new();
19641 gen_load_gpr(t0, rt);
19642 tcg_gen_movi_tl(t1, imm);
19643 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19645 /* Load needed operands and calculate btarget */
19648 if (rt == 0 && imm == 0) {
19649 /* Unconditional branch */
19650 } else if (rt == 0 && imm != 0) {
19655 cond = TCG_COND_EQ;
19661 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19662 generate_exception_end(ctx, EXCP_RI);
19664 } else if (rt == 0 && opc == NM_BBEQZC) {
19665 /* Unconditional branch */
19666 } else if (rt == 0 && opc == NM_BBNEZC) {
19670 tcg_gen_shri_tl(t0, t0, imm);
19671 tcg_gen_andi_tl(t0, t0, 1);
19672 tcg_gen_movi_tl(t1, 0);
19674 if (opc == NM_BBEQZC) {
19675 cond = TCG_COND_EQ;
19677 cond = TCG_COND_NE;
19682 if (rt == 0 && imm == 0) {
19685 } else if (rt == 0 && imm != 0) {
19686 /* Unconditional branch */
19689 cond = TCG_COND_NE;
19693 if (rt == 0 && imm == 0) {
19694 /* Unconditional branch */
19697 cond = TCG_COND_GE;
19702 cond = TCG_COND_LT;
19705 if (rt == 0 && imm == 0) {
19706 /* Unconditional branch */
19709 cond = TCG_COND_GEU;
19714 cond = TCG_COND_LTU;
19717 MIPS_INVAL("Immediate Value Compact branch");
19718 generate_exception_end(ctx, EXCP_RI);
19722 /* branch completion */
19723 clear_branch_hflags(ctx);
19724 ctx->base.is_jmp = DISAS_NORETURN;
19726 if (bcond_compute == 0) {
19727 /* Uncoditional compact branch */
19728 gen_goto_tb(ctx, 0, ctx->btarget);
19730 /* Conditional compact branch */
19731 TCGLabel *fs = gen_new_label();
19733 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19735 gen_goto_tb(ctx, 1, ctx->btarget);
19738 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19746 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19747 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19750 TCGv t0 = tcg_temp_new();
19751 TCGv t1 = tcg_temp_new();
19754 gen_load_gpr(t0, rs);
19758 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19761 /* calculate btarget */
19762 tcg_gen_shli_tl(t0, t0, 1);
19763 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19764 gen_op_addr_add(ctx, btarget, t1, t0);
19766 /* branch completion */
19767 clear_branch_hflags(ctx);
19768 ctx->base.is_jmp = DISAS_NORETURN;
19770 /* unconditional branch to register */
19771 tcg_gen_mov_tl(cpu_PC, btarget);
19772 tcg_gen_lookup_and_goto_ptr();
19778 /* nanoMIPS Branches */
19779 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19780 int rs, int rt, int32_t offset)
19782 int bcond_compute = 0;
19783 TCGv t0 = tcg_temp_new();
19784 TCGv t1 = tcg_temp_new();
19786 /* Load needed operands and calculate btarget */
19788 /* compact branch */
19791 gen_load_gpr(t0, rs);
19792 gen_load_gpr(t1, rt);
19794 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19798 if (rs == 0 || rs == rt) {
19799 /* OPC_BLEZALC, OPC_BGEZALC */
19800 /* OPC_BGTZALC, OPC_BLTZALC */
19801 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19803 gen_load_gpr(t0, rs);
19804 gen_load_gpr(t1, rt);
19806 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19809 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19813 /* OPC_BEQZC, OPC_BNEZC */
19814 gen_load_gpr(t0, rs);
19816 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19818 /* OPC_JIC, OPC_JIALC */
19819 TCGv tbase = tcg_temp_new();
19820 TCGv toffset = tcg_temp_new();
19822 gen_load_gpr(tbase, rt);
19823 tcg_gen_movi_tl(toffset, offset);
19824 gen_op_addr_add(ctx, btarget, tbase, toffset);
19825 tcg_temp_free(tbase);
19826 tcg_temp_free(toffset);
19830 MIPS_INVAL("Compact branch/jump");
19831 generate_exception_end(ctx, EXCP_RI);
19835 if (bcond_compute == 0) {
19836 /* Uncoditional compact branch */
19839 gen_goto_tb(ctx, 0, ctx->btarget);
19842 MIPS_INVAL("Compact branch/jump");
19843 generate_exception_end(ctx, EXCP_RI);
19847 /* Conditional compact branch */
19848 TCGLabel *fs = gen_new_label();
19852 if (rs == 0 && rt != 0) {
19854 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19855 } else if (rs != 0 && rt != 0 && rs == rt) {
19857 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19860 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19864 if (rs == 0 && rt != 0) {
19866 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19867 } else if (rs != 0 && rt != 0 && rs == rt) {
19869 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19872 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19876 if (rs == 0 && rt != 0) {
19878 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19879 } else if (rs != 0 && rt != 0 && rs == rt) {
19881 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19884 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19888 if (rs == 0 && rt != 0) {
19890 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19891 } else if (rs != 0 && rt != 0 && rs == rt) {
19893 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19896 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19900 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19903 MIPS_INVAL("Compact conditional branch/jump");
19904 generate_exception_end(ctx, EXCP_RI);
19908 /* branch completion */
19909 clear_branch_hflags(ctx);
19910 ctx->base.is_jmp = DISAS_NORETURN;
19912 /* Generating branch here as compact branches don't have delay slot */
19913 gen_goto_tb(ctx, 1, ctx->btarget);
19916 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19925 /* nanoMIPS CP1 Branches */
19926 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19927 int32_t ft, int32_t offset)
19929 target_ulong btarget;
19930 TCGv_i64 t0 = tcg_temp_new_i64();
19932 gen_load_fpr64(ctx, t0, ft);
19933 tcg_gen_andi_i64(t0, t0, 1);
19935 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19939 tcg_gen_xori_i64(t0, t0, 1);
19940 ctx->hflags |= MIPS_HFLAG_BC;
19943 /* t0 already set */
19944 ctx->hflags |= MIPS_HFLAG_BC;
19947 MIPS_INVAL("cp1 cond branch");
19948 generate_exception_end(ctx, EXCP_RI);
19952 tcg_gen_trunc_i64_tl(bcond, t0);
19954 ctx->btarget = btarget;
19957 tcg_temp_free_i64(t0);
19961 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19964 t0 = tcg_temp_new();
19965 t1 = tcg_temp_new();
19967 gen_load_gpr(t0, rs);
19968 gen_load_gpr(t1, rt);
19970 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19971 /* PP.LSXS instructions require shifting */
19972 switch (extract32(ctx->opcode, 7, 4)) {
19977 tcg_gen_shli_tl(t0, t0, 1);
19984 tcg_gen_shli_tl(t0, t0, 2);
19988 tcg_gen_shli_tl(t0, t0, 3);
19992 gen_op_addr_add(ctx, t0, t0, t1);
19994 switch (extract32(ctx->opcode, 7, 4)) {
19996 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19998 gen_store_gpr(t0, rd);
20002 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20004 gen_store_gpr(t0, rd);
20008 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20010 gen_store_gpr(t0, rd);
20013 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20015 gen_store_gpr(t0, rd);
20019 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20021 gen_store_gpr(t0, rd);
20025 gen_load_gpr(t1, rd);
20026 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20032 gen_load_gpr(t1, rd);
20033 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20039 gen_load_gpr(t1, rd);
20040 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20044 /*case NM_LWC1XS:*/
20046 /*case NM_LDC1XS:*/
20048 /*case NM_SWC1XS:*/
20050 /*case NM_SDC1XS:*/
20051 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20052 check_cp1_enabled(ctx);
20053 switch (extract32(ctx->opcode, 7, 4)) {
20055 /*case NM_LWC1XS:*/
20056 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20059 /*case NM_LDC1XS:*/
20060 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20063 /*case NM_SWC1XS:*/
20064 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20067 /*case NM_SDC1XS:*/
20068 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20072 generate_exception_err(ctx, EXCP_CpU, 1);
20076 generate_exception_end(ctx, EXCP_RI);
20084 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20088 rt = extract32(ctx->opcode, 21, 5);
20089 rs = extract32(ctx->opcode, 16, 5);
20090 rd = extract32(ctx->opcode, 11, 5);
20092 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20093 generate_exception_end(ctx, EXCP_RI);
20096 check_cp1_enabled(ctx);
20097 switch (extract32(ctx->opcode, 0, 3)) {
20099 switch (extract32(ctx->opcode, 3, 7)) {
20101 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20104 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20107 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20110 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20113 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20116 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20119 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20122 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20125 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20128 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20131 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20134 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20137 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20140 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20143 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20146 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20149 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20152 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20155 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20158 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20161 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20164 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20167 generate_exception_end(ctx, EXCP_RI);
20172 switch (extract32(ctx->opcode, 3, 3)) {
20174 switch (extract32(ctx->opcode, 9, 1)) {
20176 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20179 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20184 switch (extract32(ctx->opcode, 9, 1)) {
20186 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20189 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20194 switch (extract32(ctx->opcode, 9, 1)) {
20196 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20199 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20204 switch (extract32(ctx->opcode, 9, 1)) {
20206 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20209 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20214 switch (extract32(ctx->opcode, 6, 8)) {
20216 gen_cp1(ctx, OPC_CFC1, rt, rs);
20219 gen_cp1(ctx, OPC_CTC1, rt, rs);
20222 gen_cp1(ctx, OPC_MFC1, rt, rs);
20225 gen_cp1(ctx, OPC_MTC1, rt, rs);
20228 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20231 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20234 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20237 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20240 switch (extract32(ctx->opcode, 6, 9)) {
20242 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20245 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20248 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20251 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20254 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20257 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20260 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20263 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20266 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20269 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20272 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20275 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20278 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20281 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20284 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20287 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20290 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20293 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20296 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20299 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20302 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20305 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20308 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20311 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20314 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20317 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20320 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20323 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20326 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20329 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20332 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20335 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20338 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20341 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20344 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20347 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20350 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20353 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20356 generate_exception_end(ctx, EXCP_RI);
20365 switch (extract32(ctx->opcode, 3, 3)) {
20366 case NM_CMP_CONDN_S:
20367 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20369 case NM_CMP_CONDN_D:
20370 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20373 generate_exception_end(ctx, EXCP_RI);
20378 generate_exception_end(ctx, EXCP_RI);
20383 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20384 int rd, int rs, int rt)
20387 TCGv t0 = tcg_temp_new();
20388 TCGv v1_t = tcg_temp_new();
20389 TCGv v2_t = tcg_temp_new();
20391 gen_load_gpr(v1_t, rs);
20392 gen_load_gpr(v2_t, rt);
20397 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20401 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20405 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20407 case NM_CMPU_EQ_QB:
20409 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20411 case NM_CMPU_LT_QB:
20413 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20415 case NM_CMPU_LE_QB:
20417 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20419 case NM_CMPGU_EQ_QB:
20421 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20422 gen_store_gpr(v1_t, ret);
20424 case NM_CMPGU_LT_QB:
20426 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20427 gen_store_gpr(v1_t, ret);
20429 case NM_CMPGU_LE_QB:
20431 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20432 gen_store_gpr(v1_t, ret);
20434 case NM_CMPGDU_EQ_QB:
20436 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20437 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20438 gen_store_gpr(v1_t, ret);
20440 case NM_CMPGDU_LT_QB:
20442 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20443 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20444 gen_store_gpr(v1_t, ret);
20446 case NM_CMPGDU_LE_QB:
20448 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20449 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20450 gen_store_gpr(v1_t, ret);
20454 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20455 gen_store_gpr(v1_t, ret);
20459 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20460 gen_store_gpr(v1_t, ret);
20464 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20465 gen_store_gpr(v1_t, ret);
20469 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20470 gen_store_gpr(v1_t, ret);
20474 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20475 gen_store_gpr(v1_t, ret);
20479 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20480 gen_store_gpr(v1_t, ret);
20484 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20485 gen_store_gpr(v1_t, ret);
20489 switch (extract32(ctx->opcode, 10, 1)) {
20492 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20493 gen_store_gpr(v1_t, ret);
20497 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20498 gen_store_gpr(v1_t, ret);
20502 case NM_ADDQH_R_PH:
20504 switch (extract32(ctx->opcode, 10, 1)) {
20507 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20508 gen_store_gpr(v1_t, ret);
20512 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20513 gen_store_gpr(v1_t, ret);
20519 switch (extract32(ctx->opcode, 10, 1)) {
20522 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20523 gen_store_gpr(v1_t, ret);
20527 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20528 gen_store_gpr(v1_t, ret);
20534 switch (extract32(ctx->opcode, 10, 1)) {
20537 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20538 gen_store_gpr(v1_t, ret);
20542 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20543 gen_store_gpr(v1_t, ret);
20549 switch (extract32(ctx->opcode, 10, 1)) {
20552 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20553 gen_store_gpr(v1_t, ret);
20557 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20558 gen_store_gpr(v1_t, ret);
20562 case NM_ADDUH_R_QB:
20564 switch (extract32(ctx->opcode, 10, 1)) {
20567 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20568 gen_store_gpr(v1_t, ret);
20572 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20573 gen_store_gpr(v1_t, ret);
20577 case NM_SHRAV_R_PH:
20579 switch (extract32(ctx->opcode, 10, 1)) {
20582 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20583 gen_store_gpr(v1_t, ret);
20587 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20588 gen_store_gpr(v1_t, ret);
20592 case NM_SHRAV_R_QB:
20594 switch (extract32(ctx->opcode, 10, 1)) {
20597 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20598 gen_store_gpr(v1_t, ret);
20602 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20603 gen_store_gpr(v1_t, ret);
20609 switch (extract32(ctx->opcode, 10, 1)) {
20612 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20613 gen_store_gpr(v1_t, ret);
20617 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20618 gen_store_gpr(v1_t, ret);
20622 case NM_SUBQH_R_PH:
20624 switch (extract32(ctx->opcode, 10, 1)) {
20627 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20628 gen_store_gpr(v1_t, ret);
20632 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20633 gen_store_gpr(v1_t, ret);
20639 switch (extract32(ctx->opcode, 10, 1)) {
20642 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20643 gen_store_gpr(v1_t, ret);
20647 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20648 gen_store_gpr(v1_t, ret);
20654 switch (extract32(ctx->opcode, 10, 1)) {
20657 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20658 gen_store_gpr(v1_t, ret);
20662 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20663 gen_store_gpr(v1_t, ret);
20669 switch (extract32(ctx->opcode, 10, 1)) {
20672 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20673 gen_store_gpr(v1_t, ret);
20677 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20678 gen_store_gpr(v1_t, ret);
20682 case NM_SUBUH_R_QB:
20684 switch (extract32(ctx->opcode, 10, 1)) {
20687 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20688 gen_store_gpr(v1_t, ret);
20692 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20693 gen_store_gpr(v1_t, ret);
20697 case NM_SHLLV_S_PH:
20699 switch (extract32(ctx->opcode, 10, 1)) {
20702 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20703 gen_store_gpr(v1_t, ret);
20707 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20708 gen_store_gpr(v1_t, ret);
20712 case NM_PRECR_SRA_R_PH_W:
20714 switch (extract32(ctx->opcode, 10, 1)) {
20716 /* PRECR_SRA_PH_W */
20718 TCGv_i32 sa_t = tcg_const_i32(rd);
20719 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20721 gen_store_gpr(v1_t, rt);
20722 tcg_temp_free_i32(sa_t);
20726 /* PRECR_SRA_R_PH_W */
20728 TCGv_i32 sa_t = tcg_const_i32(rd);
20729 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20731 gen_store_gpr(v1_t, rt);
20732 tcg_temp_free_i32(sa_t);
20737 case NM_MULEU_S_PH_QBL:
20739 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20740 gen_store_gpr(v1_t, ret);
20742 case NM_MULEU_S_PH_QBR:
20744 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20745 gen_store_gpr(v1_t, ret);
20747 case NM_MULQ_RS_PH:
20749 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20750 gen_store_gpr(v1_t, ret);
20754 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20755 gen_store_gpr(v1_t, ret);
20759 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20760 gen_store_gpr(v1_t, ret);
20764 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20765 gen_store_gpr(v1_t, ret);
20769 gen_load_gpr(t0, rs);
20771 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20773 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20777 gen_helper_modsub(v1_t, v1_t, v2_t);
20778 gen_store_gpr(v1_t, ret);
20782 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20783 gen_store_gpr(v1_t, ret);
20787 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20788 gen_store_gpr(v1_t, ret);
20792 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20793 gen_store_gpr(v1_t, ret);
20797 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20798 gen_store_gpr(v1_t, ret);
20802 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20803 gen_store_gpr(v1_t, ret);
20808 TCGv tv0 = tcg_temp_new();
20809 TCGv tv1 = tcg_temp_new();
20810 int16_t imm = extract32(ctx->opcode, 16, 7);
20812 tcg_gen_movi_tl(tv0, rd >> 3);
20813 tcg_gen_movi_tl(tv1, imm);
20814 gen_helper_shilo(tv0, tv1, cpu_env);
20817 case NM_MULEQ_S_W_PHL:
20819 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20820 gen_store_gpr(v1_t, ret);
20822 case NM_MULEQ_S_W_PHR:
20824 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20825 gen_store_gpr(v1_t, ret);
20829 switch (extract32(ctx->opcode, 10, 1)) {
20832 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20833 gen_store_gpr(v1_t, ret);
20837 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20838 gen_store_gpr(v1_t, ret);
20842 case NM_PRECR_QB_PH:
20844 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20845 gen_store_gpr(v1_t, ret);
20847 case NM_PRECRQ_QB_PH:
20849 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20850 gen_store_gpr(v1_t, ret);
20852 case NM_PRECRQ_PH_W:
20854 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20855 gen_store_gpr(v1_t, ret);
20857 case NM_PRECRQ_RS_PH_W:
20859 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20860 gen_store_gpr(v1_t, ret);
20862 case NM_PRECRQU_S_QB_PH:
20864 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20865 gen_store_gpr(v1_t, ret);
20869 tcg_gen_movi_tl(t0, rd);
20870 gen_helper_shra_r_w(v1_t, t0, v1_t);
20871 gen_store_gpr(v1_t, rt);
20875 tcg_gen_movi_tl(t0, rd >> 1);
20876 switch (extract32(ctx->opcode, 10, 1)) {
20879 gen_helper_shra_ph(v1_t, t0, v1_t);
20880 gen_store_gpr(v1_t, rt);
20884 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20885 gen_store_gpr(v1_t, rt);
20891 tcg_gen_movi_tl(t0, rd >> 1);
20892 switch (extract32(ctx->opcode, 10, 2)) {
20895 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20896 gen_store_gpr(v1_t, rt);
20900 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20901 gen_store_gpr(v1_t, rt);
20904 generate_exception_end(ctx, EXCP_RI);
20910 tcg_gen_movi_tl(t0, rd);
20911 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20912 gen_store_gpr(v1_t, rt);
20918 imm = sextract32(ctx->opcode, 11, 11);
20919 imm = (int16_t)(imm << 6) >> 6;
20921 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20926 generate_exception_end(ctx, EXCP_RI);
20931 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20939 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20940 ctx->opcode = (ctx->opcode << 16) | insn;
20942 rt = extract32(ctx->opcode, 21, 5);
20943 rs = extract32(ctx->opcode, 16, 5);
20944 rd = extract32(ctx->opcode, 11, 5);
20946 op = extract32(ctx->opcode, 26, 6);
20951 switch (extract32(ctx->opcode, 19, 2)) {
20954 generate_exception_end(ctx, EXCP_RI);
20957 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20958 generate_exception_end(ctx, EXCP_SYSCALL);
20960 generate_exception_end(ctx, EXCP_RI);
20964 generate_exception_end(ctx, EXCP_BREAK);
20967 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20968 gen_helper_do_semihosting(cpu_env);
20970 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20971 generate_exception_end(ctx, EXCP_RI);
20973 generate_exception_end(ctx, EXCP_DBp);
20980 imm = extract32(ctx->opcode, 0, 16);
20982 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20984 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20986 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20991 offset = sextract32(ctx->opcode, 0, 1) << 21 |
20992 extract32(ctx->opcode, 1, 20) << 1;
20993 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20994 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20998 switch (ctx->opcode & 0x07) {
21000 gen_pool32a0_nanomips_insn(env, ctx);
21004 int32_t op1 = extract32(ctx->opcode, 3, 7);
21005 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21009 switch (extract32(ctx->opcode, 3, 3)) {
21011 gen_p_lsx(ctx, rd, rs, rt);
21014 /* In nanoMIPS, the shift field directly encodes the shift
21015 * amount, meaning that the supported shift values are in
21016 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
21017 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21018 extract32(ctx->opcode, 9, 2) - 1);
21021 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21024 gen_pool32axf_nanomips_insn(env, ctx);
21027 generate_exception_end(ctx, EXCP_RI);
21032 generate_exception_end(ctx, EXCP_RI);
21037 switch (ctx->opcode & 0x03) {
21040 offset = extract32(ctx->opcode, 0, 21);
21041 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21045 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21048 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21051 generate_exception_end(ctx, EXCP_RI);
21057 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21058 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21059 switch (extract32(ctx->opcode, 16, 5)) {
21063 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21069 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21070 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21076 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21082 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21085 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21092 t0 = tcg_temp_new();
21094 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21097 tcg_gen_movi_tl(t0, addr);
21098 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21106 t0 = tcg_temp_new();
21107 t1 = tcg_temp_new();
21109 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21112 tcg_gen_movi_tl(t0, addr);
21113 gen_load_gpr(t1, rt);
21115 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21122 generate_exception_end(ctx, EXCP_RI);
21128 switch (extract32(ctx->opcode, 12, 4)) {
21130 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21133 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21136 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21139 switch (extract32(ctx->opcode, 20, 1)) {
21141 switch (ctx->opcode & 3) {
21143 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21144 extract32(ctx->opcode, 2, 1),
21145 extract32(ctx->opcode, 3, 9) << 3);
21148 case NM_RESTORE_JRC:
21149 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21150 extract32(ctx->opcode, 2, 1),
21151 extract32(ctx->opcode, 3, 9) << 3);
21152 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21153 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21157 generate_exception_end(ctx, EXCP_RI);
21162 generate_exception_end(ctx, EXCP_RI);
21167 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21170 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21174 TCGv t0 = tcg_temp_new();
21176 imm = extract32(ctx->opcode, 0, 12);
21177 gen_load_gpr(t0, rs);
21178 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21179 gen_store_gpr(t0, rt);
21185 imm = (int16_t) extract32(ctx->opcode, 0, 12);
21186 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21190 int shift = extract32(ctx->opcode, 0, 5);
21191 switch (extract32(ctx->opcode, 5, 4)) {
21193 if (rt == 0 && shift == 0) {
21195 } else if (rt == 0 && shift == 3) {
21196 /* EHB - treat as NOP */
21197 } else if (rt == 0 && shift == 5) {
21198 /* PAUSE - treat as NOP */
21199 } else if (rt == 0 && shift == 6) {
21201 gen_sync(extract32(ctx->opcode, 16, 5));
21204 gen_shift_imm(ctx, OPC_SLL, rt, rs,
21205 extract32(ctx->opcode, 0, 5));
21209 gen_shift_imm(ctx, OPC_SRL, rt, rs,
21210 extract32(ctx->opcode, 0, 5));
21213 gen_shift_imm(ctx, OPC_SRA, rt, rs,
21214 extract32(ctx->opcode, 0, 5));
21217 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21218 extract32(ctx->opcode, 0, 5));
21226 TCGv t0 = tcg_temp_new();
21227 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21228 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21230 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21232 gen_load_gpr(t0, rs);
21233 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21236 tcg_temp_free_i32(shift);
21237 tcg_temp_free_i32(shiftx);
21238 tcg_temp_free_i32(stripe);
21242 switch (((ctx->opcode >> 10) & 2) |
21243 (extract32(ctx->opcode, 5, 1))) {
21246 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21247 extract32(ctx->opcode, 6, 5));
21250 generate_exception_end(ctx, EXCP_RI);
21255 switch (((ctx->opcode >> 10) & 2) |
21256 (extract32(ctx->opcode, 5, 1))) {
21259 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21260 extract32(ctx->opcode, 6, 5));
21263 generate_exception_end(ctx, EXCP_RI);
21268 generate_exception_end(ctx, EXCP_RI);
21273 gen_pool32f_nanomips_insn(ctx);
21278 switch (extract32(ctx->opcode, 1, 1)) {
21281 tcg_gen_movi_tl(cpu_gpr[rt],
21282 sextract32(ctx->opcode, 0, 1) << 31 |
21283 extract32(ctx->opcode, 2, 10) << 21 |
21284 extract32(ctx->opcode, 12, 9) << 12);
21289 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21290 extract32(ctx->opcode, 2, 10) << 21 |
21291 extract32(ctx->opcode, 12, 9) << 12;
21293 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21294 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21301 uint32_t u = extract32(ctx->opcode, 0, 18);
21303 switch (extract32(ctx->opcode, 18, 3)) {
21305 gen_ld(ctx, OPC_LB, rt, 28, u);
21308 gen_st(ctx, OPC_SB, rt, 28, u);
21311 gen_ld(ctx, OPC_LBU, rt, 28, u);
21315 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21320 switch (ctx->opcode & 1) {
21322 gen_ld(ctx, OPC_LH, rt, 28, u);
21325 gen_ld(ctx, OPC_LHU, rt, 28, u);
21331 switch (ctx->opcode & 1) {
21333 gen_st(ctx, OPC_SH, rt, 28, u);
21336 generate_exception_end(ctx, EXCP_RI);
21342 switch (ctx->opcode & 0x3) {
21344 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21347 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21350 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21353 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21358 generate_exception_end(ctx, EXCP_RI);
21365 uint32_t u = extract32(ctx->opcode, 0, 12);
21367 switch (extract32(ctx->opcode, 12, 4)) {
21371 /* Break the TB to be able to sync copied instructions
21373 ctx->base.is_jmp = DISAS_STOP;
21376 /* Treat as NOP. */
21380 gen_ld(ctx, OPC_LB, rt, rs, u);
21383 gen_ld(ctx, OPC_LH, rt, rs, u);
21386 gen_ld(ctx, OPC_LW, rt, rs, u);
21389 gen_ld(ctx, OPC_LBU, rt, rs, u);
21392 gen_ld(ctx, OPC_LHU, rt, rs, u);
21395 gen_st(ctx, OPC_SB, rt, rs, u);
21398 gen_st(ctx, OPC_SH, rt, rs, u);
21401 gen_st(ctx, OPC_SW, rt, rs, u);
21404 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21407 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21410 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21413 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21416 generate_exception_end(ctx, EXCP_RI);
21423 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21424 extract32(ctx->opcode, 0, 8);
21426 switch (extract32(ctx->opcode, 8, 3)) {
21428 switch (extract32(ctx->opcode, 11, 4)) {
21430 gen_ld(ctx, OPC_LB, rt, rs, s);
21433 gen_ld(ctx, OPC_LH, rt, rs, s);
21436 gen_ld(ctx, OPC_LW, rt, rs, s);
21439 gen_ld(ctx, OPC_LBU, rt, rs, s);
21442 gen_ld(ctx, OPC_LHU, rt, rs, s);
21445 gen_st(ctx, OPC_SB, rt, rs, s);
21448 gen_st(ctx, OPC_SH, rt, rs, s);
21451 gen_st(ctx, OPC_SW, rt, rs, s);
21454 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21457 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21460 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21463 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21468 /* Break the TB to be able to sync copied instructions
21470 ctx->base.is_jmp = DISAS_STOP;
21473 /* Treat as NOP. */
21477 generate_exception_end(ctx, EXCP_RI);
21482 switch (extract32(ctx->opcode, 11, 4)) {
21487 TCGv t0 = tcg_temp_new();
21488 TCGv t1 = tcg_temp_new();
21490 gen_base_offset_addr(ctx, t0, rs, s);
21492 switch (extract32(ctx->opcode, 11, 4)) {
21494 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21496 gen_store_gpr(t0, rt);
21499 gen_load_gpr(t1, rt);
21500 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21509 switch (ctx->opcode & 0x03) {
21511 gen_ld(ctx, OPC_LL, rt, rs, s);
21515 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21520 switch (ctx->opcode & 0x03) {
21522 gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
21526 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21532 check_cp0_enabled(ctx);
21533 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21534 gen_cache_operation(ctx, rt, rs, s);
21540 switch (extract32(ctx->opcode, 11, 4)) {
21543 check_cp0_enabled(ctx);
21544 gen_ld(ctx, OPC_LBE, rt, rs, s);
21548 check_cp0_enabled(ctx);
21549 gen_st(ctx, OPC_SBE, rt, rs, s);
21553 check_cp0_enabled(ctx);
21554 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21558 /* case NM_SYNCIE */
21560 check_cp0_enabled(ctx);
21561 /* Break the TB to be able to sync copied instructions
21563 ctx->base.is_jmp = DISAS_STOP;
21565 /* case NM_PREFE */
21567 check_cp0_enabled(ctx);
21568 /* Treat as NOP. */
21573 check_cp0_enabled(ctx);
21574 gen_ld(ctx, OPC_LHE, rt, rs, s);
21578 check_cp0_enabled(ctx);
21579 gen_st(ctx, OPC_SHE, rt, rs, s);
21583 check_cp0_enabled(ctx);
21584 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21587 check_nms_dl_il_sl_tl_l2c(ctx);
21588 gen_cache_operation(ctx, rt, rs, s);
21592 check_cp0_enabled(ctx);
21593 gen_ld(ctx, OPC_LWE, rt, rs, s);
21597 check_cp0_enabled(ctx);
21598 gen_st(ctx, OPC_SWE, rt, rs, s);
21601 switch (extract32(ctx->opcode, 2, 2)) {
21605 check_cp0_enabled(ctx);
21606 gen_ld(ctx, OPC_LLE, rt, rs, s);
21611 check_cp0_enabled(ctx);
21612 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21615 generate_exception_end(ctx, EXCP_RI);
21620 switch (extract32(ctx->opcode, 2, 2)) {
21624 check_cp0_enabled(ctx);
21625 gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
21630 check_cp0_enabled(ctx);
21631 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21635 generate_exception_end(ctx, EXCP_RI);
21645 int count = extract32(ctx->opcode, 12, 3);
21648 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21649 extract32(ctx->opcode, 0, 8);
21650 TCGv va = tcg_temp_new();
21651 TCGv t1 = tcg_temp_new();
21652 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21653 NM_P_LS_UAWM ? MO_UNALN : 0;
21655 count = (count == 0) ? 8 : count;
21656 while (counter != count) {
21657 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21658 int this_offset = offset + (counter << 2);
21660 gen_base_offset_addr(ctx, va, rs, this_offset);
21662 switch (extract32(ctx->opcode, 11, 1)) {
21664 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21666 gen_store_gpr(t1, this_rt);
21667 if ((this_rt == rs) &&
21668 (counter != (count - 1))) {
21669 /* UNPREDICTABLE */
21673 this_rt = (rt == 0) ? 0 : this_rt;
21674 gen_load_gpr(t1, this_rt);
21675 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21686 generate_exception_end(ctx, EXCP_RI);
21694 TCGv t0 = tcg_temp_new();
21695 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21696 extract32(ctx->opcode, 1, 20) << 1;
21697 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21698 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21699 extract32(ctx->opcode, 21, 3));
21700 gen_load_gpr(t0, rt);
21701 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21702 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21708 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21709 extract32(ctx->opcode, 1, 24) << 1;
21711 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21713 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21716 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21721 switch (extract32(ctx->opcode, 12, 4)) {
21724 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21727 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21730 generate_exception_end(ctx, EXCP_RI);
21736 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21737 extract32(ctx->opcode, 1, 13) << 1;
21738 switch (extract32(ctx->opcode, 14, 2)) {
21741 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21744 s = sextract32(ctx->opcode, 0, 1) << 14 |
21745 extract32(ctx->opcode, 1, 13) << 1;
21746 check_cp1_enabled(ctx);
21747 switch (extract32(ctx->opcode, 16, 5)) {
21749 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21752 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21757 int32_t imm = extract32(ctx->opcode, 1, 13) |
21758 extract32(ctx->opcode, 0, 1) << 13;
21760 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21765 generate_exception_end(ctx, EXCP_RI);
21771 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21773 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21777 if (rs == rt || rt == 0) {
21778 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21779 } else if (rs == 0) {
21780 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21782 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21790 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21791 extract32(ctx->opcode, 1, 13) << 1;
21792 switch (extract32(ctx->opcode, 14, 2)) {
21795 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21798 if (rs != 0 && rt != 0 && rs == rt) {
21800 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21802 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21806 if (rs == 0 || rs == rt) {
21808 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21810 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21814 generate_exception_end(ctx, EXCP_RI);
21821 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21822 extract32(ctx->opcode, 1, 10) << 1;
21823 uint32_t u = extract32(ctx->opcode, 11, 7);
21825 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21830 generate_exception_end(ctx, EXCP_RI);
21836 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21839 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
21840 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
21841 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
21845 /* make sure instructions are on a halfword boundary */
21846 if (ctx->base.pc_next & 0x1) {
21847 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21848 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21849 tcg_temp_free(tmp);
21850 generate_exception_end(ctx, EXCP_AdEL);
21854 op = extract32(ctx->opcode, 10, 6);
21857 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21860 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21861 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21864 switch (extract32(ctx->opcode, 3, 2)) {
21865 case NM_P16_SYSCALL:
21866 if (extract32(ctx->opcode, 2, 1) == 0) {
21867 generate_exception_end(ctx, EXCP_SYSCALL);
21869 generate_exception_end(ctx, EXCP_RI);
21873 generate_exception_end(ctx, EXCP_BREAK);
21876 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21877 gen_helper_do_semihosting(cpu_env);
21879 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21880 generate_exception_end(ctx, EXCP_RI);
21882 generate_exception_end(ctx, EXCP_DBp);
21887 generate_exception_end(ctx, EXCP_RI);
21894 int shift = extract32(ctx->opcode, 0, 3);
21896 shift = (shift == 0) ? 8 : shift;
21898 switch (extract32(ctx->opcode, 3, 1)) {
21906 gen_shift_imm(ctx, opc, rt, rs, shift);
21910 switch (ctx->opcode & 1) {
21912 gen_pool16c_nanomips_insn(ctx);
21915 gen_ldxs(ctx, rt, rs, rd);
21920 switch (extract32(ctx->opcode, 6, 1)) {
21922 imm = extract32(ctx->opcode, 0, 6) << 2;
21923 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21926 generate_exception_end(ctx, EXCP_RI);
21931 switch (extract32(ctx->opcode, 3, 1)) {
21933 imm = extract32(ctx->opcode, 0, 3) << 2;
21934 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21936 case NM_P_ADDIURS5:
21937 rt = extract32(ctx->opcode, 5, 5);
21939 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21940 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21941 (extract32(ctx->opcode, 0, 3));
21942 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21948 switch (ctx->opcode & 0x1) {
21950 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21953 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21958 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21959 extract32(ctx->opcode, 5, 3);
21960 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21961 extract32(ctx->opcode, 0, 3);
21962 rt = decode_gpr_gpr4(rt);
21963 rs = decode_gpr_gpr4(rs);
21964 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21965 (extract32(ctx->opcode, 3, 1))) {
21968 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21972 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21975 generate_exception_end(ctx, EXCP_RI);
21981 int imm = extract32(ctx->opcode, 0, 7);
21982 imm = (imm == 0x7f ? -1 : imm);
21984 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21990 uint32_t u = extract32(ctx->opcode, 0, 4);
21991 u = (u == 12) ? 0xff :
21992 (u == 13) ? 0xffff : u;
21993 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21997 offset = extract32(ctx->opcode, 0, 2);
21998 switch (extract32(ctx->opcode, 2, 2)) {
22000 gen_ld(ctx, OPC_LB, rt, rs, offset);
22003 rt = decode_gpr_gpr3_src_store(
22004 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22005 gen_st(ctx, OPC_SB, rt, rs, offset);
22008 gen_ld(ctx, OPC_LBU, rt, rs, offset);
22011 generate_exception_end(ctx, EXCP_RI);
22016 offset = extract32(ctx->opcode, 1, 2) << 1;
22017 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22019 gen_ld(ctx, OPC_LH, rt, rs, offset);
22022 rt = decode_gpr_gpr3_src_store(
22023 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22024 gen_st(ctx, OPC_SH, rt, rs, offset);
22027 gen_ld(ctx, OPC_LHU, rt, rs, offset);
22030 generate_exception_end(ctx, EXCP_RI);
22035 offset = extract32(ctx->opcode, 0, 4) << 2;
22036 gen_ld(ctx, OPC_LW, rt, rs, offset);
22039 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22040 offset = extract32(ctx->opcode, 0, 5) << 2;
22041 gen_ld(ctx, OPC_LW, rt, 29, offset);
22045 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22046 extract32(ctx->opcode, 5, 3);
22047 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22048 extract32(ctx->opcode, 0, 3);
22049 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22050 (extract32(ctx->opcode, 8, 1) << 2);
22051 rt = decode_gpr_gpr4(rt);
22052 rs = decode_gpr_gpr4(rs);
22053 gen_ld(ctx, OPC_LW, rt, rs, offset);
22057 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22058 extract32(ctx->opcode, 5, 3);
22059 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22060 extract32(ctx->opcode, 0, 3);
22061 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22062 (extract32(ctx->opcode, 8, 1) << 2);
22063 rt = decode_gpr_gpr4_zero(rt);
22064 rs = decode_gpr_gpr4(rs);
22065 gen_st(ctx, OPC_SW, rt, rs, offset);
22068 offset = extract32(ctx->opcode, 0, 7) << 2;
22069 gen_ld(ctx, OPC_LW, rt, 28, offset);
22072 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22073 offset = extract32(ctx->opcode, 0, 5) << 2;
22074 gen_st(ctx, OPC_SW, rt, 29, offset);
22077 rt = decode_gpr_gpr3_src_store(
22078 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22079 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22080 offset = extract32(ctx->opcode, 0, 4) << 2;
22081 gen_st(ctx, OPC_SW, rt, rs, offset);
22084 rt = decode_gpr_gpr3_src_store(
22085 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22086 offset = extract32(ctx->opcode, 0, 7) << 2;
22087 gen_st(ctx, OPC_SW, rt, 28, offset);
22090 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22091 (sextract32(ctx->opcode, 0, 1) << 10) |
22092 (extract32(ctx->opcode, 1, 9) << 1));
22095 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22096 (sextract32(ctx->opcode, 0, 1) << 10) |
22097 (extract32(ctx->opcode, 1, 9) << 1));
22100 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22101 (sextract32(ctx->opcode, 0, 1) << 7) |
22102 (extract32(ctx->opcode, 1, 6) << 1));
22105 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22106 (sextract32(ctx->opcode, 0, 1) << 7) |
22107 (extract32(ctx->opcode, 1, 6) << 1));
22110 switch (ctx->opcode & 0xf) {
22113 switch (extract32(ctx->opcode, 4, 1)) {
22115 gen_compute_branch_nm(ctx, OPC_JR, 2,
22116 extract32(ctx->opcode, 5, 5), 0, 0);
22119 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22120 extract32(ctx->opcode, 5, 5), 31, 0);
22127 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22128 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22129 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22130 extract32(ctx->opcode, 0, 4) << 1);
22137 int count = extract32(ctx->opcode, 0, 4);
22138 int u = extract32(ctx->opcode, 4, 4) << 4;
22140 rt = 30 + extract32(ctx->opcode, 9, 1);
22141 switch (extract32(ctx->opcode, 8, 1)) {
22143 gen_save(ctx, rt, count, 0, u);
22145 case NM_RESTORE_JRC16:
22146 gen_restore(ctx, rt, count, 0, u);
22147 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22156 static const int gpr2reg1[] = {4, 5, 6, 7};
22157 static const int gpr2reg2[] = {5, 6, 7, 8};
22159 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22160 extract32(ctx->opcode, 8, 1);
22161 int r1 = gpr2reg1[rd2];
22162 int r2 = gpr2reg2[rd2];
22163 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22164 extract32(ctx->opcode, 0, 3);
22165 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22166 extract32(ctx->opcode, 5, 3);
22167 TCGv t0 = tcg_temp_new();
22168 TCGv t1 = tcg_temp_new();
22169 if (op == NM_MOVEP) {
22172 rs = decode_gpr_gpr4_zero(r3);
22173 rt = decode_gpr_gpr4_zero(r4);
22175 rd = decode_gpr_gpr4(r3);
22176 re = decode_gpr_gpr4(r4);
22180 gen_load_gpr(t0, rs);
22181 gen_load_gpr(t1, rt);
22182 tcg_gen_mov_tl(cpu_gpr[rd], t0);
22183 tcg_gen_mov_tl(cpu_gpr[re], t1);
22189 return decode_nanomips_32_48_opc(env, ctx);
22196 /* SmartMIPS extension to MIPS32 */
22198 #if defined(TARGET_MIPS64)
22200 /* MDMX extension to MIPS64 */
22204 /* MIPSDSP functions. */
22205 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22206 int rd, int base, int offset)
22211 t0 = tcg_temp_new();
22214 gen_load_gpr(t0, offset);
22215 } else if (offset == 0) {
22216 gen_load_gpr(t0, base);
22218 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22223 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22224 gen_store_gpr(t0, rd);
22227 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22228 gen_store_gpr(t0, rd);
22231 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22232 gen_store_gpr(t0, rd);
22234 #if defined(TARGET_MIPS64)
22236 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22237 gen_store_gpr(t0, rd);
22244 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22245 int ret, int v1, int v2)
22251 /* Treat as NOP. */
22255 v1_t = tcg_temp_new();
22256 v2_t = tcg_temp_new();
22258 gen_load_gpr(v1_t, v1);
22259 gen_load_gpr(v2_t, v2);
22262 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22263 case OPC_MULT_G_2E:
22267 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22269 case OPC_ADDUH_R_QB:
22270 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22273 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22275 case OPC_ADDQH_R_PH:
22276 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22279 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22281 case OPC_ADDQH_R_W:
22282 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22285 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22287 case OPC_SUBUH_R_QB:
22288 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22291 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22293 case OPC_SUBQH_R_PH:
22294 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22297 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22299 case OPC_SUBQH_R_W:
22300 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22304 case OPC_ABSQ_S_PH_DSP:
22306 case OPC_ABSQ_S_QB:
22308 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22310 case OPC_ABSQ_S_PH:
22312 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22316 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22318 case OPC_PRECEQ_W_PHL:
22320 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22321 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22323 case OPC_PRECEQ_W_PHR:
22325 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22326 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22327 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22329 case OPC_PRECEQU_PH_QBL:
22331 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22333 case OPC_PRECEQU_PH_QBR:
22335 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22337 case OPC_PRECEQU_PH_QBLA:
22339 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22341 case OPC_PRECEQU_PH_QBRA:
22343 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22345 case OPC_PRECEU_PH_QBL:
22347 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22349 case OPC_PRECEU_PH_QBR:
22351 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22353 case OPC_PRECEU_PH_QBLA:
22355 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22357 case OPC_PRECEU_PH_QBRA:
22359 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22363 case OPC_ADDU_QB_DSP:
22367 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22369 case OPC_ADDQ_S_PH:
22371 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22375 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22379 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22381 case OPC_ADDU_S_QB:
22383 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22387 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22389 case OPC_ADDU_S_PH:
22391 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22395 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22397 case OPC_SUBQ_S_PH:
22399 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22403 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22407 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22409 case OPC_SUBU_S_QB:
22411 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22415 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22417 case OPC_SUBU_S_PH:
22419 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22423 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22427 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22431 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22433 case OPC_RADDU_W_QB:
22435 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22439 case OPC_CMPU_EQ_QB_DSP:
22441 case OPC_PRECR_QB_PH:
22443 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22445 case OPC_PRECRQ_QB_PH:
22447 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22449 case OPC_PRECR_SRA_PH_W:
22452 TCGv_i32 sa_t = tcg_const_i32(v2);
22453 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22455 tcg_temp_free_i32(sa_t);
22458 case OPC_PRECR_SRA_R_PH_W:
22461 TCGv_i32 sa_t = tcg_const_i32(v2);
22462 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22464 tcg_temp_free_i32(sa_t);
22467 case OPC_PRECRQ_PH_W:
22469 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22471 case OPC_PRECRQ_RS_PH_W:
22473 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22475 case OPC_PRECRQU_S_QB_PH:
22477 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22481 #ifdef TARGET_MIPS64
22482 case OPC_ABSQ_S_QH_DSP:
22484 case OPC_PRECEQ_L_PWL:
22486 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22488 case OPC_PRECEQ_L_PWR:
22490 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22492 case OPC_PRECEQ_PW_QHL:
22494 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22496 case OPC_PRECEQ_PW_QHR:
22498 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22500 case OPC_PRECEQ_PW_QHLA:
22502 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22504 case OPC_PRECEQ_PW_QHRA:
22506 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22508 case OPC_PRECEQU_QH_OBL:
22510 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22512 case OPC_PRECEQU_QH_OBR:
22514 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22516 case OPC_PRECEQU_QH_OBLA:
22518 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22520 case OPC_PRECEQU_QH_OBRA:
22522 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22524 case OPC_PRECEU_QH_OBL:
22526 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22528 case OPC_PRECEU_QH_OBR:
22530 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22532 case OPC_PRECEU_QH_OBLA:
22534 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22536 case OPC_PRECEU_QH_OBRA:
22538 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22540 case OPC_ABSQ_S_OB:
22542 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22544 case OPC_ABSQ_S_PW:
22546 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22548 case OPC_ABSQ_S_QH:
22550 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22554 case OPC_ADDU_OB_DSP:
22556 case OPC_RADDU_L_OB:
22558 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22562 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22564 case OPC_SUBQ_S_PW:
22566 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22570 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22572 case OPC_SUBQ_S_QH:
22574 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22578 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22580 case OPC_SUBU_S_OB:
22582 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22586 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22588 case OPC_SUBU_S_QH:
22590 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22594 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22596 case OPC_SUBUH_R_OB:
22598 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22602 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22604 case OPC_ADDQ_S_PW:
22606 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22610 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22612 case OPC_ADDQ_S_QH:
22614 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22618 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22620 case OPC_ADDU_S_OB:
22622 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22626 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22628 case OPC_ADDU_S_QH:
22630 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22634 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22636 case OPC_ADDUH_R_OB:
22638 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22642 case OPC_CMPU_EQ_OB_DSP:
22644 case OPC_PRECR_OB_QH:
22646 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22648 case OPC_PRECR_SRA_QH_PW:
22651 TCGv_i32 ret_t = tcg_const_i32(ret);
22652 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22653 tcg_temp_free_i32(ret_t);
22656 case OPC_PRECR_SRA_R_QH_PW:
22659 TCGv_i32 sa_v = tcg_const_i32(ret);
22660 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22661 tcg_temp_free_i32(sa_v);
22664 case OPC_PRECRQ_OB_QH:
22666 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22668 case OPC_PRECRQ_PW_L:
22670 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22672 case OPC_PRECRQ_QH_PW:
22674 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22676 case OPC_PRECRQ_RS_QH_PW:
22678 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22680 case OPC_PRECRQU_S_OB_QH:
22682 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22689 tcg_temp_free(v1_t);
22690 tcg_temp_free(v2_t);
22693 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22694 int ret, int v1, int v2)
22702 /* Treat as NOP. */
22706 t0 = tcg_temp_new();
22707 v1_t = tcg_temp_new();
22708 v2_t = tcg_temp_new();
22710 tcg_gen_movi_tl(t0, v1);
22711 gen_load_gpr(v1_t, v1);
22712 gen_load_gpr(v2_t, v2);
22715 case OPC_SHLL_QB_DSP:
22717 op2 = MASK_SHLL_QB(ctx->opcode);
22721 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22725 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22729 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22733 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22735 case OPC_SHLL_S_PH:
22737 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22739 case OPC_SHLLV_S_PH:
22741 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22745 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22747 case OPC_SHLLV_S_W:
22749 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22753 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22757 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22761 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22765 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22769 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22771 case OPC_SHRA_R_QB:
22773 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22777 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22779 case OPC_SHRAV_R_QB:
22781 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22785 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22787 case OPC_SHRA_R_PH:
22789 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22793 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22795 case OPC_SHRAV_R_PH:
22797 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22801 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22803 case OPC_SHRAV_R_W:
22805 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22807 default: /* Invalid */
22808 MIPS_INVAL("MASK SHLL.QB");
22809 generate_exception_end(ctx, EXCP_RI);
22814 #ifdef TARGET_MIPS64
22815 case OPC_SHLL_OB_DSP:
22816 op2 = MASK_SHLL_OB(ctx->opcode);
22820 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22824 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22826 case OPC_SHLL_S_PW:
22828 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22830 case OPC_SHLLV_S_PW:
22832 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22836 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22840 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22844 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22848 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22850 case OPC_SHLL_S_QH:
22852 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22854 case OPC_SHLLV_S_QH:
22856 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22860 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22864 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22866 case OPC_SHRA_R_OB:
22868 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22870 case OPC_SHRAV_R_OB:
22872 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22876 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22880 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22882 case OPC_SHRA_R_PW:
22884 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22886 case OPC_SHRAV_R_PW:
22888 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22892 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22896 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22898 case OPC_SHRA_R_QH:
22900 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22902 case OPC_SHRAV_R_QH:
22904 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22908 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22912 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22916 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22920 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22922 default: /* Invalid */
22923 MIPS_INVAL("MASK SHLL.OB");
22924 generate_exception_end(ctx, EXCP_RI);
22932 tcg_temp_free(v1_t);
22933 tcg_temp_free(v2_t);
22936 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22937 int ret, int v1, int v2, int check_ret)
22943 if ((ret == 0) && (check_ret == 1)) {
22944 /* Treat as NOP. */
22948 t0 = tcg_temp_new_i32();
22949 v1_t = tcg_temp_new();
22950 v2_t = tcg_temp_new();
22952 tcg_gen_movi_i32(t0, ret);
22953 gen_load_gpr(v1_t, v1);
22954 gen_load_gpr(v2_t, v2);
22957 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22958 * the same mask and op1. */
22959 case OPC_MULT_G_2E:
22963 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22966 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22969 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22971 case OPC_MULQ_RS_W:
22972 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22976 case OPC_DPA_W_PH_DSP:
22978 case OPC_DPAU_H_QBL:
22980 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22982 case OPC_DPAU_H_QBR:
22984 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22986 case OPC_DPSU_H_QBL:
22988 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22990 case OPC_DPSU_H_QBR:
22992 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22996 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22998 case OPC_DPAX_W_PH:
23000 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23002 case OPC_DPAQ_S_W_PH:
23004 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23006 case OPC_DPAQX_S_W_PH:
23008 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23010 case OPC_DPAQX_SA_W_PH:
23012 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23016 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23018 case OPC_DPSX_W_PH:
23020 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23022 case OPC_DPSQ_S_W_PH:
23024 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23026 case OPC_DPSQX_S_W_PH:
23028 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23030 case OPC_DPSQX_SA_W_PH:
23032 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23034 case OPC_MULSAQ_S_W_PH:
23036 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23038 case OPC_DPAQ_SA_L_W:
23040 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23042 case OPC_DPSQ_SA_L_W:
23044 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23046 case OPC_MAQ_S_W_PHL:
23048 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23050 case OPC_MAQ_S_W_PHR:
23052 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23054 case OPC_MAQ_SA_W_PHL:
23056 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23058 case OPC_MAQ_SA_W_PHR:
23060 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23062 case OPC_MULSA_W_PH:
23064 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23068 #ifdef TARGET_MIPS64
23069 case OPC_DPAQ_W_QH_DSP:
23071 int ac = ret & 0x03;
23072 tcg_gen_movi_i32(t0, ac);
23077 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23081 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23085 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23089 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23093 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23095 case OPC_DPAQ_S_W_QH:
23097 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23099 case OPC_DPAQ_SA_L_PW:
23101 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23103 case OPC_DPAU_H_OBL:
23105 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23107 case OPC_DPAU_H_OBR:
23109 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23113 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23115 case OPC_DPSQ_S_W_QH:
23117 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23119 case OPC_DPSQ_SA_L_PW:
23121 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23123 case OPC_DPSU_H_OBL:
23125 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23127 case OPC_DPSU_H_OBR:
23129 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23131 case OPC_MAQ_S_L_PWL:
23133 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23135 case OPC_MAQ_S_L_PWR:
23137 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23139 case OPC_MAQ_S_W_QHLL:
23141 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23143 case OPC_MAQ_SA_W_QHLL:
23145 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23147 case OPC_MAQ_S_W_QHLR:
23149 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23151 case OPC_MAQ_SA_W_QHLR:
23153 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23155 case OPC_MAQ_S_W_QHRL:
23157 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23159 case OPC_MAQ_SA_W_QHRL:
23161 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23163 case OPC_MAQ_S_W_QHRR:
23165 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23167 case OPC_MAQ_SA_W_QHRR:
23169 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23171 case OPC_MULSAQ_S_L_PW:
23173 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23175 case OPC_MULSAQ_S_W_QH:
23177 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23183 case OPC_ADDU_QB_DSP:
23185 case OPC_MULEU_S_PH_QBL:
23187 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23189 case OPC_MULEU_S_PH_QBR:
23191 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23193 case OPC_MULQ_RS_PH:
23195 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23197 case OPC_MULEQ_S_W_PHL:
23199 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23201 case OPC_MULEQ_S_W_PHR:
23203 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23205 case OPC_MULQ_S_PH:
23207 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23211 #ifdef TARGET_MIPS64
23212 case OPC_ADDU_OB_DSP:
23214 case OPC_MULEQ_S_PW_QHL:
23216 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23218 case OPC_MULEQ_S_PW_QHR:
23220 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23222 case OPC_MULEU_S_QH_OBL:
23224 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23226 case OPC_MULEU_S_QH_OBR:
23228 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23230 case OPC_MULQ_RS_QH:
23232 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23239 tcg_temp_free_i32(t0);
23240 tcg_temp_free(v1_t);
23241 tcg_temp_free(v2_t);
23244 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23252 /* Treat as NOP. */
23256 t0 = tcg_temp_new();
23257 val_t = tcg_temp_new();
23258 gen_load_gpr(val_t, val);
23261 case OPC_ABSQ_S_PH_DSP:
23265 gen_helper_bitrev(cpu_gpr[ret], val_t);
23270 target_long result;
23271 imm = (ctx->opcode >> 16) & 0xFF;
23272 result = (uint32_t)imm << 24 |
23273 (uint32_t)imm << 16 |
23274 (uint32_t)imm << 8 |
23276 result = (int32_t)result;
23277 tcg_gen_movi_tl(cpu_gpr[ret], result);
23282 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23283 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23284 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23285 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23286 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23287 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23292 imm = (ctx->opcode >> 16) & 0x03FF;
23293 imm = (int16_t)(imm << 6) >> 6;
23294 tcg_gen_movi_tl(cpu_gpr[ret], \
23295 (target_long)((int32_t)imm << 16 | \
23301 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23302 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23303 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23304 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23308 #ifdef TARGET_MIPS64
23309 case OPC_ABSQ_S_QH_DSP:
23316 imm = (ctx->opcode >> 16) & 0xFF;
23317 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23318 temp = (temp << 16) | temp;
23319 temp = (temp << 32) | temp;
23320 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23328 imm = (ctx->opcode >> 16) & 0x03FF;
23329 imm = (int16_t)(imm << 6) >> 6;
23330 temp = ((target_long)imm << 32) \
23331 | ((target_long)imm & 0xFFFFFFFF);
23332 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23340 imm = (ctx->opcode >> 16) & 0x03FF;
23341 imm = (int16_t)(imm << 6) >> 6;
23343 temp = ((uint64_t)(uint16_t)imm << 48) |
23344 ((uint64_t)(uint16_t)imm << 32) |
23345 ((uint64_t)(uint16_t)imm << 16) |
23346 (uint64_t)(uint16_t)imm;
23347 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23352 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23353 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23354 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23355 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23356 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23357 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23358 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23362 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23363 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23364 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23368 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23369 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23370 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23371 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23372 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23379 tcg_temp_free(val_t);
23382 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23383 uint32_t op1, uint32_t op2,
23384 int ret, int v1, int v2, int check_ret)
23390 if ((ret == 0) && (check_ret == 1)) {
23391 /* Treat as NOP. */
23395 t1 = tcg_temp_new();
23396 v1_t = tcg_temp_new();
23397 v2_t = tcg_temp_new();
23399 gen_load_gpr(v1_t, v1);
23400 gen_load_gpr(v2_t, v2);
23403 case OPC_CMPU_EQ_QB_DSP:
23405 case OPC_CMPU_EQ_QB:
23407 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23409 case OPC_CMPU_LT_QB:
23411 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23413 case OPC_CMPU_LE_QB:
23415 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23417 case OPC_CMPGU_EQ_QB:
23419 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23421 case OPC_CMPGU_LT_QB:
23423 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23425 case OPC_CMPGU_LE_QB:
23427 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23429 case OPC_CMPGDU_EQ_QB:
23431 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23432 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23433 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23434 tcg_gen_shli_tl(t1, t1, 24);
23435 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23437 case OPC_CMPGDU_LT_QB:
23439 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23440 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23441 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23442 tcg_gen_shli_tl(t1, t1, 24);
23443 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23445 case OPC_CMPGDU_LE_QB:
23447 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23448 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23449 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23450 tcg_gen_shli_tl(t1, t1, 24);
23451 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23453 case OPC_CMP_EQ_PH:
23455 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23457 case OPC_CMP_LT_PH:
23459 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23461 case OPC_CMP_LE_PH:
23463 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23467 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23471 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23473 case OPC_PACKRL_PH:
23475 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23479 #ifdef TARGET_MIPS64
23480 case OPC_CMPU_EQ_OB_DSP:
23482 case OPC_CMP_EQ_PW:
23484 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23486 case OPC_CMP_LT_PW:
23488 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23490 case OPC_CMP_LE_PW:
23492 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23494 case OPC_CMP_EQ_QH:
23496 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23498 case OPC_CMP_LT_QH:
23500 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23502 case OPC_CMP_LE_QH:
23504 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23506 case OPC_CMPGDU_EQ_OB:
23508 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23510 case OPC_CMPGDU_LT_OB:
23512 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23514 case OPC_CMPGDU_LE_OB:
23516 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23518 case OPC_CMPGU_EQ_OB:
23520 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23522 case OPC_CMPGU_LT_OB:
23524 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23526 case OPC_CMPGU_LE_OB:
23528 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23530 case OPC_CMPU_EQ_OB:
23532 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23534 case OPC_CMPU_LT_OB:
23536 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23538 case OPC_CMPU_LE_OB:
23540 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23542 case OPC_PACKRL_PW:
23544 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23548 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23552 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23556 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23564 tcg_temp_free(v1_t);
23565 tcg_temp_free(v2_t);
23568 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23569 uint32_t op1, int rt, int rs, int sa)
23576 /* Treat as NOP. */
23580 t0 = tcg_temp_new();
23581 gen_load_gpr(t0, rs);
23584 case OPC_APPEND_DSP:
23585 switch (MASK_APPEND(ctx->opcode)) {
23588 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23590 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23594 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23595 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23596 tcg_gen_shli_tl(t0, t0, 32 - sa);
23597 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23599 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23603 if (sa != 0 && sa != 2) {
23604 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23605 tcg_gen_ext32u_tl(t0, t0);
23606 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23607 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23609 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23611 default: /* Invalid */
23612 MIPS_INVAL("MASK APPEND");
23613 generate_exception_end(ctx, EXCP_RI);
23617 #ifdef TARGET_MIPS64
23618 case OPC_DAPPEND_DSP:
23619 switch (MASK_DAPPEND(ctx->opcode)) {
23622 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23626 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23627 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23628 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23632 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23633 tcg_gen_shli_tl(t0, t0, 64 - sa);
23634 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23639 if (sa != 0 && sa != 2 && sa != 4) {
23640 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23641 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23642 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23645 default: /* Invalid */
23646 MIPS_INVAL("MASK DAPPEND");
23647 generate_exception_end(ctx, EXCP_RI);
23656 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23657 int ret, int v1, int v2, int check_ret)
23666 if ((ret == 0) && (check_ret == 1)) {
23667 /* Treat as NOP. */
23671 t0 = tcg_temp_new();
23672 t1 = tcg_temp_new();
23673 v1_t = tcg_temp_new();
23674 v2_t = tcg_temp_new();
23676 gen_load_gpr(v1_t, v1);
23677 gen_load_gpr(v2_t, v2);
23680 case OPC_EXTR_W_DSP:
23684 tcg_gen_movi_tl(t0, v2);
23685 tcg_gen_movi_tl(t1, v1);
23686 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23689 tcg_gen_movi_tl(t0, v2);
23690 tcg_gen_movi_tl(t1, v1);
23691 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23693 case OPC_EXTR_RS_W:
23694 tcg_gen_movi_tl(t0, v2);
23695 tcg_gen_movi_tl(t1, v1);
23696 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23699 tcg_gen_movi_tl(t0, v2);
23700 tcg_gen_movi_tl(t1, v1);
23701 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23703 case OPC_EXTRV_S_H:
23704 tcg_gen_movi_tl(t0, v2);
23705 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23708 tcg_gen_movi_tl(t0, v2);
23709 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23711 case OPC_EXTRV_R_W:
23712 tcg_gen_movi_tl(t0, v2);
23713 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23715 case OPC_EXTRV_RS_W:
23716 tcg_gen_movi_tl(t0, v2);
23717 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23720 tcg_gen_movi_tl(t0, v2);
23721 tcg_gen_movi_tl(t1, v1);
23722 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23725 tcg_gen_movi_tl(t0, v2);
23726 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23729 tcg_gen_movi_tl(t0, v2);
23730 tcg_gen_movi_tl(t1, v1);
23731 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23734 tcg_gen_movi_tl(t0, v2);
23735 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23738 imm = (ctx->opcode >> 20) & 0x3F;
23739 tcg_gen_movi_tl(t0, ret);
23740 tcg_gen_movi_tl(t1, imm);
23741 gen_helper_shilo(t0, t1, cpu_env);
23744 tcg_gen_movi_tl(t0, ret);
23745 gen_helper_shilo(t0, v1_t, cpu_env);
23748 tcg_gen_movi_tl(t0, ret);
23749 gen_helper_mthlip(t0, v1_t, cpu_env);
23752 imm = (ctx->opcode >> 11) & 0x3FF;
23753 tcg_gen_movi_tl(t0, imm);
23754 gen_helper_wrdsp(v1_t, t0, cpu_env);
23757 imm = (ctx->opcode >> 16) & 0x03FF;
23758 tcg_gen_movi_tl(t0, imm);
23759 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23763 #ifdef TARGET_MIPS64
23764 case OPC_DEXTR_W_DSP:
23768 tcg_gen_movi_tl(t0, ret);
23769 gen_helper_dmthlip(v1_t, t0, cpu_env);
23773 int shift = (ctx->opcode >> 19) & 0x7F;
23774 int ac = (ctx->opcode >> 11) & 0x03;
23775 tcg_gen_movi_tl(t0, shift);
23776 tcg_gen_movi_tl(t1, ac);
23777 gen_helper_dshilo(t0, t1, cpu_env);
23782 int ac = (ctx->opcode >> 11) & 0x03;
23783 tcg_gen_movi_tl(t0, ac);
23784 gen_helper_dshilo(v1_t, t0, cpu_env);
23788 tcg_gen_movi_tl(t0, v2);
23789 tcg_gen_movi_tl(t1, v1);
23791 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23794 tcg_gen_movi_tl(t0, v2);
23795 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23798 tcg_gen_movi_tl(t0, v2);
23799 tcg_gen_movi_tl(t1, v1);
23800 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23803 tcg_gen_movi_tl(t0, v2);
23804 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23807 tcg_gen_movi_tl(t0, v2);
23808 tcg_gen_movi_tl(t1, v1);
23809 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23811 case OPC_DEXTR_R_L:
23812 tcg_gen_movi_tl(t0, v2);
23813 tcg_gen_movi_tl(t1, v1);
23814 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23816 case OPC_DEXTR_RS_L:
23817 tcg_gen_movi_tl(t0, v2);
23818 tcg_gen_movi_tl(t1, v1);
23819 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23822 tcg_gen_movi_tl(t0, v2);
23823 tcg_gen_movi_tl(t1, v1);
23824 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23826 case OPC_DEXTR_R_W:
23827 tcg_gen_movi_tl(t0, v2);
23828 tcg_gen_movi_tl(t1, v1);
23829 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23831 case OPC_DEXTR_RS_W:
23832 tcg_gen_movi_tl(t0, v2);
23833 tcg_gen_movi_tl(t1, v1);
23834 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23836 case OPC_DEXTR_S_H:
23837 tcg_gen_movi_tl(t0, v2);
23838 tcg_gen_movi_tl(t1, v1);
23839 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23841 case OPC_DEXTRV_S_H:
23842 tcg_gen_movi_tl(t0, v2);
23843 tcg_gen_movi_tl(t1, v1);
23844 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23847 tcg_gen_movi_tl(t0, v2);
23848 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23850 case OPC_DEXTRV_R_L:
23851 tcg_gen_movi_tl(t0, v2);
23852 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23854 case OPC_DEXTRV_RS_L:
23855 tcg_gen_movi_tl(t0, v2);
23856 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23859 tcg_gen_movi_tl(t0, v2);
23860 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23862 case OPC_DEXTRV_R_W:
23863 tcg_gen_movi_tl(t0, v2);
23864 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23866 case OPC_DEXTRV_RS_W:
23867 tcg_gen_movi_tl(t0, v2);
23868 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23877 tcg_temp_free(v1_t);
23878 tcg_temp_free(v2_t);
23881 /* End MIPSDSP functions. */
23883 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23885 int rs, rt, rd, sa;
23888 rs = (ctx->opcode >> 21) & 0x1f;
23889 rt = (ctx->opcode >> 16) & 0x1f;
23890 rd = (ctx->opcode >> 11) & 0x1f;
23891 sa = (ctx->opcode >> 6) & 0x1f;
23893 op1 = MASK_SPECIAL(ctx->opcode);
23896 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23902 op2 = MASK_R6_MULDIV(ctx->opcode);
23912 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23915 MIPS_INVAL("special_r6 muldiv");
23916 generate_exception_end(ctx, EXCP_RI);
23922 gen_cond_move(ctx, op1, rd, rs, rt);
23926 if (rt == 0 && sa == 1) {
23927 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23928 We need additionally to check other fields */
23929 gen_cl(ctx, op1, rd, rs);
23931 generate_exception_end(ctx, EXCP_RI);
23935 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23936 gen_helper_do_semihosting(cpu_env);
23938 if (ctx->hflags & MIPS_HFLAG_SBRI) {
23939 generate_exception_end(ctx, EXCP_RI);
23941 generate_exception_end(ctx, EXCP_DBp);
23945 #if defined(TARGET_MIPS64)
23947 check_mips_64(ctx);
23948 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23952 if (rt == 0 && sa == 1) {
23953 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23954 We need additionally to check other fields */
23955 check_mips_64(ctx);
23956 gen_cl(ctx, op1, rd, rs);
23958 generate_exception_end(ctx, EXCP_RI);
23966 op2 = MASK_R6_MULDIV(ctx->opcode);
23976 check_mips_64(ctx);
23977 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23980 MIPS_INVAL("special_r6 muldiv");
23981 generate_exception_end(ctx, EXCP_RI);
23986 default: /* Invalid */
23987 MIPS_INVAL("special_r6");
23988 generate_exception_end(ctx, EXCP_RI);
23993 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
23995 int rs = extract32(ctx->opcode, 21, 5);
23996 int rt = extract32(ctx->opcode, 16, 5);
23997 int rd = extract32(ctx->opcode, 11, 5);
23998 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24001 case OPC_MOVN: /* Conditional move */
24003 gen_cond_move(ctx, op1, rd, rs, rt);
24005 case OPC_MFHI: /* Move from HI/LO */
24007 gen_HILO(ctx, op1, 0, rd);
24010 case OPC_MTLO: /* Move to HI/LO */
24011 gen_HILO(ctx, op1, 0, rs);
24015 gen_mul_txx9(ctx, op1, rd, rs, rt);
24019 gen_muldiv(ctx, op1, 0, rs, rt);
24021 #if defined(TARGET_MIPS64)
24026 check_insn_opc_user_only(ctx, INSN_R5900);
24027 gen_muldiv(ctx, op1, 0, rs, rt);
24031 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24033 default: /* Invalid */
24034 MIPS_INVAL("special_tx79");
24035 generate_exception_end(ctx, EXCP_RI);
24040 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24042 int rs, rt, rd, sa;
24045 rs = (ctx->opcode >> 21) & 0x1f;
24046 rt = (ctx->opcode >> 16) & 0x1f;
24047 rd = (ctx->opcode >> 11) & 0x1f;
24048 sa = (ctx->opcode >> 6) & 0x1f;
24050 op1 = MASK_SPECIAL(ctx->opcode);
24052 case OPC_MOVN: /* Conditional move */
24054 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24055 INSN_LOONGSON2E | INSN_LOONGSON2F);
24056 gen_cond_move(ctx, op1, rd, rs, rt);
24058 case OPC_MFHI: /* Move from HI/LO */
24060 gen_HILO(ctx, op1, rs & 3, rd);
24063 case OPC_MTLO: /* Move to HI/LO */
24064 gen_HILO(ctx, op1, rd & 3, rs);
24067 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24068 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24069 check_cp1_enabled(ctx);
24070 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24071 (ctx->opcode >> 16) & 1);
24073 generate_exception_err(ctx, EXCP_CpU, 1);
24079 check_insn(ctx, INSN_VR54XX);
24080 op1 = MASK_MUL_VR54XX(ctx->opcode);
24081 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24083 gen_muldiv(ctx, op1, rd & 3, rs, rt);
24088 gen_muldiv(ctx, op1, 0, rs, rt);
24090 #if defined(TARGET_MIPS64)
24095 check_insn(ctx, ISA_MIPS3);
24096 check_mips_64(ctx);
24097 gen_muldiv(ctx, op1, 0, rs, rt);
24101 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24104 #ifdef MIPS_STRICT_STANDARD
24105 MIPS_INVAL("SPIM");
24106 generate_exception_end(ctx, EXCP_RI);
24108 /* Implemented as RI exception for now. */
24109 MIPS_INVAL("spim (unofficial)");
24110 generate_exception_end(ctx, EXCP_RI);
24113 default: /* Invalid */
24114 MIPS_INVAL("special_legacy");
24115 generate_exception_end(ctx, EXCP_RI);
24120 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24122 int rs, rt, rd, sa;
24125 rs = (ctx->opcode >> 21) & 0x1f;
24126 rt = (ctx->opcode >> 16) & 0x1f;
24127 rd = (ctx->opcode >> 11) & 0x1f;
24128 sa = (ctx->opcode >> 6) & 0x1f;
24130 op1 = MASK_SPECIAL(ctx->opcode);
24132 case OPC_SLL: /* Shift with immediate */
24133 if (sa == 5 && rd == 0 &&
24134 rs == 0 && rt == 0) { /* PAUSE */
24135 if ((ctx->insn_flags & ISA_MIPS32R6) &&
24136 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24137 generate_exception_end(ctx, EXCP_RI);
24143 gen_shift_imm(ctx, op1, rd, rt, sa);
24146 switch ((ctx->opcode >> 21) & 0x1f) {
24148 /* rotr is decoded as srl on non-R2 CPUs */
24149 if (ctx->insn_flags & ISA_MIPS32R2) {
24154 gen_shift_imm(ctx, op1, rd, rt, sa);
24157 generate_exception_end(ctx, EXCP_RI);
24165 gen_arith(ctx, op1, rd, rs, rt);
24167 case OPC_SLLV: /* Shifts */
24169 gen_shift(ctx, op1, rd, rs, rt);
24172 switch ((ctx->opcode >> 6) & 0x1f) {
24174 /* rotrv is decoded as srlv on non-R2 CPUs */
24175 if (ctx->insn_flags & ISA_MIPS32R2) {
24180 gen_shift(ctx, op1, rd, rs, rt);
24183 generate_exception_end(ctx, EXCP_RI);
24187 case OPC_SLT: /* Set on less than */
24189 gen_slt(ctx, op1, rd, rs, rt);
24191 case OPC_AND: /* Logic*/
24195 gen_logic(ctx, op1, rd, rs, rt);
24198 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24200 case OPC_TGE: /* Traps */
24206 check_insn(ctx, ISA_MIPS2);
24207 gen_trap(ctx, op1, rs, rt, -1);
24209 case OPC_LSA: /* OPC_PMON */
24210 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24211 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24212 decode_opc_special_r6(env, ctx);
24214 /* Pmon entry point, also R4010 selsl */
24215 #ifdef MIPS_STRICT_STANDARD
24216 MIPS_INVAL("PMON / selsl");
24217 generate_exception_end(ctx, EXCP_RI);
24219 gen_helper_0e0i(pmon, sa);
24224 generate_exception_end(ctx, EXCP_SYSCALL);
24227 generate_exception_end(ctx, EXCP_BREAK);
24230 check_insn(ctx, ISA_MIPS2);
24231 gen_sync(extract32(ctx->opcode, 6, 5));
24234 #if defined(TARGET_MIPS64)
24235 /* MIPS64 specific opcodes */
24240 check_insn(ctx, ISA_MIPS3);
24241 check_mips_64(ctx);
24242 gen_shift_imm(ctx, op1, rd, rt, sa);
24245 switch ((ctx->opcode >> 21) & 0x1f) {
24247 /* drotr is decoded as dsrl on non-R2 CPUs */
24248 if (ctx->insn_flags & ISA_MIPS32R2) {
24253 check_insn(ctx, ISA_MIPS3);
24254 check_mips_64(ctx);
24255 gen_shift_imm(ctx, op1, rd, rt, sa);
24258 generate_exception_end(ctx, EXCP_RI);
24263 switch ((ctx->opcode >> 21) & 0x1f) {
24265 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24266 if (ctx->insn_flags & ISA_MIPS32R2) {
24271 check_insn(ctx, ISA_MIPS3);
24272 check_mips_64(ctx);
24273 gen_shift_imm(ctx, op1, rd, rt, sa);
24276 generate_exception_end(ctx, EXCP_RI);
24284 check_insn(ctx, ISA_MIPS3);
24285 check_mips_64(ctx);
24286 gen_arith(ctx, op1, rd, rs, rt);
24290 check_insn(ctx, ISA_MIPS3);
24291 check_mips_64(ctx);
24292 gen_shift(ctx, op1, rd, rs, rt);
24295 switch ((ctx->opcode >> 6) & 0x1f) {
24297 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24298 if (ctx->insn_flags & ISA_MIPS32R2) {
24303 check_insn(ctx, ISA_MIPS3);
24304 check_mips_64(ctx);
24305 gen_shift(ctx, op1, rd, rs, rt);
24308 generate_exception_end(ctx, EXCP_RI);
24313 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24314 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24315 decode_opc_special_r6(env, ctx);
24320 if (ctx->insn_flags & ISA_MIPS32R6) {
24321 decode_opc_special_r6(env, ctx);
24322 } else if (ctx->insn_flags & INSN_R5900) {
24323 decode_opc_special_tx79(env, ctx);
24325 decode_opc_special_legacy(env, ctx);
24331 #if defined(TARGET_MIPS64)
24335 * MMI (MultiMedia Interface) ASE instructions
24336 * ===========================================
24340 * MMI instructions category: data communication
24341 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24343 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24344 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24345 * PCPYUD PEXEH PEXTLW PPACW
24354 #if !defined(TARGET_MIPS64)
24356 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24357 #define MXU_APTN1_A 0
24358 #define MXU_APTN1_S 1
24360 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24361 #define MXU_APTN2_AA 0
24362 #define MXU_APTN2_AS 1
24363 #define MXU_APTN2_SA 2
24364 #define MXU_APTN2_SS 3
24366 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24367 #define MXU_EPTN2_AA 0
24368 #define MXU_EPTN2_AS 1
24369 #define MXU_EPTN2_SA 2
24370 #define MXU_EPTN2_SS 3
24372 /* MXU operand getting pattern 'optn2' */
24373 #define MXU_OPTN2_PTN0 0
24374 #define MXU_OPTN2_PTN1 1
24375 #define MXU_OPTN2_PTN2 2
24376 #define MXU_OPTN2_PTN3 3
24377 /* alternative naming scheme for 'optn2' */
24378 #define MXU_OPTN2_WW 0
24379 #define MXU_OPTN2_LW 1
24380 #define MXU_OPTN2_HW 2
24381 #define MXU_OPTN2_XW 3
24383 /* MXU operand getting pattern 'optn3' */
24384 #define MXU_OPTN3_PTN0 0
24385 #define MXU_OPTN3_PTN1 1
24386 #define MXU_OPTN3_PTN2 2
24387 #define MXU_OPTN3_PTN3 3
24388 #define MXU_OPTN3_PTN4 4
24389 #define MXU_OPTN3_PTN5 5
24390 #define MXU_OPTN3_PTN6 6
24391 #define MXU_OPTN3_PTN7 7
24395 * S32I2M XRa, rb - Register move from GRF to XRF
24397 static void gen_mxu_s32i2m(DisasContext *ctx)
24402 t0 = tcg_temp_new();
24404 XRa = extract32(ctx->opcode, 6, 5);
24405 Rb = extract32(ctx->opcode, 16, 5);
24407 gen_load_gpr(t0, Rb);
24409 gen_store_mxu_gpr(t0, XRa);
24410 } else if (XRa == 16) {
24411 gen_store_mxu_cr(t0);
24418 * S32M2I XRa, rb - Register move from XRF to GRF
24420 static void gen_mxu_s32m2i(DisasContext *ctx)
24425 t0 = tcg_temp_new();
24427 XRa = extract32(ctx->opcode, 6, 5);
24428 Rb = extract32(ctx->opcode, 16, 5);
24431 gen_load_mxu_gpr(t0, XRa);
24432 } else if (XRa == 16) {
24433 gen_load_mxu_cr(t0);
24436 gen_store_gpr(t0, Rb);
24442 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24444 static void gen_mxu_s8ldd(DisasContext *ctx)
24447 uint32_t XRa, Rb, s8, optn3;
24449 t0 = tcg_temp_new();
24450 t1 = tcg_temp_new();
24452 XRa = extract32(ctx->opcode, 6, 4);
24453 s8 = extract32(ctx->opcode, 10, 8);
24454 optn3 = extract32(ctx->opcode, 18, 3);
24455 Rb = extract32(ctx->opcode, 21, 5);
24457 gen_load_gpr(t0, Rb);
24458 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24461 /* XRa[7:0] = tmp8 */
24462 case MXU_OPTN3_PTN0:
24463 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24464 gen_load_mxu_gpr(t0, XRa);
24465 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24467 /* XRa[15:8] = tmp8 */
24468 case MXU_OPTN3_PTN1:
24469 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24470 gen_load_mxu_gpr(t0, XRa);
24471 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24473 /* XRa[23:16] = tmp8 */
24474 case MXU_OPTN3_PTN2:
24475 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24476 gen_load_mxu_gpr(t0, XRa);
24477 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24479 /* XRa[31:24] = tmp8 */
24480 case MXU_OPTN3_PTN3:
24481 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24482 gen_load_mxu_gpr(t0, XRa);
24483 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24485 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24486 case MXU_OPTN3_PTN4:
24487 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24488 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24490 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24491 case MXU_OPTN3_PTN5:
24492 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24493 tcg_gen_shli_tl(t1, t1, 8);
24494 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24496 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24497 case MXU_OPTN3_PTN6:
24498 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24499 tcg_gen_mov_tl(t0, t1);
24500 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24501 tcg_gen_shli_tl(t1, t1, 16);
24502 tcg_gen_or_tl(t0, t0, t1);
24504 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24505 case MXU_OPTN3_PTN7:
24506 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24507 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24508 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24512 gen_store_mxu_gpr(t0, XRa);
24519 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24521 static void gen_mxu_d16mul(DisasContext *ctx)
24523 TCGv t0, t1, t2, t3;
24524 uint32_t XRa, XRb, XRc, XRd, optn2;
24526 t0 = tcg_temp_new();
24527 t1 = tcg_temp_new();
24528 t2 = tcg_temp_new();
24529 t3 = tcg_temp_new();
24531 XRa = extract32(ctx->opcode, 6, 4);
24532 XRb = extract32(ctx->opcode, 10, 4);
24533 XRc = extract32(ctx->opcode, 14, 4);
24534 XRd = extract32(ctx->opcode, 18, 4);
24535 optn2 = extract32(ctx->opcode, 22, 2);
24537 gen_load_mxu_gpr(t1, XRb);
24538 tcg_gen_sextract_tl(t0, t1, 0, 16);
24539 tcg_gen_sextract_tl(t1, t1, 16, 16);
24540 gen_load_mxu_gpr(t3, XRc);
24541 tcg_gen_sextract_tl(t2, t3, 0, 16);
24542 tcg_gen_sextract_tl(t3, t3, 16, 16);
24545 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24546 tcg_gen_mul_tl(t3, t1, t3);
24547 tcg_gen_mul_tl(t2, t0, t2);
24549 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24550 tcg_gen_mul_tl(t3, t0, t3);
24551 tcg_gen_mul_tl(t2, t0, t2);
24553 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24554 tcg_gen_mul_tl(t3, t1, t3);
24555 tcg_gen_mul_tl(t2, t1, t2);
24557 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24558 tcg_gen_mul_tl(t3, t0, t3);
24559 tcg_gen_mul_tl(t2, t1, t2);
24562 gen_store_mxu_gpr(t3, XRa);
24563 gen_store_mxu_gpr(t2, XRd);
24572 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24575 static void gen_mxu_d16mac(DisasContext *ctx)
24577 TCGv t0, t1, t2, t3;
24578 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24580 t0 = tcg_temp_new();
24581 t1 = tcg_temp_new();
24582 t2 = tcg_temp_new();
24583 t3 = tcg_temp_new();
24585 XRa = extract32(ctx->opcode, 6, 4);
24586 XRb = extract32(ctx->opcode, 10, 4);
24587 XRc = extract32(ctx->opcode, 14, 4);
24588 XRd = extract32(ctx->opcode, 18, 4);
24589 optn2 = extract32(ctx->opcode, 22, 2);
24590 aptn2 = extract32(ctx->opcode, 24, 2);
24592 gen_load_mxu_gpr(t1, XRb);
24593 tcg_gen_sextract_tl(t0, t1, 0, 16);
24594 tcg_gen_sextract_tl(t1, t1, 16, 16);
24596 gen_load_mxu_gpr(t3, XRc);
24597 tcg_gen_sextract_tl(t2, t3, 0, 16);
24598 tcg_gen_sextract_tl(t3, t3, 16, 16);
24601 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24602 tcg_gen_mul_tl(t3, t1, t3);
24603 tcg_gen_mul_tl(t2, t0, t2);
24605 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24606 tcg_gen_mul_tl(t3, t0, t3);
24607 tcg_gen_mul_tl(t2, t0, t2);
24609 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24610 tcg_gen_mul_tl(t3, t1, t3);
24611 tcg_gen_mul_tl(t2, t1, t2);
24613 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24614 tcg_gen_mul_tl(t3, t0, t3);
24615 tcg_gen_mul_tl(t2, t1, t2);
24618 gen_load_mxu_gpr(t0, XRa);
24619 gen_load_mxu_gpr(t1, XRd);
24623 tcg_gen_add_tl(t3, t0, t3);
24624 tcg_gen_add_tl(t2, t1, t2);
24627 tcg_gen_add_tl(t3, t0, t3);
24628 tcg_gen_sub_tl(t2, t1, t2);
24631 tcg_gen_sub_tl(t3, t0, t3);
24632 tcg_gen_add_tl(t2, t1, t2);
24635 tcg_gen_sub_tl(t3, t0, t3);
24636 tcg_gen_sub_tl(t2, t1, t2);
24639 gen_store_mxu_gpr(t3, XRa);
24640 gen_store_mxu_gpr(t2, XRd);
24649 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24650 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24652 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24654 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24655 uint32_t XRa, XRb, XRc, XRd, sel;
24657 t0 = tcg_temp_new();
24658 t1 = tcg_temp_new();
24659 t2 = tcg_temp_new();
24660 t3 = tcg_temp_new();
24661 t4 = tcg_temp_new();
24662 t5 = tcg_temp_new();
24663 t6 = tcg_temp_new();
24664 t7 = tcg_temp_new();
24666 XRa = extract32(ctx->opcode, 6, 4);
24667 XRb = extract32(ctx->opcode, 10, 4);
24668 XRc = extract32(ctx->opcode, 14, 4);
24669 XRd = extract32(ctx->opcode, 18, 4);
24670 sel = extract32(ctx->opcode, 22, 2);
24672 gen_load_mxu_gpr(t3, XRb);
24673 gen_load_mxu_gpr(t7, XRc);
24677 tcg_gen_ext8s_tl(t0, t3);
24678 tcg_gen_shri_tl(t3, t3, 8);
24679 tcg_gen_ext8s_tl(t1, t3);
24680 tcg_gen_shri_tl(t3, t3, 8);
24681 tcg_gen_ext8s_tl(t2, t3);
24682 tcg_gen_shri_tl(t3, t3, 8);
24683 tcg_gen_ext8s_tl(t3, t3);
24686 tcg_gen_ext8u_tl(t0, t3);
24687 tcg_gen_shri_tl(t3, t3, 8);
24688 tcg_gen_ext8u_tl(t1, t3);
24689 tcg_gen_shri_tl(t3, t3, 8);
24690 tcg_gen_ext8u_tl(t2, t3);
24691 tcg_gen_shri_tl(t3, t3, 8);
24692 tcg_gen_ext8u_tl(t3, t3);
24695 tcg_gen_ext8u_tl(t4, t7);
24696 tcg_gen_shri_tl(t7, t7, 8);
24697 tcg_gen_ext8u_tl(t5, t7);
24698 tcg_gen_shri_tl(t7, t7, 8);
24699 tcg_gen_ext8u_tl(t6, t7);
24700 tcg_gen_shri_tl(t7, t7, 8);
24701 tcg_gen_ext8u_tl(t7, t7);
24703 tcg_gen_mul_tl(t0, t0, t4);
24704 tcg_gen_mul_tl(t1, t1, t5);
24705 tcg_gen_mul_tl(t2, t2, t6);
24706 tcg_gen_mul_tl(t3, t3, t7);
24708 tcg_gen_andi_tl(t0, t0, 0xFFFF);
24709 tcg_gen_andi_tl(t1, t1, 0xFFFF);
24710 tcg_gen_andi_tl(t2, t2, 0xFFFF);
24711 tcg_gen_andi_tl(t3, t3, 0xFFFF);
24713 tcg_gen_shli_tl(t1, t1, 16);
24714 tcg_gen_shli_tl(t3, t3, 16);
24716 tcg_gen_or_tl(t0, t0, t1);
24717 tcg_gen_or_tl(t1, t2, t3);
24719 gen_store_mxu_gpr(t0, XRd);
24720 gen_store_mxu_gpr(t1, XRa);
24733 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
24734 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24736 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24739 uint32_t XRa, Rb, s12, sel;
24741 t0 = tcg_temp_new();
24742 t1 = tcg_temp_new();
24744 XRa = extract32(ctx->opcode, 6, 4);
24745 s12 = extract32(ctx->opcode, 10, 10);
24746 sel = extract32(ctx->opcode, 20, 1);
24747 Rb = extract32(ctx->opcode, 21, 5);
24749 gen_load_gpr(t0, Rb);
24751 tcg_gen_movi_tl(t1, s12);
24752 tcg_gen_shli_tl(t1, t1, 2);
24754 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24756 tcg_gen_add_tl(t1, t0, t1);
24757 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24761 tcg_gen_bswap32_tl(t1, t1);
24763 gen_store_mxu_gpr(t1, XRa);
24771 * MXU instruction category: logic
24772 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24774 * S32NOR S32AND S32OR S32XOR
24778 * S32NOR XRa, XRb, XRc
24779 * Update XRa with the result of logical bitwise 'nor' operation
24780 * applied to the content of XRb and XRc.
24782 * 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
24783 * +-----------+---------+-----+-------+-------+-------+-----------+
24784 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24785 * +-----------+---------+-----+-------+-------+-------+-----------+
24787 static void gen_mxu_S32NOR(DisasContext *ctx)
24789 uint32_t pad, XRc, XRb, XRa;
24791 pad = extract32(ctx->opcode, 21, 5);
24792 XRc = extract32(ctx->opcode, 14, 4);
24793 XRb = extract32(ctx->opcode, 10, 4);
24794 XRa = extract32(ctx->opcode, 6, 4);
24796 if (unlikely(pad != 0)) {
24797 /* opcode padding incorrect -> do nothing */
24798 } else if (unlikely(XRa == 0)) {
24799 /* destination is zero register -> do nothing */
24800 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24801 /* both operands zero registers -> just set destination to all 1s */
24802 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
24803 } else if (unlikely(XRb == 0)) {
24804 /* XRb zero register -> just set destination to the negation of XRc */
24805 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24806 } else if (unlikely(XRc == 0)) {
24807 /* XRa zero register -> just set destination to the negation of XRb */
24808 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24809 } else if (unlikely(XRb == XRc)) {
24810 /* both operands same -> just set destination to the negation of XRb */
24811 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24813 /* the most general case */
24814 tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24819 * S32AND XRa, XRb, XRc
24820 * Update XRa with the result of logical bitwise 'and' operation
24821 * applied to the content of XRb and XRc.
24823 * 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
24824 * +-----------+---------+-----+-------+-------+-------+-----------+
24825 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24826 * +-----------+---------+-----+-------+-------+-------+-----------+
24828 static void gen_mxu_S32AND(DisasContext *ctx)
24830 uint32_t pad, XRc, XRb, XRa;
24832 pad = extract32(ctx->opcode, 21, 5);
24833 XRc = extract32(ctx->opcode, 14, 4);
24834 XRb = extract32(ctx->opcode, 10, 4);
24835 XRa = extract32(ctx->opcode, 6, 4);
24837 if (unlikely(pad != 0)) {
24838 /* opcode padding incorrect -> do nothing */
24839 } else if (unlikely(XRa == 0)) {
24840 /* destination is zero register -> do nothing */
24841 } else if (unlikely((XRb == 0) || (XRc == 0))) {
24842 /* one of operands zero register -> just set destination to all 0s */
24843 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24844 } else if (unlikely(XRb == XRc)) {
24845 /* both operands same -> just set destination to one of them */
24846 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24848 /* the most general case */
24849 tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24854 * S32OR XRa, XRb, XRc
24855 * Update XRa with the result of logical bitwise 'or' operation
24856 * applied to the content of XRb and XRc.
24858 * 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
24859 * +-----------+---------+-----+-------+-------+-------+-----------+
24860 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24861 * +-----------+---------+-----+-------+-------+-------+-----------+
24863 static void gen_mxu_S32OR(DisasContext *ctx)
24865 uint32_t pad, XRc, XRb, XRa;
24867 pad = extract32(ctx->opcode, 21, 5);
24868 XRc = extract32(ctx->opcode, 14, 4);
24869 XRb = extract32(ctx->opcode, 10, 4);
24870 XRa = extract32(ctx->opcode, 6, 4);
24872 if (unlikely(pad != 0)) {
24873 /* opcode padding incorrect -> do nothing */
24874 } else if (unlikely(XRa == 0)) {
24875 /* destination is zero register -> do nothing */
24876 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24877 /* both operands zero registers -> just set destination to all 0s */
24878 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24879 } else if (unlikely(XRb == 0)) {
24880 /* XRb zero register -> just set destination to the content of XRc */
24881 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24882 } else if (unlikely(XRc == 0)) {
24883 /* XRc zero register -> just set destination to the content of XRb */
24884 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24885 } else if (unlikely(XRb == XRc)) {
24886 /* both operands same -> just set destination to one of them */
24887 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24889 /* the most general case */
24890 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24895 * S32XOR XRa, XRb, XRc
24896 * Update XRa with the result of logical bitwise 'xor' operation
24897 * applied to the content of XRb and XRc.
24899 * 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
24900 * +-----------+---------+-----+-------+-------+-------+-----------+
24901 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24902 * +-----------+---------+-----+-------+-------+-------+-----------+
24904 static void gen_mxu_S32XOR(DisasContext *ctx)
24906 uint32_t pad, XRc, XRb, XRa;
24908 pad = extract32(ctx->opcode, 21, 5);
24909 XRc = extract32(ctx->opcode, 14, 4);
24910 XRb = extract32(ctx->opcode, 10, 4);
24911 XRa = extract32(ctx->opcode, 6, 4);
24913 if (unlikely(pad != 0)) {
24914 /* opcode padding incorrect -> do nothing */
24915 } else if (unlikely(XRa == 0)) {
24916 /* destination is zero register -> do nothing */
24917 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24918 /* both operands zero registers -> just set destination to all 0s */
24919 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24920 } else if (unlikely(XRb == 0)) {
24921 /* XRb zero register -> just set destination to the content of XRc */
24922 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24923 } else if (unlikely(XRc == 0)) {
24924 /* XRc zero register -> just set destination to the content of XRb */
24925 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24926 } else if (unlikely(XRb == XRc)) {
24927 /* both operands same -> just set destination to all 0s */
24928 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24930 /* the most general case */
24931 tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24937 * MXU instruction category max/min
24938 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24940 * S32MAX D16MAX Q8MAX
24941 * S32MIN D16MIN Q8MIN
24945 * S32MAX XRa, XRb, XRc
24946 * Update XRa with the maximum of signed 32-bit integers contained
24949 * S32MIN XRa, XRb, XRc
24950 * Update XRa with the minimum of signed 32-bit integers contained
24953 * 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
24954 * +-----------+---------+-----+-------+-------+-------+-----------+
24955 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
24956 * +-----------+---------+-----+-------+-------+-------+-----------+
24958 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
24960 uint32_t pad, opc, XRc, XRb, XRa;
24962 pad = extract32(ctx->opcode, 21, 5);
24963 opc = extract32(ctx->opcode, 18, 3);
24964 XRc = extract32(ctx->opcode, 14, 4);
24965 XRb = extract32(ctx->opcode, 10, 4);
24966 XRa = extract32(ctx->opcode, 6, 4);
24968 if (unlikely(pad != 0)) {
24969 /* opcode padding incorrect -> do nothing */
24970 } else if (unlikely(XRa == 0)) {
24971 /* destination is zero register -> do nothing */
24972 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24973 /* both operands zero registers -> just set destination to zero */
24974 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24975 } else if (unlikely((XRb == 0) || (XRc == 0))) {
24976 /* exactly one operand is zero register - find which one is not...*/
24977 uint32_t XRx = XRb ? XRb : XRc;
24978 /* ...and do max/min operation with one operand 0 */
24979 if (opc == OPC_MXU_S32MAX) {
24980 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24982 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24984 } else if (unlikely(XRb == XRc)) {
24985 /* both operands same -> just set destination to one of them */
24986 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24988 /* the most general case */
24989 if (opc == OPC_MXU_S32MAX) {
24990 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
24993 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25001 * Update XRa with the 16-bit-wise maximums of signed integers
25002 * contained in XRb and XRc.
25005 * Update XRa with the 16-bit-wise minimums of signed integers
25006 * contained in XRb and XRc.
25008 * 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
25009 * +-----------+---------+-----+-------+-------+-------+-----------+
25010 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25011 * +-----------+---------+-----+-------+-------+-------+-----------+
25013 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25015 uint32_t pad, opc, XRc, XRb, XRa;
25017 pad = extract32(ctx->opcode, 21, 5);
25018 opc = extract32(ctx->opcode, 18, 3);
25019 XRc = extract32(ctx->opcode, 14, 4);
25020 XRb = extract32(ctx->opcode, 10, 4);
25021 XRa = extract32(ctx->opcode, 6, 4);
25023 if (unlikely(pad != 0)) {
25024 /* opcode padding incorrect -> do nothing */
25025 } else if (unlikely(XRc == 0)) {
25026 /* destination is zero register -> do nothing */
25027 } else if (unlikely((XRb == 0) && (XRa == 0))) {
25028 /* both operands zero registers -> just set destination to zero */
25029 tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25030 } else if (unlikely((XRb == 0) || (XRa == 0))) {
25031 /* exactly one operand is zero register - find which one is not...*/
25032 uint32_t XRx = XRb ? XRb : XRc;
25033 /* ...and do half-word-wise max/min with one operand 0 */
25034 TCGv_i32 t0 = tcg_temp_new();
25035 TCGv_i32 t1 = tcg_const_i32(0);
25037 /* the left half-word first */
25038 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25039 if (opc == OPC_MXU_D16MAX) {
25040 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25042 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25045 /* the right half-word */
25046 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25047 /* move half-words to the leftmost position */
25048 tcg_gen_shli_i32(t0, t0, 16);
25049 /* t0 will be max/min of t0 and t1 */
25050 if (opc == OPC_MXU_D16MAX) {
25051 tcg_gen_smax_i32(t0, t0, t1);
25053 tcg_gen_smin_i32(t0, t0, t1);
25055 /* return resulting half-words to its original position */
25056 tcg_gen_shri_i32(t0, t0, 16);
25057 /* finaly update the destination */
25058 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25062 } else if (unlikely(XRb == XRc)) {
25063 /* both operands same -> just set destination to one of them */
25064 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25066 /* the most general case */
25067 TCGv_i32 t0 = tcg_temp_new();
25068 TCGv_i32 t1 = tcg_temp_new();
25070 /* the left half-word first */
25071 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25072 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25073 if (opc == OPC_MXU_D16MAX) {
25074 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25076 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25079 /* the right half-word */
25080 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25081 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25082 /* move half-words to the leftmost position */
25083 tcg_gen_shli_i32(t0, t0, 16);
25084 tcg_gen_shli_i32(t1, t1, 16);
25085 /* t0 will be max/min of t0 and t1 */
25086 if (opc == OPC_MXU_D16MAX) {
25087 tcg_gen_smax_i32(t0, t0, t1);
25089 tcg_gen_smin_i32(t0, t0, t1);
25091 /* return resulting half-words to its original position */
25092 tcg_gen_shri_i32(t0, t0, 16);
25093 /* finaly update the destination */
25094 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25103 * Update XRa with the 8-bit-wise maximums of signed integers
25104 * contained in XRb and XRc.
25107 * Update XRa with the 8-bit-wise minimums of signed integers
25108 * contained in XRb and XRc.
25110 * 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
25111 * +-----------+---------+-----+-------+-------+-------+-----------+
25112 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25113 * +-----------+---------+-----+-------+-------+-------+-----------+
25115 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25117 uint32_t pad, opc, XRc, XRb, XRa;
25119 pad = extract32(ctx->opcode, 21, 5);
25120 opc = extract32(ctx->opcode, 18, 3);
25121 XRc = extract32(ctx->opcode, 14, 4);
25122 XRb = extract32(ctx->opcode, 10, 4);
25123 XRa = extract32(ctx->opcode, 6, 4);
25125 if (unlikely(pad != 0)) {
25126 /* opcode padding incorrect -> do nothing */
25127 } else if (unlikely(XRa == 0)) {
25128 /* destination is zero register -> do nothing */
25129 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25130 /* both operands zero registers -> just set destination to zero */
25131 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25132 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25133 /* exactly one operand is zero register - make it be the first...*/
25134 uint32_t XRx = XRb ? XRb : XRc;
25135 /* ...and do byte-wise max/min with one operand 0 */
25136 TCGv_i32 t0 = tcg_temp_new();
25137 TCGv_i32 t1 = tcg_const_i32(0);
25140 /* the leftmost byte (byte 3) first */
25141 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25142 if (opc == OPC_MXU_Q8MAX) {
25143 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25145 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25148 /* bytes 2, 1, 0 */
25149 for (i = 2; i >= 0; i--) {
25150 /* extract the byte */
25151 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25152 /* move the byte to the leftmost position */
25153 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25154 /* t0 will be max/min of t0 and t1 */
25155 if (opc == OPC_MXU_Q8MAX) {
25156 tcg_gen_smax_i32(t0, t0, t1);
25158 tcg_gen_smin_i32(t0, t0, t1);
25160 /* return resulting byte to its original position */
25161 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25162 /* finaly update the destination */
25163 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25168 } else if (unlikely(XRb == XRc)) {
25169 /* both operands same -> just set destination to one of them */
25170 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25172 /* the most general case */
25173 TCGv_i32 t0 = tcg_temp_new();
25174 TCGv_i32 t1 = tcg_temp_new();
25177 /* the leftmost bytes (bytes 3) first */
25178 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25179 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25180 if (opc == OPC_MXU_Q8MAX) {
25181 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25183 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25186 /* bytes 2, 1, 0 */
25187 for (i = 2; i >= 0; i--) {
25188 /* extract corresponding bytes */
25189 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25190 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25191 /* move the bytes to the leftmost position */
25192 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25193 tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25194 /* t0 will be max/min of t0 and t1 */
25195 if (opc == OPC_MXU_Q8MAX) {
25196 tcg_gen_smax_i32(t0, t0, t1);
25198 tcg_gen_smin_i32(t0, t0, t1);
25200 /* return resulting byte to its original position */
25201 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25202 /* finaly update the destination */
25203 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25213 * MXU instruction category: align
25214 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25220 * S32ALNI XRc, XRb, XRa, optn3
25221 * Arrange bytes from XRb and XRc according to one of five sets of
25222 * rules determined by optn3, and place the result in XRa.
25224 * 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
25225 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25226 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25227 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25230 static void gen_mxu_S32ALNI(DisasContext *ctx)
25232 uint32_t optn3, pad, XRc, XRb, XRa;
25234 optn3 = extract32(ctx->opcode, 23, 3);
25235 pad = extract32(ctx->opcode, 21, 2);
25236 XRc = extract32(ctx->opcode, 14, 4);
25237 XRb = extract32(ctx->opcode, 10, 4);
25238 XRa = extract32(ctx->opcode, 6, 4);
25240 if (unlikely(pad != 0)) {
25241 /* opcode padding incorrect -> do nothing */
25242 } else if (unlikely(XRa == 0)) {
25243 /* destination is zero register -> do nothing */
25244 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25245 /* both operands zero registers -> just set destination to all 0s */
25246 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25247 } else if (unlikely(XRb == 0)) {
25248 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25250 case MXU_OPTN3_PTN0:
25251 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25253 case MXU_OPTN3_PTN1:
25254 case MXU_OPTN3_PTN2:
25255 case MXU_OPTN3_PTN3:
25256 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25259 case MXU_OPTN3_PTN4:
25260 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25263 } else if (unlikely(XRc == 0)) {
25264 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25266 case MXU_OPTN3_PTN0:
25267 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25269 case MXU_OPTN3_PTN1:
25270 case MXU_OPTN3_PTN2:
25271 case MXU_OPTN3_PTN3:
25272 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25274 case MXU_OPTN3_PTN4:
25275 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25278 } else if (unlikely(XRb == XRc)) {
25279 /* both operands same -> just rotation or moving from any of them */
25281 case MXU_OPTN3_PTN0:
25282 case MXU_OPTN3_PTN4:
25283 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25285 case MXU_OPTN3_PTN1:
25286 case MXU_OPTN3_PTN2:
25287 case MXU_OPTN3_PTN3:
25288 tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25292 /* the most general case */
25294 case MXU_OPTN3_PTN0:
25298 /* +---------------+ */
25299 /* | A B C D | E F G H */
25300 /* +-------+-------+ */
25305 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25308 case MXU_OPTN3_PTN1:
25312 /* +-------------------+ */
25313 /* A | B C D E | F G H */
25314 /* +---------+---------+ */
25319 TCGv_i32 t0 = tcg_temp_new();
25320 TCGv_i32 t1 = tcg_temp_new();
25322 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25323 tcg_gen_shli_i32(t0, t0, 8);
25325 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25326 tcg_gen_shri_i32(t1, t1, 24);
25328 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25334 case MXU_OPTN3_PTN2:
25338 /* +-------------------+ */
25339 /* A B | C D E F | G H */
25340 /* +---------+---------+ */
25345 TCGv_i32 t0 = tcg_temp_new();
25346 TCGv_i32 t1 = tcg_temp_new();
25348 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25349 tcg_gen_shli_i32(t0, t0, 16);
25351 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25352 tcg_gen_shri_i32(t1, t1, 16);
25354 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25360 case MXU_OPTN3_PTN3:
25364 /* +-------------------+ */
25365 /* A B C | D E F G | H */
25366 /* +---------+---------+ */
25371 TCGv_i32 t0 = tcg_temp_new();
25372 TCGv_i32 t1 = tcg_temp_new();
25374 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25375 tcg_gen_shli_i32(t0, t0, 24);
25377 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25378 tcg_gen_shri_i32(t1, t1, 8);
25380 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25386 case MXU_OPTN3_PTN4:
25390 /* +---------------+ */
25391 /* A B C D | E F G H | */
25392 /* +-------+-------+ */
25397 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25406 * Decoding engine for MXU
25407 * =======================
25412 * Decode MXU pool00
25414 * 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
25415 * +-----------+---------+-----+-------+-------+-------+-----------+
25416 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25417 * +-----------+---------+-----+-------+-------+-------+-----------+
25420 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25422 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25425 case OPC_MXU_S32MAX:
25426 case OPC_MXU_S32MIN:
25427 gen_mxu_S32MAX_S32MIN(ctx);
25429 case OPC_MXU_D16MAX:
25430 case OPC_MXU_D16MIN:
25431 gen_mxu_D16MAX_D16MIN(ctx);
25433 case OPC_MXU_Q8MAX:
25434 case OPC_MXU_Q8MIN:
25435 gen_mxu_Q8MAX_Q8MIN(ctx);
25437 case OPC_MXU_Q8SLT:
25438 /* TODO: Implement emulation of Q8SLT instruction. */
25439 MIPS_INVAL("OPC_MXU_Q8SLT");
25440 generate_exception_end(ctx, EXCP_RI);
25442 case OPC_MXU_Q8SLTU:
25443 /* TODO: Implement emulation of Q8SLTU instruction. */
25444 MIPS_INVAL("OPC_MXU_Q8SLTU");
25445 generate_exception_end(ctx, EXCP_RI);
25448 MIPS_INVAL("decode_opc_mxu");
25449 generate_exception_end(ctx, EXCP_RI);
25456 * Decode MXU pool01
25458 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25459 * 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
25460 * +-----------+---------+-----+-------+-------+-------+-----------+
25461 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25462 * +-----------+---------+-----+-------+-------+-------+-----------+
25465 * 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
25466 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25467 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25468 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25471 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25473 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25476 case OPC_MXU_S32SLT:
25477 /* TODO: Implement emulation of S32SLT instruction. */
25478 MIPS_INVAL("OPC_MXU_S32SLT");
25479 generate_exception_end(ctx, EXCP_RI);
25481 case OPC_MXU_D16SLT:
25482 /* TODO: Implement emulation of D16SLT instruction. */
25483 MIPS_INVAL("OPC_MXU_D16SLT");
25484 generate_exception_end(ctx, EXCP_RI);
25486 case OPC_MXU_D16AVG:
25487 /* TODO: Implement emulation of D16AVG instruction. */
25488 MIPS_INVAL("OPC_MXU_D16AVG");
25489 generate_exception_end(ctx, EXCP_RI);
25491 case OPC_MXU_D16AVGR:
25492 /* TODO: Implement emulation of D16AVGR instruction. */
25493 MIPS_INVAL("OPC_MXU_D16AVGR");
25494 generate_exception_end(ctx, EXCP_RI);
25496 case OPC_MXU_Q8AVG:
25497 /* TODO: Implement emulation of Q8AVG instruction. */
25498 MIPS_INVAL("OPC_MXU_Q8AVG");
25499 generate_exception_end(ctx, EXCP_RI);
25501 case OPC_MXU_Q8AVGR:
25502 /* TODO: Implement emulation of Q8AVGR instruction. */
25503 MIPS_INVAL("OPC_MXU_Q8AVGR");
25504 generate_exception_end(ctx, EXCP_RI);
25506 case OPC_MXU_Q8ADD:
25507 /* TODO: Implement emulation of Q8ADD instruction. */
25508 MIPS_INVAL("OPC_MXU_Q8ADD");
25509 generate_exception_end(ctx, EXCP_RI);
25512 MIPS_INVAL("decode_opc_mxu");
25513 generate_exception_end(ctx, EXCP_RI);
25520 * Decode MXU pool02
25522 * 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
25523 * +-----------+---------+-----+-------+-------+-------+-----------+
25524 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
25525 * +-----------+---------+-----+-------+-------+-------+-----------+
25528 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25530 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25533 case OPC_MXU_S32CPS:
25534 /* TODO: Implement emulation of S32CPS instruction. */
25535 MIPS_INVAL("OPC_MXU_S32CPS");
25536 generate_exception_end(ctx, EXCP_RI);
25538 case OPC_MXU_D16CPS:
25539 /* TODO: Implement emulation of D16CPS instruction. */
25540 MIPS_INVAL("OPC_MXU_D16CPS");
25541 generate_exception_end(ctx, EXCP_RI);
25543 case OPC_MXU_Q8ABD:
25544 /* TODO: Implement emulation of Q8ABD instruction. */
25545 MIPS_INVAL("OPC_MXU_Q8ABD");
25546 generate_exception_end(ctx, EXCP_RI);
25548 case OPC_MXU_Q16SAT:
25549 /* TODO: Implement emulation of Q16SAT instruction. */
25550 MIPS_INVAL("OPC_MXU_Q16SAT");
25551 generate_exception_end(ctx, EXCP_RI);
25554 MIPS_INVAL("decode_opc_mxu");
25555 generate_exception_end(ctx, EXCP_RI);
25562 * Decode MXU pool03
25565 * 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
25566 * +-----------+---+---+-------+-------+-------+-------+-----------+
25567 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
25568 * +-----------+---+---+-------+-------+-------+-------+-----------+
25571 * 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
25572 * +-----------+---+---+-------+-------+-------+-------+-----------+
25573 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
25574 * +-----------+---+---+-------+-------+-------+-------+-----------+
25577 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25579 uint32_t opcode = extract32(ctx->opcode, 24, 2);
25582 case OPC_MXU_D16MULF:
25583 /* TODO: Implement emulation of D16MULF instruction. */
25584 MIPS_INVAL("OPC_MXU_D16MULF");
25585 generate_exception_end(ctx, EXCP_RI);
25587 case OPC_MXU_D16MULE:
25588 /* TODO: Implement emulation of D16MULE instruction. */
25589 MIPS_INVAL("OPC_MXU_D16MULE");
25590 generate_exception_end(ctx, EXCP_RI);
25593 MIPS_INVAL("decode_opc_mxu");
25594 generate_exception_end(ctx, EXCP_RI);
25601 * Decode MXU pool04
25603 * 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
25604 * +-----------+---------+-+-------------------+-------+-----------+
25605 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
25606 * +-----------+---------+-+-------------------+-------+-----------+
25609 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25611 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25614 case OPC_MXU_S32LDD:
25615 case OPC_MXU_S32LDDR:
25616 gen_mxu_s32ldd_s32lddr(ctx);
25619 MIPS_INVAL("decode_opc_mxu");
25620 generate_exception_end(ctx, EXCP_RI);
25627 * Decode MXU pool05
25629 * 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
25630 * +-----------+---------+-+-------------------+-------+-----------+
25631 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
25632 * +-----------+---------+-+-------------------+-------+-----------+
25635 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25637 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25640 case OPC_MXU_S32STD:
25641 /* TODO: Implement emulation of S32STD instruction. */
25642 MIPS_INVAL("OPC_MXU_S32STD");
25643 generate_exception_end(ctx, EXCP_RI);
25645 case OPC_MXU_S32STDR:
25646 /* TODO: Implement emulation of S32STDR instruction. */
25647 MIPS_INVAL("OPC_MXU_S32STDR");
25648 generate_exception_end(ctx, EXCP_RI);
25651 MIPS_INVAL("decode_opc_mxu");
25652 generate_exception_end(ctx, EXCP_RI);
25659 * Decode MXU pool06
25661 * 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
25662 * +-----------+---------+---------+---+-------+-------+-----------+
25663 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
25664 * +-----------+---------+---------+---+-------+-------+-----------+
25667 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25669 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25672 case OPC_MXU_S32LDDV:
25673 /* TODO: Implement emulation of S32LDDV instruction. */
25674 MIPS_INVAL("OPC_MXU_S32LDDV");
25675 generate_exception_end(ctx, EXCP_RI);
25677 case OPC_MXU_S32LDDVR:
25678 /* TODO: Implement emulation of S32LDDVR instruction. */
25679 MIPS_INVAL("OPC_MXU_S32LDDVR");
25680 generate_exception_end(ctx, EXCP_RI);
25683 MIPS_INVAL("decode_opc_mxu");
25684 generate_exception_end(ctx, EXCP_RI);
25691 * Decode MXU pool07
25693 * 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
25694 * +-----------+---------+---------+---+-------+-------+-----------+
25695 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
25696 * +-----------+---------+---------+---+-------+-------+-----------+
25699 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
25701 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25704 case OPC_MXU_S32STDV:
25705 /* TODO: Implement emulation of S32TDV instruction. */
25706 MIPS_INVAL("OPC_MXU_S32TDV");
25707 generate_exception_end(ctx, EXCP_RI);
25709 case OPC_MXU_S32STDVR:
25710 /* TODO: Implement emulation of S32TDVR instruction. */
25711 MIPS_INVAL("OPC_MXU_S32TDVR");
25712 generate_exception_end(ctx, EXCP_RI);
25715 MIPS_INVAL("decode_opc_mxu");
25716 generate_exception_end(ctx, EXCP_RI);
25723 * Decode MXU pool08
25725 * 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
25726 * +-----------+---------+-+-------------------+-------+-----------+
25727 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
25728 * +-----------+---------+-+-------------------+-------+-----------+
25731 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
25733 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25736 case OPC_MXU_S32LDI:
25737 /* TODO: Implement emulation of S32LDI instruction. */
25738 MIPS_INVAL("OPC_MXU_S32LDI");
25739 generate_exception_end(ctx, EXCP_RI);
25741 case OPC_MXU_S32LDIR:
25742 /* TODO: Implement emulation of S32LDIR instruction. */
25743 MIPS_INVAL("OPC_MXU_S32LDIR");
25744 generate_exception_end(ctx, EXCP_RI);
25747 MIPS_INVAL("decode_opc_mxu");
25748 generate_exception_end(ctx, EXCP_RI);
25755 * Decode MXU pool09
25757 * 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
25758 * +-----------+---------+-+-------------------+-------+-----------+
25759 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
25760 * +-----------+---------+-+-------------------+-------+-----------+
25763 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
25765 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25768 case OPC_MXU_S32SDI:
25769 /* TODO: Implement emulation of S32SDI instruction. */
25770 MIPS_INVAL("OPC_MXU_S32SDI");
25771 generate_exception_end(ctx, EXCP_RI);
25773 case OPC_MXU_S32SDIR:
25774 /* TODO: Implement emulation of S32SDIR instruction. */
25775 MIPS_INVAL("OPC_MXU_S32SDIR");
25776 generate_exception_end(ctx, EXCP_RI);
25779 MIPS_INVAL("decode_opc_mxu");
25780 generate_exception_end(ctx, EXCP_RI);
25787 * Decode MXU pool10
25789 * 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
25790 * +-----------+---------+---------+---+-------+-------+-----------+
25791 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
25792 * +-----------+---------+---------+---+-------+-------+-----------+
25795 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25797 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25800 case OPC_MXU_S32LDIV:
25801 /* TODO: Implement emulation of S32LDIV instruction. */
25802 MIPS_INVAL("OPC_MXU_S32LDIV");
25803 generate_exception_end(ctx, EXCP_RI);
25805 case OPC_MXU_S32LDIVR:
25806 /* TODO: Implement emulation of S32LDIVR instruction. */
25807 MIPS_INVAL("OPC_MXU_S32LDIVR");
25808 generate_exception_end(ctx, EXCP_RI);
25811 MIPS_INVAL("decode_opc_mxu");
25812 generate_exception_end(ctx, EXCP_RI);
25819 * Decode MXU pool11
25821 * 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
25822 * +-----------+---------+---------+---+-------+-------+-----------+
25823 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
25824 * +-----------+---------+---------+---+-------+-------+-----------+
25827 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25829 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25832 case OPC_MXU_S32SDIV:
25833 /* TODO: Implement emulation of S32SDIV instruction. */
25834 MIPS_INVAL("OPC_MXU_S32SDIV");
25835 generate_exception_end(ctx, EXCP_RI);
25837 case OPC_MXU_S32SDIVR:
25838 /* TODO: Implement emulation of S32SDIVR instruction. */
25839 MIPS_INVAL("OPC_MXU_S32SDIVR");
25840 generate_exception_end(ctx, EXCP_RI);
25843 MIPS_INVAL("decode_opc_mxu");
25844 generate_exception_end(ctx, EXCP_RI);
25851 * Decode MXU pool12
25853 * 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
25854 * +-----------+---+---+-------+-------+-------+-------+-----------+
25855 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
25856 * +-----------+---+---+-------+-------+-------+-------+-----------+
25859 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
25861 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25864 case OPC_MXU_D32ACC:
25865 /* TODO: Implement emulation of D32ACC instruction. */
25866 MIPS_INVAL("OPC_MXU_D32ACC");
25867 generate_exception_end(ctx, EXCP_RI);
25869 case OPC_MXU_D32ACCM:
25870 /* TODO: Implement emulation of D32ACCM instruction. */
25871 MIPS_INVAL("OPC_MXU_D32ACCM");
25872 generate_exception_end(ctx, EXCP_RI);
25874 case OPC_MXU_D32ASUM:
25875 /* TODO: Implement emulation of D32ASUM instruction. */
25876 MIPS_INVAL("OPC_MXU_D32ASUM");
25877 generate_exception_end(ctx, EXCP_RI);
25880 MIPS_INVAL("decode_opc_mxu");
25881 generate_exception_end(ctx, EXCP_RI);
25888 * Decode MXU pool13
25890 * 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
25891 * +-----------+---+---+-------+-------+-------+-------+-----------+
25892 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
25893 * +-----------+---+---+-------+-------+-------+-------+-----------+
25896 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
25898 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25901 case OPC_MXU_Q16ACC:
25902 /* TODO: Implement emulation of Q16ACC instruction. */
25903 MIPS_INVAL("OPC_MXU_Q16ACC");
25904 generate_exception_end(ctx, EXCP_RI);
25906 case OPC_MXU_Q16ACCM:
25907 /* TODO: Implement emulation of Q16ACCM instruction. */
25908 MIPS_INVAL("OPC_MXU_Q16ACCM");
25909 generate_exception_end(ctx, EXCP_RI);
25911 case OPC_MXU_Q16ASUM:
25912 /* TODO: Implement emulation of Q16ASUM instruction. */
25913 MIPS_INVAL("OPC_MXU_Q16ASUM");
25914 generate_exception_end(ctx, EXCP_RI);
25917 MIPS_INVAL("decode_opc_mxu");
25918 generate_exception_end(ctx, EXCP_RI);
25925 * Decode MXU pool14
25928 * 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
25929 * +-----------+---+---+-------+-------+-------+-------+-----------+
25930 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
25931 * +-----------+---+---+-------+-------+-------+-------+-----------+
25934 * 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
25935 * +-----------+---+---+-------+-------+-------+-------+-----------+
25936 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
25937 * +-----------+---+---+-------+-------+-------+-------+-----------+
25940 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
25942 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25945 case OPC_MXU_Q8ADDE:
25946 /* TODO: Implement emulation of Q8ADDE instruction. */
25947 MIPS_INVAL("OPC_MXU_Q8ADDE");
25948 generate_exception_end(ctx, EXCP_RI);
25950 case OPC_MXU_D8SUM:
25951 /* TODO: Implement emulation of D8SUM instruction. */
25952 MIPS_INVAL("OPC_MXU_D8SUM");
25953 generate_exception_end(ctx, EXCP_RI);
25955 case OPC_MXU_D8SUMC:
25956 /* TODO: Implement emulation of D8SUMC instruction. */
25957 MIPS_INVAL("OPC_MXU_D8SUMC");
25958 generate_exception_end(ctx, EXCP_RI);
25961 MIPS_INVAL("decode_opc_mxu");
25962 generate_exception_end(ctx, EXCP_RI);
25969 * Decode MXU pool15
25971 * S32MUL, S32MULU, S32EXTRV:
25972 * 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
25973 * +-----------+---------+---------+---+-------+-------+-----------+
25974 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
25975 * +-----------+---------+---------+---+-------+-------+-----------+
25978 * 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
25979 * +-----------+---------+---------+---+-------+-------+-----------+
25980 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
25981 * +-----------+---------+---------+---+-------+-------+-----------+
25984 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
25986 uint32_t opcode = extract32(ctx->opcode, 14, 2);
25989 case OPC_MXU_S32MUL:
25990 /* TODO: Implement emulation of S32MUL instruction. */
25991 MIPS_INVAL("OPC_MXU_S32MUL");
25992 generate_exception_end(ctx, EXCP_RI);
25994 case OPC_MXU_S32MULU:
25995 /* TODO: Implement emulation of S32MULU instruction. */
25996 MIPS_INVAL("OPC_MXU_S32MULU");
25997 generate_exception_end(ctx, EXCP_RI);
25999 case OPC_MXU_S32EXTR:
26000 /* TODO: Implement emulation of S32EXTR instruction. */
26001 MIPS_INVAL("OPC_MXU_S32EXTR");
26002 generate_exception_end(ctx, EXCP_RI);
26004 case OPC_MXU_S32EXTRV:
26005 /* TODO: Implement emulation of S32EXTRV instruction. */
26006 MIPS_INVAL("OPC_MXU_S32EXTRV");
26007 generate_exception_end(ctx, EXCP_RI);
26010 MIPS_INVAL("decode_opc_mxu");
26011 generate_exception_end(ctx, EXCP_RI);
26018 * Decode MXU pool16
26021 * 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
26022 * +-----------+---------+-----+-------+-------+-------+-----------+
26023 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26024 * +-----------+---------+-----+-------+-------+-------+-----------+
26027 * 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
26028 * +-----------+---------+-----+-------+-------+-------+-----------+
26029 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26030 * +-----------+---------+-----+-------+-------+-------+-----------+
26033 * 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
26034 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26035 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26036 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26039 * 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
26040 * +-----------+-----+---+-----+-------+---------------+-----------+
26041 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26042 * +-----------+-----+---+-----+-------+---------------+-----------+
26044 * S32NOR, S32AND, S32OR, S32XOR:
26045 * 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
26046 * +-----------+---------+-----+-------+-------+-------+-----------+
26047 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26048 * +-----------+---------+-----+-------+-------+-------+-----------+
26051 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26053 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26056 case OPC_MXU_D32SARW:
26057 /* TODO: Implement emulation of D32SARW instruction. */
26058 MIPS_INVAL("OPC_MXU_D32SARW");
26059 generate_exception_end(ctx, EXCP_RI);
26061 case OPC_MXU_S32ALN:
26062 /* TODO: Implement emulation of S32ALN instruction. */
26063 MIPS_INVAL("OPC_MXU_S32ALN");
26064 generate_exception_end(ctx, EXCP_RI);
26066 case OPC_MXU_S32ALNI:
26067 gen_mxu_S32ALNI(ctx);
26069 case OPC_MXU_S32LUI:
26070 /* TODO: Implement emulation of S32LUI instruction. */
26071 MIPS_INVAL("OPC_MXU_S32LUI");
26072 generate_exception_end(ctx, EXCP_RI);
26074 case OPC_MXU_S32NOR:
26075 gen_mxu_S32NOR(ctx);
26077 case OPC_MXU_S32AND:
26078 gen_mxu_S32AND(ctx);
26080 case OPC_MXU_S32OR:
26081 gen_mxu_S32OR(ctx);
26083 case OPC_MXU_S32XOR:
26084 gen_mxu_S32XOR(ctx);
26087 MIPS_INVAL("decode_opc_mxu");
26088 generate_exception_end(ctx, EXCP_RI);
26095 * Decode MXU pool17
26097 * 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
26098 * +-----------+---------+---------+---+---------+-----+-----------+
26099 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26100 * +-----------+---------+---------+---+---------+-----+-----------+
26103 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26105 uint32_t opcode = extract32(ctx->opcode, 6, 2);
26109 /* TODO: Implement emulation of LXW instruction. */
26110 MIPS_INVAL("OPC_MXU_LXW");
26111 generate_exception_end(ctx, EXCP_RI);
26114 /* TODO: Implement emulation of LXH instruction. */
26115 MIPS_INVAL("OPC_MXU_LXH");
26116 generate_exception_end(ctx, EXCP_RI);
26119 /* TODO: Implement emulation of LXHU instruction. */
26120 MIPS_INVAL("OPC_MXU_LXHU");
26121 generate_exception_end(ctx, EXCP_RI);
26124 /* TODO: Implement emulation of LXB instruction. */
26125 MIPS_INVAL("OPC_MXU_LXB");
26126 generate_exception_end(ctx, EXCP_RI);
26129 /* TODO: Implement emulation of LXBU instruction. */
26130 MIPS_INVAL("OPC_MXU_LXBU");
26131 generate_exception_end(ctx, EXCP_RI);
26134 MIPS_INVAL("decode_opc_mxu");
26135 generate_exception_end(ctx, EXCP_RI);
26141 * Decode MXU pool18
26143 * 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
26144 * +-----------+---------+-----+-------+-------+-------+-----------+
26145 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26146 * +-----------+---------+-----+-------+-------+-------+-----------+
26149 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26151 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26154 case OPC_MXU_D32SLLV:
26155 /* TODO: Implement emulation of D32SLLV instruction. */
26156 MIPS_INVAL("OPC_MXU_D32SLLV");
26157 generate_exception_end(ctx, EXCP_RI);
26159 case OPC_MXU_D32SLRV:
26160 /* TODO: Implement emulation of D32SLRV instruction. */
26161 MIPS_INVAL("OPC_MXU_D32SLRV");
26162 generate_exception_end(ctx, EXCP_RI);
26164 case OPC_MXU_D32SARV:
26165 /* TODO: Implement emulation of D32SARV instruction. */
26166 MIPS_INVAL("OPC_MXU_D32SARV");
26167 generate_exception_end(ctx, EXCP_RI);
26169 case OPC_MXU_Q16SLLV:
26170 /* TODO: Implement emulation of Q16SLLV instruction. */
26171 MIPS_INVAL("OPC_MXU_Q16SLLV");
26172 generate_exception_end(ctx, EXCP_RI);
26174 case OPC_MXU_Q16SLRV:
26175 /* TODO: Implement emulation of Q16SLRV instruction. */
26176 MIPS_INVAL("OPC_MXU_Q16SLRV");
26177 generate_exception_end(ctx, EXCP_RI);
26179 case OPC_MXU_Q16SARV:
26180 /* TODO: Implement emulation of Q16SARV instruction. */
26181 MIPS_INVAL("OPC_MXU_Q16SARV");
26182 generate_exception_end(ctx, EXCP_RI);
26185 MIPS_INVAL("decode_opc_mxu");
26186 generate_exception_end(ctx, EXCP_RI);
26193 * Decode MXU pool19
26195 * 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
26196 * +-----------+---+---+-------+-------+-------+-------+-----------+
26197 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
26198 * +-----------+---+---+-------+-------+-------+-------+-----------+
26201 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26203 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26206 case OPC_MXU_Q8MUL:
26207 case OPC_MXU_Q8MULSU:
26208 gen_mxu_q8mul_q8mulsu(ctx);
26211 MIPS_INVAL("decode_opc_mxu");
26212 generate_exception_end(ctx, EXCP_RI);
26219 * Decode MXU pool20
26221 * 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
26222 * +-----------+---------+-----+-------+-------+-------+-----------+
26223 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
26224 * +-----------+---------+-----+-------+-------+-------+-----------+
26227 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26229 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26232 case OPC_MXU_Q8MOVZ:
26233 /* TODO: Implement emulation of Q8MOVZ instruction. */
26234 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26235 generate_exception_end(ctx, EXCP_RI);
26237 case OPC_MXU_Q8MOVN:
26238 /* TODO: Implement emulation of Q8MOVN instruction. */
26239 MIPS_INVAL("OPC_MXU_Q8MOVN");
26240 generate_exception_end(ctx, EXCP_RI);
26242 case OPC_MXU_D16MOVZ:
26243 /* TODO: Implement emulation of D16MOVZ instruction. */
26244 MIPS_INVAL("OPC_MXU_D16MOVZ");
26245 generate_exception_end(ctx, EXCP_RI);
26247 case OPC_MXU_D16MOVN:
26248 /* TODO: Implement emulation of D16MOVN instruction. */
26249 MIPS_INVAL("OPC_MXU_D16MOVN");
26250 generate_exception_end(ctx, EXCP_RI);
26252 case OPC_MXU_S32MOVZ:
26253 /* TODO: Implement emulation of S32MOVZ instruction. */
26254 MIPS_INVAL("OPC_MXU_S32MOVZ");
26255 generate_exception_end(ctx, EXCP_RI);
26257 case OPC_MXU_S32MOVN:
26258 /* TODO: Implement emulation of S32MOVN instruction. */
26259 MIPS_INVAL("OPC_MXU_S32MOVN");
26260 generate_exception_end(ctx, EXCP_RI);
26263 MIPS_INVAL("decode_opc_mxu");
26264 generate_exception_end(ctx, EXCP_RI);
26271 * Decode MXU pool21
26273 * 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
26274 * +-----------+---+---+-------+-------+-------+-------+-----------+
26275 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
26276 * +-----------+---+---+-------+-------+-------+-------+-----------+
26279 static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26281 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26284 case OPC_MXU_Q8MAC:
26285 /* TODO: Implement emulation of Q8MAC instruction. */
26286 MIPS_INVAL("OPC_MXU_Q8MAC");
26287 generate_exception_end(ctx, EXCP_RI);
26289 case OPC_MXU_Q8MACSU:
26290 /* TODO: Implement emulation of Q8MACSU instruction. */
26291 MIPS_INVAL("OPC_MXU_Q8MACSU");
26292 generate_exception_end(ctx, EXCP_RI);
26295 MIPS_INVAL("decode_opc_mxu");
26296 generate_exception_end(ctx, EXCP_RI);
26303 * Main MXU decoding function
26305 * 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
26306 * +-----------+---------------------------------------+-----------+
26307 * | SPECIAL2 | |x x x x x x|
26308 * +-----------+---------------------------------------+-----------+
26311 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26314 * TODO: Investigate necessity of including handling of
26315 * CLZ, CLO, SDBB in this function, as they belong to
26316 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26318 uint32_t opcode = extract32(ctx->opcode, 0, 6);
26320 if (opcode == OPC__MXU_MUL) {
26321 uint32_t rs, rt, rd, op1;
26323 rs = extract32(ctx->opcode, 21, 5);
26324 rt = extract32(ctx->opcode, 16, 5);
26325 rd = extract32(ctx->opcode, 11, 5);
26326 op1 = MASK_SPECIAL2(ctx->opcode);
26328 gen_arith(ctx, op1, rd, rs, rt);
26333 if (opcode == OPC_MXU_S32M2I) {
26334 gen_mxu_s32m2i(ctx);
26338 if (opcode == OPC_MXU_S32I2M) {
26339 gen_mxu_s32i2m(ctx);
26344 TCGv t_mxu_cr = tcg_temp_new();
26345 TCGLabel *l_exit = gen_new_label();
26347 gen_load_mxu_cr(t_mxu_cr);
26348 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26349 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26352 case OPC_MXU_S32MADD:
26353 /* TODO: Implement emulation of S32MADD instruction. */
26354 MIPS_INVAL("OPC_MXU_S32MADD");
26355 generate_exception_end(ctx, EXCP_RI);
26357 case OPC_MXU_S32MADDU:
26358 /* TODO: Implement emulation of S32MADDU instruction. */
26359 MIPS_INVAL("OPC_MXU_S32MADDU");
26360 generate_exception_end(ctx, EXCP_RI);
26362 case OPC_MXU__POOL00:
26363 decode_opc_mxu__pool00(env, ctx);
26365 case OPC_MXU_S32MSUB:
26366 /* TODO: Implement emulation of S32MSUB instruction. */
26367 MIPS_INVAL("OPC_MXU_S32MSUB");
26368 generate_exception_end(ctx, EXCP_RI);
26370 case OPC_MXU_S32MSUBU:
26371 /* TODO: Implement emulation of S32MSUBU instruction. */
26372 MIPS_INVAL("OPC_MXU_S32MSUBU");
26373 generate_exception_end(ctx, EXCP_RI);
26375 case OPC_MXU__POOL01:
26376 decode_opc_mxu__pool01(env, ctx);
26378 case OPC_MXU__POOL02:
26379 decode_opc_mxu__pool02(env, ctx);
26381 case OPC_MXU_D16MUL:
26382 gen_mxu_d16mul(ctx);
26384 case OPC_MXU__POOL03:
26385 decode_opc_mxu__pool03(env, ctx);
26387 case OPC_MXU_D16MAC:
26388 gen_mxu_d16mac(ctx);
26390 case OPC_MXU_D16MACF:
26391 /* TODO: Implement emulation of D16MACF instruction. */
26392 MIPS_INVAL("OPC_MXU_D16MACF");
26393 generate_exception_end(ctx, EXCP_RI);
26395 case OPC_MXU_D16MADL:
26396 /* TODO: Implement emulation of D16MADL instruction. */
26397 MIPS_INVAL("OPC_MXU_D16MADL");
26398 generate_exception_end(ctx, EXCP_RI);
26400 case OPC_MXU_S16MAD:
26401 /* TODO: Implement emulation of S16MAD instruction. */
26402 MIPS_INVAL("OPC_MXU_S16MAD");
26403 generate_exception_end(ctx, EXCP_RI);
26405 case OPC_MXU_Q16ADD:
26406 /* TODO: Implement emulation of Q16ADD instruction. */
26407 MIPS_INVAL("OPC_MXU_Q16ADD");
26408 generate_exception_end(ctx, EXCP_RI);
26410 case OPC_MXU_D16MACE:
26411 /* TODO: Implement emulation of D16MACE instruction. */
26412 MIPS_INVAL("OPC_MXU_D16MACE");
26413 generate_exception_end(ctx, EXCP_RI);
26415 case OPC_MXU__POOL04:
26416 decode_opc_mxu__pool04(env, ctx);
26418 case OPC_MXU__POOL05:
26419 decode_opc_mxu__pool05(env, ctx);
26421 case OPC_MXU__POOL06:
26422 decode_opc_mxu__pool06(env, ctx);
26424 case OPC_MXU__POOL07:
26425 decode_opc_mxu__pool07(env, ctx);
26427 case OPC_MXU__POOL08:
26428 decode_opc_mxu__pool08(env, ctx);
26430 case OPC_MXU__POOL09:
26431 decode_opc_mxu__pool09(env, ctx);
26433 case OPC_MXU__POOL10:
26434 decode_opc_mxu__pool10(env, ctx);
26436 case OPC_MXU__POOL11:
26437 decode_opc_mxu__pool11(env, ctx);
26439 case OPC_MXU_D32ADD:
26440 /* TODO: Implement emulation of D32ADD instruction. */
26441 MIPS_INVAL("OPC_MXU_D32ADD");
26442 generate_exception_end(ctx, EXCP_RI);
26444 case OPC_MXU__POOL12:
26445 decode_opc_mxu__pool12(env, ctx);
26447 case OPC_MXU__POOL13:
26448 decode_opc_mxu__pool13(env, ctx);
26450 case OPC_MXU__POOL14:
26451 decode_opc_mxu__pool14(env, ctx);
26453 case OPC_MXU_Q8ACCE:
26454 /* TODO: Implement emulation of Q8ACCE instruction. */
26455 MIPS_INVAL("OPC_MXU_Q8ACCE");
26456 generate_exception_end(ctx, EXCP_RI);
26458 case OPC_MXU_S8LDD:
26459 gen_mxu_s8ldd(ctx);
26461 case OPC_MXU_S8STD:
26462 /* TODO: Implement emulation of S8STD instruction. */
26463 MIPS_INVAL("OPC_MXU_S8STD");
26464 generate_exception_end(ctx, EXCP_RI);
26466 case OPC_MXU_S8LDI:
26467 /* TODO: Implement emulation of S8LDI instruction. */
26468 MIPS_INVAL("OPC_MXU_S8LDI");
26469 generate_exception_end(ctx, EXCP_RI);
26471 case OPC_MXU_S8SDI:
26472 /* TODO: Implement emulation of S8SDI instruction. */
26473 MIPS_INVAL("OPC_MXU_S8SDI");
26474 generate_exception_end(ctx, EXCP_RI);
26476 case OPC_MXU__POOL15:
26477 decode_opc_mxu__pool15(env, ctx);
26479 case OPC_MXU__POOL16:
26480 decode_opc_mxu__pool16(env, ctx);
26482 case OPC_MXU__POOL17:
26483 decode_opc_mxu__pool17(env, ctx);
26485 case OPC_MXU_S16LDD:
26486 /* TODO: Implement emulation of S16LDD instruction. */
26487 MIPS_INVAL("OPC_MXU_S16LDD");
26488 generate_exception_end(ctx, EXCP_RI);
26490 case OPC_MXU_S16STD:
26491 /* TODO: Implement emulation of S16STD instruction. */
26492 MIPS_INVAL("OPC_MXU_S16STD");
26493 generate_exception_end(ctx, EXCP_RI);
26495 case OPC_MXU_S16LDI:
26496 /* TODO: Implement emulation of S16LDI instruction. */
26497 MIPS_INVAL("OPC_MXU_S16LDI");
26498 generate_exception_end(ctx, EXCP_RI);
26500 case OPC_MXU_S16SDI:
26501 /* TODO: Implement emulation of S16SDI instruction. */
26502 MIPS_INVAL("OPC_MXU_S16SDI");
26503 generate_exception_end(ctx, EXCP_RI);
26505 case OPC_MXU_D32SLL:
26506 /* TODO: Implement emulation of D32SLL instruction. */
26507 MIPS_INVAL("OPC_MXU_D32SLL");
26508 generate_exception_end(ctx, EXCP_RI);
26510 case OPC_MXU_D32SLR:
26511 /* TODO: Implement emulation of D32SLR instruction. */
26512 MIPS_INVAL("OPC_MXU_D32SLR");
26513 generate_exception_end(ctx, EXCP_RI);
26515 case OPC_MXU_D32SARL:
26516 /* TODO: Implement emulation of D32SARL instruction. */
26517 MIPS_INVAL("OPC_MXU_D32SARL");
26518 generate_exception_end(ctx, EXCP_RI);
26520 case OPC_MXU_D32SAR:
26521 /* TODO: Implement emulation of D32SAR instruction. */
26522 MIPS_INVAL("OPC_MXU_D32SAR");
26523 generate_exception_end(ctx, EXCP_RI);
26525 case OPC_MXU_Q16SLL:
26526 /* TODO: Implement emulation of Q16SLL instruction. */
26527 MIPS_INVAL("OPC_MXU_Q16SLL");
26528 generate_exception_end(ctx, EXCP_RI);
26530 case OPC_MXU_Q16SLR:
26531 /* TODO: Implement emulation of Q16SLR instruction. */
26532 MIPS_INVAL("OPC_MXU_Q16SLR");
26533 generate_exception_end(ctx, EXCP_RI);
26535 case OPC_MXU__POOL18:
26536 decode_opc_mxu__pool18(env, ctx);
26538 case OPC_MXU_Q16SAR:
26539 /* TODO: Implement emulation of Q16SAR instruction. */
26540 MIPS_INVAL("OPC_MXU_Q16SAR");
26541 generate_exception_end(ctx, EXCP_RI);
26543 case OPC_MXU__POOL19:
26544 decode_opc_mxu__pool19(env, ctx);
26546 case OPC_MXU__POOL20:
26547 decode_opc_mxu__pool20(env, ctx);
26549 case OPC_MXU__POOL21:
26550 decode_opc_mxu__pool21(env, ctx);
26552 case OPC_MXU_Q16SCOP:
26553 /* TODO: Implement emulation of Q16SCOP instruction. */
26554 MIPS_INVAL("OPC_MXU_Q16SCOP");
26555 generate_exception_end(ctx, EXCP_RI);
26557 case OPC_MXU_Q8MADL:
26558 /* TODO: Implement emulation of Q8MADL instruction. */
26559 MIPS_INVAL("OPC_MXU_Q8MADL");
26560 generate_exception_end(ctx, EXCP_RI);
26562 case OPC_MXU_S32SFL:
26563 /* TODO: Implement emulation of S32SFL instruction. */
26564 MIPS_INVAL("OPC_MXU_S32SFL");
26565 generate_exception_end(ctx, EXCP_RI);
26567 case OPC_MXU_Q8SAD:
26568 /* TODO: Implement emulation of Q8SAD instruction. */
26569 MIPS_INVAL("OPC_MXU_Q8SAD");
26570 generate_exception_end(ctx, EXCP_RI);
26573 MIPS_INVAL("decode_opc_mxu");
26574 generate_exception_end(ctx, EXCP_RI);
26577 gen_set_label(l_exit);
26578 tcg_temp_free(t_mxu_cr);
26582 #endif /* !defined(TARGET_MIPS64) */
26585 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26590 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26592 rs = (ctx->opcode >> 21) & 0x1f;
26593 rt = (ctx->opcode >> 16) & 0x1f;
26594 rd = (ctx->opcode >> 11) & 0x1f;
26596 op1 = MASK_SPECIAL2(ctx->opcode);
26598 case OPC_MADD: /* Multiply and add/sub */
26602 check_insn(ctx, ISA_MIPS32);
26603 gen_muldiv(ctx, op1, rd & 3, rs, rt);
26606 gen_arith(ctx, op1, rd, rs, rt);
26609 case OPC_DIVU_G_2F:
26610 case OPC_MULT_G_2F:
26611 case OPC_MULTU_G_2F:
26613 case OPC_MODU_G_2F:
26614 check_insn(ctx, INSN_LOONGSON2F);
26615 gen_loongson_integer(ctx, op1, rd, rs, rt);
26619 check_insn(ctx, ISA_MIPS32);
26620 gen_cl(ctx, op1, rd, rs);
26623 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26624 gen_helper_do_semihosting(cpu_env);
26626 /* XXX: not clear which exception should be raised
26627 * when in debug mode...
26629 check_insn(ctx, ISA_MIPS32);
26630 generate_exception_end(ctx, EXCP_DBp);
26633 #if defined(TARGET_MIPS64)
26636 check_insn(ctx, ISA_MIPS64);
26637 check_mips_64(ctx);
26638 gen_cl(ctx, op1, rd, rs);
26640 case OPC_DMULT_G_2F:
26641 case OPC_DMULTU_G_2F:
26642 case OPC_DDIV_G_2F:
26643 case OPC_DDIVU_G_2F:
26644 case OPC_DMOD_G_2F:
26645 case OPC_DMODU_G_2F:
26646 check_insn(ctx, INSN_LOONGSON2F);
26647 gen_loongson_integer(ctx, op1, rd, rs, rt);
26650 default: /* Invalid */
26651 MIPS_INVAL("special2_legacy");
26652 generate_exception_end(ctx, EXCP_RI);
26657 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26659 int rs, rt, rd, sa;
26663 rs = (ctx->opcode >> 21) & 0x1f;
26664 rt = (ctx->opcode >> 16) & 0x1f;
26665 rd = (ctx->opcode >> 11) & 0x1f;
26666 sa = (ctx->opcode >> 6) & 0x1f;
26667 imm = (int16_t)ctx->opcode >> 7;
26669 op1 = MASK_SPECIAL3(ctx->opcode);
26673 /* hint codes 24-31 are reserved and signal RI */
26674 generate_exception_end(ctx, EXCP_RI);
26676 /* Treat as NOP. */
26679 check_cp0_enabled(ctx);
26680 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26681 gen_cache_operation(ctx, rt, rs, imm);
26685 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
26688 gen_ld(ctx, op1, rt, rs, imm);
26693 /* Treat as NOP. */
26696 op2 = MASK_BSHFL(ctx->opcode);
26702 gen_align(ctx, 32, rd, rs, rt, sa & 3);
26705 gen_bitswap(ctx, op2, rd, rt);
26710 #if defined(TARGET_MIPS64)
26712 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
26715 gen_ld(ctx, op1, rt, rs, imm);
26718 check_mips_64(ctx);
26721 /* Treat as NOP. */
26724 op2 = MASK_DBSHFL(ctx->opcode);
26734 gen_align(ctx, 64, rd, rs, rt, sa & 7);
26737 gen_bitswap(ctx, op2, rd, rt);
26744 default: /* Invalid */
26745 MIPS_INVAL("special3_r6");
26746 generate_exception_end(ctx, EXCP_RI);
26751 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
26756 rs = (ctx->opcode >> 21) & 0x1f;
26757 rt = (ctx->opcode >> 16) & 0x1f;
26758 rd = (ctx->opcode >> 11) & 0x1f;
26760 op1 = MASK_SPECIAL3(ctx->opcode);
26763 case OPC_DIVU_G_2E:
26765 case OPC_MODU_G_2E:
26766 case OPC_MULT_G_2E:
26767 case OPC_MULTU_G_2E:
26768 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26769 * the same mask and op1. */
26770 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
26771 op2 = MASK_ADDUH_QB(ctx->opcode);
26774 case OPC_ADDUH_R_QB:
26776 case OPC_ADDQH_R_PH:
26778 case OPC_ADDQH_R_W:
26780 case OPC_SUBUH_R_QB:
26782 case OPC_SUBQH_R_PH:
26784 case OPC_SUBQH_R_W:
26785 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26790 case OPC_MULQ_RS_W:
26791 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26794 MIPS_INVAL("MASK ADDUH.QB");
26795 generate_exception_end(ctx, EXCP_RI);
26798 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
26799 gen_loongson_integer(ctx, op1, rd, rs, rt);
26801 generate_exception_end(ctx, EXCP_RI);
26805 op2 = MASK_LX(ctx->opcode);
26807 #if defined(TARGET_MIPS64)
26813 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26815 default: /* Invalid */
26816 MIPS_INVAL("MASK LX");
26817 generate_exception_end(ctx, EXCP_RI);
26821 case OPC_ABSQ_S_PH_DSP:
26822 op2 = MASK_ABSQ_S_PH(ctx->opcode);
26824 case OPC_ABSQ_S_QB:
26825 case OPC_ABSQ_S_PH:
26827 case OPC_PRECEQ_W_PHL:
26828 case OPC_PRECEQ_W_PHR:
26829 case OPC_PRECEQU_PH_QBL:
26830 case OPC_PRECEQU_PH_QBR:
26831 case OPC_PRECEQU_PH_QBLA:
26832 case OPC_PRECEQU_PH_QBRA:
26833 case OPC_PRECEU_PH_QBL:
26834 case OPC_PRECEU_PH_QBR:
26835 case OPC_PRECEU_PH_QBLA:
26836 case OPC_PRECEU_PH_QBRA:
26837 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26844 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26847 MIPS_INVAL("MASK ABSQ_S.PH");
26848 generate_exception_end(ctx, EXCP_RI);
26852 case OPC_ADDU_QB_DSP:
26853 op2 = MASK_ADDU_QB(ctx->opcode);
26856 case OPC_ADDQ_S_PH:
26859 case OPC_ADDU_S_QB:
26861 case OPC_ADDU_S_PH:
26863 case OPC_SUBQ_S_PH:
26866 case OPC_SUBU_S_QB:
26868 case OPC_SUBU_S_PH:
26872 case OPC_RADDU_W_QB:
26873 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26875 case OPC_MULEU_S_PH_QBL:
26876 case OPC_MULEU_S_PH_QBR:
26877 case OPC_MULQ_RS_PH:
26878 case OPC_MULEQ_S_W_PHL:
26879 case OPC_MULEQ_S_W_PHR:
26880 case OPC_MULQ_S_PH:
26881 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26883 default: /* Invalid */
26884 MIPS_INVAL("MASK ADDU.QB");
26885 generate_exception_end(ctx, EXCP_RI);
26890 case OPC_CMPU_EQ_QB_DSP:
26891 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
26893 case OPC_PRECR_SRA_PH_W:
26894 case OPC_PRECR_SRA_R_PH_W:
26895 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
26897 case OPC_PRECR_QB_PH:
26898 case OPC_PRECRQ_QB_PH:
26899 case OPC_PRECRQ_PH_W:
26900 case OPC_PRECRQ_RS_PH_W:
26901 case OPC_PRECRQU_S_QB_PH:
26902 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26904 case OPC_CMPU_EQ_QB:
26905 case OPC_CMPU_LT_QB:
26906 case OPC_CMPU_LE_QB:
26907 case OPC_CMP_EQ_PH:
26908 case OPC_CMP_LT_PH:
26909 case OPC_CMP_LE_PH:
26910 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
26912 case OPC_CMPGU_EQ_QB:
26913 case OPC_CMPGU_LT_QB:
26914 case OPC_CMPGU_LE_QB:
26915 case OPC_CMPGDU_EQ_QB:
26916 case OPC_CMPGDU_LT_QB:
26917 case OPC_CMPGDU_LE_QB:
26920 case OPC_PACKRL_PH:
26921 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26923 default: /* Invalid */
26924 MIPS_INVAL("MASK CMPU.EQ.QB");
26925 generate_exception_end(ctx, EXCP_RI);
26929 case OPC_SHLL_QB_DSP:
26930 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26932 case OPC_DPA_W_PH_DSP:
26933 op2 = MASK_DPA_W_PH(ctx->opcode);
26935 case OPC_DPAU_H_QBL:
26936 case OPC_DPAU_H_QBR:
26937 case OPC_DPSU_H_QBL:
26938 case OPC_DPSU_H_QBR:
26940 case OPC_DPAX_W_PH:
26941 case OPC_DPAQ_S_W_PH:
26942 case OPC_DPAQX_S_W_PH:
26943 case OPC_DPAQX_SA_W_PH:
26945 case OPC_DPSX_W_PH:
26946 case OPC_DPSQ_S_W_PH:
26947 case OPC_DPSQX_S_W_PH:
26948 case OPC_DPSQX_SA_W_PH:
26949 case OPC_MULSAQ_S_W_PH:
26950 case OPC_DPAQ_SA_L_W:
26951 case OPC_DPSQ_SA_L_W:
26952 case OPC_MAQ_S_W_PHL:
26953 case OPC_MAQ_S_W_PHR:
26954 case OPC_MAQ_SA_W_PHL:
26955 case OPC_MAQ_SA_W_PHR:
26956 case OPC_MULSA_W_PH:
26957 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26959 default: /* Invalid */
26960 MIPS_INVAL("MASK DPAW.PH");
26961 generate_exception_end(ctx, EXCP_RI);
26966 op2 = MASK_INSV(ctx->opcode);
26977 t0 = tcg_temp_new();
26978 t1 = tcg_temp_new();
26980 gen_load_gpr(t0, rt);
26981 gen_load_gpr(t1, rs);
26983 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
26989 default: /* Invalid */
26990 MIPS_INVAL("MASK INSV");
26991 generate_exception_end(ctx, EXCP_RI);
26995 case OPC_APPEND_DSP:
26996 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26998 case OPC_EXTR_W_DSP:
26999 op2 = MASK_EXTR_W(ctx->opcode);
27003 case OPC_EXTR_RS_W:
27005 case OPC_EXTRV_S_H:
27007 case OPC_EXTRV_R_W:
27008 case OPC_EXTRV_RS_W:
27013 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27016 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27022 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27024 default: /* Invalid */
27025 MIPS_INVAL("MASK EXTR.W");
27026 generate_exception_end(ctx, EXCP_RI);
27030 #if defined(TARGET_MIPS64)
27031 case OPC_DDIV_G_2E:
27032 case OPC_DDIVU_G_2E:
27033 case OPC_DMULT_G_2E:
27034 case OPC_DMULTU_G_2E:
27035 case OPC_DMOD_G_2E:
27036 case OPC_DMODU_G_2E:
27037 check_insn(ctx, INSN_LOONGSON2E);
27038 gen_loongson_integer(ctx, op1, rd, rs, rt);
27040 case OPC_ABSQ_S_QH_DSP:
27041 op2 = MASK_ABSQ_S_QH(ctx->opcode);
27043 case OPC_PRECEQ_L_PWL:
27044 case OPC_PRECEQ_L_PWR:
27045 case OPC_PRECEQ_PW_QHL:
27046 case OPC_PRECEQ_PW_QHR:
27047 case OPC_PRECEQ_PW_QHLA:
27048 case OPC_PRECEQ_PW_QHRA:
27049 case OPC_PRECEQU_QH_OBL:
27050 case OPC_PRECEQU_QH_OBR:
27051 case OPC_PRECEQU_QH_OBLA:
27052 case OPC_PRECEQU_QH_OBRA:
27053 case OPC_PRECEU_QH_OBL:
27054 case OPC_PRECEU_QH_OBR:
27055 case OPC_PRECEU_QH_OBLA:
27056 case OPC_PRECEU_QH_OBRA:
27057 case OPC_ABSQ_S_OB:
27058 case OPC_ABSQ_S_PW:
27059 case OPC_ABSQ_S_QH:
27060 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27068 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27070 default: /* Invalid */
27071 MIPS_INVAL("MASK ABSQ_S.QH");
27072 generate_exception_end(ctx, EXCP_RI);
27076 case OPC_ADDU_OB_DSP:
27077 op2 = MASK_ADDU_OB(ctx->opcode);
27079 case OPC_RADDU_L_OB:
27081 case OPC_SUBQ_S_PW:
27083 case OPC_SUBQ_S_QH:
27085 case OPC_SUBU_S_OB:
27087 case OPC_SUBU_S_QH:
27089 case OPC_SUBUH_R_OB:
27091 case OPC_ADDQ_S_PW:
27093 case OPC_ADDQ_S_QH:
27095 case OPC_ADDU_S_OB:
27097 case OPC_ADDU_S_QH:
27099 case OPC_ADDUH_R_OB:
27100 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27102 case OPC_MULEQ_S_PW_QHL:
27103 case OPC_MULEQ_S_PW_QHR:
27104 case OPC_MULEU_S_QH_OBL:
27105 case OPC_MULEU_S_QH_OBR:
27106 case OPC_MULQ_RS_QH:
27107 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27109 default: /* Invalid */
27110 MIPS_INVAL("MASK ADDU.OB");
27111 generate_exception_end(ctx, EXCP_RI);
27115 case OPC_CMPU_EQ_OB_DSP:
27116 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27118 case OPC_PRECR_SRA_QH_PW:
27119 case OPC_PRECR_SRA_R_QH_PW:
27120 /* Return value is rt. */
27121 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27123 case OPC_PRECR_OB_QH:
27124 case OPC_PRECRQ_OB_QH:
27125 case OPC_PRECRQ_PW_L:
27126 case OPC_PRECRQ_QH_PW:
27127 case OPC_PRECRQ_RS_QH_PW:
27128 case OPC_PRECRQU_S_OB_QH:
27129 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27131 case OPC_CMPU_EQ_OB:
27132 case OPC_CMPU_LT_OB:
27133 case OPC_CMPU_LE_OB:
27134 case OPC_CMP_EQ_QH:
27135 case OPC_CMP_LT_QH:
27136 case OPC_CMP_LE_QH:
27137 case OPC_CMP_EQ_PW:
27138 case OPC_CMP_LT_PW:
27139 case OPC_CMP_LE_PW:
27140 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27142 case OPC_CMPGDU_EQ_OB:
27143 case OPC_CMPGDU_LT_OB:
27144 case OPC_CMPGDU_LE_OB:
27145 case OPC_CMPGU_EQ_OB:
27146 case OPC_CMPGU_LT_OB:
27147 case OPC_CMPGU_LE_OB:
27148 case OPC_PACKRL_PW:
27152 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27154 default: /* Invalid */
27155 MIPS_INVAL("MASK CMPU_EQ.OB");
27156 generate_exception_end(ctx, EXCP_RI);
27160 case OPC_DAPPEND_DSP:
27161 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27163 case OPC_DEXTR_W_DSP:
27164 op2 = MASK_DEXTR_W(ctx->opcode);
27171 case OPC_DEXTR_R_L:
27172 case OPC_DEXTR_RS_L:
27174 case OPC_DEXTR_R_W:
27175 case OPC_DEXTR_RS_W:
27176 case OPC_DEXTR_S_H:
27178 case OPC_DEXTRV_R_L:
27179 case OPC_DEXTRV_RS_L:
27180 case OPC_DEXTRV_S_H:
27182 case OPC_DEXTRV_R_W:
27183 case OPC_DEXTRV_RS_W:
27184 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27189 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27191 default: /* Invalid */
27192 MIPS_INVAL("MASK EXTR.W");
27193 generate_exception_end(ctx, EXCP_RI);
27197 case OPC_DPAQ_W_QH_DSP:
27198 op2 = MASK_DPAQ_W_QH(ctx->opcode);
27200 case OPC_DPAU_H_OBL:
27201 case OPC_DPAU_H_OBR:
27202 case OPC_DPSU_H_OBL:
27203 case OPC_DPSU_H_OBR:
27205 case OPC_DPAQ_S_W_QH:
27207 case OPC_DPSQ_S_W_QH:
27208 case OPC_MULSAQ_S_W_QH:
27209 case OPC_DPAQ_SA_L_PW:
27210 case OPC_DPSQ_SA_L_PW:
27211 case OPC_MULSAQ_S_L_PW:
27212 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27214 case OPC_MAQ_S_W_QHLL:
27215 case OPC_MAQ_S_W_QHLR:
27216 case OPC_MAQ_S_W_QHRL:
27217 case OPC_MAQ_S_W_QHRR:
27218 case OPC_MAQ_SA_W_QHLL:
27219 case OPC_MAQ_SA_W_QHLR:
27220 case OPC_MAQ_SA_W_QHRL:
27221 case OPC_MAQ_SA_W_QHRR:
27222 case OPC_MAQ_S_L_PWL:
27223 case OPC_MAQ_S_L_PWR:
27228 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27230 default: /* Invalid */
27231 MIPS_INVAL("MASK DPAQ.W.QH");
27232 generate_exception_end(ctx, EXCP_RI);
27236 case OPC_DINSV_DSP:
27237 op2 = MASK_INSV(ctx->opcode);
27248 t0 = tcg_temp_new();
27249 t1 = tcg_temp_new();
27251 gen_load_gpr(t0, rt);
27252 gen_load_gpr(t1, rs);
27254 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27260 default: /* Invalid */
27261 MIPS_INVAL("MASK DINSV");
27262 generate_exception_end(ctx, EXCP_RI);
27266 case OPC_SHLL_OB_DSP:
27267 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27270 default: /* Invalid */
27271 MIPS_INVAL("special3_legacy");
27272 generate_exception_end(ctx, EXCP_RI);
27278 #if defined(TARGET_MIPS64)
27280 static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27282 uint32_t opc = MASK_MMI0(ctx->opcode);
27285 case MMI_OPC_0_PADDW: /* TODO: MMI_OPC_0_PADDW */
27286 case MMI_OPC_0_PSUBW: /* TODO: MMI_OPC_0_PSUBW */
27287 case MMI_OPC_0_PCGTW: /* TODO: MMI_OPC_0_PCGTW */
27288 case MMI_OPC_0_PMAXW: /* TODO: MMI_OPC_0_PMAXW */
27289 case MMI_OPC_0_PADDH: /* TODO: MMI_OPC_0_PADDH */
27290 case MMI_OPC_0_PSUBH: /* TODO: MMI_OPC_0_PSUBH */
27291 case MMI_OPC_0_PCGTH: /* TODO: MMI_OPC_0_PCGTH */
27292 case MMI_OPC_0_PMAXH: /* TODO: MMI_OPC_0_PMAXH */
27293 case MMI_OPC_0_PADDB: /* TODO: MMI_OPC_0_PADDB */
27294 case MMI_OPC_0_PSUBB: /* TODO: MMI_OPC_0_PSUBB */
27295 case MMI_OPC_0_PCGTB: /* TODO: MMI_OPC_0_PCGTB */
27296 case MMI_OPC_0_PADDSW: /* TODO: MMI_OPC_0_PADDSW */
27297 case MMI_OPC_0_PSUBSW: /* TODO: MMI_OPC_0_PSUBSW */
27298 case MMI_OPC_0_PEXTLW: /* TODO: MMI_OPC_0_PEXTLW */
27299 case MMI_OPC_0_PPACW: /* TODO: MMI_OPC_0_PPACW */
27300 case MMI_OPC_0_PADDSH: /* TODO: MMI_OPC_0_PADDSH */
27301 case MMI_OPC_0_PSUBSH: /* TODO: MMI_OPC_0_PSUBSH */
27302 case MMI_OPC_0_PEXTLH: /* TODO: MMI_OPC_0_PEXTLH */
27303 case MMI_OPC_0_PPACH: /* TODO: MMI_OPC_0_PPACH */
27304 case MMI_OPC_0_PADDSB: /* TODO: MMI_OPC_0_PADDSB */
27305 case MMI_OPC_0_PSUBSB: /* TODO: MMI_OPC_0_PSUBSB */
27306 case MMI_OPC_0_PEXTLB: /* TODO: MMI_OPC_0_PEXTLB */
27307 case MMI_OPC_0_PPACB: /* TODO: MMI_OPC_0_PPACB */
27308 case MMI_OPC_0_PEXT5: /* TODO: MMI_OPC_0_PEXT5 */
27309 case MMI_OPC_0_PPAC5: /* TODO: MMI_OPC_0_PPAC5 */
27310 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27313 MIPS_INVAL("TX79 MMI class MMI0");
27314 generate_exception_end(ctx, EXCP_RI);
27319 static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27321 uint32_t opc = MASK_MMI1(ctx->opcode);
27324 case MMI_OPC_1_PABSW: /* TODO: MMI_OPC_1_PABSW */
27325 case MMI_OPC_1_PCEQW: /* TODO: MMI_OPC_1_PCEQW */
27326 case MMI_OPC_1_PMINW: /* TODO: MMI_OPC_1_PMINW */
27327 case MMI_OPC_1_PADSBH: /* TODO: MMI_OPC_1_PADSBH */
27328 case MMI_OPC_1_PABSH: /* TODO: MMI_OPC_1_PABSH */
27329 case MMI_OPC_1_PCEQH: /* TODO: MMI_OPC_1_PCEQH */
27330 case MMI_OPC_1_PMINH: /* TODO: MMI_OPC_1_PMINH */
27331 case MMI_OPC_1_PCEQB: /* TODO: MMI_OPC_1_PCEQB */
27332 case MMI_OPC_1_PADDUW: /* TODO: MMI_OPC_1_PADDUW */
27333 case MMI_OPC_1_PSUBUW: /* TODO: MMI_OPC_1_PSUBUW */
27334 case MMI_OPC_1_PEXTUW: /* TODO: MMI_OPC_1_PEXTUW */
27335 case MMI_OPC_1_PADDUH: /* TODO: MMI_OPC_1_PADDUH */
27336 case MMI_OPC_1_PSUBUH: /* TODO: MMI_OPC_1_PSUBUH */
27337 case MMI_OPC_1_PEXTUH: /* TODO: MMI_OPC_1_PEXTUH */
27338 case MMI_OPC_1_PADDUB: /* TODO: MMI_OPC_1_PADDUB */
27339 case MMI_OPC_1_PSUBUB: /* TODO: MMI_OPC_1_PSUBUB */
27340 case MMI_OPC_1_PEXTUB: /* TODO: MMI_OPC_1_PEXTUB */
27341 case MMI_OPC_1_QFSRV: /* TODO: MMI_OPC_1_QFSRV */
27342 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27345 MIPS_INVAL("TX79 MMI class MMI1");
27346 generate_exception_end(ctx, EXCP_RI);
27351 static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27353 uint32_t opc = MASK_MMI2(ctx->opcode);
27356 case MMI_OPC_2_PMADDW: /* TODO: MMI_OPC_2_PMADDW */
27357 case MMI_OPC_2_PSLLVW: /* TODO: MMI_OPC_2_PSLLVW */
27358 case MMI_OPC_2_PSRLVW: /* TODO: MMI_OPC_2_PSRLVW */
27359 case MMI_OPC_2_PMSUBW: /* TODO: MMI_OPC_2_PMSUBW */
27360 case MMI_OPC_2_PMFHI: /* TODO: MMI_OPC_2_PMFHI */
27361 case MMI_OPC_2_PMFLO: /* TODO: MMI_OPC_2_PMFLO */
27362 case MMI_OPC_2_PINTH: /* TODO: MMI_OPC_2_PINTH */
27363 case MMI_OPC_2_PMULTW: /* TODO: MMI_OPC_2_PMULTW */
27364 case MMI_OPC_2_PDIVW: /* TODO: MMI_OPC_2_PDIVW */
27365 case MMI_OPC_2_PCPYLD: /* TODO: MMI_OPC_2_PCPYLD */
27366 case MMI_OPC_2_PMADDH: /* TODO: MMI_OPC_2_PMADDH */
27367 case MMI_OPC_2_PHMADH: /* TODO: MMI_OPC_2_PHMADH */
27368 case MMI_OPC_2_PAND: /* TODO: MMI_OPC_2_PAND */
27369 case MMI_OPC_2_PXOR: /* TODO: MMI_OPC_2_PXOR */
27370 case MMI_OPC_2_PMSUBH: /* TODO: MMI_OPC_2_PMSUBH */
27371 case MMI_OPC_2_PHMSBH: /* TODO: MMI_OPC_2_PHMSBH */
27372 case MMI_OPC_2_PEXEH: /* TODO: MMI_OPC_2_PEXEH */
27373 case MMI_OPC_2_PREVH: /* TODO: MMI_OPC_2_PREVH */
27374 case MMI_OPC_2_PMULTH: /* TODO: MMI_OPC_2_PMULTH */
27375 case MMI_OPC_2_PDIVBW: /* TODO: MMI_OPC_2_PDIVBW */
27376 case MMI_OPC_2_PEXEW: /* TODO: MMI_OPC_2_PEXEW */
27377 case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */
27378 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27381 MIPS_INVAL("TX79 MMI class MMI2");
27382 generate_exception_end(ctx, EXCP_RI);
27387 static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27389 uint32_t opc = MASK_MMI3(ctx->opcode);
27392 case MMI_OPC_3_PMADDUW: /* TODO: MMI_OPC_3_PMADDUW */
27393 case MMI_OPC_3_PSRAVW: /* TODO: MMI_OPC_3_PSRAVW */
27394 case MMI_OPC_3_PMTHI: /* TODO: MMI_OPC_3_PMTHI */
27395 case MMI_OPC_3_PMTLO: /* TODO: MMI_OPC_3_PMTLO */
27396 case MMI_OPC_3_PINTEH: /* TODO: MMI_OPC_3_PINTEH */
27397 case MMI_OPC_3_PMULTUW: /* TODO: MMI_OPC_3_PMULTUW */
27398 case MMI_OPC_3_PDIVUW: /* TODO: MMI_OPC_3_PDIVUW */
27399 case MMI_OPC_3_PCPYUD: /* TODO: MMI_OPC_3_PCPYUD */
27400 case MMI_OPC_3_POR: /* TODO: MMI_OPC_3_POR */
27401 case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */
27402 case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */
27403 case MMI_OPC_3_PCPYH: /* TODO: MMI_OPC_3_PCPYH */
27404 case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */
27405 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27408 MIPS_INVAL("TX79 MMI class MMI3");
27409 generate_exception_end(ctx, EXCP_RI);
27414 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27416 uint32_t opc = MASK_MMI(ctx->opcode);
27417 int rs = extract32(ctx->opcode, 21, 5);
27418 int rt = extract32(ctx->opcode, 16, 5);
27419 int rd = extract32(ctx->opcode, 11, 5);
27422 case MMI_OPC_CLASS_MMI0:
27423 decode_mmi0(env, ctx);
27425 case MMI_OPC_CLASS_MMI1:
27426 decode_mmi1(env, ctx);
27428 case MMI_OPC_CLASS_MMI2:
27429 decode_mmi2(env, ctx);
27431 case MMI_OPC_CLASS_MMI3:
27432 decode_mmi3(env, ctx);
27434 case MMI_OPC_MULT1:
27435 case MMI_OPC_MULTU1:
27437 case MMI_OPC_MADDU:
27438 case MMI_OPC_MADD1:
27439 case MMI_OPC_MADDU1:
27440 gen_mul_txx9(ctx, opc, rd, rs, rt);
27443 case MMI_OPC_DIVU1:
27444 gen_div1_tx79(ctx, opc, rs, rt);
27446 case MMI_OPC_MTLO1:
27447 case MMI_OPC_MTHI1:
27448 gen_HILO1_tx79(ctx, opc, rs);
27450 case MMI_OPC_MFLO1:
27451 case MMI_OPC_MFHI1:
27452 gen_HILO1_tx79(ctx, opc, rd);
27454 case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */
27455 case MMI_OPC_PMFHL: /* TODO: MMI_OPC_PMFHL */
27456 case MMI_OPC_PMTHL: /* TODO: MMI_OPC_PMTHL */
27457 case MMI_OPC_PSLLH: /* TODO: MMI_OPC_PSLLH */
27458 case MMI_OPC_PSRLH: /* TODO: MMI_OPC_PSRLH */
27459 case MMI_OPC_PSRAH: /* TODO: MMI_OPC_PSRAH */
27460 case MMI_OPC_PSLLW: /* TODO: MMI_OPC_PSLLW */
27461 case MMI_OPC_PSRLW: /* TODO: MMI_OPC_PSRLW */
27462 case MMI_OPC_PSRAW: /* TODO: MMI_OPC_PSRAW */
27463 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI */
27466 MIPS_INVAL("TX79 MMI class");
27467 generate_exception_end(ctx, EXCP_RI);
27472 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27474 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_LQ */
27477 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27479 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_SQ */
27483 * The TX79-specific instruction Store Quadword
27485 * +--------+-------+-------+------------------------+
27486 * | 011111 | base | rt | offset | SQ
27487 * +--------+-------+-------+------------------------+
27490 * has the same opcode as the Read Hardware Register instruction
27492 * +--------+-------+-------+-------+-------+--------+
27493 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
27494 * +--------+-------+-------+-------+-------+--------+
27497 * that is required, trapped and emulated by the Linux kernel. However, all
27498 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27499 * offset is odd. Therefore all valid SQ instructions can execute normally.
27500 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27501 * between SQ and RDHWR, as the Linux kernel does.
27503 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27505 int base = extract32(ctx->opcode, 21, 5);
27506 int rt = extract32(ctx->opcode, 16, 5);
27507 int offset = extract32(ctx->opcode, 0, 16);
27509 #ifdef CONFIG_USER_ONLY
27510 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27511 uint32_t op2 = extract32(ctx->opcode, 6, 5);
27513 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27514 int rd = extract32(ctx->opcode, 11, 5);
27516 gen_rdhwr(ctx, rt, rd, 0);
27521 gen_mmi_sq(ctx, base, rt, offset);
27526 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27528 int rs, rt, rd, sa;
27532 rs = (ctx->opcode >> 21) & 0x1f;
27533 rt = (ctx->opcode >> 16) & 0x1f;
27534 rd = (ctx->opcode >> 11) & 0x1f;
27535 sa = (ctx->opcode >> 6) & 0x1f;
27536 imm = sextract32(ctx->opcode, 7, 9);
27538 op1 = MASK_SPECIAL3(ctx->opcode);
27541 * EVA loads and stores overlap Loongson 2E instructions decoded by
27542 * decode_opc_special3_legacy(), so be careful to allow their decoding when
27549 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27557 check_cp0_enabled(ctx);
27558 gen_ld(ctx, op1, rt, rs, imm);
27562 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27567 check_cp0_enabled(ctx);
27568 gen_st(ctx, op1, rt, rs, imm);
27571 check_cp0_enabled(ctx);
27572 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
27575 check_cp0_enabled(ctx);
27576 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27577 gen_cache_operation(ctx, rt, rs, imm);
27579 /* Treat as NOP. */
27582 check_cp0_enabled(ctx);
27583 /* Treat as NOP. */
27591 check_insn(ctx, ISA_MIPS32R2);
27592 gen_bitops(ctx, op1, rt, rs, sa, rd);
27595 op2 = MASK_BSHFL(ctx->opcode);
27602 check_insn(ctx, ISA_MIPS32R6);
27603 decode_opc_special3_r6(env, ctx);
27606 check_insn(ctx, ISA_MIPS32R2);
27607 gen_bshfl(ctx, op2, rt, rd);
27611 #if defined(TARGET_MIPS64)
27618 check_insn(ctx, ISA_MIPS64R2);
27619 check_mips_64(ctx);
27620 gen_bitops(ctx, op1, rt, rs, sa, rd);
27623 op2 = MASK_DBSHFL(ctx->opcode);
27634 check_insn(ctx, ISA_MIPS32R6);
27635 decode_opc_special3_r6(env, ctx);
27638 check_insn(ctx, ISA_MIPS64R2);
27639 check_mips_64(ctx);
27640 op2 = MASK_DBSHFL(ctx->opcode);
27641 gen_bshfl(ctx, op2, rt, rd);
27647 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27652 TCGv t0 = tcg_temp_new();
27653 TCGv t1 = tcg_temp_new();
27655 gen_load_gpr(t0, rt);
27656 gen_load_gpr(t1, rs);
27657 gen_helper_fork(t0, t1);
27665 TCGv t0 = tcg_temp_new();
27667 gen_load_gpr(t0, rs);
27668 gen_helper_yield(t0, cpu_env, t0);
27669 gen_store_gpr(t0, rd);
27674 if (ctx->insn_flags & ISA_MIPS32R6) {
27675 decode_opc_special3_r6(env, ctx);
27677 decode_opc_special3_legacy(env, ctx);
27682 /* MIPS SIMD Architecture (MSA) */
27683 static inline int check_msa_access(DisasContext *ctx)
27685 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
27686 !(ctx->hflags & MIPS_HFLAG_F64))) {
27687 generate_exception_end(ctx, EXCP_RI);
27691 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
27692 if (ctx->insn_flags & ASE_MSA) {
27693 generate_exception_end(ctx, EXCP_MSADIS);
27696 generate_exception_end(ctx, EXCP_RI);
27703 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
27705 /* generates tcg ops to check if any element is 0 */
27706 /* Note this function only works with MSA_WRLEN = 128 */
27707 uint64_t eval_zero_or_big = 0;
27708 uint64_t eval_big = 0;
27709 TCGv_i64 t0 = tcg_temp_new_i64();
27710 TCGv_i64 t1 = tcg_temp_new_i64();
27713 eval_zero_or_big = 0x0101010101010101ULL;
27714 eval_big = 0x8080808080808080ULL;
27717 eval_zero_or_big = 0x0001000100010001ULL;
27718 eval_big = 0x8000800080008000ULL;
27721 eval_zero_or_big = 0x0000000100000001ULL;
27722 eval_big = 0x8000000080000000ULL;
27725 eval_zero_or_big = 0x0000000000000001ULL;
27726 eval_big = 0x8000000000000000ULL;
27729 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
27730 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
27731 tcg_gen_andi_i64(t0, t0, eval_big);
27732 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
27733 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
27734 tcg_gen_andi_i64(t1, t1, eval_big);
27735 tcg_gen_or_i64(t0, t0, t1);
27736 /* if all bits are zero then all elements are not zero */
27737 /* if some bit is non-zero then some element is zero */
27738 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
27739 tcg_gen_trunc_i64_tl(tresult, t0);
27740 tcg_temp_free_i64(t0);
27741 tcg_temp_free_i64(t1);
27744 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
27746 uint8_t df = (ctx->opcode >> 21) & 0x3;
27747 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27748 int64_t s16 = (int16_t)ctx->opcode;
27750 check_msa_access(ctx);
27752 if (ctx->hflags & MIPS_HFLAG_BMASK) {
27753 generate_exception_end(ctx, EXCP_RI);
27760 TCGv_i64 t0 = tcg_temp_new_i64();
27761 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
27762 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
27763 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
27764 tcg_gen_trunc_i64_tl(bcond, t0);
27765 tcg_temp_free_i64(t0);
27772 gen_check_zero_element(bcond, df, wt);
27778 gen_check_zero_element(bcond, df, wt);
27779 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
27783 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
27785 ctx->hflags |= MIPS_HFLAG_BC;
27786 ctx->hflags |= MIPS_HFLAG_BDS32;
27789 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
27791 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
27792 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
27793 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27794 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27796 TCGv_i32 twd = tcg_const_i32(wd);
27797 TCGv_i32 tws = tcg_const_i32(ws);
27798 TCGv_i32 ti8 = tcg_const_i32(i8);
27800 switch (MASK_MSA_I8(ctx->opcode)) {
27802 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
27805 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
27808 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
27811 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
27814 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27817 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27820 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27826 uint8_t df = (ctx->opcode >> 24) & 0x3;
27827 if (df == DF_DOUBLE) {
27828 generate_exception_end(ctx, EXCP_RI);
27830 TCGv_i32 tdf = tcg_const_i32(df);
27831 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27832 tcg_temp_free_i32(tdf);
27837 MIPS_INVAL("MSA instruction");
27838 generate_exception_end(ctx, EXCP_RI);
27842 tcg_temp_free_i32(twd);
27843 tcg_temp_free_i32(tws);
27844 tcg_temp_free_i32(ti8);
27847 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
27849 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27850 uint8_t df = (ctx->opcode >> 21) & 0x3;
27851 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
27852 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
27853 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27854 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27856 TCGv_i32 tdf = tcg_const_i32(df);
27857 TCGv_i32 twd = tcg_const_i32(wd);
27858 TCGv_i32 tws = tcg_const_i32(ws);
27859 TCGv_i32 timm = tcg_temp_new_i32();
27860 tcg_gen_movi_i32(timm, u5);
27862 switch (MASK_MSA_I5(ctx->opcode)) {
27864 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
27867 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
27869 case OPC_MAXI_S_df:
27870 tcg_gen_movi_i32(timm, s5);
27871 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
27873 case OPC_MAXI_U_df:
27874 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
27876 case OPC_MINI_S_df:
27877 tcg_gen_movi_i32(timm, s5);
27878 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
27880 case OPC_MINI_U_df:
27881 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
27884 tcg_gen_movi_i32(timm, s5);
27885 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
27887 case OPC_CLTI_S_df:
27888 tcg_gen_movi_i32(timm, s5);
27889 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
27891 case OPC_CLTI_U_df:
27892 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
27894 case OPC_CLEI_S_df:
27895 tcg_gen_movi_i32(timm, s5);
27896 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
27898 case OPC_CLEI_U_df:
27899 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
27903 int32_t s10 = sextract32(ctx->opcode, 11, 10);
27904 tcg_gen_movi_i32(timm, s10);
27905 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
27909 MIPS_INVAL("MSA instruction");
27910 generate_exception_end(ctx, EXCP_RI);
27914 tcg_temp_free_i32(tdf);
27915 tcg_temp_free_i32(twd);
27916 tcg_temp_free_i32(tws);
27917 tcg_temp_free_i32(timm);
27920 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
27922 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27923 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
27924 uint32_t df = 0, m = 0;
27925 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27926 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27933 if ((dfm & 0x40) == 0x00) {
27936 } else if ((dfm & 0x60) == 0x40) {
27939 } else if ((dfm & 0x70) == 0x60) {
27942 } else if ((dfm & 0x78) == 0x70) {
27946 generate_exception_end(ctx, EXCP_RI);
27950 tdf = tcg_const_i32(df);
27951 tm = tcg_const_i32(m);
27952 twd = tcg_const_i32(wd);
27953 tws = tcg_const_i32(ws);
27955 switch (MASK_MSA_BIT(ctx->opcode)) {
27957 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
27960 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
27963 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
27966 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
27969 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
27972 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
27974 case OPC_BINSLI_df:
27975 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
27977 case OPC_BINSRI_df:
27978 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
27981 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
27984 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
27987 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
27990 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
27993 MIPS_INVAL("MSA instruction");
27994 generate_exception_end(ctx, EXCP_RI);
27998 tcg_temp_free_i32(tdf);
27999 tcg_temp_free_i32(tm);
28000 tcg_temp_free_i32(twd);
28001 tcg_temp_free_i32(tws);
28004 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28006 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28007 uint8_t df = (ctx->opcode >> 21) & 0x3;
28008 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28009 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28010 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28012 TCGv_i32 tdf = tcg_const_i32(df);
28013 TCGv_i32 twd = tcg_const_i32(wd);
28014 TCGv_i32 tws = tcg_const_i32(ws);
28015 TCGv_i32 twt = tcg_const_i32(wt);
28017 switch (MASK_MSA_3R(ctx->opcode)) {
28019 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28022 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28025 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28028 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28030 case OPC_SUBS_S_df:
28031 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28034 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28037 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28040 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28043 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28046 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28048 case OPC_ADDS_A_df:
28049 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28051 case OPC_SUBS_U_df:
28052 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28055 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28058 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28061 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28064 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28067 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28070 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28072 case OPC_ADDS_S_df:
28073 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28075 case OPC_SUBSUS_U_df:
28076 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28079 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28082 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28085 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28088 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28091 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28094 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28096 case OPC_ADDS_U_df:
28097 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28099 case OPC_SUBSUU_S_df:
28100 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28103 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28106 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28109 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28112 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28115 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28117 case OPC_ASUB_S_df:
28118 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28121 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28124 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28127 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28130 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28133 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28136 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28138 case OPC_ASUB_U_df:
28139 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28142 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28145 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28148 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28151 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28153 case OPC_AVER_S_df:
28154 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28157 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28160 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28163 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28166 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28168 case OPC_AVER_U_df:
28169 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28172 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28175 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28178 case OPC_DOTP_S_df:
28179 case OPC_DOTP_U_df:
28180 case OPC_DPADD_S_df:
28181 case OPC_DPADD_U_df:
28182 case OPC_DPSUB_S_df:
28183 case OPC_HADD_S_df:
28184 case OPC_DPSUB_U_df:
28185 case OPC_HADD_U_df:
28186 case OPC_HSUB_S_df:
28187 case OPC_HSUB_U_df:
28188 if (df == DF_BYTE) {
28189 generate_exception_end(ctx, EXCP_RI);
28192 switch (MASK_MSA_3R(ctx->opcode)) {
28193 case OPC_DOTP_S_df:
28194 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28196 case OPC_DOTP_U_df:
28197 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28199 case OPC_DPADD_S_df:
28200 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28202 case OPC_DPADD_U_df:
28203 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28205 case OPC_DPSUB_S_df:
28206 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28208 case OPC_HADD_S_df:
28209 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28211 case OPC_DPSUB_U_df:
28212 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28214 case OPC_HADD_U_df:
28215 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28217 case OPC_HSUB_S_df:
28218 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28220 case OPC_HSUB_U_df:
28221 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28226 MIPS_INVAL("MSA instruction");
28227 generate_exception_end(ctx, EXCP_RI);
28230 tcg_temp_free_i32(twd);
28231 tcg_temp_free_i32(tws);
28232 tcg_temp_free_i32(twt);
28233 tcg_temp_free_i32(tdf);
28236 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28238 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28239 uint8_t source = (ctx->opcode >> 11) & 0x1f;
28240 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28241 TCGv telm = tcg_temp_new();
28242 TCGv_i32 tsr = tcg_const_i32(source);
28243 TCGv_i32 tdt = tcg_const_i32(dest);
28245 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28247 gen_load_gpr(telm, source);
28248 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28251 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28252 gen_store_gpr(telm, dest);
28255 gen_helper_msa_move_v(cpu_env, tdt, tsr);
28258 MIPS_INVAL("MSA instruction");
28259 generate_exception_end(ctx, EXCP_RI);
28263 tcg_temp_free(telm);
28264 tcg_temp_free_i32(tdt);
28265 tcg_temp_free_i32(tsr);
28268 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28271 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28272 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28273 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28275 TCGv_i32 tws = tcg_const_i32(ws);
28276 TCGv_i32 twd = tcg_const_i32(wd);
28277 TCGv_i32 tn = tcg_const_i32(n);
28278 TCGv_i32 tdf = tcg_const_i32(df);
28280 switch (MASK_MSA_ELM(ctx->opcode)) {
28282 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28284 case OPC_SPLATI_df:
28285 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28288 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28290 case OPC_COPY_S_df:
28291 case OPC_COPY_U_df:
28292 case OPC_INSERT_df:
28293 #if !defined(TARGET_MIPS64)
28294 /* Double format valid only for MIPS64 */
28295 if (df == DF_DOUBLE) {
28296 generate_exception_end(ctx, EXCP_RI);
28300 switch (MASK_MSA_ELM(ctx->opcode)) {
28301 case OPC_COPY_S_df:
28302 if (likely(wd != 0)) {
28303 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
28306 case OPC_COPY_U_df:
28307 if (likely(wd != 0)) {
28308 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
28311 case OPC_INSERT_df:
28312 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
28317 MIPS_INVAL("MSA instruction");
28318 generate_exception_end(ctx, EXCP_RI);
28320 tcg_temp_free_i32(twd);
28321 tcg_temp_free_i32(tws);
28322 tcg_temp_free_i32(tn);
28323 tcg_temp_free_i32(tdf);
28326 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28328 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28329 uint32_t df = 0, n = 0;
28331 if ((dfn & 0x30) == 0x00) {
28334 } else if ((dfn & 0x38) == 0x20) {
28337 } else if ((dfn & 0x3c) == 0x30) {
28340 } else if ((dfn & 0x3e) == 0x38) {
28343 } else if (dfn == 0x3E) {
28344 /* CTCMSA, CFCMSA, MOVE.V */
28345 gen_msa_elm_3e(env, ctx);
28348 generate_exception_end(ctx, EXCP_RI);
28352 gen_msa_elm_df(env, ctx, df, n);
28355 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28357 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28358 uint8_t df = (ctx->opcode >> 21) & 0x1;
28359 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28360 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28361 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28363 TCGv_i32 twd = tcg_const_i32(wd);
28364 TCGv_i32 tws = tcg_const_i32(ws);
28365 TCGv_i32 twt = tcg_const_i32(wt);
28366 TCGv_i32 tdf = tcg_temp_new_i32();
28368 /* adjust df value for floating-point instruction */
28369 tcg_gen_movi_i32(tdf, df + 2);
28371 switch (MASK_MSA_3RF(ctx->opcode)) {
28373 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28376 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28379 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28382 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28385 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28388 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28391 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28394 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28397 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28400 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28403 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28406 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28409 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28412 tcg_gen_movi_i32(tdf, df + 1);
28413 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28416 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28419 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28421 case OPC_MADD_Q_df:
28422 tcg_gen_movi_i32(tdf, df + 1);
28423 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28426 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28428 case OPC_MSUB_Q_df:
28429 tcg_gen_movi_i32(tdf, df + 1);
28430 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28433 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28436 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28439 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28442 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28445 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28448 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28451 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28454 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28457 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28460 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28463 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28466 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28469 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28471 case OPC_MULR_Q_df:
28472 tcg_gen_movi_i32(tdf, df + 1);
28473 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28476 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28478 case OPC_FMIN_A_df:
28479 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28481 case OPC_MADDR_Q_df:
28482 tcg_gen_movi_i32(tdf, df + 1);
28483 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28486 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28489 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28491 case OPC_MSUBR_Q_df:
28492 tcg_gen_movi_i32(tdf, df + 1);
28493 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28496 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28498 case OPC_FMAX_A_df:
28499 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28502 MIPS_INVAL("MSA instruction");
28503 generate_exception_end(ctx, EXCP_RI);
28507 tcg_temp_free_i32(twd);
28508 tcg_temp_free_i32(tws);
28509 tcg_temp_free_i32(twt);
28510 tcg_temp_free_i32(tdf);
28513 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28515 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28516 (op & (0x7 << 18)))
28517 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28518 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28519 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28520 uint8_t df = (ctx->opcode >> 16) & 0x3;
28521 TCGv_i32 twd = tcg_const_i32(wd);
28522 TCGv_i32 tws = tcg_const_i32(ws);
28523 TCGv_i32 twt = tcg_const_i32(wt);
28524 TCGv_i32 tdf = tcg_const_i32(df);
28526 switch (MASK_MSA_2R(ctx->opcode)) {
28528 #if !defined(TARGET_MIPS64)
28529 /* Double format valid only for MIPS64 */
28530 if (df == DF_DOUBLE) {
28531 generate_exception_end(ctx, EXCP_RI);
28535 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28538 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28541 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28544 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28547 MIPS_INVAL("MSA instruction");
28548 generate_exception_end(ctx, EXCP_RI);
28552 tcg_temp_free_i32(twd);
28553 tcg_temp_free_i32(tws);
28554 tcg_temp_free_i32(twt);
28555 tcg_temp_free_i32(tdf);
28558 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28560 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28561 (op & (0xf << 17)))
28562 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28563 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28564 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28565 uint8_t df = (ctx->opcode >> 16) & 0x1;
28566 TCGv_i32 twd = tcg_const_i32(wd);
28567 TCGv_i32 tws = tcg_const_i32(ws);
28568 TCGv_i32 twt = tcg_const_i32(wt);
28569 /* adjust df value for floating-point instruction */
28570 TCGv_i32 tdf = tcg_const_i32(df + 2);
28572 switch (MASK_MSA_2RF(ctx->opcode)) {
28573 case OPC_FCLASS_df:
28574 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28576 case OPC_FTRUNC_S_df:
28577 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28579 case OPC_FTRUNC_U_df:
28580 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28583 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28585 case OPC_FRSQRT_df:
28586 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28589 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28592 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28595 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28597 case OPC_FEXUPL_df:
28598 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28600 case OPC_FEXUPR_df:
28601 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28604 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28607 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28609 case OPC_FTINT_S_df:
28610 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28612 case OPC_FTINT_U_df:
28613 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
28615 case OPC_FFINT_S_df:
28616 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
28618 case OPC_FFINT_U_df:
28619 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
28623 tcg_temp_free_i32(twd);
28624 tcg_temp_free_i32(tws);
28625 tcg_temp_free_i32(twt);
28626 tcg_temp_free_i32(tdf);
28629 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
28631 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
28632 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28633 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28634 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28635 TCGv_i32 twd = tcg_const_i32(wd);
28636 TCGv_i32 tws = tcg_const_i32(ws);
28637 TCGv_i32 twt = tcg_const_i32(wt);
28639 switch (MASK_MSA_VEC(ctx->opcode)) {
28641 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
28644 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
28647 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
28650 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
28653 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
28656 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
28659 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
28662 MIPS_INVAL("MSA instruction");
28663 generate_exception_end(ctx, EXCP_RI);
28667 tcg_temp_free_i32(twd);
28668 tcg_temp_free_i32(tws);
28669 tcg_temp_free_i32(twt);
28672 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
28674 switch (MASK_MSA_VEC(ctx->opcode)) {
28682 gen_msa_vec_v(env, ctx);
28685 gen_msa_2r(env, ctx);
28688 gen_msa_2rf(env, ctx);
28691 MIPS_INVAL("MSA instruction");
28692 generate_exception_end(ctx, EXCP_RI);
28697 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
28699 uint32_t opcode = ctx->opcode;
28700 check_insn(ctx, ASE_MSA);
28701 check_msa_access(ctx);
28703 switch (MASK_MSA_MINOR(opcode)) {
28704 case OPC_MSA_I8_00:
28705 case OPC_MSA_I8_01:
28706 case OPC_MSA_I8_02:
28707 gen_msa_i8(env, ctx);
28709 case OPC_MSA_I5_06:
28710 case OPC_MSA_I5_07:
28711 gen_msa_i5(env, ctx);
28713 case OPC_MSA_BIT_09:
28714 case OPC_MSA_BIT_0A:
28715 gen_msa_bit(env, ctx);
28717 case OPC_MSA_3R_0D:
28718 case OPC_MSA_3R_0E:
28719 case OPC_MSA_3R_0F:
28720 case OPC_MSA_3R_10:
28721 case OPC_MSA_3R_11:
28722 case OPC_MSA_3R_12:
28723 case OPC_MSA_3R_13:
28724 case OPC_MSA_3R_14:
28725 case OPC_MSA_3R_15:
28726 gen_msa_3r(env, ctx);
28729 gen_msa_elm(env, ctx);
28731 case OPC_MSA_3RF_1A:
28732 case OPC_MSA_3RF_1B:
28733 case OPC_MSA_3RF_1C:
28734 gen_msa_3rf(env, ctx);
28737 gen_msa_vec(env, ctx);
28748 int32_t s10 = sextract32(ctx->opcode, 16, 10);
28749 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
28750 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28751 uint8_t df = (ctx->opcode >> 0) & 0x3;
28753 TCGv_i32 twd = tcg_const_i32(wd);
28754 TCGv taddr = tcg_temp_new();
28755 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
28757 switch (MASK_MSA_MINOR(opcode)) {
28759 gen_helper_msa_ld_b(cpu_env, twd, taddr);
28762 gen_helper_msa_ld_h(cpu_env, twd, taddr);
28765 gen_helper_msa_ld_w(cpu_env, twd, taddr);
28768 gen_helper_msa_ld_d(cpu_env, twd, taddr);
28771 gen_helper_msa_st_b(cpu_env, twd, taddr);
28774 gen_helper_msa_st_h(cpu_env, twd, taddr);
28777 gen_helper_msa_st_w(cpu_env, twd, taddr);
28780 gen_helper_msa_st_d(cpu_env, twd, taddr);
28784 tcg_temp_free_i32(twd);
28785 tcg_temp_free(taddr);
28789 MIPS_INVAL("MSA instruction");
28790 generate_exception_end(ctx, EXCP_RI);
28796 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
28799 int rs, rt, rd, sa;
28803 /* make sure instructions are on a word boundary */
28804 if (ctx->base.pc_next & 0x3) {
28805 env->CP0_BadVAddr = ctx->base.pc_next;
28806 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
28810 /* Handle blikely not taken case */
28811 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
28812 TCGLabel *l1 = gen_new_label();
28814 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
28815 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
28816 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
28820 op = MASK_OP_MAJOR(ctx->opcode);
28821 rs = (ctx->opcode >> 21) & 0x1f;
28822 rt = (ctx->opcode >> 16) & 0x1f;
28823 rd = (ctx->opcode >> 11) & 0x1f;
28824 sa = (ctx->opcode >> 6) & 0x1f;
28825 imm = (int16_t)ctx->opcode;
28828 decode_opc_special(env, ctx);
28831 #if defined(TARGET_MIPS64)
28832 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
28833 decode_mmi(env, ctx);
28835 if (ctx->insn_flags & ASE_MXU) {
28836 decode_opc_mxu(env, ctx);
28839 decode_opc_special2_legacy(env, ctx);
28843 #if defined(TARGET_MIPS64)
28844 if (ctx->insn_flags & INSN_R5900) {
28845 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
28847 decode_opc_special3(env, ctx);
28850 decode_opc_special3(env, ctx);
28854 op1 = MASK_REGIMM(ctx->opcode);
28856 case OPC_BLTZL: /* REGIMM branches */
28860 check_insn(ctx, ISA_MIPS2);
28861 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28865 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28869 if (ctx->insn_flags & ISA_MIPS32R6) {
28871 /* OPC_NAL, OPC_BAL */
28872 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
28874 generate_exception_end(ctx, EXCP_RI);
28877 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28880 case OPC_TGEI: /* REGIMM traps */
28887 check_insn(ctx, ISA_MIPS2);
28888 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28889 gen_trap(ctx, op1, rs, -1, imm);
28892 check_insn(ctx, ISA_MIPS32R6);
28893 generate_exception_end(ctx, EXCP_RI);
28896 check_insn(ctx, ISA_MIPS32R2);
28897 /* Break the TB to be able to sync copied instructions
28899 ctx->base.is_jmp = DISAS_STOP;
28901 case OPC_BPOSGE32: /* MIPS DSP branch */
28902 #if defined(TARGET_MIPS64)
28906 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
28908 #if defined(TARGET_MIPS64)
28910 check_insn(ctx, ISA_MIPS32R6);
28911 check_mips_64(ctx);
28913 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28917 check_insn(ctx, ISA_MIPS32R6);
28918 check_mips_64(ctx);
28920 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28924 default: /* Invalid */
28925 MIPS_INVAL("regimm");
28926 generate_exception_end(ctx, EXCP_RI);
28931 check_cp0_enabled(ctx);
28932 op1 = MASK_CP0(ctx->opcode);
28940 #if defined(TARGET_MIPS64)
28944 #ifndef CONFIG_USER_ONLY
28945 gen_cp0(env, ctx, op1, rt, rd);
28946 #endif /* !CONFIG_USER_ONLY */
28964 #ifndef CONFIG_USER_ONLY
28965 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
28966 #endif /* !CONFIG_USER_ONLY */
28969 #ifndef CONFIG_USER_ONLY
28972 TCGv t0 = tcg_temp_new();
28974 op2 = MASK_MFMC0(ctx->opcode);
28978 gen_helper_dmt(t0);
28979 gen_store_gpr(t0, rt);
28983 gen_helper_emt(t0);
28984 gen_store_gpr(t0, rt);
28988 gen_helper_dvpe(t0, cpu_env);
28989 gen_store_gpr(t0, rt);
28993 gen_helper_evpe(t0, cpu_env);
28994 gen_store_gpr(t0, rt);
28997 check_insn(ctx, ISA_MIPS32R6);
28999 gen_helper_dvp(t0, cpu_env);
29000 gen_store_gpr(t0, rt);
29004 check_insn(ctx, ISA_MIPS32R6);
29006 gen_helper_evp(t0, cpu_env);
29007 gen_store_gpr(t0, rt);
29011 check_insn(ctx, ISA_MIPS32R2);
29012 save_cpu_state(ctx, 1);
29013 gen_helper_di(t0, cpu_env);
29014 gen_store_gpr(t0, rt);
29015 /* Stop translation as we may have switched
29016 the execution mode. */
29017 ctx->base.is_jmp = DISAS_STOP;
29020 check_insn(ctx, ISA_MIPS32R2);
29021 save_cpu_state(ctx, 1);
29022 gen_helper_ei(t0, cpu_env);
29023 gen_store_gpr(t0, rt);
29024 /* DISAS_STOP isn't sufficient, we need to ensure we break
29025 out of translated code to check for pending interrupts */
29026 gen_save_pc(ctx->base.pc_next + 4);
29027 ctx->base.is_jmp = DISAS_EXIT;
29029 default: /* Invalid */
29030 MIPS_INVAL("mfmc0");
29031 generate_exception_end(ctx, EXCP_RI);
29036 #endif /* !CONFIG_USER_ONLY */
29039 check_insn(ctx, ISA_MIPS32R2);
29040 gen_load_srsgpr(rt, rd);
29043 check_insn(ctx, ISA_MIPS32R2);
29044 gen_store_srsgpr(rt, rd);
29048 generate_exception_end(ctx, EXCP_RI);
29052 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29053 if (ctx->insn_flags & ISA_MIPS32R6) {
29054 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29055 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29058 /* Arithmetic with immediate opcode */
29059 gen_arith_imm(ctx, op, rt, rs, imm);
29063 gen_arith_imm(ctx, op, rt, rs, imm);
29065 case OPC_SLTI: /* Set on less than with immediate opcode */
29067 gen_slt_imm(ctx, op, rt, rs, imm);
29069 case OPC_ANDI: /* Arithmetic with immediate opcode */
29070 case OPC_LUI: /* OPC_AUI */
29073 gen_logic_imm(ctx, op, rt, rs, imm);
29075 case OPC_J: /* Jump */
29077 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29078 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29081 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29082 if (ctx->insn_flags & ISA_MIPS32R6) {
29084 generate_exception_end(ctx, EXCP_RI);
29087 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29088 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29091 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29094 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29095 if (ctx->insn_flags & ISA_MIPS32R6) {
29097 generate_exception_end(ctx, EXCP_RI);
29100 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29101 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29104 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29107 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29110 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29112 check_insn(ctx, ISA_MIPS32R6);
29113 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29114 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29117 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29120 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29122 check_insn(ctx, ISA_MIPS32R6);
29123 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29124 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29129 check_insn(ctx, ISA_MIPS2);
29130 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29134 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29136 case OPC_LL: /* Load and stores */
29137 check_insn(ctx, ISA_MIPS2);
29138 if (ctx->insn_flags & INSN_R5900) {
29139 check_insn_opc_user_only(ctx, INSN_R5900);
29144 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29152 gen_ld(ctx, op, rt, rs, imm);
29156 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29161 gen_st(ctx, op, rt, rs, imm);
29164 check_insn(ctx, ISA_MIPS2);
29165 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29166 if (ctx->insn_flags & INSN_R5900) {
29167 check_insn_opc_user_only(ctx, INSN_R5900);
29169 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
29172 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29173 check_cp0_enabled(ctx);
29174 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29175 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29176 gen_cache_operation(ctx, rt, rs, imm);
29178 /* Treat as NOP. */
29181 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29182 if (ctx->insn_flags & INSN_R5900) {
29183 /* Treat as NOP. */
29185 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29186 /* Treat as NOP. */
29190 /* Floating point (COP1). */
29195 gen_cop1_ldst(ctx, op, rt, rs, imm);
29199 op1 = MASK_CP1(ctx->opcode);
29204 check_cp1_enabled(ctx);
29205 check_insn(ctx, ISA_MIPS32R2);
29211 check_cp1_enabled(ctx);
29212 gen_cp1(ctx, op1, rt, rd);
29214 #if defined(TARGET_MIPS64)
29217 check_cp1_enabled(ctx);
29218 check_insn(ctx, ISA_MIPS3);
29219 check_mips_64(ctx);
29220 gen_cp1(ctx, op1, rt, rd);
29223 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29224 check_cp1_enabled(ctx);
29225 if (ctx->insn_flags & ISA_MIPS32R6) {
29227 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29232 check_insn(ctx, ASE_MIPS3D);
29233 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29234 (rt >> 2) & 0x7, imm << 2);
29238 check_cp1_enabled(ctx);
29239 check_insn(ctx, ISA_MIPS32R6);
29240 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29244 check_cp1_enabled(ctx);
29245 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29247 check_insn(ctx, ASE_MIPS3D);
29250 check_cp1_enabled(ctx);
29251 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29252 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29253 (rt >> 2) & 0x7, imm << 2);
29260 check_cp1_enabled(ctx);
29261 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29267 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29268 check_cp1_enabled(ctx);
29269 if (ctx->insn_flags & ISA_MIPS32R6) {
29271 case R6_OPC_CMP_AF_S:
29272 case R6_OPC_CMP_UN_S:
29273 case R6_OPC_CMP_EQ_S:
29274 case R6_OPC_CMP_UEQ_S:
29275 case R6_OPC_CMP_LT_S:
29276 case R6_OPC_CMP_ULT_S:
29277 case R6_OPC_CMP_LE_S:
29278 case R6_OPC_CMP_ULE_S:
29279 case R6_OPC_CMP_SAF_S:
29280 case R6_OPC_CMP_SUN_S:
29281 case R6_OPC_CMP_SEQ_S:
29282 case R6_OPC_CMP_SEUQ_S:
29283 case R6_OPC_CMP_SLT_S:
29284 case R6_OPC_CMP_SULT_S:
29285 case R6_OPC_CMP_SLE_S:
29286 case R6_OPC_CMP_SULE_S:
29287 case R6_OPC_CMP_OR_S:
29288 case R6_OPC_CMP_UNE_S:
29289 case R6_OPC_CMP_NE_S:
29290 case R6_OPC_CMP_SOR_S:
29291 case R6_OPC_CMP_SUNE_S:
29292 case R6_OPC_CMP_SNE_S:
29293 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29295 case R6_OPC_CMP_AF_D:
29296 case R6_OPC_CMP_UN_D:
29297 case R6_OPC_CMP_EQ_D:
29298 case R6_OPC_CMP_UEQ_D:
29299 case R6_OPC_CMP_LT_D:
29300 case R6_OPC_CMP_ULT_D:
29301 case R6_OPC_CMP_LE_D:
29302 case R6_OPC_CMP_ULE_D:
29303 case R6_OPC_CMP_SAF_D:
29304 case R6_OPC_CMP_SUN_D:
29305 case R6_OPC_CMP_SEQ_D:
29306 case R6_OPC_CMP_SEUQ_D:
29307 case R6_OPC_CMP_SLT_D:
29308 case R6_OPC_CMP_SULT_D:
29309 case R6_OPC_CMP_SLE_D:
29310 case R6_OPC_CMP_SULE_D:
29311 case R6_OPC_CMP_OR_D:
29312 case R6_OPC_CMP_UNE_D:
29313 case R6_OPC_CMP_NE_D:
29314 case R6_OPC_CMP_SOR_D:
29315 case R6_OPC_CMP_SUNE_D:
29316 case R6_OPC_CMP_SNE_D:
29317 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29320 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29321 rt, rd, sa, (imm >> 8) & 0x7);
29326 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29341 check_insn(ctx, ASE_MSA);
29342 gen_msa_branch(env, ctx, op1);
29346 generate_exception_end(ctx, EXCP_RI);
29351 /* Compact branches [R6] and COP2 [non-R6] */
29352 case OPC_BC: /* OPC_LWC2 */
29353 case OPC_BALC: /* OPC_SWC2 */
29354 if (ctx->insn_flags & ISA_MIPS32R6) {
29355 /* OPC_BC, OPC_BALC */
29356 gen_compute_compact_branch(ctx, op, 0, 0,
29357 sextract32(ctx->opcode << 2, 0, 28));
29359 /* OPC_LWC2, OPC_SWC2 */
29360 /* COP2: Not implemented. */
29361 generate_exception_err(ctx, EXCP_CpU, 2);
29364 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29365 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29366 if (ctx->insn_flags & ISA_MIPS32R6) {
29368 /* OPC_BEQZC, OPC_BNEZC */
29369 gen_compute_compact_branch(ctx, op, rs, 0,
29370 sextract32(ctx->opcode << 2, 0, 23));
29372 /* OPC_JIC, OPC_JIALC */
29373 gen_compute_compact_branch(ctx, op, 0, rt, imm);
29376 /* OPC_LWC2, OPC_SWC2 */
29377 /* COP2: Not implemented. */
29378 generate_exception_err(ctx, EXCP_CpU, 2);
29382 check_insn(ctx, INSN_LOONGSON2F);
29383 /* Note that these instructions use different fields. */
29384 gen_loongson_multimedia(ctx, sa, rd, rt);
29388 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29389 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29390 check_cp1_enabled(ctx);
29391 op1 = MASK_CP3(ctx->opcode);
29395 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29401 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29402 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29405 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29406 /* Treat as NOP. */
29409 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29423 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29424 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29428 generate_exception_end(ctx, EXCP_RI);
29432 generate_exception_err(ctx, EXCP_CpU, 1);
29436 #if defined(TARGET_MIPS64)
29437 /* MIPS64 opcodes */
29439 if (ctx->insn_flags & INSN_R5900) {
29440 check_insn_opc_user_only(ctx, INSN_R5900);
29445 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29449 check_insn(ctx, ISA_MIPS3);
29450 check_mips_64(ctx);
29451 gen_ld(ctx, op, rt, rs, imm);
29455 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29458 check_insn(ctx, ISA_MIPS3);
29459 check_mips_64(ctx);
29460 gen_st(ctx, op, rt, rs, imm);
29463 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29464 check_insn(ctx, ISA_MIPS3);
29465 if (ctx->insn_flags & INSN_R5900) {
29466 check_insn_opc_user_only(ctx, INSN_R5900);
29468 check_mips_64(ctx);
29469 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
29471 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29472 if (ctx->insn_flags & ISA_MIPS32R6) {
29473 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29474 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29477 check_insn(ctx, ISA_MIPS3);
29478 check_mips_64(ctx);
29479 gen_arith_imm(ctx, op, rt, rs, imm);
29483 check_insn(ctx, ISA_MIPS3);
29484 check_mips_64(ctx);
29485 gen_arith_imm(ctx, op, rt, rs, imm);
29488 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29489 if (ctx->insn_flags & ISA_MIPS32R6) {
29490 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29492 MIPS_INVAL("major opcode");
29493 generate_exception_end(ctx, EXCP_RI);
29497 case OPC_DAUI: /* OPC_JALX */
29498 if (ctx->insn_flags & ISA_MIPS32R6) {
29499 #if defined(TARGET_MIPS64)
29501 check_mips_64(ctx);
29503 generate_exception(ctx, EXCP_RI);
29504 } else if (rt != 0) {
29505 TCGv t0 = tcg_temp_new();
29506 gen_load_gpr(t0, rs);
29507 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29511 generate_exception_end(ctx, EXCP_RI);
29512 MIPS_INVAL("major opcode");
29516 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29517 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29518 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29521 case OPC_MSA: /* OPC_MDMX */
29522 if (ctx->insn_flags & INSN_R5900) {
29523 #if defined(TARGET_MIPS64)
29524 gen_mmi_lq(env, ctx); /* MMI_OPC_LQ */
29527 /* MDMX: Not implemented. */
29532 check_insn(ctx, ISA_MIPS32R6);
29533 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29535 default: /* Invalid */
29536 MIPS_INVAL("major opcode");
29537 generate_exception_end(ctx, EXCP_RI);
29542 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29544 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29545 CPUMIPSState *env = cs->env_ptr;
29547 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29548 ctx->saved_pc = -1;
29549 ctx->insn_flags = env->insn_flags;
29550 ctx->CP0_Config1 = env->CP0_Config1;
29551 ctx->CP0_Config2 = env->CP0_Config2;
29552 ctx->CP0_Config3 = env->CP0_Config3;
29553 ctx->CP0_Config5 = env->CP0_Config5;
29555 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29556 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29557 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29558 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29559 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29560 ctx->PAMask = env->PAMask;
29561 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29562 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29563 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29564 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29565 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29566 /* Restore delay slot state from the tb context. */
29567 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29568 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29569 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29570 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29571 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29572 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29573 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29574 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29575 restore_cpu_state(env, ctx);
29576 #ifdef CONFIG_USER_ONLY
29577 ctx->mem_idx = MIPS_HFLAG_UM;
29579 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29581 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29582 MO_UNALN : MO_ALIGN;
29584 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29588 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29592 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29594 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29596 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29600 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29601 const CPUBreakpoint *bp)
29603 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29605 save_cpu_state(ctx, 1);
29606 ctx->base.is_jmp = DISAS_NORETURN;
29607 gen_helper_raise_exception_debug(cpu_env);
29608 /* The address covered by the breakpoint must be included in
29609 [tb->pc, tb->pc + tb->size) in order to for it to be
29610 properly cleared -- thus we increment the PC here so that
29611 the logic setting tb->size below does the right thing. */
29612 ctx->base.pc_next += 4;
29616 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
29618 CPUMIPSState *env = cs->env_ptr;
29619 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29623 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
29624 if (ctx->insn_flags & ISA_NANOMIPS32) {
29625 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29626 insn_bytes = decode_nanomips_opc(env, ctx);
29627 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
29628 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
29630 decode_opc(env, ctx);
29631 } else if (ctx->insn_flags & ASE_MICROMIPS) {
29632 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29633 insn_bytes = decode_micromips_opc(env, ctx);
29634 } else if (ctx->insn_flags & ASE_MIPS16) {
29635 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29636 insn_bytes = decode_mips16_opc(env, ctx);
29638 generate_exception_end(ctx, EXCP_RI);
29639 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
29643 if (ctx->hflags & MIPS_HFLAG_BMASK) {
29644 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
29645 MIPS_HFLAG_FBNSLOT))) {
29646 /* force to generate branch as there is neither delay nor
29650 if ((ctx->hflags & MIPS_HFLAG_M16) &&
29651 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
29652 /* Force to generate branch as microMIPS R6 doesn't restrict
29653 branches in the forbidden slot. */
29658 gen_branch(ctx, insn_bytes);
29660 ctx->base.pc_next += insn_bytes;
29662 if (ctx->base.is_jmp != DISAS_NEXT) {
29665 /* Execute a branch and its delay slot as a single instruction.
29666 This is what GDB expects and is consistent with what the
29667 hardware does (e.g. if a delay slot instruction faults, the
29668 reported PC is the PC of the branch). */
29669 if (ctx->base.singlestep_enabled &&
29670 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
29671 ctx->base.is_jmp = DISAS_TOO_MANY;
29673 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
29674 ctx->base.is_jmp = DISAS_TOO_MANY;
29678 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29680 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29682 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
29683 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
29684 gen_helper_raise_exception_debug(cpu_env);
29686 switch (ctx->base.is_jmp) {
29688 gen_save_pc(ctx->base.pc_next);
29689 tcg_gen_lookup_and_goto_ptr();
29692 case DISAS_TOO_MANY:
29693 save_cpu_state(ctx, 0);
29694 gen_goto_tb(ctx, 0, ctx->base.pc_next);
29697 tcg_gen_exit_tb(NULL, 0);
29699 case DISAS_NORETURN:
29702 g_assert_not_reached();
29707 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
29709 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
29710 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
29713 static const TranslatorOps mips_tr_ops = {
29714 .init_disas_context = mips_tr_init_disas_context,
29715 .tb_start = mips_tr_tb_start,
29716 .insn_start = mips_tr_insn_start,
29717 .breakpoint_check = mips_tr_breakpoint_check,
29718 .translate_insn = mips_tr_translate_insn,
29719 .tb_stop = mips_tr_tb_stop,
29720 .disas_log = mips_tr_disas_log,
29723 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
29727 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
29730 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
29734 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
29736 #define printfpr(fp) \
29739 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
29740 " fd:%13g fs:%13g psu: %13g\n", \
29741 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
29742 (double)(fp)->fd, \
29743 (double)(fp)->fs[FP_ENDIAN_IDX], \
29744 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
29747 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
29748 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
29749 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
29750 " fd:%13g fs:%13g psu:%13g\n", \
29751 tmp.w[FP_ENDIAN_IDX], tmp.d, \
29753 (double)tmp.fs[FP_ENDIAN_IDX], \
29754 (double)tmp.fs[!FP_ENDIAN_IDX]); \
29759 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
29760 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
29761 get_float_exception_flags(&env->active_fpu.fp_status));
29762 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
29763 fpu_fprintf(f, "%3s: ", fregnames[i]);
29764 printfpr(&env->active_fpu.fpr[i]);
29770 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
29773 MIPSCPU *cpu = MIPS_CPU(cs);
29774 CPUMIPSState *env = &cpu->env;
29777 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29778 " LO=0x" TARGET_FMT_lx " ds %04x "
29779 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
29780 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29781 env->hflags, env->btarget, env->bcond);
29782 for (i = 0; i < 32; i++) {
29784 cpu_fprintf(f, "GPR%02d:", i);
29785 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
29787 cpu_fprintf(f, "\n");
29790 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
29791 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
29792 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29794 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
29795 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
29796 env->CP0_Config2, env->CP0_Config3);
29797 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
29798 env->CP0_Config4, env->CP0_Config5);
29799 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
29800 fpu_dump_state(env, f, cpu_fprintf, flags);
29804 void mips_tcg_init(void)
29809 for (i = 1; i < 32; i++)
29810 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
29811 offsetof(CPUMIPSState, active_tc.gpr[i]),
29814 for (i = 0; i < 32; i++) {
29815 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
29817 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
29818 /* The scalar floating-point unit (FPU) registers are mapped on
29819 * the MSA vector registers. */
29820 fpu_f64[i] = msa_wr_d[i * 2];
29821 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
29822 msa_wr_d[i * 2 + 1] =
29823 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
29826 cpu_PC = tcg_global_mem_new(cpu_env,
29827 offsetof(CPUMIPSState, active_tc.PC), "PC");
29828 for (i = 0; i < MIPS_DSP_ACC; i++) {
29829 cpu_HI[i] = tcg_global_mem_new(cpu_env,
29830 offsetof(CPUMIPSState, active_tc.HI[i]),
29832 cpu_LO[i] = tcg_global_mem_new(cpu_env,
29833 offsetof(CPUMIPSState, active_tc.LO[i]),
29836 cpu_dspctrl = tcg_global_mem_new(cpu_env,
29837 offsetof(CPUMIPSState, active_tc.DSPControl),
29839 bcond = tcg_global_mem_new(cpu_env,
29840 offsetof(CPUMIPSState, bcond), "bcond");
29841 btarget = tcg_global_mem_new(cpu_env,
29842 offsetof(CPUMIPSState, btarget), "btarget");
29843 hflags = tcg_global_mem_new_i32(cpu_env,
29844 offsetof(CPUMIPSState, hflags), "hflags");
29846 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
29847 offsetof(CPUMIPSState, active_fpu.fcr0),
29849 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
29850 offsetof(CPUMIPSState, active_fpu.fcr31),
29852 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
29854 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
29857 #if defined(TARGET_MIPS64)
29859 for (i = 1; i < 32; i++) {
29860 cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
29861 offsetof(CPUMIPSState,
29867 #if !defined(TARGET_MIPS64)
29868 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29869 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29870 offsetof(CPUMIPSState,
29871 active_tc.mxu_gpr[i]),
29875 mxu_CR = tcg_global_mem_new(cpu_env,
29876 offsetof(CPUMIPSState, active_tc.mxu_cr),
29877 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
29881 #include "translate_init.inc.c"
29883 void cpu_mips_realize_env(CPUMIPSState *env)
29885 env->exception_base = (int32_t)0xBFC00000;
29887 #ifndef CONFIG_USER_ONLY
29888 mmu_init(env, env->cpu_model);
29890 fpu_init(env, env->cpu_model);
29891 mvp_init(env, env->cpu_model);
29894 bool cpu_supports_cps_smp(const char *cpu_type)
29896 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29897 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
29900 bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
29902 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29903 return (mcc->cpu_def->insn_flags & isa) != 0;
29906 void cpu_set_exception_base(int vp_index, target_ulong address)
29908 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
29909 vp->env.exception_base = address;
29912 void cpu_state_reset(CPUMIPSState *env)
29914 MIPSCPU *cpu = mips_env_get_cpu(env);
29915 CPUState *cs = CPU(cpu);
29917 /* Reset registers to their default values */
29918 env->CP0_PRid = env->cpu_model->CP0_PRid;
29919 env->CP0_Config0 = env->cpu_model->CP0_Config0;
29920 #ifdef TARGET_WORDS_BIGENDIAN
29921 env->CP0_Config0 |= (1 << CP0C0_BE);
29923 env->CP0_Config1 = env->cpu_model->CP0_Config1;
29924 env->CP0_Config2 = env->cpu_model->CP0_Config2;
29925 env->CP0_Config3 = env->cpu_model->CP0_Config3;
29926 env->CP0_Config4 = env->cpu_model->CP0_Config4;
29927 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
29928 env->CP0_Config5 = env->cpu_model->CP0_Config5;
29929 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
29930 env->CP0_Config6 = env->cpu_model->CP0_Config6;
29931 env->CP0_Config7 = env->cpu_model->CP0_Config7;
29932 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
29933 << env->cpu_model->CP0_LLAddr_shift;
29934 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
29935 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
29936 env->CCRes = env->cpu_model->CCRes;
29937 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
29938 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
29939 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
29940 env->current_tc = 0;
29941 env->SEGBITS = env->cpu_model->SEGBITS;
29942 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
29943 #if defined(TARGET_MIPS64)
29944 if (env->cpu_model->insn_flags & ISA_MIPS3) {
29945 env->SEGMask |= 3ULL << 62;
29948 env->PABITS = env->cpu_model->PABITS;
29949 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
29950 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
29951 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
29952 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
29953 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
29954 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
29955 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
29956 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
29957 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
29958 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
29959 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
29960 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
29961 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
29962 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
29963 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
29964 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
29965 env->msair = env->cpu_model->MSAIR;
29966 env->insn_flags = env->cpu_model->insn_flags;
29968 #if defined(CONFIG_USER_ONLY)
29969 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
29970 # ifdef TARGET_MIPS64
29971 /* Enable 64-bit register mode. */
29972 env->CP0_Status |= (1 << CP0St_PX);
29974 # ifdef TARGET_ABI_MIPSN64
29975 /* Enable 64-bit address mode. */
29976 env->CP0_Status |= (1 << CP0St_UX);
29978 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
29979 hardware registers. */
29980 env->CP0_HWREna |= 0x0000000F;
29981 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
29982 env->CP0_Status |= (1 << CP0St_CU1);
29984 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
29985 env->CP0_Status |= (1 << CP0St_MX);
29987 # if defined(TARGET_MIPS64)
29988 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
29989 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
29990 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
29991 env->CP0_Status |= (1 << CP0St_FR);
29995 if (env->hflags & MIPS_HFLAG_BMASK) {
29996 /* If the exception was raised from a delay slot,
29997 come back to the jump. */
29998 env->CP0_ErrorEPC = (env->active_tc.PC
29999 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
30001 env->CP0_ErrorEPC = env->active_tc.PC;
30003 env->active_tc.PC = env->exception_base;
30004 env->CP0_Random = env->tlb->nb_tlb - 1;
30005 env->tlb->tlb_in_use = env->tlb->nb_tlb;
30006 env->CP0_Wired = 0;
30007 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
30008 env->CP0_EBase = (cs->cpu_index & 0x3FF);
30009 if (mips_um_ksegs_enabled()) {
30010 env->CP0_EBase |= 0x40000000;
30012 env->CP0_EBase |= (int32_t)0x80000000;
30014 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
30015 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
30017 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
30019 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30020 /* vectored interrupts not implemented, timer on int 7,
30021 no performance counters. */
30022 env->CP0_IntCtl = 0xe0000000;
30026 for (i = 0; i < 7; i++) {
30027 env->CP0_WatchLo[i] = 0;
30028 env->CP0_WatchHi[i] = 0x80000000;
30030 env->CP0_WatchLo[7] = 0;
30031 env->CP0_WatchHi[7] = 0;
30033 /* Count register increments in debug mode, EJTAG version 1 */
30034 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30036 cpu_mips_store_count(env, 1);
30038 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30041 /* Only TC0 on VPE 0 starts as active. */
30042 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30043 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30044 env->tcs[i].CP0_TCHalt = 1;
30046 env->active_tc.CP0_TCHalt = 1;
30049 if (cs->cpu_index == 0) {
30050 /* VPE0 starts up enabled. */
30051 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30052 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30054 /* TC0 starts up unhalted. */
30056 env->active_tc.CP0_TCHalt = 0;
30057 env->tcs[0].CP0_TCHalt = 0;
30058 /* With thread 0 active. */
30059 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30060 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30065 * Configure default legacy segmentation control. We use this regardless of
30066 * whether segmentation control is presented to the guest.
30068 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30069 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
30070 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30071 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30072 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30073 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30075 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30076 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30077 (3 << CP0SC_C)) << 16;
30078 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30079 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30080 (1 << CP0SC_EU) | (2 << CP0SC_C);
30081 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30082 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30083 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30084 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30085 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30087 if ((env->insn_flags & ISA_MIPS32R6) &&
30088 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30089 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30090 env->CP0_Status |= (1 << CP0St_FR);
30093 if (env->insn_flags & ISA_MIPS32R6) {
30095 env->CP0_PWSize = 0x40;
30101 env->CP0_PWField = 0x0C30C302;
30108 env->CP0_PWField = 0x02;
30111 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30112 /* microMIPS on reset when Config3.ISA is 3 */
30113 env->hflags |= MIPS_HFLAG_M16;
30117 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30121 compute_hflags(env);
30122 restore_fp_status(env);
30123 restore_pamask(env);
30124 cs->exception_index = EXCP_NONE;
30126 if (semihosting_get_argc()) {
30127 /* UHI interface can be used to obtain argc and argv */
30128 env->active_tc.gpr[4] = -1;
30132 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30133 target_ulong *data)
30135 env->active_tc.PC = data[0];
30136 env->hflags &= ~MIPS_HFLAG_BMASK;
30137 env->hflags |= data[1];
30138 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30139 case MIPS_HFLAG_BR:
30141 case MIPS_HFLAG_BC:
30142 case MIPS_HFLAG_BL:
30144 env->btarget = data[2];