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_i32 hflags;
2454 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2455 static TCGv_i64 fpu_f64[32];
2456 static TCGv_i64 msa_wr_d[64];
2458 #if !defined(TARGET_MIPS64)
2460 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2464 #include "exec/gen-icount.h"
2466 #define gen_helper_0e0i(name, arg) do { \
2467 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2468 gen_helper_##name(cpu_env, helper_tmp); \
2469 tcg_temp_free_i32(helper_tmp); \
2472 #define gen_helper_0e1i(name, arg1, arg2) do { \
2473 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2474 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2475 tcg_temp_free_i32(helper_tmp); \
2478 #define gen_helper_1e0i(name, ret, arg1) do { \
2479 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2480 gen_helper_##name(ret, cpu_env, helper_tmp); \
2481 tcg_temp_free_i32(helper_tmp); \
2484 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2485 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2486 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2487 tcg_temp_free_i32(helper_tmp); \
2490 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2491 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2492 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2493 tcg_temp_free_i32(helper_tmp); \
2496 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2497 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2498 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2499 tcg_temp_free_i32(helper_tmp); \
2502 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2503 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2504 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2505 tcg_temp_free_i32(helper_tmp); \
2508 typedef struct DisasContext {
2509 DisasContextBase base;
2510 target_ulong saved_pc;
2511 target_ulong page_start;
2513 uint64_t insn_flags;
2514 int32_t CP0_Config1;
2515 int32_t CP0_Config2;
2516 int32_t CP0_Config3;
2517 int32_t CP0_Config5;
2518 /* Routine used to access memory */
2520 TCGMemOp default_tcg_memop_mask;
2521 uint32_t hflags, saved_hflags;
2522 target_ulong btarget;
2533 int CP0_LLAddr_shift;
2543 #define DISAS_STOP DISAS_TARGET_0
2544 #define DISAS_EXIT DISAS_TARGET_1
2546 static const char * const regnames[] = {
2547 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2548 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2549 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2550 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2553 static const char * const regnames_HI[] = {
2554 "HI0", "HI1", "HI2", "HI3",
2557 static const char * const regnames_LO[] = {
2558 "LO0", "LO1", "LO2", "LO3",
2561 static const char * const fregnames[] = {
2562 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2563 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2564 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2565 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2568 static const char * const msaregnames[] = {
2569 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2570 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2571 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2572 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2573 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2574 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2575 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2576 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2577 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2578 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2579 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2580 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2581 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2582 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2583 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2584 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2587 #if !defined(TARGET_MIPS64)
2588 static const char * const mxuregnames[] = {
2589 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2590 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2594 #define LOG_DISAS(...) \
2596 if (MIPS_DEBUG_DISAS) { \
2597 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2601 #define MIPS_INVAL(op) \
2603 if (MIPS_DEBUG_DISAS) { \
2604 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2605 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2606 ctx->base.pc_next, ctx->opcode, op, \
2607 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2608 ((ctx->opcode >> 16) & 0x1F)); \
2612 /* General purpose registers moves. */
2613 static inline void gen_load_gpr (TCGv t, int reg)
2616 tcg_gen_movi_tl(t, 0);
2618 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2621 static inline void gen_store_gpr (TCGv t, int reg)
2624 tcg_gen_mov_tl(cpu_gpr[reg], t);
2627 /* Moves to/from shadow registers. */
2628 static inline void gen_load_srsgpr (int from, int to)
2630 TCGv t0 = tcg_temp_new();
2633 tcg_gen_movi_tl(t0, 0);
2635 TCGv_i32 t2 = tcg_temp_new_i32();
2636 TCGv_ptr addr = tcg_temp_new_ptr();
2638 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2639 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2640 tcg_gen_andi_i32(t2, t2, 0xf);
2641 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2642 tcg_gen_ext_i32_ptr(addr, t2);
2643 tcg_gen_add_ptr(addr, cpu_env, addr);
2645 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2646 tcg_temp_free_ptr(addr);
2647 tcg_temp_free_i32(t2);
2649 gen_store_gpr(t0, to);
2653 static inline void gen_store_srsgpr (int from, int to)
2656 TCGv t0 = tcg_temp_new();
2657 TCGv_i32 t2 = tcg_temp_new_i32();
2658 TCGv_ptr addr = tcg_temp_new_ptr();
2660 gen_load_gpr(t0, from);
2661 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2662 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2663 tcg_gen_andi_i32(t2, t2, 0xf);
2664 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2665 tcg_gen_ext_i32_ptr(addr, t2);
2666 tcg_gen_add_ptr(addr, cpu_env, addr);
2668 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2669 tcg_temp_free_ptr(addr);
2670 tcg_temp_free_i32(t2);
2675 #if !defined(TARGET_MIPS64)
2676 /* MXU General purpose registers moves. */
2677 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2680 tcg_gen_movi_tl(t, 0);
2681 } else if (reg <= 15) {
2682 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2686 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2688 if (reg > 0 && reg <= 15) {
2689 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2693 /* MXU control register moves. */
2694 static inline void gen_load_mxu_cr(TCGv t)
2696 tcg_gen_mov_tl(t, mxu_CR);
2699 static inline void gen_store_mxu_cr(TCGv t)
2701 /* TODO: Add handling of RW rules for MXU_CR. */
2702 tcg_gen_mov_tl(mxu_CR, t);
2708 static inline void gen_save_pc(target_ulong pc)
2710 tcg_gen_movi_tl(cpu_PC, pc);
2713 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2715 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2716 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2717 gen_save_pc(ctx->base.pc_next);
2718 ctx->saved_pc = ctx->base.pc_next;
2720 if (ctx->hflags != ctx->saved_hflags) {
2721 tcg_gen_movi_i32(hflags, ctx->hflags);
2722 ctx->saved_hflags = ctx->hflags;
2723 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2729 tcg_gen_movi_tl(btarget, ctx->btarget);
2735 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2737 ctx->saved_hflags = ctx->hflags;
2738 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2744 ctx->btarget = env->btarget;
2749 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2751 TCGv_i32 texcp = tcg_const_i32(excp);
2752 TCGv_i32 terr = tcg_const_i32(err);
2753 save_cpu_state(ctx, 1);
2754 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2755 tcg_temp_free_i32(terr);
2756 tcg_temp_free_i32(texcp);
2757 ctx->base.is_jmp = DISAS_NORETURN;
2760 static inline void generate_exception(DisasContext *ctx, int excp)
2762 gen_helper_0e0i(raise_exception, excp);
2765 static inline void generate_exception_end(DisasContext *ctx, int excp)
2767 generate_exception_err(ctx, excp, 0);
2770 /* Floating point register moves. */
2771 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2773 if (ctx->hflags & MIPS_HFLAG_FRE) {
2774 generate_exception(ctx, EXCP_RI);
2776 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2779 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2782 if (ctx->hflags & MIPS_HFLAG_FRE) {
2783 generate_exception(ctx, EXCP_RI);
2785 t64 = tcg_temp_new_i64();
2786 tcg_gen_extu_i32_i64(t64, t);
2787 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2788 tcg_temp_free_i64(t64);
2791 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2793 if (ctx->hflags & MIPS_HFLAG_F64) {
2794 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2796 gen_load_fpr32(ctx, t, reg | 1);
2800 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2802 if (ctx->hflags & MIPS_HFLAG_F64) {
2803 TCGv_i64 t64 = tcg_temp_new_i64();
2804 tcg_gen_extu_i32_i64(t64, t);
2805 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2806 tcg_temp_free_i64(t64);
2808 gen_store_fpr32(ctx, t, reg | 1);
2812 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2814 if (ctx->hflags & MIPS_HFLAG_F64) {
2815 tcg_gen_mov_i64(t, fpu_f64[reg]);
2817 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2821 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2823 if (ctx->hflags & MIPS_HFLAG_F64) {
2824 tcg_gen_mov_i64(fpu_f64[reg], t);
2827 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2828 t0 = tcg_temp_new_i64();
2829 tcg_gen_shri_i64(t0, t, 32);
2830 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2831 tcg_temp_free_i64(t0);
2835 static inline int get_fp_bit (int cc)
2843 /* Addresses computation */
2844 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2846 tcg_gen_add_tl(ret, arg0, arg1);
2848 #if defined(TARGET_MIPS64)
2849 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2850 tcg_gen_ext32s_i64(ret, ret);
2855 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2858 tcg_gen_addi_tl(ret, base, ofs);
2860 #if defined(TARGET_MIPS64)
2861 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2862 tcg_gen_ext32s_i64(ret, ret);
2867 /* Addresses computation (translation time) */
2868 static target_long addr_add(DisasContext *ctx, target_long base,
2871 target_long sum = base + offset;
2873 #if defined(TARGET_MIPS64)
2874 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2881 /* Sign-extract the low 32-bits to a target_long. */
2882 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2884 #if defined(TARGET_MIPS64)
2885 tcg_gen_ext32s_i64(ret, arg);
2887 tcg_gen_extrl_i64_i32(ret, arg);
2891 /* Sign-extract the high 32-bits to a target_long. */
2892 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2894 #if defined(TARGET_MIPS64)
2895 tcg_gen_sari_i64(ret, arg, 32);
2897 tcg_gen_extrh_i64_i32(ret, arg);
2901 static inline void check_cp0_enabled(DisasContext *ctx)
2903 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2904 generate_exception_err(ctx, EXCP_CpU, 0);
2907 static inline void check_cp1_enabled(DisasContext *ctx)
2909 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2910 generate_exception_err(ctx, EXCP_CpU, 1);
2913 /* Verify that the processor is running with COP1X instructions enabled.
2914 This is associated with the nabla symbol in the MIPS32 and MIPS64
2917 static inline void check_cop1x(DisasContext *ctx)
2919 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2920 generate_exception_end(ctx, EXCP_RI);
2923 /* Verify that the processor is running with 64-bit floating-point
2924 operations enabled. */
2926 static inline void check_cp1_64bitmode(DisasContext *ctx)
2928 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2929 generate_exception_end(ctx, EXCP_RI);
2933 * Verify if floating point register is valid; an operation is not defined
2934 * if bit 0 of any register specification is set and the FR bit in the
2935 * Status register equals zero, since the register numbers specify an
2936 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2937 * in the Status register equals one, both even and odd register numbers
2938 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2940 * Multiple 64 bit wide registers can be checked by calling
2941 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2943 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2945 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2946 generate_exception_end(ctx, EXCP_RI);
2949 /* Verify that the processor is running with DSP instructions enabled.
2950 This is enabled by CP0 Status register MX(24) bit.
2953 static inline void check_dsp(DisasContext *ctx)
2955 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2956 if (ctx->insn_flags & ASE_DSP) {
2957 generate_exception_end(ctx, EXCP_DSPDIS);
2959 generate_exception_end(ctx, EXCP_RI);
2964 static inline void check_dsp_r2(DisasContext *ctx)
2966 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2967 if (ctx->insn_flags & ASE_DSP) {
2968 generate_exception_end(ctx, EXCP_DSPDIS);
2970 generate_exception_end(ctx, EXCP_RI);
2975 static inline void check_dsp_r3(DisasContext *ctx)
2977 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2978 if (ctx->insn_flags & ASE_DSP) {
2979 generate_exception_end(ctx, EXCP_DSPDIS);
2981 generate_exception_end(ctx, EXCP_RI);
2986 /* This code generates a "reserved instruction" exception if the
2987 CPU does not support the instruction set corresponding to flags. */
2988 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2990 if (unlikely(!(ctx->insn_flags & flags))) {
2991 generate_exception_end(ctx, EXCP_RI);
2995 /* This code generates a "reserved instruction" exception if the
2996 CPU has corresponding flag set which indicates that the instruction
2997 has been removed. */
2998 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3000 if (unlikely(ctx->insn_flags & flags)) {
3001 generate_exception_end(ctx, EXCP_RI);
3006 * The Linux kernel traps certain reserved instruction exceptions to
3007 * emulate the corresponding instructions. QEMU is the kernel in user
3008 * mode, so those traps are emulated by accepting the instructions.
3010 * A reserved instruction exception is generated for flagged CPUs if
3011 * QEMU runs in system mode.
3013 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3015 #ifndef CONFIG_USER_ONLY
3016 check_insn_opc_removed(ctx, flags);
3020 /* This code generates a "reserved instruction" exception if the
3021 CPU does not support 64-bit paired-single (PS) floating point data type */
3022 static inline void check_ps(DisasContext *ctx)
3024 if (unlikely(!ctx->ps)) {
3025 generate_exception(ctx, EXCP_RI);
3027 check_cp1_64bitmode(ctx);
3030 #ifdef TARGET_MIPS64
3031 /* This code generates a "reserved instruction" exception if 64-bit
3032 instructions are not enabled. */
3033 static inline void check_mips_64(DisasContext *ctx)
3035 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
3036 generate_exception_end(ctx, EXCP_RI);
3040 #ifndef CONFIG_USER_ONLY
3041 static inline void check_mvh(DisasContext *ctx)
3043 if (unlikely(!ctx->mvh)) {
3044 generate_exception(ctx, EXCP_RI);
3050 * This code generates a "reserved instruction" exception if the
3051 * Config5 XNP bit is set.
3053 static inline void check_xnp(DisasContext *ctx)
3055 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3056 generate_exception_end(ctx, EXCP_RI);
3060 #ifndef CONFIG_USER_ONLY
3062 * This code generates a "reserved instruction" exception if the
3063 * Config3 PW bit is NOT set.
3065 static inline void check_pw(DisasContext *ctx)
3067 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3068 generate_exception_end(ctx, EXCP_RI);
3074 * This code generates a "reserved instruction" exception if the
3075 * Config3 MT bit is NOT set.
3077 static inline void check_mt(DisasContext *ctx)
3079 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3080 generate_exception_end(ctx, EXCP_RI);
3084 #ifndef CONFIG_USER_ONLY
3086 * This code generates a "coprocessor unusable" exception if CP0 is not
3087 * available, and, if that is not the case, generates a "reserved instruction"
3088 * exception if the Config5 MT bit is NOT set. This is needed for availability
3089 * control of some of MT ASE instructions.
3091 static inline void check_cp0_mt(DisasContext *ctx)
3093 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3094 generate_exception_err(ctx, EXCP_CpU, 0);
3096 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3097 generate_exception_err(ctx, EXCP_RI, 0);
3104 * This code generates a "reserved instruction" exception if the
3105 * Config5 NMS bit is set.
3107 static inline void check_nms(DisasContext *ctx)
3109 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3110 generate_exception_end(ctx, EXCP_RI);
3115 * This code generates a "reserved instruction" exception if the
3116 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3117 * Config2 TL, and Config5 L2C are unset.
3119 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3121 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3122 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3123 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3124 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3125 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3126 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3128 generate_exception_end(ctx, EXCP_RI);
3133 * This code generates a "reserved instruction" exception if the
3134 * Config5 EVA bit is NOT set.
3136 static inline void check_eva(DisasContext *ctx)
3138 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3139 generate_exception_end(ctx, EXCP_RI);
3144 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3145 calling interface for 32 and 64-bit FPRs. No sense in changing
3146 all callers for gen_load_fpr32 when we need the CTX parameter for
3148 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3149 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3150 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3151 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3152 int ft, int fs, int cc) \
3154 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3155 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3164 check_cp1_registers(ctx, fs | ft); \
3172 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3173 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3175 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3176 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3177 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3178 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3179 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3180 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3181 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3182 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3183 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3184 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3185 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3186 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3187 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3188 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3189 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3190 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
3193 tcg_temp_free_i##bits (fp0); \
3194 tcg_temp_free_i##bits (fp1); \
3197 FOP_CONDS(, 0, d, FMT_D, 64)
3198 FOP_CONDS(abs, 1, d, FMT_D, 64)
3199 FOP_CONDS(, 0, s, FMT_S, 32)
3200 FOP_CONDS(abs, 1, s, FMT_S, 32)
3201 FOP_CONDS(, 0, ps, FMT_PS, 64)
3202 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3205 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3206 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3207 int ft, int fs, int fd) \
3209 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3210 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3211 if (ifmt == FMT_D) { \
3212 check_cp1_registers(ctx, fs | ft | fd); \
3214 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3215 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3218 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3221 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3224 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3227 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3230 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3233 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3236 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3239 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3242 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3245 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3248 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3251 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3254 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3257 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3260 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3263 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3266 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3269 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3272 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3275 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3278 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3281 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3287 tcg_temp_free_i ## bits (fp0); \
3288 tcg_temp_free_i ## bits (fp1); \
3291 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3292 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3294 #undef gen_ldcmp_fpr32
3295 #undef gen_ldcmp_fpr64
3297 /* load/store instructions. */
3298 #ifdef CONFIG_USER_ONLY
3299 #define OP_LD_ATOMIC(insn,fname) \
3300 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3301 DisasContext *ctx) \
3303 TCGv t0 = tcg_temp_new(); \
3304 tcg_gen_mov_tl(t0, arg1); \
3305 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3306 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3307 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3308 tcg_temp_free(t0); \
3311 #define OP_LD_ATOMIC(insn,fname) \
3312 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3313 DisasContext *ctx) \
3315 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3318 OP_LD_ATOMIC(ll,ld32s);
3319 #if defined(TARGET_MIPS64)
3320 OP_LD_ATOMIC(lld,ld64);
3324 #ifdef CONFIG_USER_ONLY
3325 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
3326 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3327 DisasContext *ctx) \
3329 TCGv t0 = tcg_temp_new(); \
3330 TCGLabel *l1 = gen_new_label(); \
3331 TCGLabel *l2 = gen_new_label(); \
3333 tcg_gen_andi_tl(t0, arg2, almask); \
3334 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
3335 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
3336 generate_exception(ctx, EXCP_AdES); \
3337 gen_set_label(l1); \
3338 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3339 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
3340 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
3341 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
3342 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
3343 generate_exception_end(ctx, EXCP_SC); \
3344 gen_set_label(l2); \
3345 tcg_gen_movi_tl(t0, 0); \
3346 gen_store_gpr(t0, rt); \
3347 tcg_temp_free(t0); \
3350 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
3351 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3352 DisasContext *ctx) \
3354 TCGv t0 = tcg_temp_new(); \
3355 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
3356 gen_store_gpr(t0, rt); \
3357 tcg_temp_free(t0); \
3360 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
3361 #if defined(TARGET_MIPS64)
3362 OP_ST_ATOMIC(scd,st64,ld64,0x7);
3366 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3367 int base, int offset)
3370 tcg_gen_movi_tl(addr, offset);
3371 } else if (offset == 0) {
3372 gen_load_gpr(addr, base);
3374 tcg_gen_movi_tl(addr, offset);
3375 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3379 static target_ulong pc_relative_pc (DisasContext *ctx)
3381 target_ulong pc = ctx->base.pc_next;
3383 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3384 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3389 pc &= ~(target_ulong)3;
3394 static void gen_ld(DisasContext *ctx, uint32_t opc,
3395 int rt, int base, int offset)
3398 int mem_idx = ctx->mem_idx;
3400 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3401 /* Loongson CPU uses a load to zero register for prefetch.
3402 We emulate it as a NOP. On other CPU we must perform the
3403 actual memory access. */
3407 t0 = tcg_temp_new();
3408 gen_base_offset_addr(ctx, t0, base, offset);
3411 #if defined(TARGET_MIPS64)
3413 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3414 ctx->default_tcg_memop_mask);
3415 gen_store_gpr(t0, rt);
3418 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3419 ctx->default_tcg_memop_mask);
3420 gen_store_gpr(t0, rt);
3424 op_ld_lld(t0, t0, mem_idx, ctx);
3425 gen_store_gpr(t0, rt);
3428 t1 = tcg_temp_new();
3429 /* Do a byte access to possibly trigger a page
3430 fault with the unaligned address. */
3431 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3432 tcg_gen_andi_tl(t1, t0, 7);
3433 #ifndef TARGET_WORDS_BIGENDIAN
3434 tcg_gen_xori_tl(t1, t1, 7);
3436 tcg_gen_shli_tl(t1, t1, 3);
3437 tcg_gen_andi_tl(t0, t0, ~7);
3438 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3439 tcg_gen_shl_tl(t0, t0, t1);
3440 t2 = tcg_const_tl(-1);
3441 tcg_gen_shl_tl(t2, t2, t1);
3442 gen_load_gpr(t1, rt);
3443 tcg_gen_andc_tl(t1, t1, t2);
3445 tcg_gen_or_tl(t0, t0, t1);
3447 gen_store_gpr(t0, rt);
3450 t1 = tcg_temp_new();
3451 /* Do a byte access to possibly trigger a page
3452 fault with the unaligned address. */
3453 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3454 tcg_gen_andi_tl(t1, t0, 7);
3455 #ifdef TARGET_WORDS_BIGENDIAN
3456 tcg_gen_xori_tl(t1, t1, 7);
3458 tcg_gen_shli_tl(t1, t1, 3);
3459 tcg_gen_andi_tl(t0, t0, ~7);
3460 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3461 tcg_gen_shr_tl(t0, t0, t1);
3462 tcg_gen_xori_tl(t1, t1, 63);
3463 t2 = tcg_const_tl(0xfffffffffffffffeull);
3464 tcg_gen_shl_tl(t2, t2, t1);
3465 gen_load_gpr(t1, rt);
3466 tcg_gen_and_tl(t1, t1, t2);
3468 tcg_gen_or_tl(t0, t0, t1);
3470 gen_store_gpr(t0, rt);
3473 t1 = tcg_const_tl(pc_relative_pc(ctx));
3474 gen_op_addr_add(ctx, t0, t0, t1);
3476 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3477 gen_store_gpr(t0, rt);
3481 t1 = tcg_const_tl(pc_relative_pc(ctx));
3482 gen_op_addr_add(ctx, t0, t0, t1);
3484 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3485 gen_store_gpr(t0, rt);
3488 mem_idx = MIPS_HFLAG_UM;
3491 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3492 ctx->default_tcg_memop_mask);
3493 gen_store_gpr(t0, rt);
3496 mem_idx = MIPS_HFLAG_UM;
3499 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3500 ctx->default_tcg_memop_mask);
3501 gen_store_gpr(t0, rt);
3504 mem_idx = MIPS_HFLAG_UM;
3507 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3508 ctx->default_tcg_memop_mask);
3509 gen_store_gpr(t0, rt);
3512 mem_idx = MIPS_HFLAG_UM;
3515 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3516 gen_store_gpr(t0, rt);
3519 mem_idx = MIPS_HFLAG_UM;
3522 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3523 gen_store_gpr(t0, rt);
3526 mem_idx = MIPS_HFLAG_UM;
3529 t1 = tcg_temp_new();
3530 /* Do a byte access to possibly trigger a page
3531 fault with the unaligned address. */
3532 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3533 tcg_gen_andi_tl(t1, t0, 3);
3534 #ifndef TARGET_WORDS_BIGENDIAN
3535 tcg_gen_xori_tl(t1, t1, 3);
3537 tcg_gen_shli_tl(t1, t1, 3);
3538 tcg_gen_andi_tl(t0, t0, ~3);
3539 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3540 tcg_gen_shl_tl(t0, t0, t1);
3541 t2 = tcg_const_tl(-1);
3542 tcg_gen_shl_tl(t2, t2, t1);
3543 gen_load_gpr(t1, rt);
3544 tcg_gen_andc_tl(t1, t1, t2);
3546 tcg_gen_or_tl(t0, t0, t1);
3548 tcg_gen_ext32s_tl(t0, t0);
3549 gen_store_gpr(t0, rt);
3552 mem_idx = MIPS_HFLAG_UM;
3555 t1 = tcg_temp_new();
3556 /* Do a byte access to possibly trigger a page
3557 fault with the unaligned address. */
3558 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3559 tcg_gen_andi_tl(t1, t0, 3);
3560 #ifdef TARGET_WORDS_BIGENDIAN
3561 tcg_gen_xori_tl(t1, t1, 3);
3563 tcg_gen_shli_tl(t1, t1, 3);
3564 tcg_gen_andi_tl(t0, t0, ~3);
3565 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3566 tcg_gen_shr_tl(t0, t0, t1);
3567 tcg_gen_xori_tl(t1, t1, 31);
3568 t2 = tcg_const_tl(0xfffffffeull);
3569 tcg_gen_shl_tl(t2, t2, t1);
3570 gen_load_gpr(t1, rt);
3571 tcg_gen_and_tl(t1, t1, t2);
3573 tcg_gen_or_tl(t0, t0, t1);
3575 tcg_gen_ext32s_tl(t0, t0);
3576 gen_store_gpr(t0, rt);
3579 mem_idx = MIPS_HFLAG_UM;
3583 op_ld_ll(t0, t0, mem_idx, ctx);
3584 gen_store_gpr(t0, rt);
3590 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3591 uint32_t reg1, uint32_t reg2)
3593 TCGv taddr = tcg_temp_new();
3594 TCGv_i64 tval = tcg_temp_new_i64();
3595 TCGv tmp1 = tcg_temp_new();
3596 TCGv tmp2 = tcg_temp_new();
3598 gen_base_offset_addr(ctx, taddr, base, offset);
3599 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3600 #ifdef TARGET_WORDS_BIGENDIAN
3601 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3603 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3605 gen_store_gpr(tmp1, reg1);
3606 tcg_temp_free(tmp1);
3607 gen_store_gpr(tmp2, reg2);
3608 tcg_temp_free(tmp2);
3609 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3610 tcg_temp_free_i64(tval);
3611 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3612 tcg_temp_free(taddr);
3616 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3617 int base, int offset)
3619 TCGv t0 = tcg_temp_new();
3620 TCGv t1 = tcg_temp_new();
3621 int mem_idx = ctx->mem_idx;
3623 gen_base_offset_addr(ctx, t0, base, offset);
3624 gen_load_gpr(t1, rt);
3626 #if defined(TARGET_MIPS64)
3628 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3629 ctx->default_tcg_memop_mask);
3632 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3635 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3639 mem_idx = MIPS_HFLAG_UM;
3642 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3643 ctx->default_tcg_memop_mask);
3646 mem_idx = MIPS_HFLAG_UM;
3649 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3650 ctx->default_tcg_memop_mask);
3653 mem_idx = MIPS_HFLAG_UM;
3656 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3659 mem_idx = MIPS_HFLAG_UM;
3662 gen_helper_0e2i(swl, t1, t0, mem_idx);
3665 mem_idx = MIPS_HFLAG_UM;
3668 gen_helper_0e2i(swr, t1, t0, mem_idx);
3676 /* Store conditional */
3677 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3678 int base, int16_t offset)
3681 int mem_idx = ctx->mem_idx;
3683 #ifdef CONFIG_USER_ONLY
3684 t0 = tcg_temp_local_new();
3685 t1 = tcg_temp_local_new();
3687 t0 = tcg_temp_new();
3688 t1 = tcg_temp_new();
3690 gen_base_offset_addr(ctx, t0, base, offset);
3691 gen_load_gpr(t1, rt);
3693 #if defined(TARGET_MIPS64)
3696 op_st_scd(t1, t0, rt, mem_idx, ctx);
3700 mem_idx = MIPS_HFLAG_UM;
3704 op_st_sc(t1, t0, rt, mem_idx, ctx);
3711 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3712 uint32_t reg1, uint32_t reg2)
3714 TCGv taddr = tcg_temp_local_new();
3715 TCGv lladdr = tcg_temp_local_new();
3716 TCGv_i64 tval = tcg_temp_new_i64();
3717 TCGv_i64 llval = tcg_temp_new_i64();
3718 TCGv_i64 val = tcg_temp_new_i64();
3719 TCGv tmp1 = tcg_temp_new();
3720 TCGv tmp2 = tcg_temp_new();
3721 TCGLabel *lab_fail = gen_new_label();
3722 TCGLabel *lab_done = gen_new_label();
3724 gen_base_offset_addr(ctx, taddr, base, offset);
3726 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3727 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3729 gen_load_gpr(tmp1, reg1);
3730 gen_load_gpr(tmp2, reg2);
3732 #ifdef TARGET_WORDS_BIGENDIAN
3733 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3735 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3738 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3739 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3740 ctx->mem_idx, MO_64);
3742 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3744 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3746 gen_set_label(lab_fail);
3749 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3751 gen_set_label(lab_done);
3752 tcg_gen_movi_tl(lladdr, -1);
3753 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3756 /* Load and store */
3757 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3760 /* Don't do NOP if destination is zero: we must perform the actual
3765 TCGv_i32 fp0 = tcg_temp_new_i32();
3766 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3767 ctx->default_tcg_memop_mask);
3768 gen_store_fpr32(ctx, fp0, ft);
3769 tcg_temp_free_i32(fp0);
3774 TCGv_i32 fp0 = tcg_temp_new_i32();
3775 gen_load_fpr32(ctx, fp0, ft);
3776 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3777 ctx->default_tcg_memop_mask);
3778 tcg_temp_free_i32(fp0);
3783 TCGv_i64 fp0 = tcg_temp_new_i64();
3784 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3785 ctx->default_tcg_memop_mask);
3786 gen_store_fpr64(ctx, fp0, ft);
3787 tcg_temp_free_i64(fp0);
3792 TCGv_i64 fp0 = tcg_temp_new_i64();
3793 gen_load_fpr64(ctx, fp0, ft);
3794 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3795 ctx->default_tcg_memop_mask);
3796 tcg_temp_free_i64(fp0);
3800 MIPS_INVAL("flt_ldst");
3801 generate_exception_end(ctx, EXCP_RI);
3806 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3807 int rs, int16_t imm)
3809 TCGv t0 = tcg_temp_new();
3811 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3812 check_cp1_enabled(ctx);
3816 check_insn(ctx, ISA_MIPS2);
3819 gen_base_offset_addr(ctx, t0, rs, imm);
3820 gen_flt_ldst(ctx, op, rt, t0);
3823 generate_exception_err(ctx, EXCP_CpU, 1);
3828 /* Arithmetic with immediate operand */
3829 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3830 int rt, int rs, int imm)
3832 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3834 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3835 /* If no destination, treat it as a NOP.
3836 For addi, we must generate the overflow exception when needed. */
3842 TCGv t0 = tcg_temp_local_new();
3843 TCGv t1 = tcg_temp_new();
3844 TCGv t2 = tcg_temp_new();
3845 TCGLabel *l1 = gen_new_label();
3847 gen_load_gpr(t1, rs);
3848 tcg_gen_addi_tl(t0, t1, uimm);
3849 tcg_gen_ext32s_tl(t0, t0);
3851 tcg_gen_xori_tl(t1, t1, ~uimm);
3852 tcg_gen_xori_tl(t2, t0, uimm);
3853 tcg_gen_and_tl(t1, t1, t2);
3855 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3857 /* operands of same sign, result different sign */
3858 generate_exception(ctx, EXCP_OVERFLOW);
3860 tcg_gen_ext32s_tl(t0, t0);
3861 gen_store_gpr(t0, rt);
3867 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3868 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3870 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3873 #if defined(TARGET_MIPS64)
3876 TCGv t0 = tcg_temp_local_new();
3877 TCGv t1 = tcg_temp_new();
3878 TCGv t2 = tcg_temp_new();
3879 TCGLabel *l1 = gen_new_label();
3881 gen_load_gpr(t1, rs);
3882 tcg_gen_addi_tl(t0, t1, uimm);
3884 tcg_gen_xori_tl(t1, t1, ~uimm);
3885 tcg_gen_xori_tl(t2, t0, uimm);
3886 tcg_gen_and_tl(t1, t1, t2);
3888 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3890 /* operands of same sign, result different sign */
3891 generate_exception(ctx, EXCP_OVERFLOW);
3893 gen_store_gpr(t0, rt);
3899 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3901 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3908 /* Logic with immediate operand */
3909 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3910 int rt, int rs, int16_t imm)
3915 /* If no destination, treat it as a NOP. */
3918 uimm = (uint16_t)imm;
3921 if (likely(rs != 0))
3922 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3924 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3928 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3930 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3933 if (likely(rs != 0))
3934 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3936 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3939 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3941 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3942 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3944 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3953 /* Set on less than with immediate operand */
3954 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3955 int rt, int rs, int16_t imm)
3957 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3961 /* If no destination, treat it as a NOP. */
3964 t0 = tcg_temp_new();
3965 gen_load_gpr(t0, rs);
3968 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3971 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3977 /* Shifts with immediate operand */
3978 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3979 int rt, int rs, int16_t imm)
3981 target_ulong uimm = ((uint16_t)imm) & 0x1f;
3985 /* If no destination, treat it as a NOP. */
3989 t0 = tcg_temp_new();
3990 gen_load_gpr(t0, rs);
3993 tcg_gen_shli_tl(t0, t0, uimm);
3994 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3997 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4001 tcg_gen_ext32u_tl(t0, t0);
4002 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4004 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4009 TCGv_i32 t1 = tcg_temp_new_i32();
4011 tcg_gen_trunc_tl_i32(t1, t0);
4012 tcg_gen_rotri_i32(t1, t1, uimm);
4013 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
4014 tcg_temp_free_i32(t1);
4016 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4019 #if defined(TARGET_MIPS64)
4021 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
4024 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4027 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4031 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
4033 tcg_gen_mov_tl(cpu_gpr[rt], t0);
4037 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4040 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4043 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4046 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4054 static void gen_arith(DisasContext *ctx, uint32_t opc,
4055 int rd, int rs, int rt)
4057 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4058 && opc != OPC_DADD && opc != OPC_DSUB) {
4059 /* If no destination, treat it as a NOP.
4060 For add & sub, we must generate the overflow exception when needed. */
4067 TCGv t0 = tcg_temp_local_new();
4068 TCGv t1 = tcg_temp_new();
4069 TCGv t2 = tcg_temp_new();
4070 TCGLabel *l1 = gen_new_label();
4072 gen_load_gpr(t1, rs);
4073 gen_load_gpr(t2, rt);
4074 tcg_gen_add_tl(t0, t1, t2);
4075 tcg_gen_ext32s_tl(t0, t0);
4076 tcg_gen_xor_tl(t1, t1, t2);
4077 tcg_gen_xor_tl(t2, t0, t2);
4078 tcg_gen_andc_tl(t1, t2, t1);
4080 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4082 /* operands of same sign, result different sign */
4083 generate_exception(ctx, EXCP_OVERFLOW);
4085 gen_store_gpr(t0, rd);
4090 if (rs != 0 && rt != 0) {
4091 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4092 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4093 } else if (rs == 0 && rt != 0) {
4094 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4095 } else if (rs != 0 && rt == 0) {
4096 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4098 tcg_gen_movi_tl(cpu_gpr[rd], 0);
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_sub_tl(t0, t1, t2);
4111 tcg_gen_ext32s_tl(t0, t0);
4112 tcg_gen_xor_tl(t2, t1, t2);
4113 tcg_gen_xor_tl(t1, t0, t1);
4114 tcg_gen_and_tl(t1, t1, t2);
4116 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4118 /* operands of different sign, first operand and result different sign */
4119 generate_exception(ctx, EXCP_OVERFLOW);
4121 gen_store_gpr(t0, rd);
4126 if (rs != 0 && rt != 0) {
4127 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4128 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4129 } else if (rs == 0 && rt != 0) {
4130 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4131 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4132 } else if (rs != 0 && rt == 0) {
4133 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4135 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4138 #if defined(TARGET_MIPS64)
4141 TCGv t0 = tcg_temp_local_new();
4142 TCGv t1 = tcg_temp_new();
4143 TCGv t2 = tcg_temp_new();
4144 TCGLabel *l1 = gen_new_label();
4146 gen_load_gpr(t1, rs);
4147 gen_load_gpr(t2, rt);
4148 tcg_gen_add_tl(t0, t1, t2);
4149 tcg_gen_xor_tl(t1, t1, t2);
4150 tcg_gen_xor_tl(t2, t0, t2);
4151 tcg_gen_andc_tl(t1, t2, t1);
4153 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4155 /* operands of same sign, result different sign */
4156 generate_exception(ctx, EXCP_OVERFLOW);
4158 gen_store_gpr(t0, rd);
4163 if (rs != 0 && rt != 0) {
4164 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4165 } else if (rs == 0 && rt != 0) {
4166 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4167 } else if (rs != 0 && rt == 0) {
4168 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4170 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4175 TCGv t0 = tcg_temp_local_new();
4176 TCGv t1 = tcg_temp_new();
4177 TCGv t2 = tcg_temp_new();
4178 TCGLabel *l1 = gen_new_label();
4180 gen_load_gpr(t1, rs);
4181 gen_load_gpr(t2, rt);
4182 tcg_gen_sub_tl(t0, t1, t2);
4183 tcg_gen_xor_tl(t2, t1, t2);
4184 tcg_gen_xor_tl(t1, t0, t1);
4185 tcg_gen_and_tl(t1, t1, t2);
4187 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4189 /* operands of different sign, first operand and result different sign */
4190 generate_exception(ctx, EXCP_OVERFLOW);
4192 gen_store_gpr(t0, rd);
4197 if (rs != 0 && rt != 0) {
4198 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4199 } else if (rs == 0 && rt != 0) {
4200 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4201 } else if (rs != 0 && rt == 0) {
4202 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4204 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4209 if (likely(rs != 0 && rt != 0)) {
4210 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4211 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4213 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4219 /* Conditional move */
4220 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4221 int rd, int rs, int rt)
4226 /* If no destination, treat it as a NOP. */
4230 t0 = tcg_temp_new();
4231 gen_load_gpr(t0, rt);
4232 t1 = tcg_const_tl(0);
4233 t2 = tcg_temp_new();
4234 gen_load_gpr(t2, rs);
4237 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4240 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4243 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4246 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4255 static void gen_logic(DisasContext *ctx, uint32_t opc,
4256 int rd, int rs, int rt)
4259 /* If no destination, treat it as a NOP. */
4265 if (likely(rs != 0 && rt != 0)) {
4266 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4268 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4272 if (rs != 0 && rt != 0) {
4273 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4274 } else if (rs == 0 && rt != 0) {
4275 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4276 } else if (rs != 0 && rt == 0) {
4277 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4279 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4283 if (likely(rs != 0 && rt != 0)) {
4284 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4285 } else if (rs == 0 && rt != 0) {
4286 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4287 } else if (rs != 0 && rt == 0) {
4288 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4290 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4294 if (likely(rs != 0 && rt != 0)) {
4295 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4296 } else if (rs == 0 && rt != 0) {
4297 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4298 } else if (rs != 0 && rt == 0) {
4299 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4301 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4307 /* Set on lower than */
4308 static void gen_slt(DisasContext *ctx, uint32_t opc,
4309 int rd, int rs, int rt)
4314 /* If no destination, treat it as a NOP. */
4318 t0 = tcg_temp_new();
4319 t1 = tcg_temp_new();
4320 gen_load_gpr(t0, rs);
4321 gen_load_gpr(t1, rt);
4324 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4327 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4335 static void gen_shift(DisasContext *ctx, uint32_t opc,
4336 int rd, int rs, int rt)
4341 /* If no destination, treat it as a NOP.
4342 For add & sub, we must generate the overflow exception when needed. */
4346 t0 = tcg_temp_new();
4347 t1 = tcg_temp_new();
4348 gen_load_gpr(t0, rs);
4349 gen_load_gpr(t1, rt);
4352 tcg_gen_andi_tl(t0, t0, 0x1f);
4353 tcg_gen_shl_tl(t0, t1, t0);
4354 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4357 tcg_gen_andi_tl(t0, t0, 0x1f);
4358 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4361 tcg_gen_ext32u_tl(t1, t1);
4362 tcg_gen_andi_tl(t0, t0, 0x1f);
4363 tcg_gen_shr_tl(t0, t1, t0);
4364 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4368 TCGv_i32 t2 = tcg_temp_new_i32();
4369 TCGv_i32 t3 = tcg_temp_new_i32();
4371 tcg_gen_trunc_tl_i32(t2, t0);
4372 tcg_gen_trunc_tl_i32(t3, t1);
4373 tcg_gen_andi_i32(t2, t2, 0x1f);
4374 tcg_gen_rotr_i32(t2, t3, t2);
4375 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4376 tcg_temp_free_i32(t2);
4377 tcg_temp_free_i32(t3);
4380 #if defined(TARGET_MIPS64)
4382 tcg_gen_andi_tl(t0, t0, 0x3f);
4383 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4386 tcg_gen_andi_tl(t0, t0, 0x3f);
4387 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4390 tcg_gen_andi_tl(t0, t0, 0x3f);
4391 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4394 tcg_gen_andi_tl(t0, t0, 0x3f);
4395 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4403 /* Copy GPR to and from TX79 HI1/LO1 register. */
4404 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4406 if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4413 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4416 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4420 tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4422 tcg_gen_movi_tl(cpu_HI[1], 0);
4427 tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4429 tcg_gen_movi_tl(cpu_LO[1], 0);
4433 MIPS_INVAL("mfthilo1 TX79");
4434 generate_exception_end(ctx, EXCP_RI);
4439 /* Arithmetic on HI/LO registers */
4440 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4442 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4453 #if defined(TARGET_MIPS64)
4455 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4459 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4463 #if defined(TARGET_MIPS64)
4465 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4469 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4474 #if defined(TARGET_MIPS64)
4476 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4480 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4483 tcg_gen_movi_tl(cpu_HI[acc], 0);
4488 #if defined(TARGET_MIPS64)
4490 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4494 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4497 tcg_gen_movi_tl(cpu_LO[acc], 0);
4503 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4506 TCGv t0 = tcg_const_tl(addr);
4507 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4508 gen_store_gpr(t0, reg);
4512 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4518 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4521 offset = sextract32(ctx->opcode << 2, 0, 21);
4522 addr = addr_add(ctx, pc, offset);
4523 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4527 offset = sextract32(ctx->opcode << 2, 0, 21);
4528 addr = addr_add(ctx, pc, offset);
4529 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4531 #if defined(TARGET_MIPS64)
4534 offset = sextract32(ctx->opcode << 2, 0, 21);
4535 addr = addr_add(ctx, pc, offset);
4536 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4540 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4543 offset = sextract32(ctx->opcode, 0, 16) << 16;
4544 addr = addr_add(ctx, pc, offset);
4545 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4550 offset = sextract32(ctx->opcode, 0, 16) << 16;
4551 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4552 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4555 #if defined(TARGET_MIPS64)
4556 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4557 case R6_OPC_LDPC + (1 << 16):
4558 case R6_OPC_LDPC + (2 << 16):
4559 case R6_OPC_LDPC + (3 << 16):
4561 offset = sextract32(ctx->opcode << 3, 0, 21);
4562 addr = addr_add(ctx, (pc & ~0x7), offset);
4563 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4567 MIPS_INVAL("OPC_PCREL");
4568 generate_exception_end(ctx, EXCP_RI);
4575 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4584 t0 = tcg_temp_new();
4585 t1 = tcg_temp_new();
4587 gen_load_gpr(t0, rs);
4588 gen_load_gpr(t1, rt);
4593 TCGv t2 = tcg_temp_new();
4594 TCGv t3 = tcg_temp_new();
4595 tcg_gen_ext32s_tl(t0, t0);
4596 tcg_gen_ext32s_tl(t1, t1);
4597 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4598 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4599 tcg_gen_and_tl(t2, t2, t3);
4600 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4601 tcg_gen_or_tl(t2, t2, t3);
4602 tcg_gen_movi_tl(t3, 0);
4603 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4604 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4605 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4612 TCGv t2 = tcg_temp_new();
4613 TCGv t3 = tcg_temp_new();
4614 tcg_gen_ext32s_tl(t0, t0);
4615 tcg_gen_ext32s_tl(t1, t1);
4616 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4617 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4618 tcg_gen_and_tl(t2, t2, t3);
4619 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4620 tcg_gen_or_tl(t2, t2, t3);
4621 tcg_gen_movi_tl(t3, 0);
4622 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4623 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4624 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4631 TCGv t2 = tcg_const_tl(0);
4632 TCGv t3 = tcg_const_tl(1);
4633 tcg_gen_ext32u_tl(t0, t0);
4634 tcg_gen_ext32u_tl(t1, t1);
4635 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4636 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4637 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4644 TCGv t2 = tcg_const_tl(0);
4645 TCGv t3 = tcg_const_tl(1);
4646 tcg_gen_ext32u_tl(t0, t0);
4647 tcg_gen_ext32u_tl(t1, t1);
4648 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4649 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4650 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
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_mul_i32(t2, t2, t3);
4662 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4663 tcg_temp_free_i32(t2);
4664 tcg_temp_free_i32(t3);
4669 TCGv_i32 t2 = tcg_temp_new_i32();
4670 TCGv_i32 t3 = tcg_temp_new_i32();
4671 tcg_gen_trunc_tl_i32(t2, t0);
4672 tcg_gen_trunc_tl_i32(t3, t1);
4673 tcg_gen_muls2_i32(t2, t3, t2, t3);
4674 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4675 tcg_temp_free_i32(t2);
4676 tcg_temp_free_i32(t3);
4681 TCGv_i32 t2 = tcg_temp_new_i32();
4682 TCGv_i32 t3 = tcg_temp_new_i32();
4683 tcg_gen_trunc_tl_i32(t2, t0);
4684 tcg_gen_trunc_tl_i32(t3, t1);
4685 tcg_gen_mul_i32(t2, t2, t3);
4686 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4687 tcg_temp_free_i32(t2);
4688 tcg_temp_free_i32(t3);
4693 TCGv_i32 t2 = tcg_temp_new_i32();
4694 TCGv_i32 t3 = tcg_temp_new_i32();
4695 tcg_gen_trunc_tl_i32(t2, t0);
4696 tcg_gen_trunc_tl_i32(t3, t1);
4697 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4698 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4699 tcg_temp_free_i32(t2);
4700 tcg_temp_free_i32(t3);
4703 #if defined(TARGET_MIPS64)
4706 TCGv t2 = tcg_temp_new();
4707 TCGv t3 = tcg_temp_new();
4708 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4709 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4710 tcg_gen_and_tl(t2, t2, t3);
4711 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4712 tcg_gen_or_tl(t2, t2, t3);
4713 tcg_gen_movi_tl(t3, 0);
4714 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4715 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4722 TCGv t2 = tcg_temp_new();
4723 TCGv t3 = tcg_temp_new();
4724 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4725 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4726 tcg_gen_and_tl(t2, t2, t3);
4727 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4728 tcg_gen_or_tl(t2, t2, t3);
4729 tcg_gen_movi_tl(t3, 0);
4730 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4731 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4738 TCGv t2 = tcg_const_tl(0);
4739 TCGv t3 = tcg_const_tl(1);
4740 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4741 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4748 TCGv t2 = tcg_const_tl(0);
4749 TCGv t3 = tcg_const_tl(1);
4750 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4751 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4757 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4761 TCGv t2 = tcg_temp_new();
4762 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4767 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4771 TCGv t2 = tcg_temp_new();
4772 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4778 MIPS_INVAL("r6 mul/div");
4779 generate_exception_end(ctx, EXCP_RI);
4787 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4791 t0 = tcg_temp_new();
4792 t1 = tcg_temp_new();
4794 gen_load_gpr(t0, rs);
4795 gen_load_gpr(t1, rt);
4800 TCGv t2 = tcg_temp_new();
4801 TCGv t3 = tcg_temp_new();
4802 tcg_gen_ext32s_tl(t0, t0);
4803 tcg_gen_ext32s_tl(t1, t1);
4804 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4805 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4806 tcg_gen_and_tl(t2, t2, t3);
4807 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4808 tcg_gen_or_tl(t2, t2, t3);
4809 tcg_gen_movi_tl(t3, 0);
4810 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4811 tcg_gen_div_tl(cpu_LO[1], t0, t1);
4812 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4813 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4814 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4821 TCGv t2 = tcg_const_tl(0);
4822 TCGv t3 = tcg_const_tl(1);
4823 tcg_gen_ext32u_tl(t0, t0);
4824 tcg_gen_ext32u_tl(t1, t1);
4825 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4826 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4827 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4828 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4829 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4835 MIPS_INVAL("div1 TX79");
4836 generate_exception_end(ctx, EXCP_RI);
4844 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4845 int acc, int rs, int rt)
4849 t0 = tcg_temp_new();
4850 t1 = tcg_temp_new();
4852 gen_load_gpr(t0, rs);
4853 gen_load_gpr(t1, rt);
4862 TCGv t2 = tcg_temp_new();
4863 TCGv t3 = tcg_temp_new();
4864 tcg_gen_ext32s_tl(t0, t0);
4865 tcg_gen_ext32s_tl(t1, t1);
4866 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4867 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4868 tcg_gen_and_tl(t2, t2, t3);
4869 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4870 tcg_gen_or_tl(t2, t2, t3);
4871 tcg_gen_movi_tl(t3, 0);
4872 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4873 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4874 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4875 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4876 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4883 TCGv t2 = tcg_const_tl(0);
4884 TCGv t3 = tcg_const_tl(1);
4885 tcg_gen_ext32u_tl(t0, t0);
4886 tcg_gen_ext32u_tl(t1, t1);
4887 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4888 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4889 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4890 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4891 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4898 TCGv_i32 t2 = tcg_temp_new_i32();
4899 TCGv_i32 t3 = tcg_temp_new_i32();
4900 tcg_gen_trunc_tl_i32(t2, t0);
4901 tcg_gen_trunc_tl_i32(t3, t1);
4902 tcg_gen_muls2_i32(t2, t3, t2, t3);
4903 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4904 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4905 tcg_temp_free_i32(t2);
4906 tcg_temp_free_i32(t3);
4911 TCGv_i32 t2 = tcg_temp_new_i32();
4912 TCGv_i32 t3 = tcg_temp_new_i32();
4913 tcg_gen_trunc_tl_i32(t2, t0);
4914 tcg_gen_trunc_tl_i32(t3, t1);
4915 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4916 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4917 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4918 tcg_temp_free_i32(t2);
4919 tcg_temp_free_i32(t3);
4922 #if defined(TARGET_MIPS64)
4925 TCGv t2 = tcg_temp_new();
4926 TCGv t3 = tcg_temp_new();
4927 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4928 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4929 tcg_gen_and_tl(t2, t2, t3);
4930 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4931 tcg_gen_or_tl(t2, t2, t3);
4932 tcg_gen_movi_tl(t3, 0);
4933 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4934 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4935 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4942 TCGv t2 = tcg_const_tl(0);
4943 TCGv t3 = tcg_const_tl(1);
4944 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4945 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4946 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4952 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4955 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
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_add_i64(t2, t2, t3);
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_add_i64(t2, t2, t3);
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);
4994 TCGv_i64 t2 = tcg_temp_new_i64();
4995 TCGv_i64 t3 = tcg_temp_new_i64();
4997 tcg_gen_ext_tl_i64(t2, t0);
4998 tcg_gen_ext_tl_i64(t3, t1);
4999 tcg_gen_mul_i64(t2, t2, t3);
5000 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5001 tcg_gen_sub_i64(t2, t3, t2);
5002 tcg_temp_free_i64(t3);
5003 gen_move_low32(cpu_LO[acc], t2);
5004 gen_move_high32(cpu_HI[acc], t2);
5005 tcg_temp_free_i64(t2);
5010 TCGv_i64 t2 = tcg_temp_new_i64();
5011 TCGv_i64 t3 = tcg_temp_new_i64();
5013 tcg_gen_ext32u_tl(t0, t0);
5014 tcg_gen_ext32u_tl(t1, t1);
5015 tcg_gen_extu_tl_i64(t2, t0);
5016 tcg_gen_extu_tl_i64(t3, t1);
5017 tcg_gen_mul_i64(t2, t2, t3);
5018 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5019 tcg_gen_sub_i64(t2, t3, t2);
5020 tcg_temp_free_i64(t3);
5021 gen_move_low32(cpu_LO[acc], t2);
5022 gen_move_high32(cpu_HI[acc], t2);
5023 tcg_temp_free_i64(t2);
5027 MIPS_INVAL("mul/div");
5028 generate_exception_end(ctx, EXCP_RI);
5037 * These MULT[U] and MADD[U] instructions implemented in for example
5038 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5039 * architectures are special three-operand variants with the syntax
5041 * MULT[U][1] rd, rs, rt
5045 * (rd, LO, HI) <- rs * rt
5049 * MADD[U][1] rd, rs, rt
5053 * (rd, LO, HI) <- (LO, HI) + rs * rt
5055 * where the low-order 32-bits of the result is placed into both the
5056 * GPR rd and the special register LO. The high-order 32-bits of the
5057 * result is placed into the special register HI.
5059 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5060 * which is the zero register that always reads as 0.
5062 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5063 int rd, int rs, int rt)
5065 TCGv t0 = tcg_temp_new();
5066 TCGv t1 = tcg_temp_new();
5069 gen_load_gpr(t0, rs);
5070 gen_load_gpr(t1, rt);
5078 TCGv_i32 t2 = tcg_temp_new_i32();
5079 TCGv_i32 t3 = tcg_temp_new_i32();
5080 tcg_gen_trunc_tl_i32(t2, t0);
5081 tcg_gen_trunc_tl_i32(t3, t1);
5082 tcg_gen_muls2_i32(t2, t3, t2, t3);
5084 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5086 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5087 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5088 tcg_temp_free_i32(t2);
5089 tcg_temp_free_i32(t3);
5092 case MMI_OPC_MULTU1:
5097 TCGv_i32 t2 = tcg_temp_new_i32();
5098 TCGv_i32 t3 = tcg_temp_new_i32();
5099 tcg_gen_trunc_tl_i32(t2, t0);
5100 tcg_gen_trunc_tl_i32(t3, t1);
5101 tcg_gen_mulu2_i32(t2, t3, t2, t3);
5103 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5105 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5106 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5107 tcg_temp_free_i32(t2);
5108 tcg_temp_free_i32(t3);
5116 TCGv_i64 t2 = tcg_temp_new_i64();
5117 TCGv_i64 t3 = tcg_temp_new_i64();
5119 tcg_gen_ext_tl_i64(t2, t0);
5120 tcg_gen_ext_tl_i64(t3, t1);
5121 tcg_gen_mul_i64(t2, t2, t3);
5122 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5123 tcg_gen_add_i64(t2, t2, t3);
5124 tcg_temp_free_i64(t3);
5125 gen_move_low32(cpu_LO[acc], t2);
5126 gen_move_high32(cpu_HI[acc], t2);
5128 gen_move_low32(cpu_gpr[rd], t2);
5130 tcg_temp_free_i64(t2);
5133 case MMI_OPC_MADDU1:
5138 TCGv_i64 t2 = tcg_temp_new_i64();
5139 TCGv_i64 t3 = tcg_temp_new_i64();
5141 tcg_gen_ext32u_tl(t0, t0);
5142 tcg_gen_ext32u_tl(t1, t1);
5143 tcg_gen_extu_tl_i64(t2, t0);
5144 tcg_gen_extu_tl_i64(t3, t1);
5145 tcg_gen_mul_i64(t2, t2, t3);
5146 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5147 tcg_gen_add_i64(t2, t2, t3);
5148 tcg_temp_free_i64(t3);
5149 gen_move_low32(cpu_LO[acc], t2);
5150 gen_move_high32(cpu_HI[acc], t2);
5152 gen_move_low32(cpu_gpr[rd], t2);
5154 tcg_temp_free_i64(t2);
5158 MIPS_INVAL("mul/madd TXx9");
5159 generate_exception_end(ctx, EXCP_RI);
5168 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5169 int rd, int rs, int rt)
5171 TCGv t0 = tcg_temp_new();
5172 TCGv t1 = tcg_temp_new();
5174 gen_load_gpr(t0, rs);
5175 gen_load_gpr(t1, rt);
5178 case OPC_VR54XX_MULS:
5179 gen_helper_muls(t0, cpu_env, t0, t1);
5181 case OPC_VR54XX_MULSU:
5182 gen_helper_mulsu(t0, cpu_env, t0, t1);
5184 case OPC_VR54XX_MACC:
5185 gen_helper_macc(t0, cpu_env, t0, t1);
5187 case OPC_VR54XX_MACCU:
5188 gen_helper_maccu(t0, cpu_env, t0, t1);
5190 case OPC_VR54XX_MSAC:
5191 gen_helper_msac(t0, cpu_env, t0, t1);
5193 case OPC_VR54XX_MSACU:
5194 gen_helper_msacu(t0, cpu_env, t0, t1);
5196 case OPC_VR54XX_MULHI:
5197 gen_helper_mulhi(t0, cpu_env, t0, t1);
5199 case OPC_VR54XX_MULHIU:
5200 gen_helper_mulhiu(t0, cpu_env, t0, t1);
5202 case OPC_VR54XX_MULSHI:
5203 gen_helper_mulshi(t0, cpu_env, t0, t1);
5205 case OPC_VR54XX_MULSHIU:
5206 gen_helper_mulshiu(t0, cpu_env, t0, t1);
5208 case OPC_VR54XX_MACCHI:
5209 gen_helper_macchi(t0, cpu_env, t0, t1);
5211 case OPC_VR54XX_MACCHIU:
5212 gen_helper_macchiu(t0, cpu_env, t0, t1);
5214 case OPC_VR54XX_MSACHI:
5215 gen_helper_msachi(t0, cpu_env, t0, t1);
5217 case OPC_VR54XX_MSACHIU:
5218 gen_helper_msachiu(t0, cpu_env, t0, t1);
5221 MIPS_INVAL("mul vr54xx");
5222 generate_exception_end(ctx, EXCP_RI);
5225 gen_store_gpr(t0, rd);
5232 static void gen_cl (DisasContext *ctx, uint32_t opc,
5242 gen_load_gpr(t0, rs);
5247 #if defined(TARGET_MIPS64)
5251 tcg_gen_not_tl(t0, t0);
5260 tcg_gen_ext32u_tl(t0, t0);
5261 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5262 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5264 #if defined(TARGET_MIPS64)
5269 tcg_gen_clzi_i64(t0, t0, 64);
5275 /* Godson integer instructions */
5276 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5277 int rd, int rs, int rt)
5289 case OPC_MULTU_G_2E:
5290 case OPC_MULTU_G_2F:
5291 #if defined(TARGET_MIPS64)
5292 case OPC_DMULT_G_2E:
5293 case OPC_DMULT_G_2F:
5294 case OPC_DMULTU_G_2E:
5295 case OPC_DMULTU_G_2F:
5297 t0 = tcg_temp_new();
5298 t1 = tcg_temp_new();
5301 t0 = tcg_temp_local_new();
5302 t1 = tcg_temp_local_new();
5306 gen_load_gpr(t0, rs);
5307 gen_load_gpr(t1, rt);
5312 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5313 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5315 case OPC_MULTU_G_2E:
5316 case OPC_MULTU_G_2F:
5317 tcg_gen_ext32u_tl(t0, t0);
5318 tcg_gen_ext32u_tl(t1, t1);
5319 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5320 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5325 TCGLabel *l1 = gen_new_label();
5326 TCGLabel *l2 = gen_new_label();
5327 TCGLabel *l3 = gen_new_label();
5328 tcg_gen_ext32s_tl(t0, t0);
5329 tcg_gen_ext32s_tl(t1, t1);
5330 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5331 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5334 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5335 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5336 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5339 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5340 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5347 TCGLabel *l1 = gen_new_label();
5348 TCGLabel *l2 = gen_new_label();
5349 tcg_gen_ext32u_tl(t0, t0);
5350 tcg_gen_ext32u_tl(t1, t1);
5351 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5352 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5355 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5356 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5363 TCGLabel *l1 = gen_new_label();
5364 TCGLabel *l2 = gen_new_label();
5365 TCGLabel *l3 = gen_new_label();
5366 tcg_gen_ext32u_tl(t0, t0);
5367 tcg_gen_ext32u_tl(t1, t1);
5368 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5369 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5370 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5372 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5375 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5376 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5383 TCGLabel *l1 = gen_new_label();
5384 TCGLabel *l2 = gen_new_label();
5385 tcg_gen_ext32u_tl(t0, t0);
5386 tcg_gen_ext32u_tl(t1, t1);
5387 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5388 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5391 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5392 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5396 #if defined(TARGET_MIPS64)
5397 case OPC_DMULT_G_2E:
5398 case OPC_DMULT_G_2F:
5399 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5401 case OPC_DMULTU_G_2E:
5402 case OPC_DMULTU_G_2F:
5403 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5408 TCGLabel *l1 = gen_new_label();
5409 TCGLabel *l2 = gen_new_label();
5410 TCGLabel *l3 = gen_new_label();
5411 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5412 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5415 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5416 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5417 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5420 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5424 case OPC_DDIVU_G_2E:
5425 case OPC_DDIVU_G_2F:
5427 TCGLabel *l1 = gen_new_label();
5428 TCGLabel *l2 = gen_new_label();
5429 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5430 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5433 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5440 TCGLabel *l1 = gen_new_label();
5441 TCGLabel *l2 = gen_new_label();
5442 TCGLabel *l3 = gen_new_label();
5443 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5444 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5445 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5447 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5450 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5454 case OPC_DMODU_G_2E:
5455 case OPC_DMODU_G_2F:
5457 TCGLabel *l1 = gen_new_label();
5458 TCGLabel *l2 = gen_new_label();
5459 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5460 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5463 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5474 /* Loongson multimedia instructions */
5475 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5477 uint32_t opc, shift_max;
5480 opc = MASK_LMI(ctx->opcode);
5486 t0 = tcg_temp_local_new_i64();
5487 t1 = tcg_temp_local_new_i64();
5490 t0 = tcg_temp_new_i64();
5491 t1 = tcg_temp_new_i64();
5495 check_cp1_enabled(ctx);
5496 gen_load_fpr64(ctx, t0, rs);
5497 gen_load_fpr64(ctx, t1, rt);
5499 #define LMI_HELPER(UP, LO) \
5500 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5501 #define LMI_HELPER_1(UP, LO) \
5502 case OPC_##UP: gen_helper_##LO(t0, t0); break
5503 #define LMI_DIRECT(UP, LO, OP) \
5504 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5507 LMI_HELPER(PADDSH, paddsh);
5508 LMI_HELPER(PADDUSH, paddush);
5509 LMI_HELPER(PADDH, paddh);
5510 LMI_HELPER(PADDW, paddw);
5511 LMI_HELPER(PADDSB, paddsb);
5512 LMI_HELPER(PADDUSB, paddusb);
5513 LMI_HELPER(PADDB, paddb);
5515 LMI_HELPER(PSUBSH, psubsh);
5516 LMI_HELPER(PSUBUSH, psubush);
5517 LMI_HELPER(PSUBH, psubh);
5518 LMI_HELPER(PSUBW, psubw);
5519 LMI_HELPER(PSUBSB, psubsb);
5520 LMI_HELPER(PSUBUSB, psubusb);
5521 LMI_HELPER(PSUBB, psubb);
5523 LMI_HELPER(PSHUFH, pshufh);
5524 LMI_HELPER(PACKSSWH, packsswh);
5525 LMI_HELPER(PACKSSHB, packsshb);
5526 LMI_HELPER(PACKUSHB, packushb);
5528 LMI_HELPER(PUNPCKLHW, punpcklhw);
5529 LMI_HELPER(PUNPCKHHW, punpckhhw);
5530 LMI_HELPER(PUNPCKLBH, punpcklbh);
5531 LMI_HELPER(PUNPCKHBH, punpckhbh);
5532 LMI_HELPER(PUNPCKLWD, punpcklwd);
5533 LMI_HELPER(PUNPCKHWD, punpckhwd);
5535 LMI_HELPER(PAVGH, pavgh);
5536 LMI_HELPER(PAVGB, pavgb);
5537 LMI_HELPER(PMAXSH, pmaxsh);
5538 LMI_HELPER(PMINSH, pminsh);
5539 LMI_HELPER(PMAXUB, pmaxub);
5540 LMI_HELPER(PMINUB, pminub);
5542 LMI_HELPER(PCMPEQW, pcmpeqw);
5543 LMI_HELPER(PCMPGTW, pcmpgtw);
5544 LMI_HELPER(PCMPEQH, pcmpeqh);
5545 LMI_HELPER(PCMPGTH, pcmpgth);
5546 LMI_HELPER(PCMPEQB, pcmpeqb);
5547 LMI_HELPER(PCMPGTB, pcmpgtb);
5549 LMI_HELPER(PSLLW, psllw);
5550 LMI_HELPER(PSLLH, psllh);
5551 LMI_HELPER(PSRLW, psrlw);
5552 LMI_HELPER(PSRLH, psrlh);
5553 LMI_HELPER(PSRAW, psraw);
5554 LMI_HELPER(PSRAH, psrah);
5556 LMI_HELPER(PMULLH, pmullh);
5557 LMI_HELPER(PMULHH, pmulhh);
5558 LMI_HELPER(PMULHUH, pmulhuh);
5559 LMI_HELPER(PMADDHW, pmaddhw);
5561 LMI_HELPER(PASUBUB, pasubub);
5562 LMI_HELPER_1(BIADD, biadd);
5563 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5565 LMI_DIRECT(PADDD, paddd, add);
5566 LMI_DIRECT(PSUBD, psubd, sub);
5567 LMI_DIRECT(XOR_CP2, xor, xor);
5568 LMI_DIRECT(NOR_CP2, nor, nor);
5569 LMI_DIRECT(AND_CP2, and, and);
5570 LMI_DIRECT(OR_CP2, or, or);
5573 tcg_gen_andc_i64(t0, t1, t0);
5577 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5580 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5583 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5586 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5590 tcg_gen_andi_i64(t1, t1, 3);
5591 tcg_gen_shli_i64(t1, t1, 4);
5592 tcg_gen_shr_i64(t0, t0, t1);
5593 tcg_gen_ext16u_i64(t0, t0);
5597 tcg_gen_add_i64(t0, t0, t1);
5598 tcg_gen_ext32s_i64(t0, t0);
5601 tcg_gen_sub_i64(t0, t0, t1);
5602 tcg_gen_ext32s_i64(t0, t0);
5624 /* Make sure shift count isn't TCG undefined behaviour. */
5625 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5630 tcg_gen_shl_i64(t0, t0, t1);
5634 /* Since SRA is UndefinedResult without sign-extended inputs,
5635 we can treat SRA and DSRA the same. */
5636 tcg_gen_sar_i64(t0, t0, t1);
5639 /* We want to shift in zeros for SRL; zero-extend first. */
5640 tcg_gen_ext32u_i64(t0, t0);
5643 tcg_gen_shr_i64(t0, t0, t1);
5647 if (shift_max == 32) {
5648 tcg_gen_ext32s_i64(t0, t0);
5651 /* Shifts larger than MAX produce zero. */
5652 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5653 tcg_gen_neg_i64(t1, t1);
5654 tcg_gen_and_i64(t0, t0, t1);
5660 TCGv_i64 t2 = tcg_temp_new_i64();
5661 TCGLabel *lab = gen_new_label();
5663 tcg_gen_mov_i64(t2, t0);
5664 tcg_gen_add_i64(t0, t1, t2);
5665 if (opc == OPC_ADD_CP2) {
5666 tcg_gen_ext32s_i64(t0, t0);
5668 tcg_gen_xor_i64(t1, t1, t2);
5669 tcg_gen_xor_i64(t2, t2, t0);
5670 tcg_gen_andc_i64(t1, t2, t1);
5671 tcg_temp_free_i64(t2);
5672 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5673 generate_exception(ctx, EXCP_OVERFLOW);
5681 TCGv_i64 t2 = tcg_temp_new_i64();
5682 TCGLabel *lab = gen_new_label();
5684 tcg_gen_mov_i64(t2, t0);
5685 tcg_gen_sub_i64(t0, t1, t2);
5686 if (opc == OPC_SUB_CP2) {
5687 tcg_gen_ext32s_i64(t0, t0);
5689 tcg_gen_xor_i64(t1, t1, t2);
5690 tcg_gen_xor_i64(t2, t2, t0);
5691 tcg_gen_and_i64(t1, t1, t2);
5692 tcg_temp_free_i64(t2);
5693 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5694 generate_exception(ctx, EXCP_OVERFLOW);
5700 tcg_gen_ext32u_i64(t0, t0);
5701 tcg_gen_ext32u_i64(t1, t1);
5702 tcg_gen_mul_i64(t0, t0, t1);
5711 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5712 FD field is the CC field? */
5714 MIPS_INVAL("loongson_cp2");
5715 generate_exception_end(ctx, EXCP_RI);
5722 gen_store_fpr64(ctx, t0, rd);
5724 tcg_temp_free_i64(t0);
5725 tcg_temp_free_i64(t1);
5729 static void gen_trap (DisasContext *ctx, uint32_t opc,
5730 int rs, int rt, int16_t imm)
5733 TCGv t0 = tcg_temp_new();
5734 TCGv t1 = tcg_temp_new();
5737 /* Load needed operands */
5745 /* Compare two registers */
5747 gen_load_gpr(t0, rs);
5748 gen_load_gpr(t1, rt);
5758 /* Compare register to immediate */
5759 if (rs != 0 || imm != 0) {
5760 gen_load_gpr(t0, rs);
5761 tcg_gen_movi_tl(t1, (int32_t)imm);
5768 case OPC_TEQ: /* rs == rs */
5769 case OPC_TEQI: /* r0 == 0 */
5770 case OPC_TGE: /* rs >= rs */
5771 case OPC_TGEI: /* r0 >= 0 */
5772 case OPC_TGEU: /* rs >= rs unsigned */
5773 case OPC_TGEIU: /* r0 >= 0 unsigned */
5775 generate_exception_end(ctx, EXCP_TRAP);
5777 case OPC_TLT: /* rs < rs */
5778 case OPC_TLTI: /* r0 < 0 */
5779 case OPC_TLTU: /* rs < rs unsigned */
5780 case OPC_TLTIU: /* r0 < 0 unsigned */
5781 case OPC_TNE: /* rs != rs */
5782 case OPC_TNEI: /* r0 != 0 */
5783 /* Never trap: treat as NOP. */
5787 TCGLabel *l1 = gen_new_label();
5792 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5796 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5800 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5804 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5808 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5812 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5815 generate_exception(ctx, EXCP_TRAP);
5822 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5824 if (unlikely(ctx->base.singlestep_enabled)) {
5828 #ifndef CONFIG_USER_ONLY
5829 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5835 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5837 if (use_goto_tb(ctx, dest)) {
5840 tcg_gen_exit_tb(ctx->base.tb, n);
5843 if (ctx->base.singlestep_enabled) {
5844 save_cpu_state(ctx, 0);
5845 gen_helper_raise_exception_debug(cpu_env);
5847 tcg_gen_lookup_and_goto_ptr();
5851 /* Branches (before delay slot) */
5852 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5854 int rs, int rt, int32_t offset,
5857 target_ulong btgt = -1;
5859 int bcond_compute = 0;
5860 TCGv t0 = tcg_temp_new();
5861 TCGv t1 = tcg_temp_new();
5863 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5864 #ifdef MIPS_DEBUG_DISAS
5865 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5866 TARGET_FMT_lx "\n", ctx->base.pc_next);
5868 generate_exception_end(ctx, EXCP_RI);
5872 /* Load needed operands */
5878 /* Compare two registers */
5880 gen_load_gpr(t0, rs);
5881 gen_load_gpr(t1, rt);
5884 btgt = ctx->base.pc_next + insn_bytes + offset;
5898 /* Compare to zero */
5900 gen_load_gpr(t0, rs);
5903 btgt = ctx->base.pc_next + insn_bytes + offset;
5906 #if defined(TARGET_MIPS64)
5908 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5910 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5913 btgt = ctx->base.pc_next + insn_bytes + offset;
5918 /* Jump to immediate */
5919 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5924 /* Jump to register */
5925 if (offset != 0 && offset != 16) {
5926 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5927 others are reserved. */
5928 MIPS_INVAL("jump hint");
5929 generate_exception_end(ctx, EXCP_RI);
5932 gen_load_gpr(btarget, rs);
5935 MIPS_INVAL("branch/jump");
5936 generate_exception_end(ctx, EXCP_RI);
5939 if (bcond_compute == 0) {
5940 /* No condition to be computed */
5942 case OPC_BEQ: /* rx == rx */
5943 case OPC_BEQL: /* rx == rx likely */
5944 case OPC_BGEZ: /* 0 >= 0 */
5945 case OPC_BGEZL: /* 0 >= 0 likely */
5946 case OPC_BLEZ: /* 0 <= 0 */
5947 case OPC_BLEZL: /* 0 <= 0 likely */
5949 ctx->hflags |= MIPS_HFLAG_B;
5951 case OPC_BGEZAL: /* 0 >= 0 */
5952 case OPC_BGEZALL: /* 0 >= 0 likely */
5953 /* Always take and link */
5955 ctx->hflags |= MIPS_HFLAG_B;
5957 case OPC_BNE: /* rx != rx */
5958 case OPC_BGTZ: /* 0 > 0 */
5959 case OPC_BLTZ: /* 0 < 0 */
5962 case OPC_BLTZAL: /* 0 < 0 */
5963 /* Handle as an unconditional branch to get correct delay
5966 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5967 ctx->hflags |= MIPS_HFLAG_B;
5969 case OPC_BLTZALL: /* 0 < 0 likely */
5970 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5971 /* Skip the instruction in the delay slot */
5972 ctx->base.pc_next += 4;
5974 case OPC_BNEL: /* rx != rx likely */
5975 case OPC_BGTZL: /* 0 > 0 likely */
5976 case OPC_BLTZL: /* 0 < 0 likely */
5977 /* Skip the instruction in the delay slot */
5978 ctx->base.pc_next += 4;
5981 ctx->hflags |= MIPS_HFLAG_B;
5984 ctx->hflags |= MIPS_HFLAG_BX;
5988 ctx->hflags |= MIPS_HFLAG_B;
5991 ctx->hflags |= MIPS_HFLAG_BR;
5995 ctx->hflags |= MIPS_HFLAG_BR;
5998 MIPS_INVAL("branch/jump");
5999 generate_exception_end(ctx, EXCP_RI);
6005 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6008 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6011 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6014 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6017 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6020 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6023 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6027 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6031 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6034 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6037 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6040 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6043 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6046 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6049 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6051 #if defined(TARGET_MIPS64)
6053 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6057 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6060 ctx->hflags |= MIPS_HFLAG_BC;
6063 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6066 ctx->hflags |= MIPS_HFLAG_BL;
6069 MIPS_INVAL("conditional branch/jump");
6070 generate_exception_end(ctx, EXCP_RI);
6075 ctx->btarget = btgt;
6077 switch (delayslot_size) {
6079 ctx->hflags |= MIPS_HFLAG_BDS16;
6082 ctx->hflags |= MIPS_HFLAG_BDS32;
6087 int post_delay = insn_bytes + delayslot_size;
6088 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6090 tcg_gen_movi_tl(cpu_gpr[blink],
6091 ctx->base.pc_next + post_delay + lowbit);
6095 if (insn_bytes == 2)
6096 ctx->hflags |= MIPS_HFLAG_B16;
6102 /* nanoMIPS Branches */
6103 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6105 int rs, int rt, int32_t offset)
6107 target_ulong btgt = -1;
6108 int bcond_compute = 0;
6109 TCGv t0 = tcg_temp_new();
6110 TCGv t1 = tcg_temp_new();
6112 /* Load needed operands */
6116 /* Compare two registers */
6118 gen_load_gpr(t0, rs);
6119 gen_load_gpr(t1, rt);
6122 btgt = ctx->base.pc_next + insn_bytes + offset;
6125 /* Compare to zero */
6127 gen_load_gpr(t0, rs);
6130 btgt = ctx->base.pc_next + insn_bytes + offset;
6133 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6135 btgt = ctx->base.pc_next + insn_bytes + offset;
6139 /* Jump to register */
6140 if (offset != 0 && offset != 16) {
6141 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6142 others are reserved. */
6143 MIPS_INVAL("jump hint");
6144 generate_exception_end(ctx, EXCP_RI);
6147 gen_load_gpr(btarget, rs);
6150 MIPS_INVAL("branch/jump");
6151 generate_exception_end(ctx, EXCP_RI);
6154 if (bcond_compute == 0) {
6155 /* No condition to be computed */
6157 case OPC_BEQ: /* rx == rx */
6159 ctx->hflags |= MIPS_HFLAG_B;
6161 case OPC_BGEZAL: /* 0 >= 0 */
6162 /* Always take and link */
6163 tcg_gen_movi_tl(cpu_gpr[31],
6164 ctx->base.pc_next + insn_bytes);
6165 ctx->hflags |= MIPS_HFLAG_B;
6167 case OPC_BNE: /* rx != rx */
6168 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6169 /* Skip the instruction in the delay slot */
6170 ctx->base.pc_next += 4;
6173 ctx->hflags |= MIPS_HFLAG_BR;
6177 tcg_gen_movi_tl(cpu_gpr[rt],
6178 ctx->base.pc_next + insn_bytes);
6180 ctx->hflags |= MIPS_HFLAG_BR;
6183 MIPS_INVAL("branch/jump");
6184 generate_exception_end(ctx, EXCP_RI);
6190 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6193 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6196 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6197 tcg_gen_movi_tl(cpu_gpr[31],
6198 ctx->base.pc_next + insn_bytes);
6201 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6203 ctx->hflags |= MIPS_HFLAG_BC;
6206 MIPS_INVAL("conditional branch/jump");
6207 generate_exception_end(ctx, EXCP_RI);
6212 ctx->btarget = btgt;
6215 if (insn_bytes == 2) {
6216 ctx->hflags |= MIPS_HFLAG_B16;
6223 /* special3 bitfield operations */
6224 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
6225 int rs, int lsb, int msb)
6227 TCGv t0 = tcg_temp_new();
6228 TCGv t1 = tcg_temp_new();
6230 gen_load_gpr(t1, rs);
6233 if (lsb + msb > 31) {
6237 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6239 /* The two checks together imply that lsb == 0,
6240 so this is a simple sign-extension. */
6241 tcg_gen_ext32s_tl(t0, t1);
6244 #if defined(TARGET_MIPS64)
6253 if (lsb + msb > 63) {
6256 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6263 gen_load_gpr(t0, rt);
6264 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6265 tcg_gen_ext32s_tl(t0, t0);
6267 #if defined(TARGET_MIPS64)
6278 gen_load_gpr(t0, rt);
6279 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6284 MIPS_INVAL("bitops");
6285 generate_exception_end(ctx, EXCP_RI);
6290 gen_store_gpr(t0, rt);
6295 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6300 /* If no destination, treat it as a NOP. */
6304 t0 = tcg_temp_new();
6305 gen_load_gpr(t0, rt);
6309 TCGv t1 = tcg_temp_new();
6310 TCGv t2 = tcg_const_tl(0x00FF00FF);
6312 tcg_gen_shri_tl(t1, t0, 8);
6313 tcg_gen_and_tl(t1, t1, t2);
6314 tcg_gen_and_tl(t0, t0, t2);
6315 tcg_gen_shli_tl(t0, t0, 8);
6316 tcg_gen_or_tl(t0, t0, t1);
6319 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6323 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6326 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6328 #if defined(TARGET_MIPS64)
6331 TCGv t1 = tcg_temp_new();
6332 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6334 tcg_gen_shri_tl(t1, t0, 8);
6335 tcg_gen_and_tl(t1, t1, t2);
6336 tcg_gen_and_tl(t0, t0, t2);
6337 tcg_gen_shli_tl(t0, t0, 8);
6338 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6345 TCGv t1 = tcg_temp_new();
6346 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6348 tcg_gen_shri_tl(t1, t0, 16);
6349 tcg_gen_and_tl(t1, t1, t2);
6350 tcg_gen_and_tl(t0, t0, t2);
6351 tcg_gen_shli_tl(t0, t0, 16);
6352 tcg_gen_or_tl(t0, t0, t1);
6353 tcg_gen_shri_tl(t1, t0, 32);
6354 tcg_gen_shli_tl(t0, t0, 32);
6355 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6362 MIPS_INVAL("bsfhl");
6363 generate_exception_end(ctx, EXCP_RI);
6370 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6379 t0 = tcg_temp_new();
6380 t1 = tcg_temp_new();
6381 gen_load_gpr(t0, rs);
6382 gen_load_gpr(t1, rt);
6383 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6384 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6385 if (opc == OPC_LSA) {
6386 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6395 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6403 t0 = tcg_temp_new();
6404 if (bits == 0 || bits == wordsz) {
6406 gen_load_gpr(t0, rt);
6408 gen_load_gpr(t0, rs);
6412 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6414 #if defined(TARGET_MIPS64)
6416 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6421 TCGv t1 = tcg_temp_new();
6422 gen_load_gpr(t0, rt);
6423 gen_load_gpr(t1, rs);
6427 TCGv_i64 t2 = tcg_temp_new_i64();
6428 tcg_gen_concat_tl_i64(t2, t1, t0);
6429 tcg_gen_shri_i64(t2, t2, 32 - bits);
6430 gen_move_low32(cpu_gpr[rd], t2);
6431 tcg_temp_free_i64(t2);
6434 #if defined(TARGET_MIPS64)
6436 tcg_gen_shli_tl(t0, t0, bits);
6437 tcg_gen_shri_tl(t1, t1, 64 - bits);
6438 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6448 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6451 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6454 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6457 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6460 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6467 t0 = tcg_temp_new();
6468 gen_load_gpr(t0, rt);
6471 gen_helper_bitswap(cpu_gpr[rd], t0);
6473 #if defined(TARGET_MIPS64)
6475 gen_helper_dbitswap(cpu_gpr[rd], t0);
6482 #ifndef CONFIG_USER_ONLY
6483 /* CP0 (MMU and control) */
6484 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6486 TCGv_i64 t0 = tcg_temp_new_i64();
6487 TCGv_i64 t1 = tcg_temp_new_i64();
6489 tcg_gen_ext_tl_i64(t0, arg);
6490 tcg_gen_ld_i64(t1, cpu_env, off);
6491 #if defined(TARGET_MIPS64)
6492 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6494 tcg_gen_concat32_i64(t1, t1, t0);
6496 tcg_gen_st_i64(t1, cpu_env, off);
6497 tcg_temp_free_i64(t1);
6498 tcg_temp_free_i64(t0);
6501 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6503 TCGv_i64 t0 = tcg_temp_new_i64();
6504 TCGv_i64 t1 = tcg_temp_new_i64();
6506 tcg_gen_ext_tl_i64(t0, arg);
6507 tcg_gen_ld_i64(t1, cpu_env, off);
6508 tcg_gen_concat32_i64(t1, t1, t0);
6509 tcg_gen_st_i64(t1, cpu_env, off);
6510 tcg_temp_free_i64(t1);
6511 tcg_temp_free_i64(t0);
6514 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6516 TCGv_i64 t0 = tcg_temp_new_i64();
6518 tcg_gen_ld_i64(t0, cpu_env, off);
6519 #if defined(TARGET_MIPS64)
6520 tcg_gen_shri_i64(t0, t0, 30);
6522 tcg_gen_shri_i64(t0, t0, 32);
6524 gen_move_low32(arg, t0);
6525 tcg_temp_free_i64(t0);
6528 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6530 TCGv_i64 t0 = tcg_temp_new_i64();
6532 tcg_gen_ld_i64(t0, cpu_env, off);
6533 tcg_gen_shri_i64(t0, t0, 32 + shift);
6534 gen_move_low32(arg, t0);
6535 tcg_temp_free_i64(t0);
6538 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6540 TCGv_i32 t0 = tcg_temp_new_i32();
6542 tcg_gen_ld_i32(t0, cpu_env, off);
6543 tcg_gen_ext_i32_tl(arg, t0);
6544 tcg_temp_free_i32(t0);
6547 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6549 tcg_gen_ld_tl(arg, cpu_env, off);
6550 tcg_gen_ext32s_tl(arg, arg);
6553 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6555 TCGv_i32 t0 = tcg_temp_new_i32();
6557 tcg_gen_trunc_tl_i32(t0, arg);
6558 tcg_gen_st_i32(t0, cpu_env, off);
6559 tcg_temp_free_i32(t0);
6562 #define CP0_CHECK(c) \
6565 goto cp0_unimplemented; \
6569 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6571 const char *register_name = "invalid";
6574 case CP0_REGISTER_02:
6577 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6578 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6579 register_name = "EntryLo0";
6582 goto cp0_unimplemented;
6585 case CP0_REGISTER_03:
6588 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6589 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6590 register_name = "EntryLo1";
6593 goto cp0_unimplemented;
6596 case CP0_REGISTER_09:
6599 CP0_CHECK(ctx->saar);
6600 gen_helper_mfhc0_saar(arg, cpu_env);
6601 register_name = "SAAR";
6604 goto cp0_unimplemented;
6607 case CP0_REGISTER_17:
6610 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6611 ctx->CP0_LLAddr_shift);
6612 register_name = "LLAddr";
6615 CP0_CHECK(ctx->mrp);
6616 gen_helper_mfhc0_maar(arg, cpu_env);
6617 register_name = "MAAR";
6620 goto cp0_unimplemented;
6623 case CP0_REGISTER_28:
6629 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6630 register_name = "TagLo";
6633 goto cp0_unimplemented;
6637 goto cp0_unimplemented;
6639 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6643 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6644 register_name, reg, sel);
6645 tcg_gen_movi_tl(arg, 0);
6648 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6650 const char *register_name = "invalid";
6651 uint64_t mask = ctx->PAMask >> 36;
6654 case CP0_REGISTER_02:
6657 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6658 tcg_gen_andi_tl(arg, arg, mask);
6659 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6660 register_name = "EntryLo0";
6663 goto cp0_unimplemented;
6666 case CP0_REGISTER_03:
6669 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6670 tcg_gen_andi_tl(arg, arg, mask);
6671 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6672 register_name = "EntryLo1";
6675 goto cp0_unimplemented;
6678 case CP0_REGISTER_09:
6681 CP0_CHECK(ctx->saar);
6682 gen_helper_mthc0_saar(cpu_env, arg);
6683 register_name = "SAAR";
6686 goto cp0_unimplemented;
6688 case CP0_REGISTER_17:
6691 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6692 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6693 relevant for modern MIPS cores supporting MTHC0, therefore
6694 treating MTHC0 to LLAddr as NOP. */
6695 register_name = "LLAddr";
6698 CP0_CHECK(ctx->mrp);
6699 gen_helper_mthc0_maar(cpu_env, arg);
6700 register_name = "MAAR";
6703 goto cp0_unimplemented;
6706 case CP0_REGISTER_28:
6712 tcg_gen_andi_tl(arg, arg, mask);
6713 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6714 register_name = "TagLo";
6717 goto cp0_unimplemented;
6721 goto cp0_unimplemented;
6723 trace_mips_translate_c0("mthc0", register_name, reg, sel);
6726 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6727 register_name, reg, sel);
6730 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6732 if (ctx->insn_flags & ISA_MIPS32R6) {
6733 tcg_gen_movi_tl(arg, 0);
6735 tcg_gen_movi_tl(arg, ~0);
6739 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6741 const char *register_name = "invalid";
6744 check_insn(ctx, ISA_MIPS32);
6747 case CP0_REGISTER_00:
6750 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6751 register_name = "Index";
6754 CP0_CHECK(ctx->insn_flags & ASE_MT);
6755 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6756 register_name = "MVPControl";
6759 CP0_CHECK(ctx->insn_flags & ASE_MT);
6760 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6761 register_name = "MVPConf0";
6764 CP0_CHECK(ctx->insn_flags & ASE_MT);
6765 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6766 register_name = "MVPConf1";
6770 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6771 register_name = "VPControl";
6774 goto cp0_unimplemented;
6777 case CP0_REGISTER_01:
6780 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6781 gen_helper_mfc0_random(arg, cpu_env);
6782 register_name = "Random";
6785 CP0_CHECK(ctx->insn_flags & ASE_MT);
6786 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6787 register_name = "VPEControl";
6790 CP0_CHECK(ctx->insn_flags & ASE_MT);
6791 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6792 register_name = "VPEConf0";
6795 CP0_CHECK(ctx->insn_flags & ASE_MT);
6796 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6797 register_name = "VPEConf1";
6800 CP0_CHECK(ctx->insn_flags & ASE_MT);
6801 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6802 register_name = "YQMask";
6805 CP0_CHECK(ctx->insn_flags & ASE_MT);
6806 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6807 register_name = "VPESchedule";
6810 CP0_CHECK(ctx->insn_flags & ASE_MT);
6811 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6812 register_name = "VPEScheFBack";
6815 CP0_CHECK(ctx->insn_flags & ASE_MT);
6816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6817 register_name = "VPEOpt";
6820 goto cp0_unimplemented;
6823 case CP0_REGISTER_02:
6827 TCGv_i64 tmp = tcg_temp_new_i64();
6828 tcg_gen_ld_i64(tmp, cpu_env,
6829 offsetof(CPUMIPSState, CP0_EntryLo0));
6830 #if defined(TARGET_MIPS64)
6832 /* Move RI/XI fields to bits 31:30 */
6833 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6834 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6837 gen_move_low32(arg, tmp);
6838 tcg_temp_free_i64(tmp);
6840 register_name = "EntryLo0";
6843 CP0_CHECK(ctx->insn_flags & ASE_MT);
6844 gen_helper_mfc0_tcstatus(arg, cpu_env);
6845 register_name = "TCStatus";
6848 CP0_CHECK(ctx->insn_flags & ASE_MT);
6849 gen_helper_mfc0_tcbind(arg, cpu_env);
6850 register_name = "TCBind";
6853 CP0_CHECK(ctx->insn_flags & ASE_MT);
6854 gen_helper_mfc0_tcrestart(arg, cpu_env);
6855 register_name = "TCRestart";
6858 CP0_CHECK(ctx->insn_flags & ASE_MT);
6859 gen_helper_mfc0_tchalt(arg, cpu_env);
6860 register_name = "TCHalt";
6863 CP0_CHECK(ctx->insn_flags & ASE_MT);
6864 gen_helper_mfc0_tccontext(arg, cpu_env);
6865 register_name = "TCContext";
6868 CP0_CHECK(ctx->insn_flags & ASE_MT);
6869 gen_helper_mfc0_tcschedule(arg, cpu_env);
6870 register_name = "TCSchedule";
6873 CP0_CHECK(ctx->insn_flags & ASE_MT);
6874 gen_helper_mfc0_tcschefback(arg, cpu_env);
6875 register_name = "TCScheFBack";
6878 goto cp0_unimplemented;
6881 case CP0_REGISTER_03:
6885 TCGv_i64 tmp = tcg_temp_new_i64();
6886 tcg_gen_ld_i64(tmp, cpu_env,
6887 offsetof(CPUMIPSState, CP0_EntryLo1));
6888 #if defined(TARGET_MIPS64)
6890 /* Move RI/XI fields to bits 31:30 */
6891 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6892 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6895 gen_move_low32(arg, tmp);
6896 tcg_temp_free_i64(tmp);
6898 register_name = "EntryLo1";
6902 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6903 register_name = "GlobalNumber";
6906 goto cp0_unimplemented;
6909 case CP0_REGISTER_04:
6912 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6913 tcg_gen_ext32s_tl(arg, arg);
6914 register_name = "Context";
6917 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6918 register_name = "ContextConfig";
6919 goto cp0_unimplemented;
6921 CP0_CHECK(ctx->ulri);
6922 tcg_gen_ld_tl(arg, cpu_env,
6923 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6924 tcg_gen_ext32s_tl(arg, arg);
6925 register_name = "UserLocal";
6928 goto cp0_unimplemented;
6931 case CP0_REGISTER_05:
6934 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6935 register_name = "PageMask";
6938 check_insn(ctx, ISA_MIPS32R2);
6939 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6940 register_name = "PageGrain";
6944 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6945 tcg_gen_ext32s_tl(arg, arg);
6946 register_name = "SegCtl0";
6950 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6951 tcg_gen_ext32s_tl(arg, arg);
6952 register_name = "SegCtl1";
6956 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6957 tcg_gen_ext32s_tl(arg, arg);
6958 register_name = "SegCtl2";
6962 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6963 register_name = "PWBase";
6967 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6968 register_name = "PWField";
6972 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6973 register_name = "PWSize";
6976 goto cp0_unimplemented;
6979 case CP0_REGISTER_06:
6982 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6983 register_name = "Wired";
6986 check_insn(ctx, ISA_MIPS32R2);
6987 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6988 register_name = "SRSConf0";
6991 check_insn(ctx, ISA_MIPS32R2);
6992 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6993 register_name = "SRSConf1";
6996 check_insn(ctx, ISA_MIPS32R2);
6997 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6998 register_name = "SRSConf2";
7001 check_insn(ctx, ISA_MIPS32R2);
7002 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7003 register_name = "SRSConf3";
7006 check_insn(ctx, ISA_MIPS32R2);
7007 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7008 register_name = "SRSConf4";
7012 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7013 register_name = "PWCtl";
7016 goto cp0_unimplemented;
7019 case CP0_REGISTER_07:
7022 check_insn(ctx, ISA_MIPS32R2);
7023 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7024 register_name = "HWREna";
7027 goto cp0_unimplemented;
7030 case CP0_REGISTER_08:
7033 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7034 tcg_gen_ext32s_tl(arg, arg);
7035 register_name = "BadVAddr";
7039 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7040 register_name = "BadInstr";
7044 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7045 register_name = "BadInstrP";
7049 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7050 tcg_gen_andi_tl(arg, arg, ~0xffff);
7051 register_name = "BadInstrX";
7054 goto cp0_unimplemented;
7057 case CP0_REGISTER_09:
7060 /* Mark as an IO operation because we read the time. */
7061 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7064 gen_helper_mfc0_count(arg, cpu_env);
7065 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7068 /* Break the TB to be able to take timer interrupts immediately
7069 after reading count. DISAS_STOP isn't sufficient, we need to
7070 ensure we break completely out of translated code. */
7071 gen_save_pc(ctx->base.pc_next + 4);
7072 ctx->base.is_jmp = DISAS_EXIT;
7073 register_name = "Count";
7076 CP0_CHECK(ctx->saar);
7077 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7078 register_name = "SAARI";
7081 CP0_CHECK(ctx->saar);
7082 gen_helper_mfc0_saar(arg, cpu_env);
7083 register_name = "SAAR";
7086 goto cp0_unimplemented;
7089 case CP0_REGISTER_10:
7092 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7093 tcg_gen_ext32s_tl(arg, arg);
7094 register_name = "EntryHi";
7097 goto cp0_unimplemented;
7100 case CP0_REGISTER_11:
7103 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7104 register_name = "Compare";
7106 /* 6,7 are implementation dependent */
7108 goto cp0_unimplemented;
7111 case CP0_REGISTER_12:
7114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7115 register_name = "Status";
7118 check_insn(ctx, ISA_MIPS32R2);
7119 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7120 register_name = "IntCtl";
7123 check_insn(ctx, ISA_MIPS32R2);
7124 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7125 register_name = "SRSCtl";
7128 check_insn(ctx, ISA_MIPS32R2);
7129 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7130 register_name = "SRSMap";
7133 goto cp0_unimplemented;
7136 case CP0_REGISTER_13:
7139 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7140 register_name = "Cause";
7143 goto cp0_unimplemented;
7146 case CP0_REGISTER_14:
7149 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7150 tcg_gen_ext32s_tl(arg, arg);
7151 register_name = "EPC";
7154 goto cp0_unimplemented;
7157 case CP0_REGISTER_15:
7160 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7161 register_name = "PRid";
7164 check_insn(ctx, ISA_MIPS32R2);
7165 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7166 tcg_gen_ext32s_tl(arg, arg);
7167 register_name = "EBase";
7170 check_insn(ctx, ISA_MIPS32R2);
7171 CP0_CHECK(ctx->cmgcr);
7172 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7173 tcg_gen_ext32s_tl(arg, arg);
7174 register_name = "CMGCRBase";
7177 goto cp0_unimplemented;
7180 case CP0_REGISTER_16:
7183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7184 register_name = "Config";
7187 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7188 register_name = "Config1";
7191 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7192 register_name = "Config2";
7195 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7196 register_name = "Config3";
7199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7200 register_name = "Config4";
7203 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7204 register_name = "Config5";
7206 /* 6,7 are implementation dependent */
7208 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7209 register_name = "Config6";
7212 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7213 register_name = "Config7";
7216 goto cp0_unimplemented;
7219 case CP0_REGISTER_17:
7222 gen_helper_mfc0_lladdr(arg, cpu_env);
7223 register_name = "LLAddr";
7226 CP0_CHECK(ctx->mrp);
7227 gen_helper_mfc0_maar(arg, cpu_env);
7228 register_name = "MAAR";
7231 CP0_CHECK(ctx->mrp);
7232 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7233 register_name = "MAARI";
7236 goto cp0_unimplemented;
7239 case CP0_REGISTER_18:
7249 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7250 gen_helper_1e0i(mfc0_watchlo, arg, sel);
7251 register_name = "WatchLo";
7254 goto cp0_unimplemented;
7257 case CP0_REGISTER_19:
7267 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7268 gen_helper_1e0i(mfc0_watchhi, arg, sel);
7269 register_name = "WatchHi";
7272 goto cp0_unimplemented;
7275 case CP0_REGISTER_20:
7278 #if defined(TARGET_MIPS64)
7279 check_insn(ctx, ISA_MIPS3);
7280 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7281 tcg_gen_ext32s_tl(arg, arg);
7282 register_name = "XContext";
7286 goto cp0_unimplemented;
7289 case CP0_REGISTER_21:
7290 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7291 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7295 register_name = "Framemask";
7298 goto cp0_unimplemented;
7301 case CP0_REGISTER_22:
7302 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7303 register_name = "'Diagnostic"; /* implementation dependent */
7305 case CP0_REGISTER_23:
7308 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7309 register_name = "Debug";
7312 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7313 register_name = "TraceControl";
7314 goto cp0_unimplemented;
7316 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7317 register_name = "TraceControl2";
7318 goto cp0_unimplemented;
7320 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7321 register_name = "UserTraceData";
7322 goto cp0_unimplemented;
7324 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7325 register_name = "TraceBPC";
7326 goto cp0_unimplemented;
7328 goto cp0_unimplemented;
7331 case CP0_REGISTER_24:
7335 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7336 tcg_gen_ext32s_tl(arg, arg);
7337 register_name = "DEPC";
7340 goto cp0_unimplemented;
7343 case CP0_REGISTER_25:
7346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7347 register_name = "Performance0";
7350 // gen_helper_mfc0_performance1(arg);
7351 register_name = "Performance1";
7352 goto cp0_unimplemented;
7354 // gen_helper_mfc0_performance2(arg);
7355 register_name = "Performance2";
7356 goto cp0_unimplemented;
7358 // gen_helper_mfc0_performance3(arg);
7359 register_name = "Performance3";
7360 goto cp0_unimplemented;
7362 // gen_helper_mfc0_performance4(arg);
7363 register_name = "Performance4";
7364 goto cp0_unimplemented;
7366 // gen_helper_mfc0_performance5(arg);
7367 register_name = "Performance5";
7368 goto cp0_unimplemented;
7370 // gen_helper_mfc0_performance6(arg);
7371 register_name = "Performance6";
7372 goto cp0_unimplemented;
7374 // gen_helper_mfc0_performance7(arg);
7375 register_name = "Performance7";
7376 goto cp0_unimplemented;
7378 goto cp0_unimplemented;
7381 case CP0_REGISTER_26:
7384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7385 register_name = "ErrCtl";
7388 goto cp0_unimplemented;
7391 case CP0_REGISTER_27:
7397 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7398 register_name = "CacheErr";
7401 goto cp0_unimplemented;
7404 case CP0_REGISTER_28:
7411 TCGv_i64 tmp = tcg_temp_new_i64();
7412 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7413 gen_move_low32(arg, tmp);
7414 tcg_temp_free_i64(tmp);
7416 register_name = "TagLo";
7422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7423 register_name = "DataLo";
7426 goto cp0_unimplemented;
7429 case CP0_REGISTER_29:
7435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7436 register_name = "TagHi";
7442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7443 register_name = "DataHi";
7446 goto cp0_unimplemented;
7449 case CP0_REGISTER_30:
7452 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7453 tcg_gen_ext32s_tl(arg, arg);
7454 register_name = "ErrorEPC";
7457 goto cp0_unimplemented;
7460 case CP0_REGISTER_31:
7464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7465 register_name = "DESAVE";
7473 CP0_CHECK(ctx->kscrexist & (1 << sel));
7474 tcg_gen_ld_tl(arg, cpu_env,
7475 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7476 tcg_gen_ext32s_tl(arg, arg);
7477 register_name = "KScratch";
7480 goto cp0_unimplemented;
7484 goto cp0_unimplemented;
7486 trace_mips_translate_c0("mfc0", register_name, reg, sel);
7490 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7491 register_name, reg, sel);
7492 gen_mfc0_unimplemented(ctx, arg);
7495 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7497 const char *register_name = "invalid";
7500 check_insn(ctx, ISA_MIPS32);
7502 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7507 case CP0_REGISTER_00:
7510 gen_helper_mtc0_index(cpu_env, arg);
7511 register_name = "Index";
7514 CP0_CHECK(ctx->insn_flags & ASE_MT);
7515 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7516 register_name = "MVPControl";
7519 CP0_CHECK(ctx->insn_flags & ASE_MT);
7521 register_name = "MVPConf0";
7524 CP0_CHECK(ctx->insn_flags & ASE_MT);
7526 register_name = "MVPConf1";
7531 register_name = "VPControl";
7534 goto cp0_unimplemented;
7537 case CP0_REGISTER_01:
7541 register_name = "Random";
7544 CP0_CHECK(ctx->insn_flags & ASE_MT);
7545 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7546 register_name = "VPEControl";
7549 CP0_CHECK(ctx->insn_flags & ASE_MT);
7550 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7551 register_name = "VPEConf0";
7554 CP0_CHECK(ctx->insn_flags & ASE_MT);
7555 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7556 register_name = "VPEConf1";
7559 CP0_CHECK(ctx->insn_flags & ASE_MT);
7560 gen_helper_mtc0_yqmask(cpu_env, arg);
7561 register_name = "YQMask";
7564 CP0_CHECK(ctx->insn_flags & ASE_MT);
7565 tcg_gen_st_tl(arg, cpu_env,
7566 offsetof(CPUMIPSState, CP0_VPESchedule));
7567 register_name = "VPESchedule";
7570 CP0_CHECK(ctx->insn_flags & ASE_MT);
7571 tcg_gen_st_tl(arg, cpu_env,
7572 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7573 register_name = "VPEScheFBack";
7576 CP0_CHECK(ctx->insn_flags & ASE_MT);
7577 gen_helper_mtc0_vpeopt(cpu_env, arg);
7578 register_name = "VPEOpt";
7581 goto cp0_unimplemented;
7584 case CP0_REGISTER_02:
7587 gen_helper_mtc0_entrylo0(cpu_env, arg);
7588 register_name = "EntryLo0";
7591 CP0_CHECK(ctx->insn_flags & ASE_MT);
7592 gen_helper_mtc0_tcstatus(cpu_env, arg);
7593 register_name = "TCStatus";
7596 CP0_CHECK(ctx->insn_flags & ASE_MT);
7597 gen_helper_mtc0_tcbind(cpu_env, arg);
7598 register_name = "TCBind";
7601 CP0_CHECK(ctx->insn_flags & ASE_MT);
7602 gen_helper_mtc0_tcrestart(cpu_env, arg);
7603 register_name = "TCRestart";
7606 CP0_CHECK(ctx->insn_flags & ASE_MT);
7607 gen_helper_mtc0_tchalt(cpu_env, arg);
7608 register_name = "TCHalt";
7611 CP0_CHECK(ctx->insn_flags & ASE_MT);
7612 gen_helper_mtc0_tccontext(cpu_env, arg);
7613 register_name = "TCContext";
7616 CP0_CHECK(ctx->insn_flags & ASE_MT);
7617 gen_helper_mtc0_tcschedule(cpu_env, arg);
7618 register_name = "TCSchedule";
7621 CP0_CHECK(ctx->insn_flags & ASE_MT);
7622 gen_helper_mtc0_tcschefback(cpu_env, arg);
7623 register_name = "TCScheFBack";
7626 goto cp0_unimplemented;
7629 case CP0_REGISTER_03:
7632 gen_helper_mtc0_entrylo1(cpu_env, arg);
7633 register_name = "EntryLo1";
7638 register_name = "GlobalNumber";
7641 goto cp0_unimplemented;
7644 case CP0_REGISTER_04:
7647 gen_helper_mtc0_context(cpu_env, arg);
7648 register_name = "Context";
7651 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7652 register_name = "ContextConfig";
7653 goto cp0_unimplemented;
7655 CP0_CHECK(ctx->ulri);
7656 tcg_gen_st_tl(arg, cpu_env,
7657 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7658 register_name = "UserLocal";
7661 goto cp0_unimplemented;
7664 case CP0_REGISTER_05:
7667 gen_helper_mtc0_pagemask(cpu_env, arg);
7668 register_name = "PageMask";
7671 check_insn(ctx, ISA_MIPS32R2);
7672 gen_helper_mtc0_pagegrain(cpu_env, arg);
7673 register_name = "PageGrain";
7674 ctx->base.is_jmp = DISAS_STOP;
7678 gen_helper_mtc0_segctl0(cpu_env, arg);
7679 register_name = "SegCtl0";
7683 gen_helper_mtc0_segctl1(cpu_env, arg);
7684 register_name = "SegCtl1";
7688 gen_helper_mtc0_segctl2(cpu_env, arg);
7689 register_name = "SegCtl2";
7693 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7694 register_name = "PWBase";
7698 gen_helper_mtc0_pwfield(cpu_env, arg);
7699 register_name = "PWField";
7703 gen_helper_mtc0_pwsize(cpu_env, arg);
7704 register_name = "PWSize";
7707 goto cp0_unimplemented;
7710 case CP0_REGISTER_06:
7713 gen_helper_mtc0_wired(cpu_env, arg);
7714 register_name = "Wired";
7717 check_insn(ctx, ISA_MIPS32R2);
7718 gen_helper_mtc0_srsconf0(cpu_env, arg);
7719 register_name = "SRSConf0";
7722 check_insn(ctx, ISA_MIPS32R2);
7723 gen_helper_mtc0_srsconf1(cpu_env, arg);
7724 register_name = "SRSConf1";
7727 check_insn(ctx, ISA_MIPS32R2);
7728 gen_helper_mtc0_srsconf2(cpu_env, arg);
7729 register_name = "SRSConf2";
7732 check_insn(ctx, ISA_MIPS32R2);
7733 gen_helper_mtc0_srsconf3(cpu_env, arg);
7734 register_name = "SRSConf3";
7737 check_insn(ctx, ISA_MIPS32R2);
7738 gen_helper_mtc0_srsconf4(cpu_env, arg);
7739 register_name = "SRSConf4";
7743 gen_helper_mtc0_pwctl(cpu_env, arg);
7744 register_name = "PWCtl";
7747 goto cp0_unimplemented;
7750 case CP0_REGISTER_07:
7753 check_insn(ctx, ISA_MIPS32R2);
7754 gen_helper_mtc0_hwrena(cpu_env, arg);
7755 ctx->base.is_jmp = DISAS_STOP;
7756 register_name = "HWREna";
7759 goto cp0_unimplemented;
7762 case CP0_REGISTER_08:
7766 register_name = "BadVAddr";
7770 register_name = "BadInstr";
7774 register_name = "BadInstrP";
7778 register_name = "BadInstrX";
7781 goto cp0_unimplemented;
7784 case CP0_REGISTER_09:
7787 gen_helper_mtc0_count(cpu_env, arg);
7788 register_name = "Count";
7791 CP0_CHECK(ctx->saar);
7792 gen_helper_mtc0_saari(cpu_env, arg);
7793 register_name = "SAARI";
7796 CP0_CHECK(ctx->saar);
7797 gen_helper_mtc0_saar(cpu_env, arg);
7798 register_name = "SAAR";
7801 goto cp0_unimplemented;
7804 case CP0_REGISTER_10:
7807 gen_helper_mtc0_entryhi(cpu_env, arg);
7808 register_name = "EntryHi";
7811 goto cp0_unimplemented;
7814 case CP0_REGISTER_11:
7817 gen_helper_mtc0_compare(cpu_env, arg);
7818 register_name = "Compare";
7820 /* 6,7 are implementation dependent */
7822 goto cp0_unimplemented;
7825 case CP0_REGISTER_12:
7828 save_cpu_state(ctx, 1);
7829 gen_helper_mtc0_status(cpu_env, arg);
7830 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7831 gen_save_pc(ctx->base.pc_next + 4);
7832 ctx->base.is_jmp = DISAS_EXIT;
7833 register_name = "Status";
7836 check_insn(ctx, ISA_MIPS32R2);
7837 gen_helper_mtc0_intctl(cpu_env, arg);
7838 /* Stop translation as we may have switched the execution mode */
7839 ctx->base.is_jmp = DISAS_STOP;
7840 register_name = "IntCtl";
7843 check_insn(ctx, ISA_MIPS32R2);
7844 gen_helper_mtc0_srsctl(cpu_env, arg);
7845 /* Stop translation as we may have switched the execution mode */
7846 ctx->base.is_jmp = DISAS_STOP;
7847 register_name = "SRSCtl";
7850 check_insn(ctx, ISA_MIPS32R2);
7851 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7852 /* Stop translation as we may have switched the execution mode */
7853 ctx->base.is_jmp = DISAS_STOP;
7854 register_name = "SRSMap";
7857 goto cp0_unimplemented;
7860 case CP0_REGISTER_13:
7863 save_cpu_state(ctx, 1);
7864 gen_helper_mtc0_cause(cpu_env, arg);
7865 /* Stop translation as we may have triggered an interrupt.
7866 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7867 * translated code to check for pending interrupts. */
7868 gen_save_pc(ctx->base.pc_next + 4);
7869 ctx->base.is_jmp = DISAS_EXIT;
7870 register_name = "Cause";
7873 goto cp0_unimplemented;
7876 case CP0_REGISTER_14:
7879 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7880 register_name = "EPC";
7883 goto cp0_unimplemented;
7886 case CP0_REGISTER_15:
7890 register_name = "PRid";
7893 check_insn(ctx, ISA_MIPS32R2);
7894 gen_helper_mtc0_ebase(cpu_env, arg);
7895 register_name = "EBase";
7898 goto cp0_unimplemented;
7901 case CP0_REGISTER_16:
7904 gen_helper_mtc0_config0(cpu_env, arg);
7905 register_name = "Config";
7906 /* Stop translation as we may have switched the execution mode */
7907 ctx->base.is_jmp = DISAS_STOP;
7910 /* ignored, read only */
7911 register_name = "Config1";
7914 gen_helper_mtc0_config2(cpu_env, arg);
7915 register_name = "Config2";
7916 /* Stop translation as we may have switched the execution mode */
7917 ctx->base.is_jmp = DISAS_STOP;
7920 gen_helper_mtc0_config3(cpu_env, arg);
7921 register_name = "Config3";
7922 /* Stop translation as we may have switched the execution mode */
7923 ctx->base.is_jmp = DISAS_STOP;
7926 gen_helper_mtc0_config4(cpu_env, arg);
7927 register_name = "Config4";
7928 ctx->base.is_jmp = DISAS_STOP;
7931 gen_helper_mtc0_config5(cpu_env, arg);
7932 register_name = "Config5";
7933 /* Stop translation as we may have switched the execution mode */
7934 ctx->base.is_jmp = DISAS_STOP;
7936 /* 6,7 are implementation dependent */
7939 register_name = "Config6";
7943 register_name = "Config7";
7946 register_name = "Invalid config selector";
7947 goto cp0_unimplemented;
7950 case CP0_REGISTER_17:
7953 gen_helper_mtc0_lladdr(cpu_env, arg);
7954 register_name = "LLAddr";
7957 CP0_CHECK(ctx->mrp);
7958 gen_helper_mtc0_maar(cpu_env, arg);
7959 register_name = "MAAR";
7962 CP0_CHECK(ctx->mrp);
7963 gen_helper_mtc0_maari(cpu_env, arg);
7964 register_name = "MAARI";
7967 goto cp0_unimplemented;
7970 case CP0_REGISTER_18:
7980 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7981 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7982 register_name = "WatchLo";
7985 goto cp0_unimplemented;
7988 case CP0_REGISTER_19:
7998 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7999 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8000 register_name = "WatchHi";
8003 goto cp0_unimplemented;
8006 case CP0_REGISTER_20:
8009 #if defined(TARGET_MIPS64)
8010 check_insn(ctx, ISA_MIPS3);
8011 gen_helper_mtc0_xcontext(cpu_env, arg);
8012 register_name = "XContext";
8016 goto cp0_unimplemented;
8019 case CP0_REGISTER_21:
8020 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8021 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8024 gen_helper_mtc0_framemask(cpu_env, arg);
8025 register_name = "Framemask";
8028 goto cp0_unimplemented;
8031 case CP0_REGISTER_22:
8033 register_name = "Diagnostic"; /* implementation dependent */
8035 case CP0_REGISTER_23:
8038 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8039 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8040 gen_save_pc(ctx->base.pc_next + 4);
8041 ctx->base.is_jmp = DISAS_EXIT;
8042 register_name = "Debug";
8045 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8046 register_name = "TraceControl";
8047 /* Stop translation as we may have switched the execution mode */
8048 ctx->base.is_jmp = DISAS_STOP;
8049 goto cp0_unimplemented;
8051 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8052 register_name = "TraceControl2";
8053 /* Stop translation as we may have switched the execution mode */
8054 ctx->base.is_jmp = DISAS_STOP;
8055 goto cp0_unimplemented;
8057 /* Stop translation as we may have switched the execution mode */
8058 ctx->base.is_jmp = DISAS_STOP;
8059 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8060 register_name = "UserTraceData";
8061 /* Stop translation as we may have switched the execution mode */
8062 ctx->base.is_jmp = DISAS_STOP;
8063 goto cp0_unimplemented;
8065 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8066 /* Stop translation as we may have switched the execution mode */
8067 ctx->base.is_jmp = DISAS_STOP;
8068 register_name = "TraceBPC";
8069 goto cp0_unimplemented;
8071 goto cp0_unimplemented;
8074 case CP0_REGISTER_24:
8078 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8079 register_name = "DEPC";
8082 goto cp0_unimplemented;
8085 case CP0_REGISTER_25:
8088 gen_helper_mtc0_performance0(cpu_env, arg);
8089 register_name = "Performance0";
8092 // gen_helper_mtc0_performance1(arg);
8093 register_name = "Performance1";
8094 goto cp0_unimplemented;
8096 // gen_helper_mtc0_performance2(arg);
8097 register_name = "Performance2";
8098 goto cp0_unimplemented;
8100 // gen_helper_mtc0_performance3(arg);
8101 register_name = "Performance3";
8102 goto cp0_unimplemented;
8104 // gen_helper_mtc0_performance4(arg);
8105 register_name = "Performance4";
8106 goto cp0_unimplemented;
8108 // gen_helper_mtc0_performance5(arg);
8109 register_name = "Performance5";
8110 goto cp0_unimplemented;
8112 // gen_helper_mtc0_performance6(arg);
8113 register_name = "Performance6";
8114 goto cp0_unimplemented;
8116 // gen_helper_mtc0_performance7(arg);
8117 register_name = "Performance7";
8118 goto cp0_unimplemented;
8120 goto cp0_unimplemented;
8123 case CP0_REGISTER_26:
8126 gen_helper_mtc0_errctl(cpu_env, arg);
8127 ctx->base.is_jmp = DISAS_STOP;
8128 register_name = "ErrCtl";
8131 goto cp0_unimplemented;
8134 case CP0_REGISTER_27:
8141 register_name = "CacheErr";
8144 goto cp0_unimplemented;
8147 case CP0_REGISTER_28:
8153 gen_helper_mtc0_taglo(cpu_env, arg);
8154 register_name = "TagLo";
8160 gen_helper_mtc0_datalo(cpu_env, arg);
8161 register_name = "DataLo";
8164 goto cp0_unimplemented;
8167 case CP0_REGISTER_29:
8173 gen_helper_mtc0_taghi(cpu_env, arg);
8174 register_name = "TagHi";
8180 gen_helper_mtc0_datahi(cpu_env, arg);
8181 register_name = "DataHi";
8184 register_name = "invalid sel";
8185 goto cp0_unimplemented;
8188 case CP0_REGISTER_30:
8191 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8192 register_name = "ErrorEPC";
8195 goto cp0_unimplemented;
8198 case CP0_REGISTER_31:
8202 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8203 register_name = "DESAVE";
8211 CP0_CHECK(ctx->kscrexist & (1 << sel));
8212 tcg_gen_st_tl(arg, cpu_env,
8213 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8214 register_name = "KScratch";
8217 goto cp0_unimplemented;
8221 goto cp0_unimplemented;
8223 trace_mips_translate_c0("mtc0", register_name, reg, sel);
8225 /* For simplicity assume that all writes can cause interrupts. */
8226 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8228 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8229 * translated code to check for pending interrupts. */
8230 gen_save_pc(ctx->base.pc_next + 4);
8231 ctx->base.is_jmp = DISAS_EXIT;
8236 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8237 register_name, reg, sel);
8240 #if defined(TARGET_MIPS64)
8241 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8243 const char *register_name = "invalid";
8246 check_insn(ctx, ISA_MIPS64);
8249 case CP0_REGISTER_00:
8252 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8253 register_name = "Index";
8256 CP0_CHECK(ctx->insn_flags & ASE_MT);
8257 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8258 register_name = "MVPControl";
8261 CP0_CHECK(ctx->insn_flags & ASE_MT);
8262 gen_helper_mfc0_mvpconf0(arg, cpu_env);
8263 register_name = "MVPConf0";
8266 CP0_CHECK(ctx->insn_flags & ASE_MT);
8267 gen_helper_mfc0_mvpconf1(arg, cpu_env);
8268 register_name = "MVPConf1";
8272 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8273 register_name = "VPControl";
8276 goto cp0_unimplemented;
8279 case CP0_REGISTER_01:
8282 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8283 gen_helper_mfc0_random(arg, cpu_env);
8284 register_name = "Random";
8287 CP0_CHECK(ctx->insn_flags & ASE_MT);
8288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8289 register_name = "VPEControl";
8292 CP0_CHECK(ctx->insn_flags & ASE_MT);
8293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8294 register_name = "VPEConf0";
8297 CP0_CHECK(ctx->insn_flags & ASE_MT);
8298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8299 register_name = "VPEConf1";
8302 CP0_CHECK(ctx->insn_flags & ASE_MT);
8303 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8304 register_name = "YQMask";
8307 CP0_CHECK(ctx->insn_flags & ASE_MT);
8308 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8309 register_name = "VPESchedule";
8312 CP0_CHECK(ctx->insn_flags & ASE_MT);
8313 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8314 register_name = "VPEScheFBack";
8317 CP0_CHECK(ctx->insn_flags & ASE_MT);
8318 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8319 register_name = "VPEOpt";
8322 goto cp0_unimplemented;
8325 case CP0_REGISTER_02:
8328 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8329 register_name = "EntryLo0";
8332 CP0_CHECK(ctx->insn_flags & ASE_MT);
8333 gen_helper_mfc0_tcstatus(arg, cpu_env);
8334 register_name = "TCStatus";
8337 CP0_CHECK(ctx->insn_flags & ASE_MT);
8338 gen_helper_mfc0_tcbind(arg, cpu_env);
8339 register_name = "TCBind";
8342 CP0_CHECK(ctx->insn_flags & ASE_MT);
8343 gen_helper_dmfc0_tcrestart(arg, cpu_env);
8344 register_name = "TCRestart";
8347 CP0_CHECK(ctx->insn_flags & ASE_MT);
8348 gen_helper_dmfc0_tchalt(arg, cpu_env);
8349 register_name = "TCHalt";
8352 CP0_CHECK(ctx->insn_flags & ASE_MT);
8353 gen_helper_dmfc0_tccontext(arg, cpu_env);
8354 register_name = "TCContext";
8357 CP0_CHECK(ctx->insn_flags & ASE_MT);
8358 gen_helper_dmfc0_tcschedule(arg, cpu_env);
8359 register_name = "TCSchedule";
8362 CP0_CHECK(ctx->insn_flags & ASE_MT);
8363 gen_helper_dmfc0_tcschefback(arg, cpu_env);
8364 register_name = "TCScheFBack";
8367 goto cp0_unimplemented;
8370 case CP0_REGISTER_03:
8373 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8374 register_name = "EntryLo1";
8378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8379 register_name = "GlobalNumber";
8382 goto cp0_unimplemented;
8385 case CP0_REGISTER_04:
8388 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8389 register_name = "Context";
8392 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8393 register_name = "ContextConfig";
8394 goto cp0_unimplemented;
8396 CP0_CHECK(ctx->ulri);
8397 tcg_gen_ld_tl(arg, cpu_env,
8398 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8399 register_name = "UserLocal";
8402 goto cp0_unimplemented;
8405 case CP0_REGISTER_05:
8408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8409 register_name = "PageMask";
8412 check_insn(ctx, ISA_MIPS32R2);
8413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8414 register_name = "PageGrain";
8418 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8419 register_name = "SegCtl0";
8423 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8424 register_name = "SegCtl1";
8428 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8429 register_name = "SegCtl2";
8433 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8434 register_name = "PWBase";
8438 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8439 register_name = "PWField";
8443 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8444 register_name = "PWSize";
8447 goto cp0_unimplemented;
8450 case CP0_REGISTER_06:
8453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8454 register_name = "Wired";
8457 check_insn(ctx, ISA_MIPS32R2);
8458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8459 register_name = "SRSConf0";
8462 check_insn(ctx, ISA_MIPS32R2);
8463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8464 register_name = "SRSConf1";
8467 check_insn(ctx, ISA_MIPS32R2);
8468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8469 register_name = "SRSConf2";
8472 check_insn(ctx, ISA_MIPS32R2);
8473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8474 register_name = "SRSConf3";
8477 check_insn(ctx, ISA_MIPS32R2);
8478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8479 register_name = "SRSConf4";
8483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8484 register_name = "PWCtl";
8487 goto cp0_unimplemented;
8490 case CP0_REGISTER_07:
8493 check_insn(ctx, ISA_MIPS32R2);
8494 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8495 register_name = "HWREna";
8498 goto cp0_unimplemented;
8501 case CP0_REGISTER_08:
8504 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8505 register_name = "BadVAddr";
8509 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8510 register_name = "BadInstr";
8514 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8515 register_name = "BadInstrP";
8519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8520 tcg_gen_andi_tl(arg, arg, ~0xffff);
8521 register_name = "BadInstrX";
8524 goto cp0_unimplemented;
8527 case CP0_REGISTER_09:
8530 /* Mark as an IO operation because we read the time. */
8531 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8534 gen_helper_mfc0_count(arg, cpu_env);
8535 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8538 /* Break the TB to be able to take timer interrupts immediately
8539 after reading count. DISAS_STOP isn't sufficient, we need to
8540 ensure we break completely out of translated code. */
8541 gen_save_pc(ctx->base.pc_next + 4);
8542 ctx->base.is_jmp = DISAS_EXIT;
8543 register_name = "Count";
8546 CP0_CHECK(ctx->saar);
8547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8548 register_name = "SAARI";
8551 CP0_CHECK(ctx->saar);
8552 gen_helper_dmfc0_saar(arg, cpu_env);
8553 register_name = "SAAR";
8556 goto cp0_unimplemented;
8559 case CP0_REGISTER_10:
8562 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8563 register_name = "EntryHi";
8566 goto cp0_unimplemented;
8569 case CP0_REGISTER_11:
8572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8573 register_name = "Compare";
8575 /* 6,7 are implementation dependent */
8577 goto cp0_unimplemented;
8580 case CP0_REGISTER_12:
8583 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8584 register_name = "Status";
8587 check_insn(ctx, ISA_MIPS32R2);
8588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8589 register_name = "IntCtl";
8592 check_insn(ctx, ISA_MIPS32R2);
8593 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8594 register_name = "SRSCtl";
8597 check_insn(ctx, ISA_MIPS32R2);
8598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8599 register_name = "SRSMap";
8602 goto cp0_unimplemented;
8605 case CP0_REGISTER_13:
8608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8609 register_name = "Cause";
8612 goto cp0_unimplemented;
8615 case CP0_REGISTER_14:
8618 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8619 register_name = "EPC";
8622 goto cp0_unimplemented;
8625 case CP0_REGISTER_15:
8628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8629 register_name = "PRid";
8632 check_insn(ctx, ISA_MIPS32R2);
8633 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8634 register_name = "EBase";
8637 check_insn(ctx, ISA_MIPS32R2);
8638 CP0_CHECK(ctx->cmgcr);
8639 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8640 register_name = "CMGCRBase";
8643 goto cp0_unimplemented;
8646 case CP0_REGISTER_16:
8649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8650 register_name = "Config";
8653 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8654 register_name = "Config1";
8657 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8658 register_name = "Config2";
8661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8662 register_name = "Config3";
8665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8666 register_name = "Config4";
8669 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8670 register_name = "Config5";
8672 /* 6,7 are implementation dependent */
8674 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8675 register_name = "Config6";
8678 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8679 register_name = "Config7";
8682 goto cp0_unimplemented;
8685 case CP0_REGISTER_17:
8688 gen_helper_dmfc0_lladdr(arg, cpu_env);
8689 register_name = "LLAddr";
8692 CP0_CHECK(ctx->mrp);
8693 gen_helper_dmfc0_maar(arg, cpu_env);
8694 register_name = "MAAR";
8697 CP0_CHECK(ctx->mrp);
8698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8699 register_name = "MAARI";
8702 goto cp0_unimplemented;
8705 case CP0_REGISTER_18:
8715 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8716 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8717 register_name = "WatchLo";
8720 goto cp0_unimplemented;
8723 case CP0_REGISTER_19:
8733 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8734 gen_helper_1e0i(mfc0_watchhi, arg, sel);
8735 register_name = "WatchHi";
8738 goto cp0_unimplemented;
8741 case CP0_REGISTER_20:
8744 check_insn(ctx, ISA_MIPS3);
8745 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8746 register_name = "XContext";
8749 goto cp0_unimplemented;
8752 case CP0_REGISTER_21:
8753 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8754 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8757 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8758 register_name = "Framemask";
8761 goto cp0_unimplemented;
8764 case CP0_REGISTER_22:
8765 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8766 register_name = "'Diagnostic"; /* implementation dependent */
8768 case CP0_REGISTER_23:
8771 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8772 register_name = "Debug";
8775 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8776 register_name = "TraceControl";
8777 goto cp0_unimplemented;
8779 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8780 register_name = "TraceControl2";
8781 goto cp0_unimplemented;
8783 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8784 register_name = "UserTraceData";
8785 goto cp0_unimplemented;
8787 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8788 register_name = "TraceBPC";
8789 goto cp0_unimplemented;
8791 goto cp0_unimplemented;
8794 case CP0_REGISTER_24:
8798 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8799 register_name = "DEPC";
8802 goto cp0_unimplemented;
8805 case CP0_REGISTER_25:
8808 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8809 register_name = "Performance0";
8812 // gen_helper_dmfc0_performance1(arg);
8813 register_name = "Performance1";
8814 goto cp0_unimplemented;
8816 // gen_helper_dmfc0_performance2(arg);
8817 register_name = "Performance2";
8818 goto cp0_unimplemented;
8820 // gen_helper_dmfc0_performance3(arg);
8821 register_name = "Performance3";
8822 goto cp0_unimplemented;
8824 // gen_helper_dmfc0_performance4(arg);
8825 register_name = "Performance4";
8826 goto cp0_unimplemented;
8828 // gen_helper_dmfc0_performance5(arg);
8829 register_name = "Performance5";
8830 goto cp0_unimplemented;
8832 // gen_helper_dmfc0_performance6(arg);
8833 register_name = "Performance6";
8834 goto cp0_unimplemented;
8836 // gen_helper_dmfc0_performance7(arg);
8837 register_name = "Performance7";
8838 goto cp0_unimplemented;
8840 goto cp0_unimplemented;
8843 case CP0_REGISTER_26:
8846 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8847 register_name = "ErrCtl";
8850 goto cp0_unimplemented;
8853 case CP0_REGISTER_27:
8860 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8861 register_name = "CacheErr";
8864 goto cp0_unimplemented;
8867 case CP0_REGISTER_28:
8873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8874 register_name = "TagLo";
8880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8881 register_name = "DataLo";
8884 goto cp0_unimplemented;
8887 case CP0_REGISTER_29:
8893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8894 register_name = "TagHi";
8900 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8901 register_name = "DataHi";
8904 goto cp0_unimplemented;
8907 case CP0_REGISTER_30:
8910 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8911 register_name = "ErrorEPC";
8914 goto cp0_unimplemented;
8917 case CP0_REGISTER_31:
8921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8922 register_name = "DESAVE";
8930 CP0_CHECK(ctx->kscrexist & (1 << sel));
8931 tcg_gen_ld_tl(arg, cpu_env,
8932 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8933 register_name = "KScratch";
8936 goto cp0_unimplemented;
8940 goto cp0_unimplemented;
8942 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
8946 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
8947 register_name, reg, sel);
8948 gen_mfc0_unimplemented(ctx, arg);
8951 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8953 const char *register_name = "invalid";
8956 check_insn(ctx, ISA_MIPS64);
8958 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8963 case CP0_REGISTER_00:
8966 gen_helper_mtc0_index(cpu_env, arg);
8967 register_name = "Index";
8970 CP0_CHECK(ctx->insn_flags & ASE_MT);
8971 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8972 register_name = "MVPControl";
8975 CP0_CHECK(ctx->insn_flags & ASE_MT);
8977 register_name = "MVPConf0";
8980 CP0_CHECK(ctx->insn_flags & ASE_MT);
8982 register_name = "MVPConf1";
8987 register_name = "VPControl";
8990 goto cp0_unimplemented;
8993 case CP0_REGISTER_01:
8997 register_name = "Random";
9000 CP0_CHECK(ctx->insn_flags & ASE_MT);
9001 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9002 register_name = "VPEControl";
9005 CP0_CHECK(ctx->insn_flags & ASE_MT);
9006 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9007 register_name = "VPEConf0";
9010 CP0_CHECK(ctx->insn_flags & ASE_MT);
9011 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9012 register_name = "VPEConf1";
9015 CP0_CHECK(ctx->insn_flags & ASE_MT);
9016 gen_helper_mtc0_yqmask(cpu_env, arg);
9017 register_name = "YQMask";
9020 CP0_CHECK(ctx->insn_flags & ASE_MT);
9021 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9022 register_name = "VPESchedule";
9025 CP0_CHECK(ctx->insn_flags & ASE_MT);
9026 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9027 register_name = "VPEScheFBack";
9030 CP0_CHECK(ctx->insn_flags & ASE_MT);
9031 gen_helper_mtc0_vpeopt(cpu_env, arg);
9032 register_name = "VPEOpt";
9035 goto cp0_unimplemented;
9038 case CP0_REGISTER_02:
9041 gen_helper_dmtc0_entrylo0(cpu_env, arg);
9042 register_name = "EntryLo0";
9045 CP0_CHECK(ctx->insn_flags & ASE_MT);
9046 gen_helper_mtc0_tcstatus(cpu_env, arg);
9047 register_name = "TCStatus";
9050 CP0_CHECK(ctx->insn_flags & ASE_MT);
9051 gen_helper_mtc0_tcbind(cpu_env, arg);
9052 register_name = "TCBind";
9055 CP0_CHECK(ctx->insn_flags & ASE_MT);
9056 gen_helper_mtc0_tcrestart(cpu_env, arg);
9057 register_name = "TCRestart";
9060 CP0_CHECK(ctx->insn_flags & ASE_MT);
9061 gen_helper_mtc0_tchalt(cpu_env, arg);
9062 register_name = "TCHalt";
9065 CP0_CHECK(ctx->insn_flags & ASE_MT);
9066 gen_helper_mtc0_tccontext(cpu_env, arg);
9067 register_name = "TCContext";
9070 CP0_CHECK(ctx->insn_flags & ASE_MT);
9071 gen_helper_mtc0_tcschedule(cpu_env, arg);
9072 register_name = "TCSchedule";
9075 CP0_CHECK(ctx->insn_flags & ASE_MT);
9076 gen_helper_mtc0_tcschefback(cpu_env, arg);
9077 register_name = "TCScheFBack";
9080 goto cp0_unimplemented;
9083 case CP0_REGISTER_03:
9086 gen_helper_dmtc0_entrylo1(cpu_env, arg);
9087 register_name = "EntryLo1";
9092 register_name = "GlobalNumber";
9095 goto cp0_unimplemented;
9098 case CP0_REGISTER_04:
9101 gen_helper_mtc0_context(cpu_env, arg);
9102 register_name = "Context";
9105 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
9106 register_name = "ContextConfig";
9107 goto cp0_unimplemented;
9109 CP0_CHECK(ctx->ulri);
9110 tcg_gen_st_tl(arg, cpu_env,
9111 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9112 register_name = "UserLocal";
9115 goto cp0_unimplemented;
9118 case CP0_REGISTER_05:
9121 gen_helper_mtc0_pagemask(cpu_env, arg);
9122 register_name = "PageMask";
9125 check_insn(ctx, ISA_MIPS32R2);
9126 gen_helper_mtc0_pagegrain(cpu_env, arg);
9127 register_name = "PageGrain";
9131 gen_helper_mtc0_segctl0(cpu_env, arg);
9132 register_name = "SegCtl0";
9136 gen_helper_mtc0_segctl1(cpu_env, arg);
9137 register_name = "SegCtl1";
9141 gen_helper_mtc0_segctl2(cpu_env, arg);
9142 register_name = "SegCtl2";
9146 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9147 register_name = "PWBase";
9151 gen_helper_mtc0_pwfield(cpu_env, arg);
9152 register_name = "PWField";
9156 gen_helper_mtc0_pwsize(cpu_env, arg);
9157 register_name = "PWSize";
9160 goto cp0_unimplemented;
9163 case CP0_REGISTER_06:
9166 gen_helper_mtc0_wired(cpu_env, arg);
9167 register_name = "Wired";
9170 check_insn(ctx, ISA_MIPS32R2);
9171 gen_helper_mtc0_srsconf0(cpu_env, arg);
9172 register_name = "SRSConf0";
9175 check_insn(ctx, ISA_MIPS32R2);
9176 gen_helper_mtc0_srsconf1(cpu_env, arg);
9177 register_name = "SRSConf1";
9180 check_insn(ctx, ISA_MIPS32R2);
9181 gen_helper_mtc0_srsconf2(cpu_env, arg);
9182 register_name = "SRSConf2";
9185 check_insn(ctx, ISA_MIPS32R2);
9186 gen_helper_mtc0_srsconf3(cpu_env, arg);
9187 register_name = "SRSConf3";
9190 check_insn(ctx, ISA_MIPS32R2);
9191 gen_helper_mtc0_srsconf4(cpu_env, arg);
9192 register_name = "SRSConf4";
9196 gen_helper_mtc0_pwctl(cpu_env, arg);
9197 register_name = "PWCtl";
9200 goto cp0_unimplemented;
9203 case CP0_REGISTER_07:
9206 check_insn(ctx, ISA_MIPS32R2);
9207 gen_helper_mtc0_hwrena(cpu_env, arg);
9208 ctx->base.is_jmp = DISAS_STOP;
9209 register_name = "HWREna";
9212 goto cp0_unimplemented;
9215 case CP0_REGISTER_08:
9219 register_name = "BadVAddr";
9223 register_name = "BadInstr";
9227 register_name = "BadInstrP";
9231 register_name = "BadInstrX";
9234 goto cp0_unimplemented;
9237 case CP0_REGISTER_09:
9240 gen_helper_mtc0_count(cpu_env, arg);
9241 register_name = "Count";
9244 CP0_CHECK(ctx->saar);
9245 gen_helper_mtc0_saari(cpu_env, arg);
9246 register_name = "SAARI";
9249 CP0_CHECK(ctx->saar);
9250 gen_helper_mtc0_saar(cpu_env, arg);
9251 register_name = "SAAR";
9254 goto cp0_unimplemented;
9256 /* Stop translation as we may have switched the execution mode */
9257 ctx->base.is_jmp = DISAS_STOP;
9259 case CP0_REGISTER_10:
9262 gen_helper_mtc0_entryhi(cpu_env, arg);
9263 register_name = "EntryHi";
9266 goto cp0_unimplemented;
9269 case CP0_REGISTER_11:
9272 gen_helper_mtc0_compare(cpu_env, arg);
9273 register_name = "Compare";
9275 /* 6,7 are implementation dependent */
9277 goto cp0_unimplemented;
9279 /* Stop translation as we may have switched the execution mode */
9280 ctx->base.is_jmp = DISAS_STOP;
9282 case CP0_REGISTER_12:
9285 save_cpu_state(ctx, 1);
9286 gen_helper_mtc0_status(cpu_env, arg);
9287 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9288 gen_save_pc(ctx->base.pc_next + 4);
9289 ctx->base.is_jmp = DISAS_EXIT;
9290 register_name = "Status";
9293 check_insn(ctx, ISA_MIPS32R2);
9294 gen_helper_mtc0_intctl(cpu_env, arg);
9295 /* Stop translation as we may have switched the execution mode */
9296 ctx->base.is_jmp = DISAS_STOP;
9297 register_name = "IntCtl";
9300 check_insn(ctx, ISA_MIPS32R2);
9301 gen_helper_mtc0_srsctl(cpu_env, arg);
9302 /* Stop translation as we may have switched the execution mode */
9303 ctx->base.is_jmp = DISAS_STOP;
9304 register_name = "SRSCtl";
9307 check_insn(ctx, ISA_MIPS32R2);
9308 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9309 /* Stop translation as we may have switched the execution mode */
9310 ctx->base.is_jmp = DISAS_STOP;
9311 register_name = "SRSMap";
9314 goto cp0_unimplemented;
9317 case CP0_REGISTER_13:
9320 save_cpu_state(ctx, 1);
9321 gen_helper_mtc0_cause(cpu_env, arg);
9322 /* Stop translation as we may have triggered an interrupt.
9323 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9324 * translated code to check for pending interrupts. */
9325 gen_save_pc(ctx->base.pc_next + 4);
9326 ctx->base.is_jmp = DISAS_EXIT;
9327 register_name = "Cause";
9330 goto cp0_unimplemented;
9333 case CP0_REGISTER_14:
9336 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9337 register_name = "EPC";
9340 goto cp0_unimplemented;
9343 case CP0_REGISTER_15:
9347 register_name = "PRid";
9350 check_insn(ctx, ISA_MIPS32R2);
9351 gen_helper_mtc0_ebase(cpu_env, arg);
9352 register_name = "EBase";
9355 goto cp0_unimplemented;
9358 case CP0_REGISTER_16:
9361 gen_helper_mtc0_config0(cpu_env, arg);
9362 register_name = "Config";
9363 /* Stop translation as we may have switched the execution mode */
9364 ctx->base.is_jmp = DISAS_STOP;
9367 /* ignored, read only */
9368 register_name = "Config1";
9371 gen_helper_mtc0_config2(cpu_env, arg);
9372 register_name = "Config2";
9373 /* Stop translation as we may have switched the execution mode */
9374 ctx->base.is_jmp = DISAS_STOP;
9377 gen_helper_mtc0_config3(cpu_env, arg);
9378 register_name = "Config3";
9379 /* Stop translation as we may have switched the execution mode */
9380 ctx->base.is_jmp = DISAS_STOP;
9383 /* currently ignored */
9384 register_name = "Config4";
9387 gen_helper_mtc0_config5(cpu_env, arg);
9388 register_name = "Config5";
9389 /* Stop translation as we may have switched the execution mode */
9390 ctx->base.is_jmp = DISAS_STOP;
9392 /* 6,7 are implementation dependent */
9394 register_name = "Invalid config selector";
9395 goto cp0_unimplemented;
9398 case CP0_REGISTER_17:
9401 gen_helper_mtc0_lladdr(cpu_env, arg);
9402 register_name = "LLAddr";
9405 CP0_CHECK(ctx->mrp);
9406 gen_helper_mtc0_maar(cpu_env, arg);
9407 register_name = "MAAR";
9410 CP0_CHECK(ctx->mrp);
9411 gen_helper_mtc0_maari(cpu_env, arg);
9412 register_name = "MAARI";
9415 goto cp0_unimplemented;
9418 case CP0_REGISTER_18:
9428 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9429 gen_helper_0e1i(mtc0_watchlo, arg, sel);
9430 register_name = "WatchLo";
9433 goto cp0_unimplemented;
9436 case CP0_REGISTER_19:
9446 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9447 gen_helper_0e1i(mtc0_watchhi, arg, sel);
9448 register_name = "WatchHi";
9451 goto cp0_unimplemented;
9454 case CP0_REGISTER_20:
9457 check_insn(ctx, ISA_MIPS3);
9458 gen_helper_mtc0_xcontext(cpu_env, arg);
9459 register_name = "XContext";
9462 goto cp0_unimplemented;
9465 case CP0_REGISTER_21:
9466 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9467 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9470 gen_helper_mtc0_framemask(cpu_env, arg);
9471 register_name = "Framemask";
9474 goto cp0_unimplemented;
9477 case CP0_REGISTER_22:
9479 register_name = "Diagnostic"; /* implementation dependent */
9481 case CP0_REGISTER_23:
9484 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9485 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9486 gen_save_pc(ctx->base.pc_next + 4);
9487 ctx->base.is_jmp = DISAS_EXIT;
9488 register_name = "Debug";
9491 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9492 /* Stop translation as we may have switched the execution mode */
9493 ctx->base.is_jmp = DISAS_STOP;
9494 register_name = "TraceControl";
9495 goto cp0_unimplemented;
9497 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9498 /* Stop translation as we may have switched the execution mode */
9499 ctx->base.is_jmp = DISAS_STOP;
9500 register_name = "TraceControl2";
9501 goto cp0_unimplemented;
9503 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9504 /* Stop translation as we may have switched the execution mode */
9505 ctx->base.is_jmp = DISAS_STOP;
9506 register_name = "UserTraceData";
9507 goto cp0_unimplemented;
9509 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9510 /* Stop translation as we may have switched the execution mode */
9511 ctx->base.is_jmp = DISAS_STOP;
9512 register_name = "TraceBPC";
9513 goto cp0_unimplemented;
9515 goto cp0_unimplemented;
9518 case CP0_REGISTER_24:
9522 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9523 register_name = "DEPC";
9526 goto cp0_unimplemented;
9529 case CP0_REGISTER_25:
9532 gen_helper_mtc0_performance0(cpu_env, arg);
9533 register_name = "Performance0";
9536 // gen_helper_mtc0_performance1(cpu_env, arg);
9537 register_name = "Performance1";
9538 goto cp0_unimplemented;
9540 // gen_helper_mtc0_performance2(cpu_env, arg);
9541 register_name = "Performance2";
9542 goto cp0_unimplemented;
9544 // gen_helper_mtc0_performance3(cpu_env, arg);
9545 register_name = "Performance3";
9546 goto cp0_unimplemented;
9548 // gen_helper_mtc0_performance4(cpu_env, arg);
9549 register_name = "Performance4";
9550 goto cp0_unimplemented;
9552 // gen_helper_mtc0_performance5(cpu_env, arg);
9553 register_name = "Performance5";
9554 goto cp0_unimplemented;
9556 // gen_helper_mtc0_performance6(cpu_env, arg);
9557 register_name = "Performance6";
9558 goto cp0_unimplemented;
9560 // gen_helper_mtc0_performance7(cpu_env, arg);
9561 register_name = "Performance7";
9562 goto cp0_unimplemented;
9564 goto cp0_unimplemented;
9567 case CP0_REGISTER_26:
9570 gen_helper_mtc0_errctl(cpu_env, arg);
9571 ctx->base.is_jmp = DISAS_STOP;
9572 register_name = "ErrCtl";
9575 goto cp0_unimplemented;
9578 case CP0_REGISTER_27:
9585 register_name = "CacheErr";
9588 goto cp0_unimplemented;
9591 case CP0_REGISTER_28:
9597 gen_helper_mtc0_taglo(cpu_env, arg);
9598 register_name = "TagLo";
9604 gen_helper_mtc0_datalo(cpu_env, arg);
9605 register_name = "DataLo";
9608 goto cp0_unimplemented;
9611 case CP0_REGISTER_29:
9617 gen_helper_mtc0_taghi(cpu_env, arg);
9618 register_name = "TagHi";
9624 gen_helper_mtc0_datahi(cpu_env, arg);
9625 register_name = "DataHi";
9628 register_name = "invalid sel";
9629 goto cp0_unimplemented;
9632 case CP0_REGISTER_30:
9635 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9636 register_name = "ErrorEPC";
9639 goto cp0_unimplemented;
9642 case CP0_REGISTER_31:
9646 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9647 register_name = "DESAVE";
9655 CP0_CHECK(ctx->kscrexist & (1 << sel));
9656 tcg_gen_st_tl(arg, cpu_env,
9657 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9658 register_name = "KScratch";
9661 goto cp0_unimplemented;
9665 goto cp0_unimplemented;
9667 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9669 /* For simplicity assume that all writes can cause interrupts. */
9670 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9672 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9673 * translated code to check for pending interrupts. */
9674 gen_save_pc(ctx->base.pc_next + 4);
9675 ctx->base.is_jmp = DISAS_EXIT;
9680 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9681 register_name, reg, sel);
9683 #endif /* TARGET_MIPS64 */
9685 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9686 int u, int sel, int h)
9688 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9689 TCGv t0 = tcg_temp_local_new();
9691 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9692 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9693 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9694 tcg_gen_movi_tl(t0, -1);
9695 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9696 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9697 tcg_gen_movi_tl(t0, -1);
9703 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9706 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9716 gen_helper_mftc0_tcstatus(t0, cpu_env);
9719 gen_helper_mftc0_tcbind(t0, cpu_env);
9722 gen_helper_mftc0_tcrestart(t0, cpu_env);
9725 gen_helper_mftc0_tchalt(t0, cpu_env);
9728 gen_helper_mftc0_tccontext(t0, cpu_env);
9731 gen_helper_mftc0_tcschedule(t0, cpu_env);
9734 gen_helper_mftc0_tcschefback(t0, cpu_env);
9737 gen_mfc0(ctx, t0, rt, sel);
9744 gen_helper_mftc0_entryhi(t0, cpu_env);
9747 gen_mfc0(ctx, t0, rt, sel);
9753 gen_helper_mftc0_status(t0, cpu_env);
9756 gen_mfc0(ctx, t0, rt, sel);
9762 gen_helper_mftc0_cause(t0, cpu_env);
9772 gen_helper_mftc0_epc(t0, cpu_env);
9782 gen_helper_mftc0_ebase(t0, cpu_env);
9799 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9809 gen_helper_mftc0_debug(t0, cpu_env);
9812 gen_mfc0(ctx, t0, rt, sel);
9817 gen_mfc0(ctx, t0, rt, sel);
9819 } else switch (sel) {
9820 /* GPR registers. */
9822 gen_helper_1e0i(mftgpr, t0, rt);
9824 /* Auxiliary CPU registers */
9828 gen_helper_1e0i(mftlo, t0, 0);
9831 gen_helper_1e0i(mfthi, t0, 0);
9834 gen_helper_1e0i(mftacx, t0, 0);
9837 gen_helper_1e0i(mftlo, t0, 1);
9840 gen_helper_1e0i(mfthi, t0, 1);
9843 gen_helper_1e0i(mftacx, t0, 1);
9846 gen_helper_1e0i(mftlo, t0, 2);
9849 gen_helper_1e0i(mfthi, t0, 2);
9852 gen_helper_1e0i(mftacx, t0, 2);
9855 gen_helper_1e0i(mftlo, t0, 3);
9858 gen_helper_1e0i(mfthi, t0, 3);
9861 gen_helper_1e0i(mftacx, t0, 3);
9864 gen_helper_mftdsp(t0, cpu_env);
9870 /* Floating point (COP1). */
9872 /* XXX: For now we support only a single FPU context. */
9874 TCGv_i32 fp0 = tcg_temp_new_i32();
9876 gen_load_fpr32(ctx, fp0, rt);
9877 tcg_gen_ext_i32_tl(t0, fp0);
9878 tcg_temp_free_i32(fp0);
9880 TCGv_i32 fp0 = tcg_temp_new_i32();
9882 gen_load_fpr32h(ctx, fp0, rt);
9883 tcg_gen_ext_i32_tl(t0, fp0);
9884 tcg_temp_free_i32(fp0);
9888 /* XXX: For now we support only a single FPU context. */
9889 gen_helper_1e0i(cfc1, t0, rt);
9891 /* COP2: Not implemented. */
9898 trace_mips_translate_tr("mftr", rt, u, sel, h);
9899 gen_store_gpr(t0, rd);
9905 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9906 generate_exception_end(ctx, EXCP_RI);
9909 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9910 int u, int sel, int h)
9912 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9913 TCGv t0 = tcg_temp_local_new();
9915 gen_load_gpr(t0, rt);
9916 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9917 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9918 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9920 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9921 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9928 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9931 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9941 gen_helper_mttc0_tcstatus(cpu_env, t0);
9944 gen_helper_mttc0_tcbind(cpu_env, t0);
9947 gen_helper_mttc0_tcrestart(cpu_env, t0);
9950 gen_helper_mttc0_tchalt(cpu_env, t0);
9953 gen_helper_mttc0_tccontext(cpu_env, t0);
9956 gen_helper_mttc0_tcschedule(cpu_env, t0);
9959 gen_helper_mttc0_tcschefback(cpu_env, t0);
9962 gen_mtc0(ctx, t0, rd, sel);
9969 gen_helper_mttc0_entryhi(cpu_env, t0);
9972 gen_mtc0(ctx, t0, rd, sel);
9978 gen_helper_mttc0_status(cpu_env, t0);
9981 gen_mtc0(ctx, t0, rd, sel);
9987 gen_helper_mttc0_cause(cpu_env, t0);
9997 gen_helper_mttc0_ebase(cpu_env, t0);
10007 gen_helper_mttc0_debug(cpu_env, t0);
10010 gen_mtc0(ctx, t0, rd, sel);
10015 gen_mtc0(ctx, t0, rd, sel);
10017 } else switch (sel) {
10018 /* GPR registers. */
10020 gen_helper_0e1i(mttgpr, t0, rd);
10022 /* Auxiliary CPU registers */
10026 gen_helper_0e1i(mttlo, t0, 0);
10029 gen_helper_0e1i(mtthi, t0, 0);
10032 gen_helper_0e1i(mttacx, t0, 0);
10035 gen_helper_0e1i(mttlo, t0, 1);
10038 gen_helper_0e1i(mtthi, t0, 1);
10041 gen_helper_0e1i(mttacx, t0, 1);
10044 gen_helper_0e1i(mttlo, t0, 2);
10047 gen_helper_0e1i(mtthi, t0, 2);
10050 gen_helper_0e1i(mttacx, t0, 2);
10053 gen_helper_0e1i(mttlo, t0, 3);
10056 gen_helper_0e1i(mtthi, t0, 3);
10059 gen_helper_0e1i(mttacx, t0, 3);
10062 gen_helper_mttdsp(cpu_env, t0);
10068 /* Floating point (COP1). */
10070 /* XXX: For now we support only a single FPU context. */
10072 TCGv_i32 fp0 = tcg_temp_new_i32();
10074 tcg_gen_trunc_tl_i32(fp0, t0);
10075 gen_store_fpr32(ctx, fp0, rd);
10076 tcg_temp_free_i32(fp0);
10078 TCGv_i32 fp0 = tcg_temp_new_i32();
10080 tcg_gen_trunc_tl_i32(fp0, t0);
10081 gen_store_fpr32h(ctx, fp0, rd);
10082 tcg_temp_free_i32(fp0);
10086 /* XXX: For now we support only a single FPU context. */
10088 TCGv_i32 fs_tmp = tcg_const_i32(rd);
10090 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10091 tcg_temp_free_i32(fs_tmp);
10093 /* Stop translation as we may have changed hflags */
10094 ctx->base.is_jmp = DISAS_STOP;
10096 /* COP2: Not implemented. */
10103 trace_mips_translate_tr("mttr", rd, u, sel, h);
10109 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10110 generate_exception_end(ctx, EXCP_RI);
10113 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
10115 const char *opn = "ldst";
10117 check_cp0_enabled(ctx);
10121 /* Treat as NOP. */
10124 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10129 TCGv t0 = tcg_temp_new();
10131 gen_load_gpr(t0, rt);
10132 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10137 #if defined(TARGET_MIPS64)
10139 check_insn(ctx, ISA_MIPS3);
10141 /* Treat as NOP. */
10144 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10148 check_insn(ctx, ISA_MIPS3);
10150 TCGv t0 = tcg_temp_new();
10152 gen_load_gpr(t0, rt);
10153 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10162 /* Treat as NOP. */
10165 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10171 TCGv t0 = tcg_temp_new();
10172 gen_load_gpr(t0, rt);
10173 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10179 check_cp0_enabled(ctx);
10181 /* Treat as NOP. */
10184 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10185 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10189 check_cp0_enabled(ctx);
10190 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10191 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10196 if (!env->tlb->helper_tlbwi)
10198 gen_helper_tlbwi(cpu_env);
10202 if (ctx->ie >= 2) {
10203 if (!env->tlb->helper_tlbinv) {
10206 gen_helper_tlbinv(cpu_env);
10207 } /* treat as nop if TLBINV not supported */
10211 if (ctx->ie >= 2) {
10212 if (!env->tlb->helper_tlbinvf) {
10215 gen_helper_tlbinvf(cpu_env);
10216 } /* treat as nop if TLBINV not supported */
10220 if (!env->tlb->helper_tlbwr)
10222 gen_helper_tlbwr(cpu_env);
10226 if (!env->tlb->helper_tlbp)
10228 gen_helper_tlbp(cpu_env);
10232 if (!env->tlb->helper_tlbr)
10234 gen_helper_tlbr(cpu_env);
10236 case OPC_ERET: /* OPC_ERETNC */
10237 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10238 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10241 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10242 if (ctx->opcode & (1 << bit_shift)) {
10245 check_insn(ctx, ISA_MIPS32R5);
10246 gen_helper_eretnc(cpu_env);
10250 check_insn(ctx, ISA_MIPS2);
10251 gen_helper_eret(cpu_env);
10253 ctx->base.is_jmp = DISAS_EXIT;
10258 check_insn(ctx, ISA_MIPS32);
10259 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10260 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10263 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10265 generate_exception_end(ctx, EXCP_RI);
10267 gen_helper_deret(cpu_env);
10268 ctx->base.is_jmp = DISAS_EXIT;
10273 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10274 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10275 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10278 /* If we get an exception, we want to restart at next instruction */
10279 ctx->base.pc_next += 4;
10280 save_cpu_state(ctx, 1);
10281 ctx->base.pc_next -= 4;
10282 gen_helper_wait(cpu_env);
10283 ctx->base.is_jmp = DISAS_NORETURN;
10288 generate_exception_end(ctx, EXCP_RI);
10291 (void)opn; /* avoid a compiler warning */
10293 #endif /* !CONFIG_USER_ONLY */
10295 /* CP1 Branches (before delay slot) */
10296 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10297 int32_t cc, int32_t offset)
10299 target_ulong btarget;
10300 TCGv_i32 t0 = tcg_temp_new_i32();
10302 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10303 generate_exception_end(ctx, EXCP_RI);
10308 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10310 btarget = ctx->base.pc_next + 4 + offset;
10314 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10315 tcg_gen_not_i32(t0, t0);
10316 tcg_gen_andi_i32(t0, t0, 1);
10317 tcg_gen_extu_i32_tl(bcond, t0);
10320 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10321 tcg_gen_not_i32(t0, t0);
10322 tcg_gen_andi_i32(t0, t0, 1);
10323 tcg_gen_extu_i32_tl(bcond, t0);
10326 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10327 tcg_gen_andi_i32(t0, t0, 1);
10328 tcg_gen_extu_i32_tl(bcond, t0);
10331 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10332 tcg_gen_andi_i32(t0, t0, 1);
10333 tcg_gen_extu_i32_tl(bcond, t0);
10335 ctx->hflags |= MIPS_HFLAG_BL;
10339 TCGv_i32 t1 = tcg_temp_new_i32();
10340 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10341 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10342 tcg_gen_nand_i32(t0, t0, t1);
10343 tcg_temp_free_i32(t1);
10344 tcg_gen_andi_i32(t0, t0, 1);
10345 tcg_gen_extu_i32_tl(bcond, t0);
10350 TCGv_i32 t1 = tcg_temp_new_i32();
10351 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10352 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10353 tcg_gen_or_i32(t0, t0, t1);
10354 tcg_temp_free_i32(t1);
10355 tcg_gen_andi_i32(t0, t0, 1);
10356 tcg_gen_extu_i32_tl(bcond, t0);
10361 TCGv_i32 t1 = tcg_temp_new_i32();
10362 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10363 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10364 tcg_gen_and_i32(t0, t0, t1);
10365 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10366 tcg_gen_and_i32(t0, t0, t1);
10367 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10368 tcg_gen_nand_i32(t0, t0, t1);
10369 tcg_temp_free_i32(t1);
10370 tcg_gen_andi_i32(t0, t0, 1);
10371 tcg_gen_extu_i32_tl(bcond, t0);
10376 TCGv_i32 t1 = tcg_temp_new_i32();
10377 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10378 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10379 tcg_gen_or_i32(t0, t0, t1);
10380 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10381 tcg_gen_or_i32(t0, t0, t1);
10382 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10383 tcg_gen_or_i32(t0, t0, t1);
10384 tcg_temp_free_i32(t1);
10385 tcg_gen_andi_i32(t0, t0, 1);
10386 tcg_gen_extu_i32_tl(bcond, t0);
10389 ctx->hflags |= MIPS_HFLAG_BC;
10392 MIPS_INVAL("cp1 cond branch");
10393 generate_exception_end(ctx, EXCP_RI);
10396 ctx->btarget = btarget;
10397 ctx->hflags |= MIPS_HFLAG_BDS32;
10399 tcg_temp_free_i32(t0);
10402 /* R6 CP1 Branches */
10403 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10404 int32_t ft, int32_t offset,
10405 int delayslot_size)
10407 target_ulong btarget;
10408 TCGv_i64 t0 = tcg_temp_new_i64();
10410 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10411 #ifdef MIPS_DEBUG_DISAS
10412 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10413 "\n", ctx->base.pc_next);
10415 generate_exception_end(ctx, EXCP_RI);
10419 gen_load_fpr64(ctx, t0, ft);
10420 tcg_gen_andi_i64(t0, t0, 1);
10422 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10426 tcg_gen_xori_i64(t0, t0, 1);
10427 ctx->hflags |= MIPS_HFLAG_BC;
10430 /* t0 already set */
10431 ctx->hflags |= MIPS_HFLAG_BC;
10434 MIPS_INVAL("cp1 cond branch");
10435 generate_exception_end(ctx, EXCP_RI);
10439 tcg_gen_trunc_i64_tl(bcond, t0);
10441 ctx->btarget = btarget;
10443 switch (delayslot_size) {
10445 ctx->hflags |= MIPS_HFLAG_BDS16;
10448 ctx->hflags |= MIPS_HFLAG_BDS32;
10453 tcg_temp_free_i64(t0);
10456 /* Coprocessor 1 (FPU) */
10458 #define FOP(func, fmt) (((fmt) << 21) | (func))
10461 OPC_ADD_S = FOP(0, FMT_S),
10462 OPC_SUB_S = FOP(1, FMT_S),
10463 OPC_MUL_S = FOP(2, FMT_S),
10464 OPC_DIV_S = FOP(3, FMT_S),
10465 OPC_SQRT_S = FOP(4, FMT_S),
10466 OPC_ABS_S = FOP(5, FMT_S),
10467 OPC_MOV_S = FOP(6, FMT_S),
10468 OPC_NEG_S = FOP(7, FMT_S),
10469 OPC_ROUND_L_S = FOP(8, FMT_S),
10470 OPC_TRUNC_L_S = FOP(9, FMT_S),
10471 OPC_CEIL_L_S = FOP(10, FMT_S),
10472 OPC_FLOOR_L_S = FOP(11, FMT_S),
10473 OPC_ROUND_W_S = FOP(12, FMT_S),
10474 OPC_TRUNC_W_S = FOP(13, FMT_S),
10475 OPC_CEIL_W_S = FOP(14, FMT_S),
10476 OPC_FLOOR_W_S = FOP(15, FMT_S),
10477 OPC_SEL_S = FOP(16, FMT_S),
10478 OPC_MOVCF_S = FOP(17, FMT_S),
10479 OPC_MOVZ_S = FOP(18, FMT_S),
10480 OPC_MOVN_S = FOP(19, FMT_S),
10481 OPC_SELEQZ_S = FOP(20, FMT_S),
10482 OPC_RECIP_S = FOP(21, FMT_S),
10483 OPC_RSQRT_S = FOP(22, FMT_S),
10484 OPC_SELNEZ_S = FOP(23, FMT_S),
10485 OPC_MADDF_S = FOP(24, FMT_S),
10486 OPC_MSUBF_S = FOP(25, FMT_S),
10487 OPC_RINT_S = FOP(26, FMT_S),
10488 OPC_CLASS_S = FOP(27, FMT_S),
10489 OPC_MIN_S = FOP(28, FMT_S),
10490 OPC_RECIP2_S = FOP(28, FMT_S),
10491 OPC_MINA_S = FOP(29, FMT_S),
10492 OPC_RECIP1_S = FOP(29, FMT_S),
10493 OPC_MAX_S = FOP(30, FMT_S),
10494 OPC_RSQRT1_S = FOP(30, FMT_S),
10495 OPC_MAXA_S = FOP(31, FMT_S),
10496 OPC_RSQRT2_S = FOP(31, FMT_S),
10497 OPC_CVT_D_S = FOP(33, FMT_S),
10498 OPC_CVT_W_S = FOP(36, FMT_S),
10499 OPC_CVT_L_S = FOP(37, FMT_S),
10500 OPC_CVT_PS_S = FOP(38, FMT_S),
10501 OPC_CMP_F_S = FOP (48, FMT_S),
10502 OPC_CMP_UN_S = FOP (49, FMT_S),
10503 OPC_CMP_EQ_S = FOP (50, FMT_S),
10504 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10505 OPC_CMP_OLT_S = FOP (52, FMT_S),
10506 OPC_CMP_ULT_S = FOP (53, FMT_S),
10507 OPC_CMP_OLE_S = FOP (54, FMT_S),
10508 OPC_CMP_ULE_S = FOP (55, FMT_S),
10509 OPC_CMP_SF_S = FOP (56, FMT_S),
10510 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10511 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10512 OPC_CMP_NGL_S = FOP (59, FMT_S),
10513 OPC_CMP_LT_S = FOP (60, FMT_S),
10514 OPC_CMP_NGE_S = FOP (61, FMT_S),
10515 OPC_CMP_LE_S = FOP (62, FMT_S),
10516 OPC_CMP_NGT_S = FOP (63, FMT_S),
10518 OPC_ADD_D = FOP(0, FMT_D),
10519 OPC_SUB_D = FOP(1, FMT_D),
10520 OPC_MUL_D = FOP(2, FMT_D),
10521 OPC_DIV_D = FOP(3, FMT_D),
10522 OPC_SQRT_D = FOP(4, FMT_D),
10523 OPC_ABS_D = FOP(5, FMT_D),
10524 OPC_MOV_D = FOP(6, FMT_D),
10525 OPC_NEG_D = FOP(7, FMT_D),
10526 OPC_ROUND_L_D = FOP(8, FMT_D),
10527 OPC_TRUNC_L_D = FOP(9, FMT_D),
10528 OPC_CEIL_L_D = FOP(10, FMT_D),
10529 OPC_FLOOR_L_D = FOP(11, FMT_D),
10530 OPC_ROUND_W_D = FOP(12, FMT_D),
10531 OPC_TRUNC_W_D = FOP(13, FMT_D),
10532 OPC_CEIL_W_D = FOP(14, FMT_D),
10533 OPC_FLOOR_W_D = FOP(15, FMT_D),
10534 OPC_SEL_D = FOP(16, FMT_D),
10535 OPC_MOVCF_D = FOP(17, FMT_D),
10536 OPC_MOVZ_D = FOP(18, FMT_D),
10537 OPC_MOVN_D = FOP(19, FMT_D),
10538 OPC_SELEQZ_D = FOP(20, FMT_D),
10539 OPC_RECIP_D = FOP(21, FMT_D),
10540 OPC_RSQRT_D = FOP(22, FMT_D),
10541 OPC_SELNEZ_D = FOP(23, FMT_D),
10542 OPC_MADDF_D = FOP(24, FMT_D),
10543 OPC_MSUBF_D = FOP(25, FMT_D),
10544 OPC_RINT_D = FOP(26, FMT_D),
10545 OPC_CLASS_D = FOP(27, FMT_D),
10546 OPC_MIN_D = FOP(28, FMT_D),
10547 OPC_RECIP2_D = FOP(28, FMT_D),
10548 OPC_MINA_D = FOP(29, FMT_D),
10549 OPC_RECIP1_D = FOP(29, FMT_D),
10550 OPC_MAX_D = FOP(30, FMT_D),
10551 OPC_RSQRT1_D = FOP(30, FMT_D),
10552 OPC_MAXA_D = FOP(31, FMT_D),
10553 OPC_RSQRT2_D = FOP(31, FMT_D),
10554 OPC_CVT_S_D = FOP(32, FMT_D),
10555 OPC_CVT_W_D = FOP(36, FMT_D),
10556 OPC_CVT_L_D = FOP(37, FMT_D),
10557 OPC_CMP_F_D = FOP (48, FMT_D),
10558 OPC_CMP_UN_D = FOP (49, FMT_D),
10559 OPC_CMP_EQ_D = FOP (50, FMT_D),
10560 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10561 OPC_CMP_OLT_D = FOP (52, FMT_D),
10562 OPC_CMP_ULT_D = FOP (53, FMT_D),
10563 OPC_CMP_OLE_D = FOP (54, FMT_D),
10564 OPC_CMP_ULE_D = FOP (55, FMT_D),
10565 OPC_CMP_SF_D = FOP (56, FMT_D),
10566 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10567 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10568 OPC_CMP_NGL_D = FOP (59, FMT_D),
10569 OPC_CMP_LT_D = FOP (60, FMT_D),
10570 OPC_CMP_NGE_D = FOP (61, FMT_D),
10571 OPC_CMP_LE_D = FOP (62, FMT_D),
10572 OPC_CMP_NGT_D = FOP (63, FMT_D),
10574 OPC_CVT_S_W = FOP(32, FMT_W),
10575 OPC_CVT_D_W = FOP(33, FMT_W),
10576 OPC_CVT_S_L = FOP(32, FMT_L),
10577 OPC_CVT_D_L = FOP(33, FMT_L),
10578 OPC_CVT_PS_PW = FOP(38, FMT_W),
10580 OPC_ADD_PS = FOP(0, FMT_PS),
10581 OPC_SUB_PS = FOP(1, FMT_PS),
10582 OPC_MUL_PS = FOP(2, FMT_PS),
10583 OPC_DIV_PS = FOP(3, FMT_PS),
10584 OPC_ABS_PS = FOP(5, FMT_PS),
10585 OPC_MOV_PS = FOP(6, FMT_PS),
10586 OPC_NEG_PS = FOP(7, FMT_PS),
10587 OPC_MOVCF_PS = FOP(17, FMT_PS),
10588 OPC_MOVZ_PS = FOP(18, FMT_PS),
10589 OPC_MOVN_PS = FOP(19, FMT_PS),
10590 OPC_ADDR_PS = FOP(24, FMT_PS),
10591 OPC_MULR_PS = FOP(26, FMT_PS),
10592 OPC_RECIP2_PS = FOP(28, FMT_PS),
10593 OPC_RECIP1_PS = FOP(29, FMT_PS),
10594 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10595 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10597 OPC_CVT_S_PU = FOP(32, FMT_PS),
10598 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10599 OPC_CVT_S_PL = FOP(40, FMT_PS),
10600 OPC_PLL_PS = FOP(44, FMT_PS),
10601 OPC_PLU_PS = FOP(45, FMT_PS),
10602 OPC_PUL_PS = FOP(46, FMT_PS),
10603 OPC_PUU_PS = FOP(47, FMT_PS),
10604 OPC_CMP_F_PS = FOP (48, FMT_PS),
10605 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10606 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10607 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10608 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10609 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10610 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10611 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10612 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10613 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10614 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10615 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10616 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10617 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10618 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10619 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10623 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10624 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10625 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10626 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10627 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10628 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10629 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10630 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10631 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10632 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10633 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10634 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10635 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10636 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10637 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10638 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10639 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10640 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10641 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10642 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10643 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10644 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10646 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10647 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10648 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10649 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10650 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10651 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10652 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10653 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10654 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10655 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10656 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10657 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10658 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10659 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10660 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10661 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10662 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10663 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10664 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10665 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10666 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10667 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10669 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10671 TCGv t0 = tcg_temp_new();
10676 TCGv_i32 fp0 = tcg_temp_new_i32();
10678 gen_load_fpr32(ctx, fp0, fs);
10679 tcg_gen_ext_i32_tl(t0, fp0);
10680 tcg_temp_free_i32(fp0);
10682 gen_store_gpr(t0, rt);
10685 gen_load_gpr(t0, rt);
10687 TCGv_i32 fp0 = tcg_temp_new_i32();
10689 tcg_gen_trunc_tl_i32(fp0, t0);
10690 gen_store_fpr32(ctx, fp0, fs);
10691 tcg_temp_free_i32(fp0);
10695 gen_helper_1e0i(cfc1, t0, fs);
10696 gen_store_gpr(t0, rt);
10699 gen_load_gpr(t0, rt);
10700 save_cpu_state(ctx, 0);
10702 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10704 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10705 tcg_temp_free_i32(fs_tmp);
10707 /* Stop translation as we may have changed hflags */
10708 ctx->base.is_jmp = DISAS_STOP;
10710 #if defined(TARGET_MIPS64)
10712 gen_load_fpr64(ctx, t0, fs);
10713 gen_store_gpr(t0, rt);
10716 gen_load_gpr(t0, rt);
10717 gen_store_fpr64(ctx, t0, fs);
10722 TCGv_i32 fp0 = tcg_temp_new_i32();
10724 gen_load_fpr32h(ctx, fp0, fs);
10725 tcg_gen_ext_i32_tl(t0, fp0);
10726 tcg_temp_free_i32(fp0);
10728 gen_store_gpr(t0, rt);
10731 gen_load_gpr(t0, rt);
10733 TCGv_i32 fp0 = tcg_temp_new_i32();
10735 tcg_gen_trunc_tl_i32(fp0, t0);
10736 gen_store_fpr32h(ctx, fp0, fs);
10737 tcg_temp_free_i32(fp0);
10741 MIPS_INVAL("cp1 move");
10742 generate_exception_end(ctx, EXCP_RI);
10750 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10757 /* Treat as NOP. */
10762 cond = TCG_COND_EQ;
10764 cond = TCG_COND_NE;
10766 l1 = gen_new_label();
10767 t0 = tcg_temp_new_i32();
10768 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10769 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10770 tcg_temp_free_i32(t0);
10772 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10774 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10779 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10783 TCGv_i32 t0 = tcg_temp_new_i32();
10784 TCGLabel *l1 = gen_new_label();
10787 cond = TCG_COND_EQ;
10789 cond = TCG_COND_NE;
10791 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10792 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10793 gen_load_fpr32(ctx, t0, fs);
10794 gen_store_fpr32(ctx, t0, fd);
10796 tcg_temp_free_i32(t0);
10799 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10802 TCGv_i32 t0 = tcg_temp_new_i32();
10804 TCGLabel *l1 = gen_new_label();
10807 cond = TCG_COND_EQ;
10809 cond = TCG_COND_NE;
10811 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10812 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10813 tcg_temp_free_i32(t0);
10814 fp0 = tcg_temp_new_i64();
10815 gen_load_fpr64(ctx, fp0, fs);
10816 gen_store_fpr64(ctx, fp0, fd);
10817 tcg_temp_free_i64(fp0);
10821 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10825 TCGv_i32 t0 = tcg_temp_new_i32();
10826 TCGLabel *l1 = gen_new_label();
10827 TCGLabel *l2 = gen_new_label();
10830 cond = TCG_COND_EQ;
10832 cond = TCG_COND_NE;
10834 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10835 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10836 gen_load_fpr32(ctx, t0, fs);
10837 gen_store_fpr32(ctx, t0, fd);
10840 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10841 tcg_gen_brcondi_i32(cond, t0, 0, l2);
10842 gen_load_fpr32h(ctx, t0, fs);
10843 gen_store_fpr32h(ctx, t0, fd);
10844 tcg_temp_free_i32(t0);
10848 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10851 TCGv_i32 t1 = tcg_const_i32(0);
10852 TCGv_i32 fp0 = tcg_temp_new_i32();
10853 TCGv_i32 fp1 = tcg_temp_new_i32();
10854 TCGv_i32 fp2 = tcg_temp_new_i32();
10855 gen_load_fpr32(ctx, fp0, fd);
10856 gen_load_fpr32(ctx, fp1, ft);
10857 gen_load_fpr32(ctx, fp2, fs);
10861 tcg_gen_andi_i32(fp0, fp0, 1);
10862 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10865 tcg_gen_andi_i32(fp1, fp1, 1);
10866 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10869 tcg_gen_andi_i32(fp1, fp1, 1);
10870 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10873 MIPS_INVAL("gen_sel_s");
10874 generate_exception_end(ctx, EXCP_RI);
10878 gen_store_fpr32(ctx, fp0, fd);
10879 tcg_temp_free_i32(fp2);
10880 tcg_temp_free_i32(fp1);
10881 tcg_temp_free_i32(fp0);
10882 tcg_temp_free_i32(t1);
10885 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10888 TCGv_i64 t1 = tcg_const_i64(0);
10889 TCGv_i64 fp0 = tcg_temp_new_i64();
10890 TCGv_i64 fp1 = tcg_temp_new_i64();
10891 TCGv_i64 fp2 = tcg_temp_new_i64();
10892 gen_load_fpr64(ctx, fp0, fd);
10893 gen_load_fpr64(ctx, fp1, ft);
10894 gen_load_fpr64(ctx, fp2, fs);
10898 tcg_gen_andi_i64(fp0, fp0, 1);
10899 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10902 tcg_gen_andi_i64(fp1, fp1, 1);
10903 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10906 tcg_gen_andi_i64(fp1, fp1, 1);
10907 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10910 MIPS_INVAL("gen_sel_d");
10911 generate_exception_end(ctx, EXCP_RI);
10915 gen_store_fpr64(ctx, fp0, fd);
10916 tcg_temp_free_i64(fp2);
10917 tcg_temp_free_i64(fp1);
10918 tcg_temp_free_i64(fp0);
10919 tcg_temp_free_i64(t1);
10922 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10923 int ft, int fs, int fd, int cc)
10925 uint32_t func = ctx->opcode & 0x3f;
10929 TCGv_i32 fp0 = tcg_temp_new_i32();
10930 TCGv_i32 fp1 = tcg_temp_new_i32();
10932 gen_load_fpr32(ctx, fp0, fs);
10933 gen_load_fpr32(ctx, fp1, ft);
10934 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10935 tcg_temp_free_i32(fp1);
10936 gen_store_fpr32(ctx, fp0, fd);
10937 tcg_temp_free_i32(fp0);
10942 TCGv_i32 fp0 = tcg_temp_new_i32();
10943 TCGv_i32 fp1 = tcg_temp_new_i32();
10945 gen_load_fpr32(ctx, fp0, fs);
10946 gen_load_fpr32(ctx, fp1, ft);
10947 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10948 tcg_temp_free_i32(fp1);
10949 gen_store_fpr32(ctx, fp0, fd);
10950 tcg_temp_free_i32(fp0);
10955 TCGv_i32 fp0 = tcg_temp_new_i32();
10956 TCGv_i32 fp1 = tcg_temp_new_i32();
10958 gen_load_fpr32(ctx, fp0, fs);
10959 gen_load_fpr32(ctx, fp1, ft);
10960 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10961 tcg_temp_free_i32(fp1);
10962 gen_store_fpr32(ctx, fp0, fd);
10963 tcg_temp_free_i32(fp0);
10968 TCGv_i32 fp0 = tcg_temp_new_i32();
10969 TCGv_i32 fp1 = tcg_temp_new_i32();
10971 gen_load_fpr32(ctx, fp0, fs);
10972 gen_load_fpr32(ctx, fp1, ft);
10973 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10974 tcg_temp_free_i32(fp1);
10975 gen_store_fpr32(ctx, fp0, fd);
10976 tcg_temp_free_i32(fp0);
10981 TCGv_i32 fp0 = tcg_temp_new_i32();
10983 gen_load_fpr32(ctx, fp0, fs);
10984 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10985 gen_store_fpr32(ctx, fp0, fd);
10986 tcg_temp_free_i32(fp0);
10991 TCGv_i32 fp0 = tcg_temp_new_i32();
10993 gen_load_fpr32(ctx, fp0, fs);
10994 if (ctx->abs2008) {
10995 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10997 gen_helper_float_abs_s(fp0, fp0);
10999 gen_store_fpr32(ctx, fp0, fd);
11000 tcg_temp_free_i32(fp0);
11005 TCGv_i32 fp0 = tcg_temp_new_i32();
11007 gen_load_fpr32(ctx, fp0, fs);
11008 gen_store_fpr32(ctx, fp0, fd);
11009 tcg_temp_free_i32(fp0);
11014 TCGv_i32 fp0 = tcg_temp_new_i32();
11016 gen_load_fpr32(ctx, fp0, fs);
11017 if (ctx->abs2008) {
11018 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
11020 gen_helper_float_chs_s(fp0, fp0);
11022 gen_store_fpr32(ctx, fp0, fd);
11023 tcg_temp_free_i32(fp0);
11026 case OPC_ROUND_L_S:
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_round_2008_l_s(fp64, cpu_env, fp32);
11036 gen_helper_float_round_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_TRUNC_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_trunc_2008_l_s(fp64, cpu_env, fp32);
11053 gen_helper_float_trunc_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);
11061 check_cp1_64bitmode(ctx);
11063 TCGv_i32 fp32 = tcg_temp_new_i32();
11064 TCGv_i64 fp64 = tcg_temp_new_i64();
11066 gen_load_fpr32(ctx, fp32, fs);
11067 if (ctx->nan2008) {
11068 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11070 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11072 tcg_temp_free_i32(fp32);
11073 gen_store_fpr64(ctx, fp64, fd);
11074 tcg_temp_free_i64(fp64);
11077 case OPC_FLOOR_L_S:
11078 check_cp1_64bitmode(ctx);
11080 TCGv_i32 fp32 = tcg_temp_new_i32();
11081 TCGv_i64 fp64 = tcg_temp_new_i64();
11083 gen_load_fpr32(ctx, fp32, fs);
11084 if (ctx->nan2008) {
11085 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11087 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11089 tcg_temp_free_i32(fp32);
11090 gen_store_fpr64(ctx, fp64, fd);
11091 tcg_temp_free_i64(fp64);
11094 case OPC_ROUND_W_S:
11096 TCGv_i32 fp0 = tcg_temp_new_i32();
11098 gen_load_fpr32(ctx, fp0, fs);
11099 if (ctx->nan2008) {
11100 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11102 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11104 gen_store_fpr32(ctx, fp0, fd);
11105 tcg_temp_free_i32(fp0);
11108 case OPC_TRUNC_W_S:
11110 TCGv_i32 fp0 = tcg_temp_new_i32();
11112 gen_load_fpr32(ctx, fp0, fs);
11113 if (ctx->nan2008) {
11114 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11116 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11118 gen_store_fpr32(ctx, fp0, fd);
11119 tcg_temp_free_i32(fp0);
11124 TCGv_i32 fp0 = tcg_temp_new_i32();
11126 gen_load_fpr32(ctx, fp0, fs);
11127 if (ctx->nan2008) {
11128 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11130 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11132 gen_store_fpr32(ctx, fp0, fd);
11133 tcg_temp_free_i32(fp0);
11136 case OPC_FLOOR_W_S:
11138 TCGv_i32 fp0 = tcg_temp_new_i32();
11140 gen_load_fpr32(ctx, fp0, fs);
11141 if (ctx->nan2008) {
11142 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11144 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11146 gen_store_fpr32(ctx, fp0, fd);
11147 tcg_temp_free_i32(fp0);
11151 check_insn(ctx, ISA_MIPS32R6);
11152 gen_sel_s(ctx, op1, fd, ft, fs);
11155 check_insn(ctx, ISA_MIPS32R6);
11156 gen_sel_s(ctx, op1, fd, ft, fs);
11159 check_insn(ctx, ISA_MIPS32R6);
11160 gen_sel_s(ctx, op1, fd, ft, fs);
11163 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11164 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11167 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11169 TCGLabel *l1 = gen_new_label();
11173 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11175 fp0 = tcg_temp_new_i32();
11176 gen_load_fpr32(ctx, fp0, fs);
11177 gen_store_fpr32(ctx, fp0, fd);
11178 tcg_temp_free_i32(fp0);
11183 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11185 TCGLabel *l1 = gen_new_label();
11189 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11190 fp0 = tcg_temp_new_i32();
11191 gen_load_fpr32(ctx, fp0, fs);
11192 gen_store_fpr32(ctx, fp0, fd);
11193 tcg_temp_free_i32(fp0);
11200 TCGv_i32 fp0 = tcg_temp_new_i32();
11202 gen_load_fpr32(ctx, fp0, fs);
11203 gen_helper_float_recip_s(fp0, cpu_env, fp0);
11204 gen_store_fpr32(ctx, fp0, fd);
11205 tcg_temp_free_i32(fp0);
11210 TCGv_i32 fp0 = tcg_temp_new_i32();
11212 gen_load_fpr32(ctx, fp0, fs);
11213 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11214 gen_store_fpr32(ctx, fp0, fd);
11215 tcg_temp_free_i32(fp0);
11219 check_insn(ctx, ISA_MIPS32R6);
11221 TCGv_i32 fp0 = tcg_temp_new_i32();
11222 TCGv_i32 fp1 = tcg_temp_new_i32();
11223 TCGv_i32 fp2 = tcg_temp_new_i32();
11224 gen_load_fpr32(ctx, fp0, fs);
11225 gen_load_fpr32(ctx, fp1, ft);
11226 gen_load_fpr32(ctx, fp2, fd);
11227 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11228 gen_store_fpr32(ctx, fp2, fd);
11229 tcg_temp_free_i32(fp2);
11230 tcg_temp_free_i32(fp1);
11231 tcg_temp_free_i32(fp0);
11235 check_insn(ctx, ISA_MIPS32R6);
11237 TCGv_i32 fp0 = tcg_temp_new_i32();
11238 TCGv_i32 fp1 = tcg_temp_new_i32();
11239 TCGv_i32 fp2 = tcg_temp_new_i32();
11240 gen_load_fpr32(ctx, fp0, fs);
11241 gen_load_fpr32(ctx, fp1, ft);
11242 gen_load_fpr32(ctx, fp2, fd);
11243 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11244 gen_store_fpr32(ctx, fp2, fd);
11245 tcg_temp_free_i32(fp2);
11246 tcg_temp_free_i32(fp1);
11247 tcg_temp_free_i32(fp0);
11251 check_insn(ctx, ISA_MIPS32R6);
11253 TCGv_i32 fp0 = tcg_temp_new_i32();
11254 gen_load_fpr32(ctx, fp0, fs);
11255 gen_helper_float_rint_s(fp0, cpu_env, fp0);
11256 gen_store_fpr32(ctx, fp0, fd);
11257 tcg_temp_free_i32(fp0);
11261 check_insn(ctx, ISA_MIPS32R6);
11263 TCGv_i32 fp0 = tcg_temp_new_i32();
11264 gen_load_fpr32(ctx, fp0, fs);
11265 gen_helper_float_class_s(fp0, cpu_env, fp0);
11266 gen_store_fpr32(ctx, fp0, fd);
11267 tcg_temp_free_i32(fp0);
11270 case OPC_MIN_S: /* OPC_RECIP2_S */
11271 if (ctx->insn_flags & ISA_MIPS32R6) {
11273 TCGv_i32 fp0 = tcg_temp_new_i32();
11274 TCGv_i32 fp1 = tcg_temp_new_i32();
11275 TCGv_i32 fp2 = tcg_temp_new_i32();
11276 gen_load_fpr32(ctx, fp0, fs);
11277 gen_load_fpr32(ctx, fp1, ft);
11278 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11279 gen_store_fpr32(ctx, fp2, fd);
11280 tcg_temp_free_i32(fp2);
11281 tcg_temp_free_i32(fp1);
11282 tcg_temp_free_i32(fp0);
11285 check_cp1_64bitmode(ctx);
11287 TCGv_i32 fp0 = tcg_temp_new_i32();
11288 TCGv_i32 fp1 = tcg_temp_new_i32();
11290 gen_load_fpr32(ctx, fp0, fs);
11291 gen_load_fpr32(ctx, fp1, ft);
11292 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11293 tcg_temp_free_i32(fp1);
11294 gen_store_fpr32(ctx, fp0, fd);
11295 tcg_temp_free_i32(fp0);
11299 case OPC_MINA_S: /* OPC_RECIP1_S */
11300 if (ctx->insn_flags & ISA_MIPS32R6) {
11302 TCGv_i32 fp0 = tcg_temp_new_i32();
11303 TCGv_i32 fp1 = tcg_temp_new_i32();
11304 TCGv_i32 fp2 = tcg_temp_new_i32();
11305 gen_load_fpr32(ctx, fp0, fs);
11306 gen_load_fpr32(ctx, fp1, ft);
11307 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11308 gen_store_fpr32(ctx, fp2, fd);
11309 tcg_temp_free_i32(fp2);
11310 tcg_temp_free_i32(fp1);
11311 tcg_temp_free_i32(fp0);
11314 check_cp1_64bitmode(ctx);
11316 TCGv_i32 fp0 = tcg_temp_new_i32();
11318 gen_load_fpr32(ctx, fp0, fs);
11319 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11320 gen_store_fpr32(ctx, fp0, fd);
11321 tcg_temp_free_i32(fp0);
11325 case OPC_MAX_S: /* OPC_RSQRT1_S */
11326 if (ctx->insn_flags & ISA_MIPS32R6) {
11328 TCGv_i32 fp0 = tcg_temp_new_i32();
11329 TCGv_i32 fp1 = tcg_temp_new_i32();
11330 gen_load_fpr32(ctx, fp0, fs);
11331 gen_load_fpr32(ctx, fp1, ft);
11332 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11333 gen_store_fpr32(ctx, fp1, fd);
11334 tcg_temp_free_i32(fp1);
11335 tcg_temp_free_i32(fp0);
11338 check_cp1_64bitmode(ctx);
11340 TCGv_i32 fp0 = tcg_temp_new_i32();
11342 gen_load_fpr32(ctx, fp0, fs);
11343 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11344 gen_store_fpr32(ctx, fp0, fd);
11345 tcg_temp_free_i32(fp0);
11349 case OPC_MAXA_S: /* OPC_RSQRT2_S */
11350 if (ctx->insn_flags & ISA_MIPS32R6) {
11352 TCGv_i32 fp0 = tcg_temp_new_i32();
11353 TCGv_i32 fp1 = tcg_temp_new_i32();
11354 gen_load_fpr32(ctx, fp0, fs);
11355 gen_load_fpr32(ctx, fp1, ft);
11356 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11357 gen_store_fpr32(ctx, fp1, fd);
11358 tcg_temp_free_i32(fp1);
11359 tcg_temp_free_i32(fp0);
11362 check_cp1_64bitmode(ctx);
11364 TCGv_i32 fp0 = tcg_temp_new_i32();
11365 TCGv_i32 fp1 = tcg_temp_new_i32();
11367 gen_load_fpr32(ctx, fp0, fs);
11368 gen_load_fpr32(ctx, fp1, ft);
11369 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11370 tcg_temp_free_i32(fp1);
11371 gen_store_fpr32(ctx, fp0, fd);
11372 tcg_temp_free_i32(fp0);
11377 check_cp1_registers(ctx, fd);
11379 TCGv_i32 fp32 = tcg_temp_new_i32();
11380 TCGv_i64 fp64 = tcg_temp_new_i64();
11382 gen_load_fpr32(ctx, fp32, fs);
11383 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11384 tcg_temp_free_i32(fp32);
11385 gen_store_fpr64(ctx, fp64, fd);
11386 tcg_temp_free_i64(fp64);
11391 TCGv_i32 fp0 = tcg_temp_new_i32();
11393 gen_load_fpr32(ctx, fp0, fs);
11394 if (ctx->nan2008) {
11395 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11397 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11399 gen_store_fpr32(ctx, fp0, fd);
11400 tcg_temp_free_i32(fp0);
11404 check_cp1_64bitmode(ctx);
11406 TCGv_i32 fp32 = tcg_temp_new_i32();
11407 TCGv_i64 fp64 = tcg_temp_new_i64();
11409 gen_load_fpr32(ctx, fp32, fs);
11410 if (ctx->nan2008) {
11411 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11413 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11415 tcg_temp_free_i32(fp32);
11416 gen_store_fpr64(ctx, fp64, fd);
11417 tcg_temp_free_i64(fp64);
11423 TCGv_i64 fp64 = tcg_temp_new_i64();
11424 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11425 TCGv_i32 fp32_1 = tcg_temp_new_i32();
11427 gen_load_fpr32(ctx, fp32_0, fs);
11428 gen_load_fpr32(ctx, fp32_1, ft);
11429 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11430 tcg_temp_free_i32(fp32_1);
11431 tcg_temp_free_i32(fp32_0);
11432 gen_store_fpr64(ctx, fp64, fd);
11433 tcg_temp_free_i64(fp64);
11439 case OPC_CMP_UEQ_S:
11440 case OPC_CMP_OLT_S:
11441 case OPC_CMP_ULT_S:
11442 case OPC_CMP_OLE_S:
11443 case OPC_CMP_ULE_S:
11445 case OPC_CMP_NGLE_S:
11446 case OPC_CMP_SEQ_S:
11447 case OPC_CMP_NGL_S:
11449 case OPC_CMP_NGE_S:
11451 case OPC_CMP_NGT_S:
11452 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11453 if (ctx->opcode & (1 << 6)) {
11454 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11456 gen_cmp_s(ctx, func-48, ft, fs, cc);
11460 check_cp1_registers(ctx, fs | ft | fd);
11462 TCGv_i64 fp0 = tcg_temp_new_i64();
11463 TCGv_i64 fp1 = tcg_temp_new_i64();
11465 gen_load_fpr64(ctx, fp0, fs);
11466 gen_load_fpr64(ctx, fp1, ft);
11467 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11468 tcg_temp_free_i64(fp1);
11469 gen_store_fpr64(ctx, fp0, fd);
11470 tcg_temp_free_i64(fp0);
11474 check_cp1_registers(ctx, fs | ft | fd);
11476 TCGv_i64 fp0 = tcg_temp_new_i64();
11477 TCGv_i64 fp1 = tcg_temp_new_i64();
11479 gen_load_fpr64(ctx, fp0, fs);
11480 gen_load_fpr64(ctx, fp1, ft);
11481 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11482 tcg_temp_free_i64(fp1);
11483 gen_store_fpr64(ctx, fp0, fd);
11484 tcg_temp_free_i64(fp0);
11488 check_cp1_registers(ctx, fs | ft | fd);
11490 TCGv_i64 fp0 = tcg_temp_new_i64();
11491 TCGv_i64 fp1 = tcg_temp_new_i64();
11493 gen_load_fpr64(ctx, fp0, fs);
11494 gen_load_fpr64(ctx, fp1, ft);
11495 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11496 tcg_temp_free_i64(fp1);
11497 gen_store_fpr64(ctx, fp0, fd);
11498 tcg_temp_free_i64(fp0);
11502 check_cp1_registers(ctx, fs | ft | fd);
11504 TCGv_i64 fp0 = tcg_temp_new_i64();
11505 TCGv_i64 fp1 = tcg_temp_new_i64();
11507 gen_load_fpr64(ctx, fp0, fs);
11508 gen_load_fpr64(ctx, fp1, ft);
11509 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11510 tcg_temp_free_i64(fp1);
11511 gen_store_fpr64(ctx, fp0, fd);
11512 tcg_temp_free_i64(fp0);
11516 check_cp1_registers(ctx, fs | fd);
11518 TCGv_i64 fp0 = tcg_temp_new_i64();
11520 gen_load_fpr64(ctx, fp0, fs);
11521 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11522 gen_store_fpr64(ctx, fp0, fd);
11523 tcg_temp_free_i64(fp0);
11527 check_cp1_registers(ctx, fs | fd);
11529 TCGv_i64 fp0 = tcg_temp_new_i64();
11531 gen_load_fpr64(ctx, fp0, fs);
11532 if (ctx->abs2008) {
11533 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11535 gen_helper_float_abs_d(fp0, fp0);
11537 gen_store_fpr64(ctx, fp0, fd);
11538 tcg_temp_free_i64(fp0);
11542 check_cp1_registers(ctx, fs | fd);
11544 TCGv_i64 fp0 = tcg_temp_new_i64();
11546 gen_load_fpr64(ctx, fp0, fs);
11547 gen_store_fpr64(ctx, fp0, fd);
11548 tcg_temp_free_i64(fp0);
11552 check_cp1_registers(ctx, fs | fd);
11554 TCGv_i64 fp0 = tcg_temp_new_i64();
11556 gen_load_fpr64(ctx, fp0, fs);
11557 if (ctx->abs2008) {
11558 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11560 gen_helper_float_chs_d(fp0, fp0);
11562 gen_store_fpr64(ctx, fp0, fd);
11563 tcg_temp_free_i64(fp0);
11566 case OPC_ROUND_L_D:
11567 check_cp1_64bitmode(ctx);
11569 TCGv_i64 fp0 = tcg_temp_new_i64();
11571 gen_load_fpr64(ctx, fp0, fs);
11572 if (ctx->nan2008) {
11573 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11575 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11577 gen_store_fpr64(ctx, fp0, fd);
11578 tcg_temp_free_i64(fp0);
11581 case OPC_TRUNC_L_D:
11582 check_cp1_64bitmode(ctx);
11584 TCGv_i64 fp0 = tcg_temp_new_i64();
11586 gen_load_fpr64(ctx, fp0, fs);
11587 if (ctx->nan2008) {
11588 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11590 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11592 gen_store_fpr64(ctx, fp0, fd);
11593 tcg_temp_free_i64(fp0);
11597 check_cp1_64bitmode(ctx);
11599 TCGv_i64 fp0 = tcg_temp_new_i64();
11601 gen_load_fpr64(ctx, fp0, fs);
11602 if (ctx->nan2008) {
11603 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11605 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11607 gen_store_fpr64(ctx, fp0, fd);
11608 tcg_temp_free_i64(fp0);
11611 case OPC_FLOOR_L_D:
11612 check_cp1_64bitmode(ctx);
11614 TCGv_i64 fp0 = tcg_temp_new_i64();
11616 gen_load_fpr64(ctx, fp0, fs);
11617 if (ctx->nan2008) {
11618 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11620 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11622 gen_store_fpr64(ctx, fp0, fd);
11623 tcg_temp_free_i64(fp0);
11626 case OPC_ROUND_W_D:
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_round_2008_w_d(fp32, cpu_env, fp64);
11636 gen_helper_float_round_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_TRUNC_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_trunc_2008_w_d(fp32, cpu_env, fp64);
11653 gen_helper_float_trunc_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_cp1_registers(ctx, fs);
11663 TCGv_i32 fp32 = tcg_temp_new_i32();
11664 TCGv_i64 fp64 = tcg_temp_new_i64();
11666 gen_load_fpr64(ctx, fp64, fs);
11667 if (ctx->nan2008) {
11668 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11670 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11672 tcg_temp_free_i64(fp64);
11673 gen_store_fpr32(ctx, fp32, fd);
11674 tcg_temp_free_i32(fp32);
11677 case OPC_FLOOR_W_D:
11678 check_cp1_registers(ctx, fs);
11680 TCGv_i32 fp32 = tcg_temp_new_i32();
11681 TCGv_i64 fp64 = tcg_temp_new_i64();
11683 gen_load_fpr64(ctx, fp64, fs);
11684 if (ctx->nan2008) {
11685 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11687 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11689 tcg_temp_free_i64(fp64);
11690 gen_store_fpr32(ctx, fp32, fd);
11691 tcg_temp_free_i32(fp32);
11695 check_insn(ctx, ISA_MIPS32R6);
11696 gen_sel_d(ctx, op1, fd, ft, fs);
11699 check_insn(ctx, ISA_MIPS32R6);
11700 gen_sel_d(ctx, op1, fd, ft, fs);
11703 check_insn(ctx, ISA_MIPS32R6);
11704 gen_sel_d(ctx, op1, fd, ft, fs);
11707 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11708 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11711 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11713 TCGLabel *l1 = gen_new_label();
11717 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11719 fp0 = tcg_temp_new_i64();
11720 gen_load_fpr64(ctx, fp0, fs);
11721 gen_store_fpr64(ctx, fp0, fd);
11722 tcg_temp_free_i64(fp0);
11727 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11729 TCGLabel *l1 = gen_new_label();
11733 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11734 fp0 = tcg_temp_new_i64();
11735 gen_load_fpr64(ctx, fp0, fs);
11736 gen_store_fpr64(ctx, fp0, fd);
11737 tcg_temp_free_i64(fp0);
11743 check_cp1_registers(ctx, fs | fd);
11745 TCGv_i64 fp0 = tcg_temp_new_i64();
11747 gen_load_fpr64(ctx, fp0, fs);
11748 gen_helper_float_recip_d(fp0, cpu_env, fp0);
11749 gen_store_fpr64(ctx, fp0, fd);
11750 tcg_temp_free_i64(fp0);
11754 check_cp1_registers(ctx, fs | fd);
11756 TCGv_i64 fp0 = tcg_temp_new_i64();
11758 gen_load_fpr64(ctx, fp0, fs);
11759 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11760 gen_store_fpr64(ctx, fp0, fd);
11761 tcg_temp_free_i64(fp0);
11765 check_insn(ctx, ISA_MIPS32R6);
11767 TCGv_i64 fp0 = tcg_temp_new_i64();
11768 TCGv_i64 fp1 = tcg_temp_new_i64();
11769 TCGv_i64 fp2 = tcg_temp_new_i64();
11770 gen_load_fpr64(ctx, fp0, fs);
11771 gen_load_fpr64(ctx, fp1, ft);
11772 gen_load_fpr64(ctx, fp2, fd);
11773 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11774 gen_store_fpr64(ctx, fp2, fd);
11775 tcg_temp_free_i64(fp2);
11776 tcg_temp_free_i64(fp1);
11777 tcg_temp_free_i64(fp0);
11781 check_insn(ctx, ISA_MIPS32R6);
11783 TCGv_i64 fp0 = tcg_temp_new_i64();
11784 TCGv_i64 fp1 = tcg_temp_new_i64();
11785 TCGv_i64 fp2 = tcg_temp_new_i64();
11786 gen_load_fpr64(ctx, fp0, fs);
11787 gen_load_fpr64(ctx, fp1, ft);
11788 gen_load_fpr64(ctx, fp2, fd);
11789 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11790 gen_store_fpr64(ctx, fp2, fd);
11791 tcg_temp_free_i64(fp2);
11792 tcg_temp_free_i64(fp1);
11793 tcg_temp_free_i64(fp0);
11797 check_insn(ctx, ISA_MIPS32R6);
11799 TCGv_i64 fp0 = tcg_temp_new_i64();
11800 gen_load_fpr64(ctx, fp0, fs);
11801 gen_helper_float_rint_d(fp0, cpu_env, fp0);
11802 gen_store_fpr64(ctx, fp0, fd);
11803 tcg_temp_free_i64(fp0);
11807 check_insn(ctx, ISA_MIPS32R6);
11809 TCGv_i64 fp0 = tcg_temp_new_i64();
11810 gen_load_fpr64(ctx, fp0, fs);
11811 gen_helper_float_class_d(fp0, cpu_env, fp0);
11812 gen_store_fpr64(ctx, fp0, fd);
11813 tcg_temp_free_i64(fp0);
11816 case OPC_MIN_D: /* OPC_RECIP2_D */
11817 if (ctx->insn_flags & ISA_MIPS32R6) {
11819 TCGv_i64 fp0 = tcg_temp_new_i64();
11820 TCGv_i64 fp1 = tcg_temp_new_i64();
11821 gen_load_fpr64(ctx, fp0, fs);
11822 gen_load_fpr64(ctx, fp1, ft);
11823 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11824 gen_store_fpr64(ctx, fp1, fd);
11825 tcg_temp_free_i64(fp1);
11826 tcg_temp_free_i64(fp0);
11829 check_cp1_64bitmode(ctx);
11831 TCGv_i64 fp0 = tcg_temp_new_i64();
11832 TCGv_i64 fp1 = tcg_temp_new_i64();
11834 gen_load_fpr64(ctx, fp0, fs);
11835 gen_load_fpr64(ctx, fp1, ft);
11836 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11837 tcg_temp_free_i64(fp1);
11838 gen_store_fpr64(ctx, fp0, fd);
11839 tcg_temp_free_i64(fp0);
11843 case OPC_MINA_D: /* OPC_RECIP1_D */
11844 if (ctx->insn_flags & ISA_MIPS32R6) {
11846 TCGv_i64 fp0 = tcg_temp_new_i64();
11847 TCGv_i64 fp1 = tcg_temp_new_i64();
11848 gen_load_fpr64(ctx, fp0, fs);
11849 gen_load_fpr64(ctx, fp1, ft);
11850 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11851 gen_store_fpr64(ctx, fp1, fd);
11852 tcg_temp_free_i64(fp1);
11853 tcg_temp_free_i64(fp0);
11856 check_cp1_64bitmode(ctx);
11858 TCGv_i64 fp0 = tcg_temp_new_i64();
11860 gen_load_fpr64(ctx, fp0, fs);
11861 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11862 gen_store_fpr64(ctx, fp0, fd);
11863 tcg_temp_free_i64(fp0);
11867 case OPC_MAX_D: /* OPC_RSQRT1_D */
11868 if (ctx->insn_flags & ISA_MIPS32R6) {
11870 TCGv_i64 fp0 = tcg_temp_new_i64();
11871 TCGv_i64 fp1 = tcg_temp_new_i64();
11872 gen_load_fpr64(ctx, fp0, fs);
11873 gen_load_fpr64(ctx, fp1, ft);
11874 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11875 gen_store_fpr64(ctx, fp1, fd);
11876 tcg_temp_free_i64(fp1);
11877 tcg_temp_free_i64(fp0);
11880 check_cp1_64bitmode(ctx);
11882 TCGv_i64 fp0 = tcg_temp_new_i64();
11884 gen_load_fpr64(ctx, fp0, fs);
11885 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11886 gen_store_fpr64(ctx, fp0, fd);
11887 tcg_temp_free_i64(fp0);
11891 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11892 if (ctx->insn_flags & ISA_MIPS32R6) {
11894 TCGv_i64 fp0 = tcg_temp_new_i64();
11895 TCGv_i64 fp1 = tcg_temp_new_i64();
11896 gen_load_fpr64(ctx, fp0, fs);
11897 gen_load_fpr64(ctx, fp1, ft);
11898 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11899 gen_store_fpr64(ctx, fp1, fd);
11900 tcg_temp_free_i64(fp1);
11901 tcg_temp_free_i64(fp0);
11904 check_cp1_64bitmode(ctx);
11906 TCGv_i64 fp0 = tcg_temp_new_i64();
11907 TCGv_i64 fp1 = tcg_temp_new_i64();
11909 gen_load_fpr64(ctx, fp0, fs);
11910 gen_load_fpr64(ctx, fp1, ft);
11911 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11912 tcg_temp_free_i64(fp1);
11913 gen_store_fpr64(ctx, fp0, fd);
11914 tcg_temp_free_i64(fp0);
11921 case OPC_CMP_UEQ_D:
11922 case OPC_CMP_OLT_D:
11923 case OPC_CMP_ULT_D:
11924 case OPC_CMP_OLE_D:
11925 case OPC_CMP_ULE_D:
11927 case OPC_CMP_NGLE_D:
11928 case OPC_CMP_SEQ_D:
11929 case OPC_CMP_NGL_D:
11931 case OPC_CMP_NGE_D:
11933 case OPC_CMP_NGT_D:
11934 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11935 if (ctx->opcode & (1 << 6)) {
11936 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11938 gen_cmp_d(ctx, func-48, ft, fs, cc);
11942 check_cp1_registers(ctx, fs);
11944 TCGv_i32 fp32 = tcg_temp_new_i32();
11945 TCGv_i64 fp64 = tcg_temp_new_i64();
11947 gen_load_fpr64(ctx, fp64, fs);
11948 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11949 tcg_temp_free_i64(fp64);
11950 gen_store_fpr32(ctx, fp32, fd);
11951 tcg_temp_free_i32(fp32);
11955 check_cp1_registers(ctx, fs);
11957 TCGv_i32 fp32 = tcg_temp_new_i32();
11958 TCGv_i64 fp64 = tcg_temp_new_i64();
11960 gen_load_fpr64(ctx, fp64, fs);
11961 if (ctx->nan2008) {
11962 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11964 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11966 tcg_temp_free_i64(fp64);
11967 gen_store_fpr32(ctx, fp32, fd);
11968 tcg_temp_free_i32(fp32);
11972 check_cp1_64bitmode(ctx);
11974 TCGv_i64 fp0 = tcg_temp_new_i64();
11976 gen_load_fpr64(ctx, fp0, fs);
11977 if (ctx->nan2008) {
11978 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11980 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11982 gen_store_fpr64(ctx, fp0, fd);
11983 tcg_temp_free_i64(fp0);
11988 TCGv_i32 fp0 = tcg_temp_new_i32();
11990 gen_load_fpr32(ctx, fp0, fs);
11991 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11992 gen_store_fpr32(ctx, fp0, fd);
11993 tcg_temp_free_i32(fp0);
11997 check_cp1_registers(ctx, fd);
11999 TCGv_i32 fp32 = tcg_temp_new_i32();
12000 TCGv_i64 fp64 = tcg_temp_new_i64();
12002 gen_load_fpr32(ctx, fp32, fs);
12003 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
12004 tcg_temp_free_i32(fp32);
12005 gen_store_fpr64(ctx, fp64, fd);
12006 tcg_temp_free_i64(fp64);
12010 check_cp1_64bitmode(ctx);
12012 TCGv_i32 fp32 = tcg_temp_new_i32();
12013 TCGv_i64 fp64 = tcg_temp_new_i64();
12015 gen_load_fpr64(ctx, fp64, fs);
12016 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
12017 tcg_temp_free_i64(fp64);
12018 gen_store_fpr32(ctx, fp32, fd);
12019 tcg_temp_free_i32(fp32);
12023 check_cp1_64bitmode(ctx);
12025 TCGv_i64 fp0 = tcg_temp_new_i64();
12027 gen_load_fpr64(ctx, fp0, fs);
12028 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
12029 gen_store_fpr64(ctx, fp0, fd);
12030 tcg_temp_free_i64(fp0);
12033 case OPC_CVT_PS_PW:
12036 TCGv_i64 fp0 = tcg_temp_new_i64();
12038 gen_load_fpr64(ctx, fp0, fs);
12039 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12040 gen_store_fpr64(ctx, fp0, fd);
12041 tcg_temp_free_i64(fp0);
12047 TCGv_i64 fp0 = tcg_temp_new_i64();
12048 TCGv_i64 fp1 = tcg_temp_new_i64();
12050 gen_load_fpr64(ctx, fp0, fs);
12051 gen_load_fpr64(ctx, fp1, ft);
12052 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12053 tcg_temp_free_i64(fp1);
12054 gen_store_fpr64(ctx, fp0, fd);
12055 tcg_temp_free_i64(fp0);
12061 TCGv_i64 fp0 = tcg_temp_new_i64();
12062 TCGv_i64 fp1 = tcg_temp_new_i64();
12064 gen_load_fpr64(ctx, fp0, fs);
12065 gen_load_fpr64(ctx, fp1, ft);
12066 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12067 tcg_temp_free_i64(fp1);
12068 gen_store_fpr64(ctx, fp0, fd);
12069 tcg_temp_free_i64(fp0);
12075 TCGv_i64 fp0 = tcg_temp_new_i64();
12076 TCGv_i64 fp1 = tcg_temp_new_i64();
12078 gen_load_fpr64(ctx, fp0, fs);
12079 gen_load_fpr64(ctx, fp1, ft);
12080 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12081 tcg_temp_free_i64(fp1);
12082 gen_store_fpr64(ctx, fp0, fd);
12083 tcg_temp_free_i64(fp0);
12089 TCGv_i64 fp0 = tcg_temp_new_i64();
12091 gen_load_fpr64(ctx, fp0, fs);
12092 gen_helper_float_abs_ps(fp0, fp0);
12093 gen_store_fpr64(ctx, fp0, fd);
12094 tcg_temp_free_i64(fp0);
12100 TCGv_i64 fp0 = tcg_temp_new_i64();
12102 gen_load_fpr64(ctx, fp0, fs);
12103 gen_store_fpr64(ctx, fp0, fd);
12104 tcg_temp_free_i64(fp0);
12110 TCGv_i64 fp0 = tcg_temp_new_i64();
12112 gen_load_fpr64(ctx, fp0, fs);
12113 gen_helper_float_chs_ps(fp0, fp0);
12114 gen_store_fpr64(ctx, fp0, fd);
12115 tcg_temp_free_i64(fp0);
12120 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12125 TCGLabel *l1 = gen_new_label();
12129 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12130 fp0 = tcg_temp_new_i64();
12131 gen_load_fpr64(ctx, fp0, fs);
12132 gen_store_fpr64(ctx, fp0, fd);
12133 tcg_temp_free_i64(fp0);
12140 TCGLabel *l1 = gen_new_label();
12144 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12145 fp0 = tcg_temp_new_i64();
12146 gen_load_fpr64(ctx, fp0, fs);
12147 gen_store_fpr64(ctx, fp0, fd);
12148 tcg_temp_free_i64(fp0);
12156 TCGv_i64 fp0 = tcg_temp_new_i64();
12157 TCGv_i64 fp1 = tcg_temp_new_i64();
12159 gen_load_fpr64(ctx, fp0, ft);
12160 gen_load_fpr64(ctx, fp1, fs);
12161 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12162 tcg_temp_free_i64(fp1);
12163 gen_store_fpr64(ctx, fp0, fd);
12164 tcg_temp_free_i64(fp0);
12170 TCGv_i64 fp0 = tcg_temp_new_i64();
12171 TCGv_i64 fp1 = tcg_temp_new_i64();
12173 gen_load_fpr64(ctx, fp0, ft);
12174 gen_load_fpr64(ctx, fp1, fs);
12175 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12176 tcg_temp_free_i64(fp1);
12177 gen_store_fpr64(ctx, fp0, fd);
12178 tcg_temp_free_i64(fp0);
12181 case OPC_RECIP2_PS:
12184 TCGv_i64 fp0 = tcg_temp_new_i64();
12185 TCGv_i64 fp1 = tcg_temp_new_i64();
12187 gen_load_fpr64(ctx, fp0, fs);
12188 gen_load_fpr64(ctx, fp1, ft);
12189 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12190 tcg_temp_free_i64(fp1);
12191 gen_store_fpr64(ctx, fp0, fd);
12192 tcg_temp_free_i64(fp0);
12195 case OPC_RECIP1_PS:
12198 TCGv_i64 fp0 = tcg_temp_new_i64();
12200 gen_load_fpr64(ctx, fp0, fs);
12201 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12202 gen_store_fpr64(ctx, fp0, fd);
12203 tcg_temp_free_i64(fp0);
12206 case OPC_RSQRT1_PS:
12209 TCGv_i64 fp0 = tcg_temp_new_i64();
12211 gen_load_fpr64(ctx, fp0, fs);
12212 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12213 gen_store_fpr64(ctx, fp0, fd);
12214 tcg_temp_free_i64(fp0);
12217 case OPC_RSQRT2_PS:
12220 TCGv_i64 fp0 = tcg_temp_new_i64();
12221 TCGv_i64 fp1 = tcg_temp_new_i64();
12223 gen_load_fpr64(ctx, fp0, fs);
12224 gen_load_fpr64(ctx, fp1, ft);
12225 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12226 tcg_temp_free_i64(fp1);
12227 gen_store_fpr64(ctx, fp0, fd);
12228 tcg_temp_free_i64(fp0);
12232 check_cp1_64bitmode(ctx);
12234 TCGv_i32 fp0 = tcg_temp_new_i32();
12236 gen_load_fpr32h(ctx, fp0, fs);
12237 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12238 gen_store_fpr32(ctx, fp0, fd);
12239 tcg_temp_free_i32(fp0);
12242 case OPC_CVT_PW_PS:
12245 TCGv_i64 fp0 = tcg_temp_new_i64();
12247 gen_load_fpr64(ctx, fp0, fs);
12248 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12249 gen_store_fpr64(ctx, fp0, fd);
12250 tcg_temp_free_i64(fp0);
12254 check_cp1_64bitmode(ctx);
12256 TCGv_i32 fp0 = tcg_temp_new_i32();
12258 gen_load_fpr32(ctx, fp0, fs);
12259 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12260 gen_store_fpr32(ctx, fp0, fd);
12261 tcg_temp_free_i32(fp0);
12267 TCGv_i32 fp0 = tcg_temp_new_i32();
12268 TCGv_i32 fp1 = tcg_temp_new_i32();
12270 gen_load_fpr32(ctx, fp0, fs);
12271 gen_load_fpr32(ctx, fp1, ft);
12272 gen_store_fpr32h(ctx, fp0, fd);
12273 gen_store_fpr32(ctx, fp1, fd);
12274 tcg_temp_free_i32(fp0);
12275 tcg_temp_free_i32(fp1);
12281 TCGv_i32 fp0 = tcg_temp_new_i32();
12282 TCGv_i32 fp1 = tcg_temp_new_i32();
12284 gen_load_fpr32(ctx, fp0, fs);
12285 gen_load_fpr32h(ctx, fp1, ft);
12286 gen_store_fpr32(ctx, fp1, fd);
12287 gen_store_fpr32h(ctx, fp0, fd);
12288 tcg_temp_free_i32(fp0);
12289 tcg_temp_free_i32(fp1);
12295 TCGv_i32 fp0 = tcg_temp_new_i32();
12296 TCGv_i32 fp1 = tcg_temp_new_i32();
12298 gen_load_fpr32h(ctx, fp0, fs);
12299 gen_load_fpr32(ctx, fp1, ft);
12300 gen_store_fpr32(ctx, fp1, fd);
12301 gen_store_fpr32h(ctx, fp0, fd);
12302 tcg_temp_free_i32(fp0);
12303 tcg_temp_free_i32(fp1);
12309 TCGv_i32 fp0 = tcg_temp_new_i32();
12310 TCGv_i32 fp1 = tcg_temp_new_i32();
12312 gen_load_fpr32h(ctx, fp0, fs);
12313 gen_load_fpr32h(ctx, fp1, ft);
12314 gen_store_fpr32(ctx, fp1, fd);
12315 gen_store_fpr32h(ctx, fp0, fd);
12316 tcg_temp_free_i32(fp0);
12317 tcg_temp_free_i32(fp1);
12321 case OPC_CMP_UN_PS:
12322 case OPC_CMP_EQ_PS:
12323 case OPC_CMP_UEQ_PS:
12324 case OPC_CMP_OLT_PS:
12325 case OPC_CMP_ULT_PS:
12326 case OPC_CMP_OLE_PS:
12327 case OPC_CMP_ULE_PS:
12328 case OPC_CMP_SF_PS:
12329 case OPC_CMP_NGLE_PS:
12330 case OPC_CMP_SEQ_PS:
12331 case OPC_CMP_NGL_PS:
12332 case OPC_CMP_LT_PS:
12333 case OPC_CMP_NGE_PS:
12334 case OPC_CMP_LE_PS:
12335 case OPC_CMP_NGT_PS:
12336 if (ctx->opcode & (1 << 6)) {
12337 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12339 gen_cmp_ps(ctx, func-48, ft, fs, cc);
12343 MIPS_INVAL("farith");
12344 generate_exception_end(ctx, EXCP_RI);
12349 /* Coprocessor 3 (FPU) */
12350 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12351 int fd, int fs, int base, int index)
12353 TCGv t0 = tcg_temp_new();
12356 gen_load_gpr(t0, index);
12357 } else if (index == 0) {
12358 gen_load_gpr(t0, base);
12360 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12362 /* Don't do NOP if destination is zero: we must perform the actual
12368 TCGv_i32 fp0 = tcg_temp_new_i32();
12370 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12371 tcg_gen_trunc_tl_i32(fp0, t0);
12372 gen_store_fpr32(ctx, fp0, fd);
12373 tcg_temp_free_i32(fp0);
12378 check_cp1_registers(ctx, fd);
12380 TCGv_i64 fp0 = tcg_temp_new_i64();
12381 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12382 gen_store_fpr64(ctx, fp0, fd);
12383 tcg_temp_free_i64(fp0);
12387 check_cp1_64bitmode(ctx);
12388 tcg_gen_andi_tl(t0, t0, ~0x7);
12390 TCGv_i64 fp0 = tcg_temp_new_i64();
12392 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12393 gen_store_fpr64(ctx, fp0, fd);
12394 tcg_temp_free_i64(fp0);
12400 TCGv_i32 fp0 = tcg_temp_new_i32();
12401 gen_load_fpr32(ctx, fp0, fs);
12402 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12403 tcg_temp_free_i32(fp0);
12408 check_cp1_registers(ctx, fs);
12410 TCGv_i64 fp0 = tcg_temp_new_i64();
12411 gen_load_fpr64(ctx, fp0, fs);
12412 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12413 tcg_temp_free_i64(fp0);
12417 check_cp1_64bitmode(ctx);
12418 tcg_gen_andi_tl(t0, t0, ~0x7);
12420 TCGv_i64 fp0 = tcg_temp_new_i64();
12421 gen_load_fpr64(ctx, fp0, fs);
12422 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12423 tcg_temp_free_i64(fp0);
12430 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12431 int fd, int fr, int fs, int ft)
12437 TCGv t0 = tcg_temp_local_new();
12438 TCGv_i32 fp = tcg_temp_new_i32();
12439 TCGv_i32 fph = tcg_temp_new_i32();
12440 TCGLabel *l1 = gen_new_label();
12441 TCGLabel *l2 = gen_new_label();
12443 gen_load_gpr(t0, fr);
12444 tcg_gen_andi_tl(t0, t0, 0x7);
12446 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12447 gen_load_fpr32(ctx, fp, fs);
12448 gen_load_fpr32h(ctx, fph, fs);
12449 gen_store_fpr32(ctx, fp, fd);
12450 gen_store_fpr32h(ctx, fph, fd);
12453 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12455 #ifdef TARGET_WORDS_BIGENDIAN
12456 gen_load_fpr32(ctx, fp, fs);
12457 gen_load_fpr32h(ctx, fph, ft);
12458 gen_store_fpr32h(ctx, fp, fd);
12459 gen_store_fpr32(ctx, fph, fd);
12461 gen_load_fpr32h(ctx, fph, fs);
12462 gen_load_fpr32(ctx, fp, ft);
12463 gen_store_fpr32(ctx, fph, fd);
12464 gen_store_fpr32h(ctx, fp, fd);
12467 tcg_temp_free_i32(fp);
12468 tcg_temp_free_i32(fph);
12474 TCGv_i32 fp0 = tcg_temp_new_i32();
12475 TCGv_i32 fp1 = tcg_temp_new_i32();
12476 TCGv_i32 fp2 = tcg_temp_new_i32();
12478 gen_load_fpr32(ctx, fp0, fs);
12479 gen_load_fpr32(ctx, fp1, ft);
12480 gen_load_fpr32(ctx, fp2, fr);
12481 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12482 tcg_temp_free_i32(fp0);
12483 tcg_temp_free_i32(fp1);
12484 gen_store_fpr32(ctx, fp2, fd);
12485 tcg_temp_free_i32(fp2);
12490 check_cp1_registers(ctx, fd | fs | ft | fr);
12492 TCGv_i64 fp0 = tcg_temp_new_i64();
12493 TCGv_i64 fp1 = tcg_temp_new_i64();
12494 TCGv_i64 fp2 = tcg_temp_new_i64();
12496 gen_load_fpr64(ctx, fp0, fs);
12497 gen_load_fpr64(ctx, fp1, ft);
12498 gen_load_fpr64(ctx, fp2, fr);
12499 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12500 tcg_temp_free_i64(fp0);
12501 tcg_temp_free_i64(fp1);
12502 gen_store_fpr64(ctx, fp2, fd);
12503 tcg_temp_free_i64(fp2);
12509 TCGv_i64 fp0 = tcg_temp_new_i64();
12510 TCGv_i64 fp1 = tcg_temp_new_i64();
12511 TCGv_i64 fp2 = tcg_temp_new_i64();
12513 gen_load_fpr64(ctx, fp0, fs);
12514 gen_load_fpr64(ctx, fp1, ft);
12515 gen_load_fpr64(ctx, fp2, fr);
12516 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12517 tcg_temp_free_i64(fp0);
12518 tcg_temp_free_i64(fp1);
12519 gen_store_fpr64(ctx, fp2, fd);
12520 tcg_temp_free_i64(fp2);
12526 TCGv_i32 fp0 = tcg_temp_new_i32();
12527 TCGv_i32 fp1 = tcg_temp_new_i32();
12528 TCGv_i32 fp2 = tcg_temp_new_i32();
12530 gen_load_fpr32(ctx, fp0, fs);
12531 gen_load_fpr32(ctx, fp1, ft);
12532 gen_load_fpr32(ctx, fp2, fr);
12533 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12534 tcg_temp_free_i32(fp0);
12535 tcg_temp_free_i32(fp1);
12536 gen_store_fpr32(ctx, fp2, fd);
12537 tcg_temp_free_i32(fp2);
12542 check_cp1_registers(ctx, fd | fs | ft | fr);
12544 TCGv_i64 fp0 = tcg_temp_new_i64();
12545 TCGv_i64 fp1 = tcg_temp_new_i64();
12546 TCGv_i64 fp2 = tcg_temp_new_i64();
12548 gen_load_fpr64(ctx, fp0, fs);
12549 gen_load_fpr64(ctx, fp1, ft);
12550 gen_load_fpr64(ctx, fp2, fr);
12551 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12552 tcg_temp_free_i64(fp0);
12553 tcg_temp_free_i64(fp1);
12554 gen_store_fpr64(ctx, fp2, fd);
12555 tcg_temp_free_i64(fp2);
12561 TCGv_i64 fp0 = tcg_temp_new_i64();
12562 TCGv_i64 fp1 = tcg_temp_new_i64();
12563 TCGv_i64 fp2 = tcg_temp_new_i64();
12565 gen_load_fpr64(ctx, fp0, fs);
12566 gen_load_fpr64(ctx, fp1, ft);
12567 gen_load_fpr64(ctx, fp2, fr);
12568 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12569 tcg_temp_free_i64(fp0);
12570 tcg_temp_free_i64(fp1);
12571 gen_store_fpr64(ctx, fp2, fd);
12572 tcg_temp_free_i64(fp2);
12578 TCGv_i32 fp0 = tcg_temp_new_i32();
12579 TCGv_i32 fp1 = tcg_temp_new_i32();
12580 TCGv_i32 fp2 = tcg_temp_new_i32();
12582 gen_load_fpr32(ctx, fp0, fs);
12583 gen_load_fpr32(ctx, fp1, ft);
12584 gen_load_fpr32(ctx, fp2, fr);
12585 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12586 tcg_temp_free_i32(fp0);
12587 tcg_temp_free_i32(fp1);
12588 gen_store_fpr32(ctx, fp2, fd);
12589 tcg_temp_free_i32(fp2);
12594 check_cp1_registers(ctx, fd | fs | ft | fr);
12596 TCGv_i64 fp0 = tcg_temp_new_i64();
12597 TCGv_i64 fp1 = tcg_temp_new_i64();
12598 TCGv_i64 fp2 = tcg_temp_new_i64();
12600 gen_load_fpr64(ctx, fp0, fs);
12601 gen_load_fpr64(ctx, fp1, ft);
12602 gen_load_fpr64(ctx, fp2, fr);
12603 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12604 tcg_temp_free_i64(fp0);
12605 tcg_temp_free_i64(fp1);
12606 gen_store_fpr64(ctx, fp2, fd);
12607 tcg_temp_free_i64(fp2);
12613 TCGv_i64 fp0 = tcg_temp_new_i64();
12614 TCGv_i64 fp1 = tcg_temp_new_i64();
12615 TCGv_i64 fp2 = tcg_temp_new_i64();
12617 gen_load_fpr64(ctx, fp0, fs);
12618 gen_load_fpr64(ctx, fp1, ft);
12619 gen_load_fpr64(ctx, fp2, fr);
12620 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12621 tcg_temp_free_i64(fp0);
12622 tcg_temp_free_i64(fp1);
12623 gen_store_fpr64(ctx, fp2, fd);
12624 tcg_temp_free_i64(fp2);
12630 TCGv_i32 fp0 = tcg_temp_new_i32();
12631 TCGv_i32 fp1 = tcg_temp_new_i32();
12632 TCGv_i32 fp2 = tcg_temp_new_i32();
12634 gen_load_fpr32(ctx, fp0, fs);
12635 gen_load_fpr32(ctx, fp1, ft);
12636 gen_load_fpr32(ctx, fp2, fr);
12637 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12638 tcg_temp_free_i32(fp0);
12639 tcg_temp_free_i32(fp1);
12640 gen_store_fpr32(ctx, fp2, fd);
12641 tcg_temp_free_i32(fp2);
12646 check_cp1_registers(ctx, fd | fs | ft | fr);
12648 TCGv_i64 fp0 = tcg_temp_new_i64();
12649 TCGv_i64 fp1 = tcg_temp_new_i64();
12650 TCGv_i64 fp2 = tcg_temp_new_i64();
12652 gen_load_fpr64(ctx, fp0, fs);
12653 gen_load_fpr64(ctx, fp1, ft);
12654 gen_load_fpr64(ctx, fp2, fr);
12655 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12656 tcg_temp_free_i64(fp0);
12657 tcg_temp_free_i64(fp1);
12658 gen_store_fpr64(ctx, fp2, fd);
12659 tcg_temp_free_i64(fp2);
12665 TCGv_i64 fp0 = tcg_temp_new_i64();
12666 TCGv_i64 fp1 = tcg_temp_new_i64();
12667 TCGv_i64 fp2 = tcg_temp_new_i64();
12669 gen_load_fpr64(ctx, fp0, fs);
12670 gen_load_fpr64(ctx, fp1, ft);
12671 gen_load_fpr64(ctx, fp2, fr);
12672 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12673 tcg_temp_free_i64(fp0);
12674 tcg_temp_free_i64(fp1);
12675 gen_store_fpr64(ctx, fp2, fd);
12676 tcg_temp_free_i64(fp2);
12680 MIPS_INVAL("flt3_arith");
12681 generate_exception_end(ctx, EXCP_RI);
12686 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12690 #if !defined(CONFIG_USER_ONLY)
12691 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12692 Therefore only check the ISA in system mode. */
12693 check_insn(ctx, ISA_MIPS32R2);
12695 t0 = tcg_temp_new();
12699 gen_helper_rdhwr_cpunum(t0, cpu_env);
12700 gen_store_gpr(t0, rt);
12703 gen_helper_rdhwr_synci_step(t0, cpu_env);
12704 gen_store_gpr(t0, rt);
12707 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12710 gen_helper_rdhwr_cc(t0, cpu_env);
12711 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12714 gen_store_gpr(t0, rt);
12715 /* Break the TB to be able to take timer interrupts immediately
12716 after reading count. DISAS_STOP isn't sufficient, we need to ensure
12717 we break completely out of translated code. */
12718 gen_save_pc(ctx->base.pc_next + 4);
12719 ctx->base.is_jmp = DISAS_EXIT;
12722 gen_helper_rdhwr_ccres(t0, cpu_env);
12723 gen_store_gpr(t0, rt);
12726 check_insn(ctx, ISA_MIPS32R6);
12728 /* Performance counter registers are not implemented other than
12729 * control register 0.
12731 generate_exception(ctx, EXCP_RI);
12733 gen_helper_rdhwr_performance(t0, cpu_env);
12734 gen_store_gpr(t0, rt);
12737 check_insn(ctx, ISA_MIPS32R6);
12738 gen_helper_rdhwr_xnp(t0, cpu_env);
12739 gen_store_gpr(t0, rt);
12742 #if defined(CONFIG_USER_ONLY)
12743 tcg_gen_ld_tl(t0, cpu_env,
12744 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12745 gen_store_gpr(t0, rt);
12748 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12749 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12750 tcg_gen_ld_tl(t0, cpu_env,
12751 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12752 gen_store_gpr(t0, rt);
12754 generate_exception_end(ctx, EXCP_RI);
12758 default: /* Invalid */
12759 MIPS_INVAL("rdhwr");
12760 generate_exception_end(ctx, EXCP_RI);
12766 static inline void clear_branch_hflags(DisasContext *ctx)
12768 ctx->hflags &= ~MIPS_HFLAG_BMASK;
12769 if (ctx->base.is_jmp == DISAS_NEXT) {
12770 save_cpu_state(ctx, 0);
12772 /* it is not safe to save ctx->hflags as hflags may be changed
12773 in execution time by the instruction in delay / forbidden slot. */
12774 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12778 static void gen_branch(DisasContext *ctx, int insn_bytes)
12780 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12781 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12782 /* Branches completion */
12783 clear_branch_hflags(ctx);
12784 ctx->base.is_jmp = DISAS_NORETURN;
12785 /* FIXME: Need to clear can_do_io. */
12786 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12787 case MIPS_HFLAG_FBNSLOT:
12788 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12791 /* unconditional branch */
12792 if (proc_hflags & MIPS_HFLAG_BX) {
12793 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12795 gen_goto_tb(ctx, 0, ctx->btarget);
12797 case MIPS_HFLAG_BL:
12798 /* blikely taken case */
12799 gen_goto_tb(ctx, 0, ctx->btarget);
12801 case MIPS_HFLAG_BC:
12802 /* Conditional branch */
12804 TCGLabel *l1 = gen_new_label();
12806 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12807 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12809 gen_goto_tb(ctx, 0, ctx->btarget);
12812 case MIPS_HFLAG_BR:
12813 /* unconditional branch to register */
12814 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12815 TCGv t0 = tcg_temp_new();
12816 TCGv_i32 t1 = tcg_temp_new_i32();
12818 tcg_gen_andi_tl(t0, btarget, 0x1);
12819 tcg_gen_trunc_tl_i32(t1, t0);
12821 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12822 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12823 tcg_gen_or_i32(hflags, hflags, t1);
12824 tcg_temp_free_i32(t1);
12826 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12828 tcg_gen_mov_tl(cpu_PC, btarget);
12830 if (ctx->base.singlestep_enabled) {
12831 save_cpu_state(ctx, 0);
12832 gen_helper_raise_exception_debug(cpu_env);
12834 tcg_gen_lookup_and_goto_ptr();
12837 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12843 /* Compact Branches */
12844 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12845 int rs, int rt, int32_t offset)
12847 int bcond_compute = 0;
12848 TCGv t0 = tcg_temp_new();
12849 TCGv t1 = tcg_temp_new();
12850 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12852 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12853 #ifdef MIPS_DEBUG_DISAS
12854 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12855 "\n", ctx->base.pc_next);
12857 generate_exception_end(ctx, EXCP_RI);
12861 /* Load needed operands and calculate btarget */
12863 /* compact branch */
12864 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12865 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12866 gen_load_gpr(t0, rs);
12867 gen_load_gpr(t1, rt);
12869 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12870 if (rs <= rt && rs == 0) {
12871 /* OPC_BEQZALC, OPC_BNEZALC */
12872 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12875 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12876 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12877 gen_load_gpr(t0, rs);
12878 gen_load_gpr(t1, rt);
12880 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12882 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12883 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12884 if (rs == 0 || rs == rt) {
12885 /* OPC_BLEZALC, OPC_BGEZALC */
12886 /* OPC_BGTZALC, OPC_BLTZALC */
12887 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12889 gen_load_gpr(t0, rs);
12890 gen_load_gpr(t1, rt);
12892 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12896 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12901 /* OPC_BEQZC, OPC_BNEZC */
12902 gen_load_gpr(t0, rs);
12904 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12906 /* OPC_JIC, OPC_JIALC */
12907 TCGv tbase = tcg_temp_new();
12908 TCGv toffset = tcg_temp_new();
12910 gen_load_gpr(tbase, rt);
12911 tcg_gen_movi_tl(toffset, offset);
12912 gen_op_addr_add(ctx, btarget, tbase, toffset);
12913 tcg_temp_free(tbase);
12914 tcg_temp_free(toffset);
12918 MIPS_INVAL("Compact branch/jump");
12919 generate_exception_end(ctx, EXCP_RI);
12923 if (bcond_compute == 0) {
12924 /* Uncoditional compact branch */
12927 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12930 ctx->hflags |= MIPS_HFLAG_BR;
12933 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12936 ctx->hflags |= MIPS_HFLAG_B;
12939 MIPS_INVAL("Compact branch/jump");
12940 generate_exception_end(ctx, EXCP_RI);
12944 /* Generating branch here as compact branches don't have delay slot */
12945 gen_branch(ctx, 4);
12947 /* Conditional compact branch */
12948 TCGLabel *fs = gen_new_label();
12949 save_cpu_state(ctx, 0);
12952 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12953 if (rs == 0 && rt != 0) {
12955 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12956 } else if (rs != 0 && rt != 0 && rs == rt) {
12958 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12961 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12964 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12965 if (rs == 0 && rt != 0) {
12967 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12968 } else if (rs != 0 && rt != 0 && rs == rt) {
12970 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12973 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12976 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12977 if (rs == 0 && rt != 0) {
12979 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12980 } else if (rs != 0 && rt != 0 && rs == rt) {
12982 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12985 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12988 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12989 if (rs == 0 && rt != 0) {
12991 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12992 } else if (rs != 0 && rt != 0 && rs == rt) {
12994 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12997 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
13000 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13001 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13003 /* OPC_BOVC, OPC_BNVC */
13004 TCGv t2 = tcg_temp_new();
13005 TCGv t3 = tcg_temp_new();
13006 TCGv t4 = tcg_temp_new();
13007 TCGv input_overflow = tcg_temp_new();
13009 gen_load_gpr(t0, rs);
13010 gen_load_gpr(t1, rt);
13011 tcg_gen_ext32s_tl(t2, t0);
13012 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
13013 tcg_gen_ext32s_tl(t3, t1);
13014 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
13015 tcg_gen_or_tl(input_overflow, input_overflow, t4);
13017 tcg_gen_add_tl(t4, t2, t3);
13018 tcg_gen_ext32s_tl(t4, t4);
13019 tcg_gen_xor_tl(t2, t2, t3);
13020 tcg_gen_xor_tl(t3, t4, t3);
13021 tcg_gen_andc_tl(t2, t3, t2);
13022 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
13023 tcg_gen_or_tl(t4, t4, input_overflow);
13024 if (opc == OPC_BOVC) {
13026 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
13029 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
13031 tcg_temp_free(input_overflow);
13035 } else if (rs < rt && rs == 0) {
13036 /* OPC_BEQZALC, OPC_BNEZALC */
13037 if (opc == OPC_BEQZALC) {
13039 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13042 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13045 /* OPC_BEQC, OPC_BNEC */
13046 if (opc == OPC_BEQC) {
13048 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13051 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13056 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13059 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13062 MIPS_INVAL("Compact conditional branch/jump");
13063 generate_exception_end(ctx, EXCP_RI);
13067 /* Generating branch here as compact branches don't have delay slot */
13068 gen_goto_tb(ctx, 1, ctx->btarget);
13071 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13079 /* ISA extensions (ASEs) */
13080 /* MIPS16 extension to MIPS32 */
13082 /* MIPS16 major opcodes */
13084 M16_OPC_ADDIUSP = 0x00,
13085 M16_OPC_ADDIUPC = 0x01,
13087 M16_OPC_JAL = 0x03,
13088 M16_OPC_BEQZ = 0x04,
13089 M16_OPC_BNEQZ = 0x05,
13090 M16_OPC_SHIFT = 0x06,
13092 M16_OPC_RRIA = 0x08,
13093 M16_OPC_ADDIU8 = 0x09,
13094 M16_OPC_SLTI = 0x0a,
13095 M16_OPC_SLTIU = 0x0b,
13098 M16_OPC_CMPI = 0x0e,
13102 M16_OPC_LWSP = 0x12,
13104 M16_OPC_LBU = 0x14,
13105 M16_OPC_LHU = 0x15,
13106 M16_OPC_LWPC = 0x16,
13107 M16_OPC_LWU = 0x17,
13110 M16_OPC_SWSP = 0x1a,
13112 M16_OPC_RRR = 0x1c,
13114 M16_OPC_EXTEND = 0x1e,
13118 /* I8 funct field */
13137 /* RR funct field */
13171 /* I64 funct field */
13179 I64_DADDIUPC = 0x6,
13183 /* RR ry field for CNVT */
13185 RR_RY_CNVT_ZEB = 0x0,
13186 RR_RY_CNVT_ZEH = 0x1,
13187 RR_RY_CNVT_ZEW = 0x2,
13188 RR_RY_CNVT_SEB = 0x4,
13189 RR_RY_CNVT_SEH = 0x5,
13190 RR_RY_CNVT_SEW = 0x6,
13193 static int xlat (int r)
13195 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13200 static void gen_mips16_save (DisasContext *ctx,
13201 int xsregs, int aregs,
13202 int do_ra, int do_s0, int do_s1,
13205 TCGv t0 = tcg_temp_new();
13206 TCGv t1 = tcg_temp_new();
13207 TCGv t2 = tcg_temp_new();
13237 generate_exception_end(ctx, EXCP_RI);
13243 gen_base_offset_addr(ctx, t0, 29, 12);
13244 gen_load_gpr(t1, 7);
13245 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13248 gen_base_offset_addr(ctx, t0, 29, 8);
13249 gen_load_gpr(t1, 6);
13250 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13253 gen_base_offset_addr(ctx, t0, 29, 4);
13254 gen_load_gpr(t1, 5);
13255 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13258 gen_base_offset_addr(ctx, t0, 29, 0);
13259 gen_load_gpr(t1, 4);
13260 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13263 gen_load_gpr(t0, 29);
13265 #define DECR_AND_STORE(reg) do { \
13266 tcg_gen_movi_tl(t2, -4); \
13267 gen_op_addr_add(ctx, t0, t0, t2); \
13268 gen_load_gpr(t1, reg); \
13269 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13273 DECR_AND_STORE(31);
13278 DECR_AND_STORE(30);
13281 DECR_AND_STORE(23);
13284 DECR_AND_STORE(22);
13287 DECR_AND_STORE(21);
13290 DECR_AND_STORE(20);
13293 DECR_AND_STORE(19);
13296 DECR_AND_STORE(18);
13300 DECR_AND_STORE(17);
13303 DECR_AND_STORE(16);
13333 generate_exception_end(ctx, EXCP_RI);
13349 #undef DECR_AND_STORE
13351 tcg_gen_movi_tl(t2, -framesize);
13352 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13358 static void gen_mips16_restore (DisasContext *ctx,
13359 int xsregs, int aregs,
13360 int do_ra, int do_s0, int do_s1,
13364 TCGv t0 = tcg_temp_new();
13365 TCGv t1 = tcg_temp_new();
13366 TCGv t2 = tcg_temp_new();
13368 tcg_gen_movi_tl(t2, framesize);
13369 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13371 #define DECR_AND_LOAD(reg) do { \
13372 tcg_gen_movi_tl(t2, -4); \
13373 gen_op_addr_add(ctx, t0, t0, t2); \
13374 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13375 gen_store_gpr(t1, reg); \
13439 generate_exception_end(ctx, EXCP_RI);
13455 #undef DECR_AND_LOAD
13457 tcg_gen_movi_tl(t2, framesize);
13458 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13464 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13465 int is_64_bit, int extended)
13469 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13470 generate_exception_end(ctx, EXCP_RI);
13474 t0 = tcg_temp_new();
13476 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13477 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13479 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13485 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13488 TCGv_i32 t0 = tcg_const_i32(op);
13489 TCGv t1 = tcg_temp_new();
13490 gen_base_offset_addr(ctx, t1, base, offset);
13491 gen_helper_cache(cpu_env, t1, t0);
13494 #if defined(TARGET_MIPS64)
13495 static void decode_i64_mips16 (DisasContext *ctx,
13496 int ry, int funct, int16_t offset,
13501 check_insn(ctx, ISA_MIPS3);
13502 check_mips_64(ctx);
13503 offset = extended ? offset : offset << 3;
13504 gen_ld(ctx, OPC_LD, ry, 29, offset);
13507 check_insn(ctx, ISA_MIPS3);
13508 check_mips_64(ctx);
13509 offset = extended ? offset : offset << 3;
13510 gen_st(ctx, OPC_SD, ry, 29, offset);
13513 check_insn(ctx, ISA_MIPS3);
13514 check_mips_64(ctx);
13515 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13516 gen_st(ctx, OPC_SD, 31, 29, offset);
13519 check_insn(ctx, ISA_MIPS3);
13520 check_mips_64(ctx);
13521 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13522 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13525 check_insn(ctx, ISA_MIPS3);
13526 check_mips_64(ctx);
13527 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13528 generate_exception_end(ctx, EXCP_RI);
13530 offset = extended ? offset : offset << 3;
13531 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13535 check_insn(ctx, ISA_MIPS3);
13536 check_mips_64(ctx);
13537 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13538 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13541 check_insn(ctx, ISA_MIPS3);
13542 check_mips_64(ctx);
13543 offset = extended ? offset : offset << 2;
13544 gen_addiupc(ctx, ry, offset, 1, extended);
13547 check_insn(ctx, ISA_MIPS3);
13548 check_mips_64(ctx);
13549 offset = extended ? offset : offset << 2;
13550 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13556 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13558 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13559 int op, rx, ry, funct, sa;
13560 int16_t imm, offset;
13562 ctx->opcode = (ctx->opcode << 16) | extend;
13563 op = (ctx->opcode >> 11) & 0x1f;
13564 sa = (ctx->opcode >> 22) & 0x1f;
13565 funct = (ctx->opcode >> 8) & 0x7;
13566 rx = xlat((ctx->opcode >> 8) & 0x7);
13567 ry = xlat((ctx->opcode >> 5) & 0x7);
13568 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13569 | ((ctx->opcode >> 21) & 0x3f) << 5
13570 | (ctx->opcode & 0x1f));
13572 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13575 case M16_OPC_ADDIUSP:
13576 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13578 case M16_OPC_ADDIUPC:
13579 gen_addiupc(ctx, rx, imm, 0, 1);
13582 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13583 /* No delay slot, so just process as a normal instruction */
13586 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13587 /* No delay slot, so just process as a normal instruction */
13589 case M16_OPC_BNEQZ:
13590 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13591 /* No delay slot, so just process as a normal instruction */
13593 case M16_OPC_SHIFT:
13594 switch (ctx->opcode & 0x3) {
13596 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13599 #if defined(TARGET_MIPS64)
13600 check_mips_64(ctx);
13601 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13603 generate_exception_end(ctx, EXCP_RI);
13607 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13610 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13614 #if defined(TARGET_MIPS64)
13616 check_insn(ctx, ISA_MIPS3);
13617 check_mips_64(ctx);
13618 gen_ld(ctx, OPC_LD, ry, rx, offset);
13622 imm = ctx->opcode & 0xf;
13623 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13624 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13625 imm = (int16_t) (imm << 1) >> 1;
13626 if ((ctx->opcode >> 4) & 0x1) {
13627 #if defined(TARGET_MIPS64)
13628 check_mips_64(ctx);
13629 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13631 generate_exception_end(ctx, EXCP_RI);
13634 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13637 case M16_OPC_ADDIU8:
13638 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13641 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13643 case M16_OPC_SLTIU:
13644 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13649 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13652 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13655 gen_st(ctx, OPC_SW, 31, 29, imm);
13658 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13661 check_insn(ctx, ISA_MIPS32);
13663 int xsregs = (ctx->opcode >> 24) & 0x7;
13664 int aregs = (ctx->opcode >> 16) & 0xf;
13665 int do_ra = (ctx->opcode >> 6) & 0x1;
13666 int do_s0 = (ctx->opcode >> 5) & 0x1;
13667 int do_s1 = (ctx->opcode >> 4) & 0x1;
13668 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13669 | (ctx->opcode & 0xf)) << 3;
13671 if (ctx->opcode & (1 << 7)) {
13672 gen_mips16_save(ctx, xsregs, aregs,
13673 do_ra, do_s0, do_s1,
13676 gen_mips16_restore(ctx, xsregs, aregs,
13677 do_ra, do_s0, do_s1,
13683 generate_exception_end(ctx, EXCP_RI);
13688 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13691 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13693 #if defined(TARGET_MIPS64)
13695 check_insn(ctx, ISA_MIPS3);
13696 check_mips_64(ctx);
13697 gen_st(ctx, OPC_SD, ry, rx, offset);
13701 gen_ld(ctx, OPC_LB, ry, rx, offset);
13704 gen_ld(ctx, OPC_LH, ry, rx, offset);
13707 gen_ld(ctx, OPC_LW, rx, 29, offset);
13710 gen_ld(ctx, OPC_LW, ry, rx, offset);
13713 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13716 gen_ld(ctx, OPC_LHU, ry, rx, offset);
13719 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13721 #if defined(TARGET_MIPS64)
13723 check_insn(ctx, ISA_MIPS3);
13724 check_mips_64(ctx);
13725 gen_ld(ctx, OPC_LWU, ry, rx, offset);
13729 gen_st(ctx, OPC_SB, ry, rx, offset);
13732 gen_st(ctx, OPC_SH, ry, rx, offset);
13735 gen_st(ctx, OPC_SW, rx, 29, offset);
13738 gen_st(ctx, OPC_SW, ry, rx, offset);
13740 #if defined(TARGET_MIPS64)
13742 decode_i64_mips16(ctx, ry, funct, offset, 1);
13746 generate_exception_end(ctx, EXCP_RI);
13753 static inline bool is_uhi(int sdbbp_code)
13755 #ifdef CONFIG_USER_ONLY
13758 return semihosting_enabled() && sdbbp_code == 1;
13762 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13766 int op, cnvt_op, op1, offset;
13770 op = (ctx->opcode >> 11) & 0x1f;
13771 sa = (ctx->opcode >> 2) & 0x7;
13772 sa = sa == 0 ? 8 : sa;
13773 rx = xlat((ctx->opcode >> 8) & 0x7);
13774 cnvt_op = (ctx->opcode >> 5) & 0x7;
13775 ry = xlat((ctx->opcode >> 5) & 0x7);
13776 op1 = offset = ctx->opcode & 0x1f;
13781 case M16_OPC_ADDIUSP:
13783 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13785 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13788 case M16_OPC_ADDIUPC:
13789 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13792 offset = (ctx->opcode & 0x7ff) << 1;
13793 offset = (int16_t)(offset << 4) >> 4;
13794 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13795 /* No delay slot, so just process as a normal instruction */
13798 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13799 offset = (((ctx->opcode & 0x1f) << 21)
13800 | ((ctx->opcode >> 5) & 0x1f) << 16
13802 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13803 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13807 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13808 ((int8_t)ctx->opcode) << 1, 0);
13809 /* No delay slot, so just process as a normal instruction */
13811 case M16_OPC_BNEQZ:
13812 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13813 ((int8_t)ctx->opcode) << 1, 0);
13814 /* No delay slot, so just process as a normal instruction */
13816 case M16_OPC_SHIFT:
13817 switch (ctx->opcode & 0x3) {
13819 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13822 #if defined(TARGET_MIPS64)
13823 check_insn(ctx, ISA_MIPS3);
13824 check_mips_64(ctx);
13825 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13827 generate_exception_end(ctx, EXCP_RI);
13831 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13834 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13838 #if defined(TARGET_MIPS64)
13840 check_insn(ctx, ISA_MIPS3);
13841 check_mips_64(ctx);
13842 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13847 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13849 if ((ctx->opcode >> 4) & 1) {
13850 #if defined(TARGET_MIPS64)
13851 check_insn(ctx, ISA_MIPS3);
13852 check_mips_64(ctx);
13853 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13855 generate_exception_end(ctx, EXCP_RI);
13858 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13862 case M16_OPC_ADDIU8:
13864 int16_t imm = (int8_t) ctx->opcode;
13866 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13871 int16_t imm = (uint8_t) ctx->opcode;
13872 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13875 case M16_OPC_SLTIU:
13877 int16_t imm = (uint8_t) ctx->opcode;
13878 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13885 funct = (ctx->opcode >> 8) & 0x7;
13888 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13889 ((int8_t)ctx->opcode) << 1, 0);
13892 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13893 ((int8_t)ctx->opcode) << 1, 0);
13896 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13899 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13900 ((int8_t)ctx->opcode) << 3);
13903 check_insn(ctx, ISA_MIPS32);
13905 int do_ra = ctx->opcode & (1 << 6);
13906 int do_s0 = ctx->opcode & (1 << 5);
13907 int do_s1 = ctx->opcode & (1 << 4);
13908 int framesize = ctx->opcode & 0xf;
13910 if (framesize == 0) {
13913 framesize = framesize << 3;
13916 if (ctx->opcode & (1 << 7)) {
13917 gen_mips16_save(ctx, 0, 0,
13918 do_ra, do_s0, do_s1, framesize);
13920 gen_mips16_restore(ctx, 0, 0,
13921 do_ra, do_s0, do_s1, framesize);
13927 int rz = xlat(ctx->opcode & 0x7);
13929 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13930 ((ctx->opcode >> 5) & 0x7);
13931 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13935 reg32 = ctx->opcode & 0x1f;
13936 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13939 generate_exception_end(ctx, EXCP_RI);
13946 int16_t imm = (uint8_t) ctx->opcode;
13948 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13953 int16_t imm = (uint8_t) ctx->opcode;
13954 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13957 #if defined(TARGET_MIPS64)
13959 check_insn(ctx, ISA_MIPS3);
13960 check_mips_64(ctx);
13961 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13965 gen_ld(ctx, OPC_LB, ry, rx, offset);
13968 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13971 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13974 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13977 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13980 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13983 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13985 #if defined (TARGET_MIPS64)
13987 check_insn(ctx, ISA_MIPS3);
13988 check_mips_64(ctx);
13989 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13993 gen_st(ctx, OPC_SB, ry, rx, offset);
13996 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13999 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14002 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
14006 int rz = xlat((ctx->opcode >> 2) & 0x7);
14009 switch (ctx->opcode & 0x3) {
14011 mips32_op = OPC_ADDU;
14014 mips32_op = OPC_SUBU;
14016 #if defined(TARGET_MIPS64)
14018 mips32_op = OPC_DADDU;
14019 check_insn(ctx, ISA_MIPS3);
14020 check_mips_64(ctx);
14023 mips32_op = OPC_DSUBU;
14024 check_insn(ctx, ISA_MIPS3);
14025 check_mips_64(ctx);
14029 generate_exception_end(ctx, EXCP_RI);
14033 gen_arith(ctx, mips32_op, rz, rx, ry);
14042 int nd = (ctx->opcode >> 7) & 0x1;
14043 int link = (ctx->opcode >> 6) & 0x1;
14044 int ra = (ctx->opcode >> 5) & 0x1;
14047 check_insn(ctx, ISA_MIPS32);
14056 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14061 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14062 gen_helper_do_semihosting(cpu_env);
14064 /* XXX: not clear which exception should be raised
14065 * when in debug mode...
14067 check_insn(ctx, ISA_MIPS32);
14068 generate_exception_end(ctx, EXCP_DBp);
14072 gen_slt(ctx, OPC_SLT, 24, rx, ry);
14075 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14078 generate_exception_end(ctx, EXCP_BREAK);
14081 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14084 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14087 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14089 #if defined (TARGET_MIPS64)
14091 check_insn(ctx, ISA_MIPS3);
14092 check_mips_64(ctx);
14093 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14097 gen_logic(ctx, OPC_XOR, 24, rx, ry);
14100 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14103 gen_logic(ctx, OPC_AND, rx, rx, ry);
14106 gen_logic(ctx, OPC_OR, rx, rx, ry);
14109 gen_logic(ctx, OPC_XOR, rx, rx, ry);
14112 gen_logic(ctx, OPC_NOR, rx, ry, 0);
14115 gen_HILO(ctx, OPC_MFHI, 0, rx);
14118 check_insn(ctx, ISA_MIPS32);
14120 case RR_RY_CNVT_ZEB:
14121 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14123 case RR_RY_CNVT_ZEH:
14124 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14126 case RR_RY_CNVT_SEB:
14127 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14129 case RR_RY_CNVT_SEH:
14130 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14132 #if defined (TARGET_MIPS64)
14133 case RR_RY_CNVT_ZEW:
14134 check_insn(ctx, ISA_MIPS64);
14135 check_mips_64(ctx);
14136 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14138 case RR_RY_CNVT_SEW:
14139 check_insn(ctx, ISA_MIPS64);
14140 check_mips_64(ctx);
14141 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14145 generate_exception_end(ctx, EXCP_RI);
14150 gen_HILO(ctx, OPC_MFLO, 0, rx);
14152 #if defined (TARGET_MIPS64)
14154 check_insn(ctx, ISA_MIPS3);
14155 check_mips_64(ctx);
14156 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14159 check_insn(ctx, ISA_MIPS3);
14160 check_mips_64(ctx);
14161 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14164 check_insn(ctx, ISA_MIPS3);
14165 check_mips_64(ctx);
14166 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14169 check_insn(ctx, ISA_MIPS3);
14170 check_mips_64(ctx);
14171 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14175 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14178 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14181 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14184 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14186 #if defined (TARGET_MIPS64)
14188 check_insn(ctx, ISA_MIPS3);
14189 check_mips_64(ctx);
14190 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14193 check_insn(ctx, ISA_MIPS3);
14194 check_mips_64(ctx);
14195 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14198 check_insn(ctx, ISA_MIPS3);
14199 check_mips_64(ctx);
14200 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14203 check_insn(ctx, ISA_MIPS3);
14204 check_mips_64(ctx);
14205 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14209 generate_exception_end(ctx, EXCP_RI);
14213 case M16_OPC_EXTEND:
14214 decode_extended_mips16_opc(env, ctx);
14217 #if defined(TARGET_MIPS64)
14219 funct = (ctx->opcode >> 8) & 0x7;
14220 decode_i64_mips16(ctx, ry, funct, offset, 0);
14224 generate_exception_end(ctx, EXCP_RI);
14231 /* microMIPS extension to MIPS32/MIPS64 */
14234 * microMIPS32/microMIPS64 major opcodes
14236 * 1. MIPS Architecture for Programmers Volume II-B:
14237 * The microMIPS32 Instruction Set (Revision 3.05)
14239 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14241 * 2. MIPS Architecture For Programmers Volume II-A:
14242 * The MIPS64 Instruction Set (Revision 3.51)
14272 POOL32S = 0x16, /* MIPS64 */
14273 DADDIU32 = 0x17, /* MIPS64 */
14302 /* 0x29 is reserved */
14315 /* 0x31 is reserved */
14328 SD32 = 0x36, /* MIPS64 */
14329 LD32 = 0x37, /* MIPS64 */
14331 /* 0x39 is reserved */
14347 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14369 /* POOL32A encoding of minor opcode field */
14372 /* These opcodes are distinguished only by bits 9..6; those bits are
14373 * what are recorded below. */
14410 /* The following can be distinguished by their lower 6 bits. */
14420 /* POOL32AXF encoding of minor opcode field extension */
14423 * 1. MIPS Architecture for Programmers Volume II-B:
14424 * The microMIPS32 Instruction Set (Revision 3.05)
14426 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14428 * 2. MIPS Architecture for Programmers VolumeIV-e:
14429 * The MIPS DSP Application-Specific Extension
14430 * to the microMIPS32 Architecture (Revision 2.34)
14432 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14447 /* begin of microMIPS32 DSP */
14449 /* bits 13..12 for 0x01 */
14455 /* bits 13..12 for 0x2a */
14461 /* bits 13..12 for 0x32 */
14465 /* end of microMIPS32 DSP */
14467 /* bits 15..12 for 0x2c */
14484 /* bits 15..12 for 0x34 */
14492 /* bits 15..12 for 0x3c */
14494 JR = 0x0, /* alias */
14502 /* bits 15..12 for 0x05 */
14506 /* bits 15..12 for 0x0d */
14518 /* bits 15..12 for 0x15 */
14524 /* bits 15..12 for 0x1d */
14528 /* bits 15..12 for 0x2d */
14533 /* bits 15..12 for 0x35 */
14540 /* POOL32B encoding of minor opcode field (bits 15..12) */
14556 /* POOL32C encoding of minor opcode field (bits 15..12) */
14577 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14590 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14603 /* POOL32F encoding of minor opcode field (bits 5..0) */
14606 /* These are the bit 7..6 values */
14615 /* These are the bit 8..6 values */
14640 MOVZ_FMT_05 = 0x05,
14674 CABS_COND_FMT = 0x1c, /* MIPS3D */
14681 /* POOL32Fxf encoding of minor opcode extension field */
14719 /* POOL32I encoding of minor opcode field (bits 25..21) */
14749 /* These overlap and are distinguished by bit16 of the instruction */
14758 /* POOL16A encoding of minor opcode field */
14765 /* POOL16B encoding of minor opcode field */
14772 /* POOL16C encoding of minor opcode field */
14792 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14816 /* POOL16D encoding of minor opcode field */
14823 /* POOL16E encoding of minor opcode field */
14830 static int mmreg (int r)
14832 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14837 /* Used for 16-bit store instructions. */
14838 static int mmreg2 (int r)
14840 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14845 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14846 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14847 #define uMIPS_RS2(op) uMIPS_RS(op)
14848 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14849 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14850 #define uMIPS_RS5(op) (op & 0x1f)
14852 /* Signed immediate */
14853 #define SIMM(op, start, width) \
14854 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14857 /* Zero-extended immediate */
14858 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14860 static void gen_addiur1sp(DisasContext *ctx)
14862 int rd = mmreg(uMIPS_RD(ctx->opcode));
14864 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14867 static void gen_addiur2(DisasContext *ctx)
14869 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14870 int rd = mmreg(uMIPS_RD(ctx->opcode));
14871 int rs = mmreg(uMIPS_RS(ctx->opcode));
14873 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14876 static void gen_addiusp(DisasContext *ctx)
14878 int encoded = ZIMM(ctx->opcode, 1, 9);
14881 if (encoded <= 1) {
14882 decoded = 256 + encoded;
14883 } else if (encoded <= 255) {
14885 } else if (encoded <= 509) {
14886 decoded = encoded - 512;
14888 decoded = encoded - 768;
14891 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14894 static void gen_addius5(DisasContext *ctx)
14896 int imm = SIMM(ctx->opcode, 1, 4);
14897 int rd = (ctx->opcode >> 5) & 0x1f;
14899 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14902 static void gen_andi16(DisasContext *ctx)
14904 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14905 31, 32, 63, 64, 255, 32768, 65535 };
14906 int rd = mmreg(uMIPS_RD(ctx->opcode));
14907 int rs = mmreg(uMIPS_RS(ctx->opcode));
14908 int encoded = ZIMM(ctx->opcode, 0, 4);
14910 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14913 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14914 int base, int16_t offset)
14919 if (ctx->hflags & MIPS_HFLAG_BMASK) {
14920 generate_exception_end(ctx, EXCP_RI);
14924 t0 = tcg_temp_new();
14926 gen_base_offset_addr(ctx, t0, base, offset);
14928 t1 = tcg_const_tl(reglist);
14929 t2 = tcg_const_i32(ctx->mem_idx);
14931 save_cpu_state(ctx, 1);
14934 gen_helper_lwm(cpu_env, t0, t1, t2);
14937 gen_helper_swm(cpu_env, t0, t1, t2);
14939 #ifdef TARGET_MIPS64
14941 gen_helper_ldm(cpu_env, t0, t1, t2);
14944 gen_helper_sdm(cpu_env, t0, t1, t2);
14950 tcg_temp_free_i32(t2);
14954 static void gen_pool16c_insn(DisasContext *ctx)
14956 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14957 int rs = mmreg(ctx->opcode & 0x7);
14959 switch (((ctx->opcode) >> 4) & 0x3f) {
14964 gen_logic(ctx, OPC_NOR, rd, rs, 0);
14970 gen_logic(ctx, OPC_XOR, rd, rd, rs);
14976 gen_logic(ctx, OPC_AND, rd, rd, rs);
14982 gen_logic(ctx, OPC_OR, rd, rd, rs);
14989 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14990 int offset = ZIMM(ctx->opcode, 0, 4);
14992 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
15001 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15002 int offset = ZIMM(ctx->opcode, 0, 4);
15004 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
15011 int reg = ctx->opcode & 0x1f;
15013 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
15019 int reg = ctx->opcode & 0x1f;
15020 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
15021 /* Let normal delay slot handling in our caller take us
15022 to the branch target. */
15027 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15028 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15032 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15033 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15037 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15041 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15044 generate_exception_end(ctx, EXCP_BREAK);
15047 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15048 gen_helper_do_semihosting(cpu_env);
15050 /* XXX: not clear which exception should be raised
15051 * when in debug mode...
15053 check_insn(ctx, ISA_MIPS32);
15054 generate_exception_end(ctx, EXCP_DBp);
15057 case JRADDIUSP + 0:
15058 case JRADDIUSP + 1:
15060 int imm = ZIMM(ctx->opcode, 0, 5);
15061 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15062 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15063 /* Let normal delay slot handling in our caller take us
15064 to the branch target. */
15068 generate_exception_end(ctx, EXCP_RI);
15073 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15076 int rd, rs, re, rt;
15077 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15078 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15079 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15080 rd = rd_enc[enc_dest];
15081 re = re_enc[enc_dest];
15082 rs = rs_rt_enc[enc_rs];
15083 rt = rs_rt_enc[enc_rt];
15085 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15087 tcg_gen_movi_tl(cpu_gpr[rd], 0);
15090 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15092 tcg_gen_movi_tl(cpu_gpr[re], 0);
15096 static void gen_pool16c_r6_insn(DisasContext *ctx)
15098 int rt = mmreg((ctx->opcode >> 7) & 0x7);
15099 int rs = mmreg((ctx->opcode >> 4) & 0x7);
15101 switch (ctx->opcode & 0xf) {
15103 gen_logic(ctx, OPC_NOR, rt, rs, 0);
15106 gen_logic(ctx, OPC_AND, rt, rt, rs);
15110 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15111 int offset = extract32(ctx->opcode, 4, 4);
15112 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15115 case R6_JRC16: /* JRCADDIUSP */
15116 if ((ctx->opcode >> 4) & 1) {
15118 int imm = extract32(ctx->opcode, 5, 5);
15119 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15120 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15123 rs = extract32(ctx->opcode, 5, 5);
15124 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15136 int enc_dest = uMIPS_RD(ctx->opcode);
15137 int enc_rt = uMIPS_RS2(ctx->opcode);
15138 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15139 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15143 gen_logic(ctx, OPC_XOR, rt, rt, rs);
15146 gen_logic(ctx, OPC_OR, rt, rt, rs);
15150 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15151 int offset = extract32(ctx->opcode, 4, 4);
15152 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15155 case JALRC16: /* BREAK16, SDBBP16 */
15156 switch (ctx->opcode & 0x3f) {
15158 case JALRC16 + 0x20:
15160 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15165 generate_exception(ctx, EXCP_BREAK);
15169 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15170 gen_helper_do_semihosting(cpu_env);
15172 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15173 generate_exception(ctx, EXCP_RI);
15175 generate_exception(ctx, EXCP_DBp);
15182 generate_exception(ctx, EXCP_RI);
15187 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15189 TCGv t0 = tcg_temp_new();
15190 TCGv t1 = tcg_temp_new();
15192 gen_load_gpr(t0, base);
15195 gen_load_gpr(t1, index);
15196 tcg_gen_shli_tl(t1, t1, 2);
15197 gen_op_addr_add(ctx, t0, t1, t0);
15200 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15201 gen_store_gpr(t1, rd);
15207 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15208 int base, int16_t offset)
15212 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15213 generate_exception_end(ctx, EXCP_RI);
15217 t0 = tcg_temp_new();
15218 t1 = tcg_temp_new();
15220 gen_base_offset_addr(ctx, t0, base, offset);
15225 generate_exception_end(ctx, EXCP_RI);
15228 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15229 gen_store_gpr(t1, rd);
15230 tcg_gen_movi_tl(t1, 4);
15231 gen_op_addr_add(ctx, t0, t0, t1);
15232 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15233 gen_store_gpr(t1, rd+1);
15236 gen_load_gpr(t1, rd);
15237 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15238 tcg_gen_movi_tl(t1, 4);
15239 gen_op_addr_add(ctx, t0, t0, t1);
15240 gen_load_gpr(t1, rd+1);
15241 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15243 #ifdef TARGET_MIPS64
15246 generate_exception_end(ctx, EXCP_RI);
15249 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15250 gen_store_gpr(t1, rd);
15251 tcg_gen_movi_tl(t1, 8);
15252 gen_op_addr_add(ctx, t0, t0, t1);
15253 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15254 gen_store_gpr(t1, rd+1);
15257 gen_load_gpr(t1, rd);
15258 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15259 tcg_gen_movi_tl(t1, 8);
15260 gen_op_addr_add(ctx, t0, t0, t1);
15261 gen_load_gpr(t1, rd+1);
15262 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15270 static void gen_sync(int stype)
15272 TCGBar tcg_mo = TCG_BAR_SC;
15275 case 0x4: /* SYNC_WMB */
15276 tcg_mo |= TCG_MO_ST_ST;
15278 case 0x10: /* SYNC_MB */
15279 tcg_mo |= TCG_MO_ALL;
15281 case 0x11: /* SYNC_ACQUIRE */
15282 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15284 case 0x12: /* SYNC_RELEASE */
15285 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15287 case 0x13: /* SYNC_RMB */
15288 tcg_mo |= TCG_MO_LD_LD;
15291 tcg_mo |= TCG_MO_ALL;
15295 tcg_gen_mb(tcg_mo);
15298 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15300 int extension = (ctx->opcode >> 6) & 0x3f;
15301 int minor = (ctx->opcode >> 12) & 0xf;
15302 uint32_t mips32_op;
15304 switch (extension) {
15306 mips32_op = OPC_TEQ;
15309 mips32_op = OPC_TGE;
15312 mips32_op = OPC_TGEU;
15315 mips32_op = OPC_TLT;
15318 mips32_op = OPC_TLTU;
15321 mips32_op = OPC_TNE;
15323 gen_trap(ctx, mips32_op, rs, rt, -1);
15325 #ifndef CONFIG_USER_ONLY
15328 check_cp0_enabled(ctx);
15330 /* Treat as NOP. */
15333 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15337 check_cp0_enabled(ctx);
15339 TCGv t0 = tcg_temp_new();
15341 gen_load_gpr(t0, rt);
15342 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15348 switch (minor & 3) {
15350 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15353 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15356 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15359 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15362 goto pool32axf_invalid;
15366 switch (minor & 3) {
15368 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15371 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15374 goto pool32axf_invalid;
15380 check_insn(ctx, ISA_MIPS32R6);
15381 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15384 gen_bshfl(ctx, OPC_SEB, rs, rt);
15387 gen_bshfl(ctx, OPC_SEH, rs, rt);
15390 mips32_op = OPC_CLO;
15393 mips32_op = OPC_CLZ;
15395 check_insn(ctx, ISA_MIPS32);
15396 gen_cl(ctx, mips32_op, rt, rs);
15399 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15400 gen_rdhwr(ctx, rt, rs, 0);
15403 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15406 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15407 mips32_op = OPC_MULT;
15410 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15411 mips32_op = OPC_MULTU;
15414 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15415 mips32_op = OPC_DIV;
15418 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15419 mips32_op = OPC_DIVU;
15422 check_insn(ctx, ISA_MIPS32);
15423 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15426 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15427 mips32_op = OPC_MADD;
15430 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15431 mips32_op = OPC_MADDU;
15434 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15435 mips32_op = OPC_MSUB;
15438 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15439 mips32_op = OPC_MSUBU;
15441 check_insn(ctx, ISA_MIPS32);
15442 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15445 goto pool32axf_invalid;
15456 generate_exception_err(ctx, EXCP_CpU, 2);
15459 goto pool32axf_invalid;
15464 case JALR: /* JALRC */
15465 case JALR_HB: /* JALRC_HB */
15466 if (ctx->insn_flags & ISA_MIPS32R6) {
15467 /* JALRC, JALRC_HB */
15468 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15470 /* JALR, JALR_HB */
15471 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15472 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15477 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15478 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15479 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15482 goto pool32axf_invalid;
15488 check_cp0_enabled(ctx);
15489 check_insn(ctx, ISA_MIPS32R2);
15490 gen_load_srsgpr(rs, rt);
15493 check_cp0_enabled(ctx);
15494 check_insn(ctx, ISA_MIPS32R2);
15495 gen_store_srsgpr(rs, rt);
15498 goto pool32axf_invalid;
15501 #ifndef CONFIG_USER_ONLY
15505 mips32_op = OPC_TLBP;
15508 mips32_op = OPC_TLBR;
15511 mips32_op = OPC_TLBWI;
15514 mips32_op = OPC_TLBWR;
15517 mips32_op = OPC_TLBINV;
15520 mips32_op = OPC_TLBINVF;
15523 mips32_op = OPC_WAIT;
15526 mips32_op = OPC_DERET;
15529 mips32_op = OPC_ERET;
15531 gen_cp0(env, ctx, mips32_op, rt, rs);
15534 goto pool32axf_invalid;
15540 check_cp0_enabled(ctx);
15542 TCGv t0 = tcg_temp_new();
15544 save_cpu_state(ctx, 1);
15545 gen_helper_di(t0, cpu_env);
15546 gen_store_gpr(t0, rs);
15547 /* Stop translation as we may have switched the execution mode */
15548 ctx->base.is_jmp = DISAS_STOP;
15553 check_cp0_enabled(ctx);
15555 TCGv t0 = tcg_temp_new();
15557 save_cpu_state(ctx, 1);
15558 gen_helper_ei(t0, cpu_env);
15559 gen_store_gpr(t0, rs);
15560 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15561 of translated code to check for pending interrupts. */
15562 gen_save_pc(ctx->base.pc_next + 4);
15563 ctx->base.is_jmp = DISAS_EXIT;
15568 goto pool32axf_invalid;
15575 gen_sync(extract32(ctx->opcode, 16, 5));
15578 generate_exception_end(ctx, EXCP_SYSCALL);
15581 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15582 gen_helper_do_semihosting(cpu_env);
15584 check_insn(ctx, ISA_MIPS32);
15585 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15586 generate_exception_end(ctx, EXCP_RI);
15588 generate_exception_end(ctx, EXCP_DBp);
15593 goto pool32axf_invalid;
15597 switch (minor & 3) {
15599 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15602 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15605 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15608 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15611 goto pool32axf_invalid;
15615 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15618 gen_HILO(ctx, OPC_MFHI, 0, rs);
15621 gen_HILO(ctx, OPC_MFLO, 0, rs);
15624 gen_HILO(ctx, OPC_MTHI, 0, rs);
15627 gen_HILO(ctx, OPC_MTLO, 0, rs);
15630 goto pool32axf_invalid;
15635 MIPS_INVAL("pool32axf");
15636 generate_exception_end(ctx, EXCP_RI);
15641 /* Values for microMIPS fmt field. Variable-width, depending on which
15642 formats the instruction supports. */
15661 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15663 int extension = (ctx->opcode >> 6) & 0x3ff;
15664 uint32_t mips32_op;
15666 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15667 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15668 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15670 switch (extension) {
15671 case FLOAT_1BIT_FMT(CFC1, 0):
15672 mips32_op = OPC_CFC1;
15674 case FLOAT_1BIT_FMT(CTC1, 0):
15675 mips32_op = OPC_CTC1;
15677 case FLOAT_1BIT_FMT(MFC1, 0):
15678 mips32_op = OPC_MFC1;
15680 case FLOAT_1BIT_FMT(MTC1, 0):
15681 mips32_op = OPC_MTC1;
15683 case FLOAT_1BIT_FMT(MFHC1, 0):
15684 mips32_op = OPC_MFHC1;
15686 case FLOAT_1BIT_FMT(MTHC1, 0):
15687 mips32_op = OPC_MTHC1;
15689 gen_cp1(ctx, mips32_op, rt, rs);
15692 /* Reciprocal square root */
15693 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15694 mips32_op = OPC_RSQRT_S;
15696 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15697 mips32_op = OPC_RSQRT_D;
15701 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15702 mips32_op = OPC_SQRT_S;
15704 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15705 mips32_op = OPC_SQRT_D;
15709 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15710 mips32_op = OPC_RECIP_S;
15712 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15713 mips32_op = OPC_RECIP_D;
15717 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15718 mips32_op = OPC_FLOOR_L_S;
15720 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15721 mips32_op = OPC_FLOOR_L_D;
15723 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15724 mips32_op = OPC_FLOOR_W_S;
15726 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15727 mips32_op = OPC_FLOOR_W_D;
15731 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15732 mips32_op = OPC_CEIL_L_S;
15734 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15735 mips32_op = OPC_CEIL_L_D;
15737 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15738 mips32_op = OPC_CEIL_W_S;
15740 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15741 mips32_op = OPC_CEIL_W_D;
15745 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15746 mips32_op = OPC_TRUNC_L_S;
15748 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15749 mips32_op = OPC_TRUNC_L_D;
15751 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15752 mips32_op = OPC_TRUNC_W_S;
15754 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15755 mips32_op = OPC_TRUNC_W_D;
15759 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15760 mips32_op = OPC_ROUND_L_S;
15762 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15763 mips32_op = OPC_ROUND_L_D;
15765 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15766 mips32_op = OPC_ROUND_W_S;
15768 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15769 mips32_op = OPC_ROUND_W_D;
15772 /* Integer to floating-point conversion */
15773 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15774 mips32_op = OPC_CVT_L_S;
15776 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15777 mips32_op = OPC_CVT_L_D;
15779 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15780 mips32_op = OPC_CVT_W_S;
15782 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15783 mips32_op = OPC_CVT_W_D;
15786 /* Paired-foo conversions */
15787 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15788 mips32_op = OPC_CVT_S_PL;
15790 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15791 mips32_op = OPC_CVT_S_PU;
15793 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15794 mips32_op = OPC_CVT_PW_PS;
15796 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15797 mips32_op = OPC_CVT_PS_PW;
15800 /* Floating-point moves */
15801 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15802 mips32_op = OPC_MOV_S;
15804 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15805 mips32_op = OPC_MOV_D;
15807 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15808 mips32_op = OPC_MOV_PS;
15811 /* Absolute value */
15812 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15813 mips32_op = OPC_ABS_S;
15815 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15816 mips32_op = OPC_ABS_D;
15818 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15819 mips32_op = OPC_ABS_PS;
15823 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15824 mips32_op = OPC_NEG_S;
15826 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15827 mips32_op = OPC_NEG_D;
15829 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15830 mips32_op = OPC_NEG_PS;
15833 /* Reciprocal square root step */
15834 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15835 mips32_op = OPC_RSQRT1_S;
15837 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15838 mips32_op = OPC_RSQRT1_D;
15840 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15841 mips32_op = OPC_RSQRT1_PS;
15844 /* Reciprocal step */
15845 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15846 mips32_op = OPC_RECIP1_S;
15848 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15849 mips32_op = OPC_RECIP1_S;
15851 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15852 mips32_op = OPC_RECIP1_PS;
15855 /* Conversions from double */
15856 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15857 mips32_op = OPC_CVT_D_S;
15859 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15860 mips32_op = OPC_CVT_D_W;
15862 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15863 mips32_op = OPC_CVT_D_L;
15866 /* Conversions from single */
15867 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15868 mips32_op = OPC_CVT_S_D;
15870 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15871 mips32_op = OPC_CVT_S_W;
15873 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15874 mips32_op = OPC_CVT_S_L;
15876 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15879 /* Conditional moves on floating-point codes */
15880 case COND_FLOAT_MOV(MOVT, 0):
15881 case COND_FLOAT_MOV(MOVT, 1):
15882 case COND_FLOAT_MOV(MOVT, 2):
15883 case COND_FLOAT_MOV(MOVT, 3):
15884 case COND_FLOAT_MOV(MOVT, 4):
15885 case COND_FLOAT_MOV(MOVT, 5):
15886 case COND_FLOAT_MOV(MOVT, 6):
15887 case COND_FLOAT_MOV(MOVT, 7):
15888 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15889 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15891 case COND_FLOAT_MOV(MOVF, 0):
15892 case COND_FLOAT_MOV(MOVF, 1):
15893 case COND_FLOAT_MOV(MOVF, 2):
15894 case COND_FLOAT_MOV(MOVF, 3):
15895 case COND_FLOAT_MOV(MOVF, 4):
15896 case COND_FLOAT_MOV(MOVF, 5):
15897 case COND_FLOAT_MOV(MOVF, 6):
15898 case COND_FLOAT_MOV(MOVF, 7):
15899 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15900 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15903 MIPS_INVAL("pool32fxf");
15904 generate_exception_end(ctx, EXCP_RI);
15909 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15913 int rt, rs, rd, rr;
15915 uint32_t op, minor, minor2, mips32_op;
15916 uint32_t cond, fmt, cc;
15918 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15919 ctx->opcode = (ctx->opcode << 16) | insn;
15921 rt = (ctx->opcode >> 21) & 0x1f;
15922 rs = (ctx->opcode >> 16) & 0x1f;
15923 rd = (ctx->opcode >> 11) & 0x1f;
15924 rr = (ctx->opcode >> 6) & 0x1f;
15925 imm = (int16_t) ctx->opcode;
15927 op = (ctx->opcode >> 26) & 0x3f;
15930 minor = ctx->opcode & 0x3f;
15933 minor = (ctx->opcode >> 6) & 0xf;
15936 mips32_op = OPC_SLL;
15939 mips32_op = OPC_SRA;
15942 mips32_op = OPC_SRL;
15945 mips32_op = OPC_ROTR;
15947 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15950 check_insn(ctx, ISA_MIPS32R6);
15951 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15954 check_insn(ctx, ISA_MIPS32R6);
15955 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15958 check_insn(ctx, ISA_MIPS32R6);
15959 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15962 goto pool32a_invalid;
15966 minor = (ctx->opcode >> 6) & 0xf;
15970 mips32_op = OPC_ADD;
15973 mips32_op = OPC_ADDU;
15976 mips32_op = OPC_SUB;
15979 mips32_op = OPC_SUBU;
15982 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15983 mips32_op = OPC_MUL;
15985 gen_arith(ctx, mips32_op, rd, rs, rt);
15989 mips32_op = OPC_SLLV;
15992 mips32_op = OPC_SRLV;
15995 mips32_op = OPC_SRAV;
15998 mips32_op = OPC_ROTRV;
16000 gen_shift(ctx, mips32_op, rd, rs, rt);
16002 /* Logical operations */
16004 mips32_op = OPC_AND;
16007 mips32_op = OPC_OR;
16010 mips32_op = OPC_NOR;
16013 mips32_op = OPC_XOR;
16015 gen_logic(ctx, mips32_op, rd, rs, rt);
16017 /* Set less than */
16019 mips32_op = OPC_SLT;
16022 mips32_op = OPC_SLTU;
16024 gen_slt(ctx, mips32_op, rd, rs, rt);
16027 goto pool32a_invalid;
16031 minor = (ctx->opcode >> 6) & 0xf;
16033 /* Conditional moves */
16034 case MOVN: /* MUL */
16035 if (ctx->insn_flags & ISA_MIPS32R6) {
16037 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16040 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16043 case MOVZ: /* MUH */
16044 if (ctx->insn_flags & ISA_MIPS32R6) {
16046 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16049 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16053 check_insn(ctx, ISA_MIPS32R6);
16054 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16057 check_insn(ctx, ISA_MIPS32R6);
16058 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16060 case LWXS: /* DIV */
16061 if (ctx->insn_flags & ISA_MIPS32R6) {
16063 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16066 gen_ldxs(ctx, rs, rt, rd);
16070 check_insn(ctx, ISA_MIPS32R6);
16071 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16074 check_insn(ctx, ISA_MIPS32R6);
16075 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16078 check_insn(ctx, ISA_MIPS32R6);
16079 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16082 goto pool32a_invalid;
16086 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16089 check_insn(ctx, ISA_MIPS32R6);
16090 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16091 extract32(ctx->opcode, 9, 2));
16094 check_insn(ctx, ISA_MIPS32R6);
16095 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16098 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16101 gen_pool32axf(env, ctx, rt, rs);
16104 generate_exception_end(ctx, EXCP_BREAK);
16107 check_insn(ctx, ISA_MIPS32R6);
16108 generate_exception_end(ctx, EXCP_RI);
16112 MIPS_INVAL("pool32a");
16113 generate_exception_end(ctx, EXCP_RI);
16118 minor = (ctx->opcode >> 12) & 0xf;
16121 check_cp0_enabled(ctx);
16122 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16123 gen_cache_operation(ctx, rt, rs, imm);
16128 /* COP2: Not implemented. */
16129 generate_exception_err(ctx, EXCP_CpU, 2);
16131 #ifdef TARGET_MIPS64
16134 check_insn(ctx, ISA_MIPS3);
16135 check_mips_64(ctx);
16140 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16142 #ifdef TARGET_MIPS64
16145 check_insn(ctx, ISA_MIPS3);
16146 check_mips_64(ctx);
16151 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16154 MIPS_INVAL("pool32b");
16155 generate_exception_end(ctx, EXCP_RI);
16160 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16161 minor = ctx->opcode & 0x3f;
16162 check_cp1_enabled(ctx);
16165 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16166 mips32_op = OPC_ALNV_PS;
16169 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16170 mips32_op = OPC_MADD_S;
16173 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16174 mips32_op = OPC_MADD_D;
16177 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16178 mips32_op = OPC_MADD_PS;
16181 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16182 mips32_op = OPC_MSUB_S;
16185 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16186 mips32_op = OPC_MSUB_D;
16189 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16190 mips32_op = OPC_MSUB_PS;
16193 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16194 mips32_op = OPC_NMADD_S;
16197 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16198 mips32_op = OPC_NMADD_D;
16201 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16202 mips32_op = OPC_NMADD_PS;
16205 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16206 mips32_op = OPC_NMSUB_S;
16209 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16210 mips32_op = OPC_NMSUB_D;
16213 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16214 mips32_op = OPC_NMSUB_PS;
16216 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16218 case CABS_COND_FMT:
16219 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16220 cond = (ctx->opcode >> 6) & 0xf;
16221 cc = (ctx->opcode >> 13) & 0x7;
16222 fmt = (ctx->opcode >> 10) & 0x3;
16225 gen_cmpabs_s(ctx, cond, rt, rs, cc);
16228 gen_cmpabs_d(ctx, cond, rt, rs, cc);
16231 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16234 goto pool32f_invalid;
16238 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16239 cond = (ctx->opcode >> 6) & 0xf;
16240 cc = (ctx->opcode >> 13) & 0x7;
16241 fmt = (ctx->opcode >> 10) & 0x3;
16244 gen_cmp_s(ctx, cond, rt, rs, cc);
16247 gen_cmp_d(ctx, cond, rt, rs, cc);
16250 gen_cmp_ps(ctx, cond, rt, rs, cc);
16253 goto pool32f_invalid;
16257 check_insn(ctx, ISA_MIPS32R6);
16258 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16261 check_insn(ctx, ISA_MIPS32R6);
16262 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16265 gen_pool32fxf(ctx, rt, rs);
16269 switch ((ctx->opcode >> 6) & 0x7) {
16271 mips32_op = OPC_PLL_PS;
16274 mips32_op = OPC_PLU_PS;
16277 mips32_op = OPC_PUL_PS;
16280 mips32_op = OPC_PUU_PS;
16283 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16284 mips32_op = OPC_CVT_PS_S;
16286 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16289 goto pool32f_invalid;
16293 check_insn(ctx, ISA_MIPS32R6);
16294 switch ((ctx->opcode >> 9) & 0x3) {
16296 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16299 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16302 goto pool32f_invalid;
16307 switch ((ctx->opcode >> 6) & 0x7) {
16309 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16310 mips32_op = OPC_LWXC1;
16313 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16314 mips32_op = OPC_SWXC1;
16317 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16318 mips32_op = OPC_LDXC1;
16321 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16322 mips32_op = OPC_SDXC1;
16325 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16326 mips32_op = OPC_LUXC1;
16329 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16330 mips32_op = OPC_SUXC1;
16332 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16335 goto pool32f_invalid;
16339 check_insn(ctx, ISA_MIPS32R6);
16340 switch ((ctx->opcode >> 9) & 0x3) {
16342 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16345 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16348 goto pool32f_invalid;
16353 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16354 fmt = (ctx->opcode >> 9) & 0x3;
16355 switch ((ctx->opcode >> 6) & 0x7) {
16359 mips32_op = OPC_RSQRT2_S;
16362 mips32_op = OPC_RSQRT2_D;
16365 mips32_op = OPC_RSQRT2_PS;
16368 goto pool32f_invalid;
16374 mips32_op = OPC_RECIP2_S;
16377 mips32_op = OPC_RECIP2_D;
16380 mips32_op = OPC_RECIP2_PS;
16383 goto pool32f_invalid;
16387 mips32_op = OPC_ADDR_PS;
16390 mips32_op = OPC_MULR_PS;
16392 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16395 goto pool32f_invalid;
16399 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16400 cc = (ctx->opcode >> 13) & 0x7;
16401 fmt = (ctx->opcode >> 9) & 0x3;
16402 switch ((ctx->opcode >> 6) & 0x7) {
16403 case MOVF_FMT: /* RINT_FMT */
16404 if (ctx->insn_flags & ISA_MIPS32R6) {
16408 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16411 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16414 goto pool32f_invalid;
16420 gen_movcf_s(ctx, rs, rt, cc, 0);
16423 gen_movcf_d(ctx, rs, rt, cc, 0);
16427 gen_movcf_ps(ctx, rs, rt, cc, 0);
16430 goto pool32f_invalid;
16434 case MOVT_FMT: /* CLASS_FMT */
16435 if (ctx->insn_flags & ISA_MIPS32R6) {
16439 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16442 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16445 goto pool32f_invalid;
16451 gen_movcf_s(ctx, rs, rt, cc, 1);
16454 gen_movcf_d(ctx, rs, rt, cc, 1);
16458 gen_movcf_ps(ctx, rs, rt, cc, 1);
16461 goto pool32f_invalid;
16466 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16469 goto pool32f_invalid;
16472 #define FINSN_3ARG_SDPS(prfx) \
16473 switch ((ctx->opcode >> 8) & 0x3) { \
16475 mips32_op = OPC_##prfx##_S; \
16478 mips32_op = OPC_##prfx##_D; \
16480 case FMT_SDPS_PS: \
16482 mips32_op = OPC_##prfx##_PS; \
16485 goto pool32f_invalid; \
16488 check_insn(ctx, ISA_MIPS32R6);
16489 switch ((ctx->opcode >> 9) & 0x3) {
16491 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16494 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16497 goto pool32f_invalid;
16501 check_insn(ctx, ISA_MIPS32R6);
16502 switch ((ctx->opcode >> 9) & 0x3) {
16504 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16507 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16510 goto pool32f_invalid;
16514 /* regular FP ops */
16515 switch ((ctx->opcode >> 6) & 0x3) {
16517 FINSN_3ARG_SDPS(ADD);
16520 FINSN_3ARG_SDPS(SUB);
16523 FINSN_3ARG_SDPS(MUL);
16526 fmt = (ctx->opcode >> 8) & 0x3;
16528 mips32_op = OPC_DIV_D;
16529 } else if (fmt == 0) {
16530 mips32_op = OPC_DIV_S;
16532 goto pool32f_invalid;
16536 goto pool32f_invalid;
16541 switch ((ctx->opcode >> 6) & 0x7) {
16542 case MOVN_FMT: /* SELEQZ_FMT */
16543 if (ctx->insn_flags & ISA_MIPS32R6) {
16545 switch ((ctx->opcode >> 9) & 0x3) {
16547 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16550 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16553 goto pool32f_invalid;
16557 FINSN_3ARG_SDPS(MOVN);
16561 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16562 FINSN_3ARG_SDPS(MOVN);
16564 case MOVZ_FMT: /* SELNEZ_FMT */
16565 if (ctx->insn_flags & ISA_MIPS32R6) {
16567 switch ((ctx->opcode >> 9) & 0x3) {
16569 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16572 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16575 goto pool32f_invalid;
16579 FINSN_3ARG_SDPS(MOVZ);
16583 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16584 FINSN_3ARG_SDPS(MOVZ);
16587 check_insn(ctx, ISA_MIPS32R6);
16588 switch ((ctx->opcode >> 9) & 0x3) {
16590 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16593 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16596 goto pool32f_invalid;
16600 check_insn(ctx, ISA_MIPS32R6);
16601 switch ((ctx->opcode >> 9) & 0x3) {
16603 mips32_op = OPC_MADDF_S;
16606 mips32_op = OPC_MADDF_D;
16609 goto pool32f_invalid;
16613 check_insn(ctx, ISA_MIPS32R6);
16614 switch ((ctx->opcode >> 9) & 0x3) {
16616 mips32_op = OPC_MSUBF_S;
16619 mips32_op = OPC_MSUBF_D;
16622 goto pool32f_invalid;
16626 goto pool32f_invalid;
16630 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16634 MIPS_INVAL("pool32f");
16635 generate_exception_end(ctx, EXCP_RI);
16639 generate_exception_err(ctx, EXCP_CpU, 1);
16643 minor = (ctx->opcode >> 21) & 0x1f;
16646 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16647 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16650 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16651 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16652 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16655 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16656 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16657 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16660 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16661 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16664 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16665 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16666 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16669 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16670 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16671 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16674 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16675 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16678 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16679 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16683 case TLTI: /* BC1EQZC */
16684 if (ctx->insn_flags & ISA_MIPS32R6) {
16686 check_cp1_enabled(ctx);
16687 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16690 mips32_op = OPC_TLTI;
16694 case TGEI: /* BC1NEZC */
16695 if (ctx->insn_flags & ISA_MIPS32R6) {
16697 check_cp1_enabled(ctx);
16698 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16701 mips32_op = OPC_TGEI;
16706 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16707 mips32_op = OPC_TLTIU;
16710 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16711 mips32_op = OPC_TGEIU;
16713 case TNEI: /* SYNCI */
16714 if (ctx->insn_flags & ISA_MIPS32R6) {
16716 /* Break the TB to be able to sync copied instructions
16718 ctx->base.is_jmp = DISAS_STOP;
16721 mips32_op = OPC_TNEI;
16726 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16727 mips32_op = OPC_TEQI;
16729 gen_trap(ctx, mips32_op, rs, -1, imm);
16734 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16735 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16736 4, rs, 0, imm << 1, 0);
16737 /* Compact branches don't have a delay slot, so just let
16738 the normal delay slot handling take us to the branch
16742 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16743 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16746 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16747 /* Break the TB to be able to sync copied instructions
16749 ctx->base.is_jmp = DISAS_STOP;
16753 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16754 /* COP2: Not implemented. */
16755 generate_exception_err(ctx, EXCP_CpU, 2);
16758 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16759 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16762 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16763 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16766 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16767 mips32_op = OPC_BC1FANY4;
16770 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16771 mips32_op = OPC_BC1TANY4;
16774 check_insn(ctx, ASE_MIPS3D);
16777 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16778 check_cp1_enabled(ctx);
16779 gen_compute_branch1(ctx, mips32_op,
16780 (ctx->opcode >> 18) & 0x7, imm << 1);
16782 generate_exception_err(ctx, EXCP_CpU, 1);
16787 /* MIPS DSP: not implemented */
16790 MIPS_INVAL("pool32i");
16791 generate_exception_end(ctx, EXCP_RI);
16796 minor = (ctx->opcode >> 12) & 0xf;
16797 offset = sextract32(ctx->opcode, 0,
16798 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16801 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16802 mips32_op = OPC_LWL;
16805 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16806 mips32_op = OPC_SWL;
16809 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16810 mips32_op = OPC_LWR;
16813 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16814 mips32_op = OPC_SWR;
16816 #if defined(TARGET_MIPS64)
16818 check_insn(ctx, ISA_MIPS3);
16819 check_mips_64(ctx);
16820 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16821 mips32_op = OPC_LDL;
16824 check_insn(ctx, ISA_MIPS3);
16825 check_mips_64(ctx);
16826 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16827 mips32_op = OPC_SDL;
16830 check_insn(ctx, ISA_MIPS3);
16831 check_mips_64(ctx);
16832 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16833 mips32_op = OPC_LDR;
16836 check_insn(ctx, ISA_MIPS3);
16837 check_mips_64(ctx);
16838 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16839 mips32_op = OPC_SDR;
16842 check_insn(ctx, ISA_MIPS3);
16843 check_mips_64(ctx);
16844 mips32_op = OPC_LWU;
16847 check_insn(ctx, ISA_MIPS3);
16848 check_mips_64(ctx);
16849 mips32_op = OPC_LLD;
16853 mips32_op = OPC_LL;
16856 gen_ld(ctx, mips32_op, rt, rs, offset);
16859 gen_st(ctx, mips32_op, rt, rs, offset);
16862 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
16864 #if defined(TARGET_MIPS64)
16866 check_insn(ctx, ISA_MIPS3);
16867 check_mips_64(ctx);
16868 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
16873 MIPS_INVAL("pool32c ld-eva");
16874 generate_exception_end(ctx, EXCP_RI);
16877 check_cp0_enabled(ctx);
16879 minor2 = (ctx->opcode >> 9) & 0x7;
16880 offset = sextract32(ctx->opcode, 0, 9);
16883 mips32_op = OPC_LBUE;
16886 mips32_op = OPC_LHUE;
16889 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16890 mips32_op = OPC_LWLE;
16893 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16894 mips32_op = OPC_LWRE;
16897 mips32_op = OPC_LBE;
16900 mips32_op = OPC_LHE;
16903 mips32_op = OPC_LLE;
16906 mips32_op = OPC_LWE;
16912 MIPS_INVAL("pool32c st-eva");
16913 generate_exception_end(ctx, EXCP_RI);
16916 check_cp0_enabled(ctx);
16918 minor2 = (ctx->opcode >> 9) & 0x7;
16919 offset = sextract32(ctx->opcode, 0, 9);
16922 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16923 mips32_op = OPC_SWLE;
16926 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16927 mips32_op = OPC_SWRE;
16930 /* Treat as no-op */
16931 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16932 /* hint codes 24-31 are reserved and signal RI */
16933 generate_exception(ctx, EXCP_RI);
16937 /* Treat as no-op */
16938 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16939 gen_cache_operation(ctx, rt, rs, offset);
16943 mips32_op = OPC_SBE;
16946 mips32_op = OPC_SHE;
16949 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16952 mips32_op = OPC_SWE;
16957 /* Treat as no-op */
16958 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16959 /* hint codes 24-31 are reserved and signal RI */
16960 generate_exception(ctx, EXCP_RI);
16964 MIPS_INVAL("pool32c");
16965 generate_exception_end(ctx, EXCP_RI);
16969 case ADDI32: /* AUI, LUI */
16970 if (ctx->insn_flags & ISA_MIPS32R6) {
16972 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16975 mips32_op = OPC_ADDI;
16980 mips32_op = OPC_ADDIU;
16982 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16985 /* Logical operations */
16987 mips32_op = OPC_ORI;
16990 mips32_op = OPC_XORI;
16993 mips32_op = OPC_ANDI;
16995 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16998 /* Set less than immediate */
17000 mips32_op = OPC_SLTI;
17003 mips32_op = OPC_SLTIU;
17005 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
17008 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17009 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17010 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
17011 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17013 case JALS32: /* BOVC, BEQC, BEQZALC */
17014 if (ctx->insn_flags & ISA_MIPS32R6) {
17017 mips32_op = OPC_BOVC;
17018 } else if (rs < rt && rs == 0) {
17020 mips32_op = OPC_BEQZALC;
17023 mips32_op = OPC_BEQC;
17025 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17028 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17029 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17030 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17033 case BEQ32: /* BC */
17034 if (ctx->insn_flags & ISA_MIPS32R6) {
17036 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17037 sextract32(ctx->opcode << 1, 0, 27));
17040 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17043 case BNE32: /* BALC */
17044 if (ctx->insn_flags & ISA_MIPS32R6) {
17046 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17047 sextract32(ctx->opcode << 1, 0, 27));
17050 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17053 case J32: /* BGTZC, BLTZC, BLTC */
17054 if (ctx->insn_flags & ISA_MIPS32R6) {
17055 if (rs == 0 && rt != 0) {
17057 mips32_op = OPC_BGTZC;
17058 } else if (rs != 0 && rt != 0 && rs == rt) {
17060 mips32_op = OPC_BLTZC;
17063 mips32_op = OPC_BLTC;
17065 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17068 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17069 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17072 case JAL32: /* BLEZC, BGEZC, BGEC */
17073 if (ctx->insn_flags & ISA_MIPS32R6) {
17074 if (rs == 0 && rt != 0) {
17076 mips32_op = OPC_BLEZC;
17077 } else if (rs != 0 && rt != 0 && rs == rt) {
17079 mips32_op = OPC_BGEZC;
17082 mips32_op = OPC_BGEC;
17084 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17087 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17088 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17089 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17092 /* Floating point (COP1) */
17094 mips32_op = OPC_LWC1;
17097 mips32_op = OPC_LDC1;
17100 mips32_op = OPC_SWC1;
17103 mips32_op = OPC_SDC1;
17105 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17107 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17108 if (ctx->insn_flags & ISA_MIPS32R6) {
17109 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17110 switch ((ctx->opcode >> 16) & 0x1f) {
17119 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17122 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17125 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17135 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17138 generate_exception(ctx, EXCP_RI);
17143 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17144 offset = SIMM(ctx->opcode, 0, 23) << 2;
17146 gen_addiupc(ctx, reg, offset, 0, 0);
17149 case BNVC: /* BNEC, BNEZALC */
17150 check_insn(ctx, ISA_MIPS32R6);
17153 mips32_op = OPC_BNVC;
17154 } else if (rs < rt && rs == 0) {
17156 mips32_op = OPC_BNEZALC;
17159 mips32_op = OPC_BNEC;
17161 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17163 case R6_BNEZC: /* JIALC */
17164 check_insn(ctx, ISA_MIPS32R6);
17167 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17168 sextract32(ctx->opcode << 1, 0, 22));
17171 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17174 case R6_BEQZC: /* JIC */
17175 check_insn(ctx, ISA_MIPS32R6);
17178 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17179 sextract32(ctx->opcode << 1, 0, 22));
17182 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17185 case BLEZALC: /* BGEZALC, BGEUC */
17186 check_insn(ctx, ISA_MIPS32R6);
17187 if (rs == 0 && rt != 0) {
17189 mips32_op = OPC_BLEZALC;
17190 } else if (rs != 0 && rt != 0 && rs == rt) {
17192 mips32_op = OPC_BGEZALC;
17195 mips32_op = OPC_BGEUC;
17197 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17199 case BGTZALC: /* BLTZALC, BLTUC */
17200 check_insn(ctx, ISA_MIPS32R6);
17201 if (rs == 0 && rt != 0) {
17203 mips32_op = OPC_BGTZALC;
17204 } else if (rs != 0 && rt != 0 && rs == rt) {
17206 mips32_op = OPC_BLTZALC;
17209 mips32_op = OPC_BLTUC;
17211 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17213 /* Loads and stores */
17215 mips32_op = OPC_LB;
17218 mips32_op = OPC_LBU;
17221 mips32_op = OPC_LH;
17224 mips32_op = OPC_LHU;
17227 mips32_op = OPC_LW;
17229 #ifdef TARGET_MIPS64
17231 check_insn(ctx, ISA_MIPS3);
17232 check_mips_64(ctx);
17233 mips32_op = OPC_LD;
17236 check_insn(ctx, ISA_MIPS3);
17237 check_mips_64(ctx);
17238 mips32_op = OPC_SD;
17242 mips32_op = OPC_SB;
17245 mips32_op = OPC_SH;
17248 mips32_op = OPC_SW;
17251 gen_ld(ctx, mips32_op, rt, rs, imm);
17254 gen_st(ctx, mips32_op, rt, rs, imm);
17257 generate_exception_end(ctx, EXCP_RI);
17262 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
17266 /* make sure instructions are on a halfword boundary */
17267 if (ctx->base.pc_next & 0x1) {
17268 env->CP0_BadVAddr = ctx->base.pc_next;
17269 generate_exception_end(ctx, EXCP_AdEL);
17273 op = (ctx->opcode >> 10) & 0x3f;
17274 /* Enforce properly-sized instructions in a delay slot */
17275 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17276 switch (op & 0x7) { /* MSB-3..MSB-5 */
17278 /* POOL32A, POOL32B, POOL32I, POOL32C */
17280 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17282 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17284 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17286 /* LB32, LH32, LWC132, LDC132, LW32 */
17287 if (ctx->hflags & MIPS_HFLAG_BDS16) {
17288 generate_exception_end(ctx, EXCP_RI);
17293 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17295 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17297 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17298 if (ctx->hflags & MIPS_HFLAG_BDS32) {
17299 generate_exception_end(ctx, EXCP_RI);
17309 int rd = mmreg(uMIPS_RD(ctx->opcode));
17310 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17311 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17314 switch (ctx->opcode & 0x1) {
17322 if (ctx->insn_flags & ISA_MIPS32R6) {
17323 /* In the Release 6 the register number location in
17324 * the instruction encoding has changed.
17326 gen_arith(ctx, opc, rs1, rd, rs2);
17328 gen_arith(ctx, opc, rd, rs1, rs2);
17334 int rd = mmreg(uMIPS_RD(ctx->opcode));
17335 int rs = mmreg(uMIPS_RS(ctx->opcode));
17336 int amount = (ctx->opcode >> 1) & 0x7;
17338 amount = amount == 0 ? 8 : amount;
17340 switch (ctx->opcode & 0x1) {
17349 gen_shift_imm(ctx, opc, rd, rs, amount);
17353 if (ctx->insn_flags & ISA_MIPS32R6) {
17354 gen_pool16c_r6_insn(ctx);
17356 gen_pool16c_insn(ctx);
17361 int rd = mmreg(uMIPS_RD(ctx->opcode));
17362 int rb = 28; /* GP */
17363 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17365 gen_ld(ctx, OPC_LW, rd, rb, offset);
17369 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17370 if (ctx->opcode & 1) {
17371 generate_exception_end(ctx, EXCP_RI);
17374 int enc_dest = uMIPS_RD(ctx->opcode);
17375 int enc_rt = uMIPS_RS2(ctx->opcode);
17376 int enc_rs = uMIPS_RS1(ctx->opcode);
17377 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17382 int rd = mmreg(uMIPS_RD(ctx->opcode));
17383 int rb = mmreg(uMIPS_RS(ctx->opcode));
17384 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17385 offset = (offset == 0xf ? -1 : offset);
17387 gen_ld(ctx, OPC_LBU, rd, rb, offset);
17392 int rd = mmreg(uMIPS_RD(ctx->opcode));
17393 int rb = mmreg(uMIPS_RS(ctx->opcode));
17394 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17396 gen_ld(ctx, OPC_LHU, rd, rb, offset);
17401 int rd = (ctx->opcode >> 5) & 0x1f;
17402 int rb = 29; /* SP */
17403 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17405 gen_ld(ctx, OPC_LW, rd, rb, offset);
17410 int rd = mmreg(uMIPS_RD(ctx->opcode));
17411 int rb = mmreg(uMIPS_RS(ctx->opcode));
17412 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17414 gen_ld(ctx, OPC_LW, rd, rb, offset);
17419 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17420 int rb = mmreg(uMIPS_RS(ctx->opcode));
17421 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17423 gen_st(ctx, OPC_SB, rd, rb, offset);
17428 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17429 int rb = mmreg(uMIPS_RS(ctx->opcode));
17430 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17432 gen_st(ctx, OPC_SH, rd, rb, offset);
17437 int rd = (ctx->opcode >> 5) & 0x1f;
17438 int rb = 29; /* SP */
17439 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17441 gen_st(ctx, OPC_SW, rd, rb, offset);
17446 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17447 int rb = mmreg(uMIPS_RS(ctx->opcode));
17448 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17450 gen_st(ctx, OPC_SW, rd, rb, offset);
17455 int rd = uMIPS_RD5(ctx->opcode);
17456 int rs = uMIPS_RS5(ctx->opcode);
17458 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17465 switch (ctx->opcode & 0x1) {
17475 switch (ctx->opcode & 0x1) {
17480 gen_addiur1sp(ctx);
17484 case B16: /* BC16 */
17485 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17486 sextract32(ctx->opcode, 0, 10) << 1,
17487 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17489 case BNEZ16: /* BNEZC16 */
17490 case BEQZ16: /* BEQZC16 */
17491 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17492 mmreg(uMIPS_RD(ctx->opcode)),
17493 0, sextract32(ctx->opcode, 0, 7) << 1,
17494 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17499 int reg = mmreg(uMIPS_RD(ctx->opcode));
17500 int imm = ZIMM(ctx->opcode, 0, 7);
17502 imm = (imm == 0x7f ? -1 : imm);
17503 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17509 generate_exception_end(ctx, EXCP_RI);
17512 decode_micromips32_opc(env, ctx);
17525 /* MAJOR, P16, and P32 pools opcodes */
17529 NM_MOVE_BALC = 0x02,
17537 NM_P16_SHIFT = 0x0c,
17555 NM_P_LS_U12 = 0x21,
17565 NM_P16_ADDU = 0x2c,
17579 NM_MOVEPREV = 0x3f,
17582 /* POOL32A instruction pool */
17584 NM_POOL32A0 = 0x00,
17585 NM_SPECIAL2 = 0x01,
17588 NM_POOL32A5 = 0x05,
17589 NM_POOL32A7 = 0x07,
17592 /* P.GP.W instruction pool */
17594 NM_ADDIUGP_W = 0x00,
17599 /* P48I instruction pool */
17603 NM_ADDIUGP48 = 0x02,
17604 NM_ADDIUPC48 = 0x03,
17609 /* P.U12 instruction pool */
17618 NM_ADDIUNEG = 0x08,
17625 /* POOL32F instruction pool */
17627 NM_POOL32F_0 = 0x00,
17628 NM_POOL32F_3 = 0x03,
17629 NM_POOL32F_5 = 0x05,
17632 /* POOL32S instruction pool */
17634 NM_POOL32S_0 = 0x00,
17635 NM_POOL32S_4 = 0x04,
17638 /* P.LUI instruction pool */
17644 /* P.GP.BH instruction pool */
17649 NM_ADDIUGP_B = 0x03,
17652 NM_P_GP_CP1 = 0x06,
17655 /* P.LS.U12 instruction pool */
17660 NM_P_PREFU12 = 0x03,
17673 /* P.LS.S9 instruction pool */
17679 NM_P_LS_UAWM = 0x05,
17682 /* P.BAL instruction pool */
17688 /* P.J instruction pool */
17691 NM_JALRC_HB = 0x01,
17692 NM_P_BALRSC = 0x08,
17695 /* P.BR1 instruction pool */
17703 /* P.BR2 instruction pool */
17710 /* P.BRI instruction pool */
17722 /* P16.SHIFT instruction pool */
17728 /* POOL16C instruction pool */
17730 NM_POOL16C_0 = 0x00,
17734 /* P16.A1 instruction pool */
17736 NM_ADDIUR1SP = 0x01,
17739 /* P16.A2 instruction pool */
17742 NM_P_ADDIURS5 = 0x01,
17745 /* P16.ADDU instruction pool */
17751 /* P16.SR instruction pool */
17754 NM_RESTORE_JRC16 = 0x01,
17757 /* P16.4X4 instruction pool */
17763 /* P16.LB instruction pool */
17770 /* P16.LH instruction pool */
17777 /* P.RI instruction pool */
17780 NM_P_SYSCALL = 0x01,
17785 /* POOL32A0 instruction pool */
17820 NM_D_E_MT_VPE = 0x56,
17828 /* CRC32 instruction pool */
17838 /* POOL32A5 instruction pool */
17840 NM_CMP_EQ_PH = 0x00,
17841 NM_CMP_LT_PH = 0x08,
17842 NM_CMP_LE_PH = 0x10,
17843 NM_CMPGU_EQ_QB = 0x18,
17844 NM_CMPGU_LT_QB = 0x20,
17845 NM_CMPGU_LE_QB = 0x28,
17846 NM_CMPGDU_EQ_QB = 0x30,
17847 NM_CMPGDU_LT_QB = 0x38,
17848 NM_CMPGDU_LE_QB = 0x40,
17849 NM_CMPU_EQ_QB = 0x48,
17850 NM_CMPU_LT_QB = 0x50,
17851 NM_CMPU_LE_QB = 0x58,
17852 NM_ADDQ_S_W = 0x60,
17853 NM_SUBQ_S_W = 0x68,
17857 NM_ADDQ_S_PH = 0x01,
17858 NM_ADDQH_R_PH = 0x09,
17859 NM_ADDQH_R_W = 0x11,
17860 NM_ADDU_S_QB = 0x19,
17861 NM_ADDU_S_PH = 0x21,
17862 NM_ADDUH_R_QB = 0x29,
17863 NM_SHRAV_R_PH = 0x31,
17864 NM_SHRAV_R_QB = 0x39,
17865 NM_SUBQ_S_PH = 0x41,
17866 NM_SUBQH_R_PH = 0x49,
17867 NM_SUBQH_R_W = 0x51,
17868 NM_SUBU_S_QB = 0x59,
17869 NM_SUBU_S_PH = 0x61,
17870 NM_SUBUH_R_QB = 0x69,
17871 NM_SHLLV_S_PH = 0x71,
17872 NM_PRECR_SRA_R_PH_W = 0x79,
17874 NM_MULEU_S_PH_QBL = 0x12,
17875 NM_MULEU_S_PH_QBR = 0x1a,
17876 NM_MULQ_RS_PH = 0x22,
17877 NM_MULQ_S_PH = 0x2a,
17878 NM_MULQ_RS_W = 0x32,
17879 NM_MULQ_S_W = 0x3a,
17882 NM_SHRAV_R_W = 0x5a,
17883 NM_SHRLV_PH = 0x62,
17884 NM_SHRLV_QB = 0x6a,
17885 NM_SHLLV_QB = 0x72,
17886 NM_SHLLV_S_W = 0x7a,
17890 NM_MULEQ_S_W_PHL = 0x04,
17891 NM_MULEQ_S_W_PHR = 0x0c,
17893 NM_MUL_S_PH = 0x05,
17894 NM_PRECR_QB_PH = 0x0d,
17895 NM_PRECRQ_QB_PH = 0x15,
17896 NM_PRECRQ_PH_W = 0x1d,
17897 NM_PRECRQ_RS_PH_W = 0x25,
17898 NM_PRECRQU_S_QB_PH = 0x2d,
17899 NM_PACKRL_PH = 0x35,
17903 NM_SHRA_R_W = 0x5e,
17904 NM_SHRA_R_PH = 0x66,
17905 NM_SHLL_S_PH = 0x76,
17906 NM_SHLL_S_W = 0x7e,
17911 /* POOL32A7 instruction pool */
17916 NM_POOL32AXF = 0x07,
17919 /* P.SR instruction pool */
17925 /* P.SHIFT instruction pool */
17933 /* P.ROTX instruction pool */
17938 /* P.INS instruction pool */
17943 /* P.EXT instruction pool */
17948 /* POOL32F_0 (fmt) instruction pool */
17953 NM_SELEQZ_S = 0x07,
17954 NM_SELEQZ_D = 0x47,
17958 NM_SELNEZ_S = 0x0f,
17959 NM_SELNEZ_D = 0x4f,
17974 /* POOL32F_3 instruction pool */
17978 NM_MINA_FMT = 0x04,
17979 NM_MAXA_FMT = 0x05,
17980 NM_POOL32FXF = 0x07,
17983 /* POOL32F_5 instruction pool */
17985 NM_CMP_CONDN_S = 0x00,
17986 NM_CMP_CONDN_D = 0x02,
17989 /* P.GP.LH instruction pool */
17995 /* P.GP.SH instruction pool */
18000 /* P.GP.CP1 instruction pool */
18008 /* P.LS.S0 instruction pool */
18025 NM_P_PREFS9 = 0x03,
18031 /* P.LS.S1 instruction pool */
18033 NM_ASET_ACLR = 0x02,
18041 /* P.LS.E0 instruction pool */
18057 /* P.PREFE instruction pool */
18063 /* P.LLE instruction pool */
18069 /* P.SCE instruction pool */
18075 /* P.LS.WM instruction pool */
18081 /* P.LS.UAWM instruction pool */
18087 /* P.BR3A instruction pool */
18093 NM_BPOSGE32C = 0x04,
18096 /* P16.RI instruction pool */
18098 NM_P16_SYSCALL = 0x01,
18103 /* POOL16C_0 instruction pool */
18105 NM_POOL16C_00 = 0x00,
18108 /* P16.JRC instruction pool */
18114 /* P.SYSCALL instruction pool */
18120 /* P.TRAP instruction pool */
18126 /* P.CMOVE instruction pool */
18132 /* POOL32Axf instruction pool */
18134 NM_POOL32AXF_1 = 0x01,
18135 NM_POOL32AXF_2 = 0x02,
18136 NM_POOL32AXF_4 = 0x04,
18137 NM_POOL32AXF_5 = 0x05,
18138 NM_POOL32AXF_7 = 0x07,
18141 /* POOL32Axf_1 instruction pool */
18143 NM_POOL32AXF_1_0 = 0x00,
18144 NM_POOL32AXF_1_1 = 0x01,
18145 NM_POOL32AXF_1_3 = 0x03,
18146 NM_POOL32AXF_1_4 = 0x04,
18147 NM_POOL32AXF_1_5 = 0x05,
18148 NM_POOL32AXF_1_7 = 0x07,
18151 /* POOL32Axf_2 instruction pool */
18153 NM_POOL32AXF_2_0_7 = 0x00,
18154 NM_POOL32AXF_2_8_15 = 0x01,
18155 NM_POOL32AXF_2_16_23 = 0x02,
18156 NM_POOL32AXF_2_24_31 = 0x03,
18159 /* POOL32Axf_7 instruction pool */
18161 NM_SHRA_R_QB = 0x0,
18166 /* POOL32Axf_1_0 instruction pool */
18174 /* POOL32Axf_1_1 instruction pool */
18180 /* POOL32Axf_1_3 instruction pool */
18188 /* POOL32Axf_1_4 instruction pool */
18194 /* POOL32Axf_1_5 instruction pool */
18196 NM_MAQ_S_W_PHR = 0x0,
18197 NM_MAQ_S_W_PHL = 0x1,
18198 NM_MAQ_SA_W_PHR = 0x2,
18199 NM_MAQ_SA_W_PHL = 0x3,
18202 /* POOL32Axf_1_7 instruction pool */
18206 NM_EXTR_RS_W = 0x2,
18210 /* POOL32Axf_2_0_7 instruction pool */
18213 NM_DPAQ_S_W_PH = 0x1,
18215 NM_DPSQ_S_W_PH = 0x3,
18222 /* POOL32Axf_2_8_15 instruction pool */
18224 NM_DPAX_W_PH = 0x0,
18225 NM_DPAQ_SA_L_W = 0x1,
18226 NM_DPSX_W_PH = 0x2,
18227 NM_DPSQ_SA_L_W = 0x3,
18230 NM_EXTRV_R_W = 0x7,
18233 /* POOL32Axf_2_16_23 instruction pool */
18235 NM_DPAU_H_QBL = 0x0,
18236 NM_DPAQX_S_W_PH = 0x1,
18237 NM_DPSU_H_QBL = 0x2,
18238 NM_DPSQX_S_W_PH = 0x3,
18241 NM_MULSA_W_PH = 0x6,
18242 NM_EXTRV_RS_W = 0x7,
18245 /* POOL32Axf_2_24_31 instruction pool */
18247 NM_DPAU_H_QBR = 0x0,
18248 NM_DPAQX_SA_W_PH = 0x1,
18249 NM_DPSU_H_QBR = 0x2,
18250 NM_DPSQX_SA_W_PH = 0x3,
18253 NM_MULSAQ_S_W_PH = 0x6,
18254 NM_EXTRV_S_H = 0x7,
18257 /* POOL32Axf_{4, 5} instruction pool */
18276 /* nanoMIPS DSP instructions */
18277 NM_ABSQ_S_QB = 0x00,
18278 NM_ABSQ_S_PH = 0x08,
18279 NM_ABSQ_S_W = 0x10,
18280 NM_PRECEQ_W_PHL = 0x28,
18281 NM_PRECEQ_W_PHR = 0x30,
18282 NM_PRECEQU_PH_QBL = 0x38,
18283 NM_PRECEQU_PH_QBR = 0x48,
18284 NM_PRECEU_PH_QBL = 0x58,
18285 NM_PRECEU_PH_QBR = 0x68,
18286 NM_PRECEQU_PH_QBLA = 0x39,
18287 NM_PRECEQU_PH_QBRA = 0x49,
18288 NM_PRECEU_PH_QBLA = 0x59,
18289 NM_PRECEU_PH_QBRA = 0x69,
18290 NM_REPLV_PH = 0x01,
18291 NM_REPLV_QB = 0x09,
18294 NM_RADDU_W_QB = 0x78,
18300 /* PP.SR instruction pool */
18304 NM_RESTORE_JRC = 0x03,
18307 /* P.SR.F instruction pool */
18310 NM_RESTOREF = 0x01,
18313 /* P16.SYSCALL instruction pool */
18315 NM_SYSCALL16 = 0x00,
18316 NM_HYPCALL16 = 0x01,
18319 /* POOL16C_00 instruction pool */
18327 /* PP.LSX and PP.LSXS instruction pool */
18365 /* ERETx instruction pool */
18371 /* POOL32FxF_{0, 1} insturction pool */
18380 NM_CVT_S_PL = 0x84,
18381 NM_CVT_S_PU = 0xa4,
18383 NM_CVT_L_S = 0x004,
18384 NM_CVT_L_D = 0x104,
18385 NM_CVT_W_S = 0x024,
18386 NM_CVT_W_D = 0x124,
18388 NM_RSQRT_S = 0x008,
18389 NM_RSQRT_D = 0x108,
18394 NM_RECIP_S = 0x048,
18395 NM_RECIP_D = 0x148,
18397 NM_FLOOR_L_S = 0x00c,
18398 NM_FLOOR_L_D = 0x10c,
18400 NM_FLOOR_W_S = 0x02c,
18401 NM_FLOOR_W_D = 0x12c,
18403 NM_CEIL_L_S = 0x04c,
18404 NM_CEIL_L_D = 0x14c,
18405 NM_CEIL_W_S = 0x06c,
18406 NM_CEIL_W_D = 0x16c,
18407 NM_TRUNC_L_S = 0x08c,
18408 NM_TRUNC_L_D = 0x18c,
18409 NM_TRUNC_W_S = 0x0ac,
18410 NM_TRUNC_W_D = 0x1ac,
18411 NM_ROUND_L_S = 0x0cc,
18412 NM_ROUND_L_D = 0x1cc,
18413 NM_ROUND_W_S = 0x0ec,
18414 NM_ROUND_W_D = 0x1ec,
18422 NM_CVT_D_S = 0x04d,
18423 NM_CVT_D_W = 0x0cd,
18424 NM_CVT_D_L = 0x14d,
18425 NM_CVT_S_D = 0x06d,
18426 NM_CVT_S_W = 0x0ed,
18427 NM_CVT_S_L = 0x16d,
18430 /* P.LL instruction pool */
18436 /* P.SC instruction pool */
18442 /* P.DVP instruction pool */
18451 * nanoMIPS decoding engine
18456 /* extraction utilities */
18458 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18459 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18460 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18461 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18462 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18463 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18465 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18466 static inline int decode_gpr_gpr3(int r)
18468 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18470 return map[r & 0x7];
18473 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18474 static inline int decode_gpr_gpr3_src_store(int r)
18476 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18478 return map[r & 0x7];
18481 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18482 static inline int decode_gpr_gpr4(int r)
18484 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18485 16, 17, 18, 19, 20, 21, 22, 23 };
18487 return map[r & 0xf];
18490 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18491 static inline int decode_gpr_gpr4_zero(int r)
18493 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18494 16, 17, 18, 19, 20, 21, 22, 23 };
18496 return map[r & 0xf];
18500 /* extraction utilities */
18502 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18503 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18504 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18505 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18506 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18507 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18510 static void gen_adjust_sp(DisasContext *ctx, int u)
18512 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18515 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18516 uint8_t gp, uint16_t u)
18519 TCGv va = tcg_temp_new();
18520 TCGv t0 = tcg_temp_new();
18522 while (counter != count) {
18523 bool use_gp = gp && (counter == count - 1);
18524 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18525 int this_offset = -((counter + 1) << 2);
18526 gen_base_offset_addr(ctx, va, 29, this_offset);
18527 gen_load_gpr(t0, this_rt);
18528 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18529 (MO_TEUL | ctx->default_tcg_memop_mask));
18533 /* adjust stack pointer */
18534 gen_adjust_sp(ctx, -u);
18540 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18541 uint8_t gp, uint16_t u)
18544 TCGv va = tcg_temp_new();
18545 TCGv t0 = tcg_temp_new();
18547 while (counter != count) {
18548 bool use_gp = gp && (counter == count - 1);
18549 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18550 int this_offset = u - ((counter + 1) << 2);
18551 gen_base_offset_addr(ctx, va, 29, this_offset);
18552 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18553 ctx->default_tcg_memop_mask);
18554 tcg_gen_ext32s_tl(t0, t0);
18555 gen_store_gpr(t0, this_rt);
18559 /* adjust stack pointer */
18560 gen_adjust_sp(ctx, u);
18566 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18568 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18569 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18571 switch (extract32(ctx->opcode, 2, 2)) {
18573 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18576 gen_logic(ctx, OPC_AND, rt, rt, rs);
18579 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18582 gen_logic(ctx, OPC_OR, rt, rt, rs);
18587 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18589 int rt = extract32(ctx->opcode, 21, 5);
18590 int rs = extract32(ctx->opcode, 16, 5);
18591 int rd = extract32(ctx->opcode, 11, 5);
18593 switch (extract32(ctx->opcode, 3, 7)) {
18595 switch (extract32(ctx->opcode, 10, 1)) {
18598 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18602 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18608 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18612 gen_bshfl(ctx, OPC_SEB, rs, rt);
18615 gen_bshfl(ctx, OPC_SEH, rs, rt);
18618 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18621 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18624 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18627 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18630 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18633 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18637 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18640 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18643 switch (extract32(ctx->opcode, 10, 1)) {
18645 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18648 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18653 gen_logic(ctx, OPC_AND, rd, rs, rt);
18656 gen_logic(ctx, OPC_OR, rd, rs, rt);
18659 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18662 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18665 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18670 #ifndef CONFIG_USER_ONLY
18671 TCGv t0 = tcg_temp_new();
18672 switch (extract32(ctx->opcode, 10, 1)) {
18675 check_cp0_enabled(ctx);
18676 gen_helper_dvp(t0, cpu_env);
18677 gen_store_gpr(t0, rt);
18682 check_cp0_enabled(ctx);
18683 gen_helper_evp(t0, cpu_env);
18684 gen_store_gpr(t0, rt);
18691 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18696 TCGv t0 = tcg_temp_new();
18697 TCGv t1 = tcg_temp_new();
18698 TCGv t2 = tcg_temp_new();
18700 gen_load_gpr(t1, rs);
18701 gen_load_gpr(t2, rt);
18702 tcg_gen_add_tl(t0, t1, t2);
18703 tcg_gen_ext32s_tl(t0, t0);
18704 tcg_gen_xor_tl(t1, t1, t2);
18705 tcg_gen_xor_tl(t2, t0, t2);
18706 tcg_gen_andc_tl(t1, t2, t1);
18708 /* operands of same sign, result different sign */
18709 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18710 gen_store_gpr(t0, rd);
18718 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18721 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18724 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18727 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18730 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18733 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18736 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18739 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18741 #ifndef CONFIG_USER_ONLY
18743 check_cp0_enabled(ctx);
18745 /* Treat as NOP. */
18748 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18751 check_cp0_enabled(ctx);
18753 TCGv t0 = tcg_temp_new();
18755 gen_load_gpr(t0, rt);
18756 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18760 case NM_D_E_MT_VPE:
18762 uint8_t sc = extract32(ctx->opcode, 10, 1);
18763 TCGv t0 = tcg_temp_new();
18770 gen_helper_dmt(t0);
18771 gen_store_gpr(t0, rt);
18772 } else if (rs == 0) {
18775 gen_helper_dvpe(t0, cpu_env);
18776 gen_store_gpr(t0, rt);
18778 generate_exception_end(ctx, EXCP_RI);
18785 gen_helper_emt(t0);
18786 gen_store_gpr(t0, rt);
18787 } else if (rs == 0) {
18790 gen_helper_evpe(t0, cpu_env);
18791 gen_store_gpr(t0, rt);
18793 generate_exception_end(ctx, EXCP_RI);
18804 TCGv t0 = tcg_temp_new();
18805 TCGv t1 = tcg_temp_new();
18807 gen_load_gpr(t0, rt);
18808 gen_load_gpr(t1, rs);
18809 gen_helper_fork(t0, t1);
18816 check_cp0_enabled(ctx);
18818 /* Treat as NOP. */
18821 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18822 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18826 check_cp0_enabled(ctx);
18827 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18828 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18833 TCGv t0 = tcg_temp_new();
18835 gen_load_gpr(t0, rs);
18836 gen_helper_yield(t0, cpu_env, t0);
18837 gen_store_gpr(t0, rt);
18843 generate_exception_end(ctx, EXCP_RI);
18849 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18850 int ret, int v1, int v2)
18856 t0 = tcg_temp_new_i32();
18858 v0_t = tcg_temp_new();
18859 v1_t = tcg_temp_new();
18861 tcg_gen_movi_i32(t0, v2 >> 3);
18863 gen_load_gpr(v0_t, ret);
18864 gen_load_gpr(v1_t, v1);
18867 case NM_MAQ_S_W_PHR:
18869 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18871 case NM_MAQ_S_W_PHL:
18873 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18875 case NM_MAQ_SA_W_PHR:
18877 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18879 case NM_MAQ_SA_W_PHL:
18881 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18884 generate_exception_end(ctx, EXCP_RI);
18888 tcg_temp_free_i32(t0);
18890 tcg_temp_free(v0_t);
18891 tcg_temp_free(v1_t);
18895 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18896 int ret, int v1, int v2)
18899 TCGv t0 = tcg_temp_new();
18900 TCGv t1 = tcg_temp_new();
18901 TCGv v0_t = tcg_temp_new();
18903 gen_load_gpr(v0_t, v1);
18906 case NM_POOL32AXF_1_0:
18908 switch (extract32(ctx->opcode, 12, 2)) {
18910 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18913 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18916 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18919 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18923 case NM_POOL32AXF_1_1:
18925 switch (extract32(ctx->opcode, 12, 2)) {
18927 tcg_gen_movi_tl(t0, v2);
18928 gen_helper_mthlip(t0, v0_t, cpu_env);
18931 tcg_gen_movi_tl(t0, v2 >> 3);
18932 gen_helper_shilo(t0, v0_t, cpu_env);
18935 generate_exception_end(ctx, EXCP_RI);
18939 case NM_POOL32AXF_1_3:
18941 imm = extract32(ctx->opcode, 14, 7);
18942 switch (extract32(ctx->opcode, 12, 2)) {
18944 tcg_gen_movi_tl(t0, imm);
18945 gen_helper_rddsp(t0, t0, cpu_env);
18946 gen_store_gpr(t0, ret);
18949 gen_load_gpr(t0, ret);
18950 tcg_gen_movi_tl(t1, imm);
18951 gen_helper_wrdsp(t0, t1, cpu_env);
18954 tcg_gen_movi_tl(t0, v2 >> 3);
18955 tcg_gen_movi_tl(t1, v1);
18956 gen_helper_extp(t0, t0, t1, cpu_env);
18957 gen_store_gpr(t0, ret);
18960 tcg_gen_movi_tl(t0, v2 >> 3);
18961 tcg_gen_movi_tl(t1, v1);
18962 gen_helper_extpdp(t0, t0, t1, cpu_env);
18963 gen_store_gpr(t0, ret);
18967 case NM_POOL32AXF_1_4:
18969 tcg_gen_movi_tl(t0, v2 >> 2);
18970 switch (extract32(ctx->opcode, 12, 1)) {
18972 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18973 gen_store_gpr(t0, ret);
18976 gen_helper_shrl_qb(t0, t0, v0_t);
18977 gen_store_gpr(t0, ret);
18981 case NM_POOL32AXF_1_5:
18982 opc = extract32(ctx->opcode, 12, 2);
18983 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18985 case NM_POOL32AXF_1_7:
18987 tcg_gen_movi_tl(t0, v2 >> 3);
18988 tcg_gen_movi_tl(t1, v1);
18989 switch (extract32(ctx->opcode, 12, 2)) {
18991 gen_helper_extr_w(t0, t0, t1, cpu_env);
18992 gen_store_gpr(t0, ret);
18995 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18996 gen_store_gpr(t0, ret);
18999 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
19000 gen_store_gpr(t0, ret);
19003 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
19004 gen_store_gpr(t0, ret);
19009 generate_exception_end(ctx, EXCP_RI);
19015 tcg_temp_free(v0_t);
19018 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
19019 TCGv v0, TCGv v1, int rd)
19023 t0 = tcg_temp_new_i32();
19025 tcg_gen_movi_i32(t0, rd >> 3);
19028 case NM_POOL32AXF_2_0_7:
19029 switch (extract32(ctx->opcode, 9, 3)) {
19032 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
19034 case NM_DPAQ_S_W_PH:
19036 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19040 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19042 case NM_DPSQ_S_W_PH:
19044 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19047 generate_exception_end(ctx, EXCP_RI);
19051 case NM_POOL32AXF_2_8_15:
19052 switch (extract32(ctx->opcode, 9, 3)) {
19055 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19057 case NM_DPAQ_SA_L_W:
19059 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19063 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19065 case NM_DPSQ_SA_L_W:
19067 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19070 generate_exception_end(ctx, EXCP_RI);
19074 case NM_POOL32AXF_2_16_23:
19075 switch (extract32(ctx->opcode, 9, 3)) {
19076 case NM_DPAU_H_QBL:
19078 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19080 case NM_DPAQX_S_W_PH:
19082 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19084 case NM_DPSU_H_QBL:
19086 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19088 case NM_DPSQX_S_W_PH:
19090 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19092 case NM_MULSA_W_PH:
19094 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19097 generate_exception_end(ctx, EXCP_RI);
19101 case NM_POOL32AXF_2_24_31:
19102 switch (extract32(ctx->opcode, 9, 3)) {
19103 case NM_DPAU_H_QBR:
19105 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19107 case NM_DPAQX_SA_W_PH:
19109 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19111 case NM_DPSU_H_QBR:
19113 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19115 case NM_DPSQX_SA_W_PH:
19117 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19119 case NM_MULSAQ_S_W_PH:
19121 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19124 generate_exception_end(ctx, EXCP_RI);
19129 generate_exception_end(ctx, EXCP_RI);
19133 tcg_temp_free_i32(t0);
19136 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19137 int rt, int rs, int rd)
19140 TCGv t0 = tcg_temp_new();
19141 TCGv t1 = tcg_temp_new();
19142 TCGv v0_t = tcg_temp_new();
19143 TCGv v1_t = tcg_temp_new();
19145 gen_load_gpr(v0_t, rt);
19146 gen_load_gpr(v1_t, rs);
19149 case NM_POOL32AXF_2_0_7:
19150 switch (extract32(ctx->opcode, 9, 3)) {
19152 case NM_DPAQ_S_W_PH:
19154 case NM_DPSQ_S_W_PH:
19155 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19160 gen_load_gpr(t0, rs);
19162 if (rd != 0 && rd != 2) {
19163 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19164 tcg_gen_ext32u_tl(t0, t0);
19165 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19166 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19168 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19174 int acc = extract32(ctx->opcode, 14, 2);
19175 TCGv_i64 t2 = tcg_temp_new_i64();
19176 TCGv_i64 t3 = tcg_temp_new_i64();
19178 gen_load_gpr(t0, rt);
19179 gen_load_gpr(t1, rs);
19180 tcg_gen_ext_tl_i64(t2, t0);
19181 tcg_gen_ext_tl_i64(t3, t1);
19182 tcg_gen_mul_i64(t2, t2, t3);
19183 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19184 tcg_gen_add_i64(t2, t2, t3);
19185 tcg_temp_free_i64(t3);
19186 gen_move_low32(cpu_LO[acc], t2);
19187 gen_move_high32(cpu_HI[acc], t2);
19188 tcg_temp_free_i64(t2);
19194 int acc = extract32(ctx->opcode, 14, 2);
19195 TCGv_i32 t2 = tcg_temp_new_i32();
19196 TCGv_i32 t3 = tcg_temp_new_i32();
19198 gen_load_gpr(t0, rs);
19199 gen_load_gpr(t1, rt);
19200 tcg_gen_trunc_tl_i32(t2, t0);
19201 tcg_gen_trunc_tl_i32(t3, t1);
19202 tcg_gen_muls2_i32(t2, t3, t2, t3);
19203 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19204 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19205 tcg_temp_free_i32(t2);
19206 tcg_temp_free_i32(t3);
19211 gen_load_gpr(v1_t, rs);
19212 tcg_gen_movi_tl(t0, rd >> 3);
19213 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19214 gen_store_gpr(t0, ret);
19218 case NM_POOL32AXF_2_8_15:
19219 switch (extract32(ctx->opcode, 9, 3)) {
19221 case NM_DPAQ_SA_L_W:
19223 case NM_DPSQ_SA_L_W:
19224 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19229 int acc = extract32(ctx->opcode, 14, 2);
19230 TCGv_i64 t2 = tcg_temp_new_i64();
19231 TCGv_i64 t3 = tcg_temp_new_i64();
19233 gen_load_gpr(t0, rs);
19234 gen_load_gpr(t1, rt);
19235 tcg_gen_ext32u_tl(t0, t0);
19236 tcg_gen_ext32u_tl(t1, t1);
19237 tcg_gen_extu_tl_i64(t2, t0);
19238 tcg_gen_extu_tl_i64(t3, t1);
19239 tcg_gen_mul_i64(t2, t2, t3);
19240 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19241 tcg_gen_add_i64(t2, t2, t3);
19242 tcg_temp_free_i64(t3);
19243 gen_move_low32(cpu_LO[acc], t2);
19244 gen_move_high32(cpu_HI[acc], t2);
19245 tcg_temp_free_i64(t2);
19251 int acc = extract32(ctx->opcode, 14, 2);
19252 TCGv_i32 t2 = tcg_temp_new_i32();
19253 TCGv_i32 t3 = tcg_temp_new_i32();
19255 gen_load_gpr(t0, rs);
19256 gen_load_gpr(t1, rt);
19257 tcg_gen_trunc_tl_i32(t2, t0);
19258 tcg_gen_trunc_tl_i32(t3, t1);
19259 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19260 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19261 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19262 tcg_temp_free_i32(t2);
19263 tcg_temp_free_i32(t3);
19268 tcg_gen_movi_tl(t0, rd >> 3);
19269 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19270 gen_store_gpr(t0, ret);
19273 generate_exception_end(ctx, EXCP_RI);
19277 case NM_POOL32AXF_2_16_23:
19278 switch (extract32(ctx->opcode, 9, 3)) {
19279 case NM_DPAU_H_QBL:
19280 case NM_DPAQX_S_W_PH:
19281 case NM_DPSU_H_QBL:
19282 case NM_DPSQX_S_W_PH:
19283 case NM_MULSA_W_PH:
19284 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19288 tcg_gen_movi_tl(t0, rd >> 3);
19289 gen_helper_extp(t0, t0, v1_t, cpu_env);
19290 gen_store_gpr(t0, ret);
19295 int acc = extract32(ctx->opcode, 14, 2);
19296 TCGv_i64 t2 = tcg_temp_new_i64();
19297 TCGv_i64 t3 = tcg_temp_new_i64();
19299 gen_load_gpr(t0, rs);
19300 gen_load_gpr(t1, rt);
19301 tcg_gen_ext_tl_i64(t2, t0);
19302 tcg_gen_ext_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);
19312 case NM_EXTRV_RS_W:
19314 tcg_gen_movi_tl(t0, rd >> 3);
19315 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19316 gen_store_gpr(t0, ret);
19320 case NM_POOL32AXF_2_24_31:
19321 switch (extract32(ctx->opcode, 9, 3)) {
19322 case NM_DPAU_H_QBR:
19323 case NM_DPAQX_SA_W_PH:
19324 case NM_DPSU_H_QBR:
19325 case NM_DPSQX_SA_W_PH:
19326 case NM_MULSAQ_S_W_PH:
19327 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19331 tcg_gen_movi_tl(t0, rd >> 3);
19332 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19333 gen_store_gpr(t0, ret);
19338 int acc = extract32(ctx->opcode, 14, 2);
19339 TCGv_i64 t2 = tcg_temp_new_i64();
19340 TCGv_i64 t3 = tcg_temp_new_i64();
19342 gen_load_gpr(t0, rs);
19343 gen_load_gpr(t1, rt);
19344 tcg_gen_ext32u_tl(t0, t0);
19345 tcg_gen_ext32u_tl(t1, t1);
19346 tcg_gen_extu_tl_i64(t2, t0);
19347 tcg_gen_extu_tl_i64(t3, t1);
19348 tcg_gen_mul_i64(t2, t2, t3);
19349 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19350 tcg_gen_sub_i64(t2, t3, t2);
19351 tcg_temp_free_i64(t3);
19352 gen_move_low32(cpu_LO[acc], t2);
19353 gen_move_high32(cpu_HI[acc], t2);
19354 tcg_temp_free_i64(t2);
19359 tcg_gen_movi_tl(t0, rd >> 3);
19360 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19361 gen_store_gpr(t0, ret);
19366 generate_exception_end(ctx, EXCP_RI);
19373 tcg_temp_free(v0_t);
19374 tcg_temp_free(v1_t);
19377 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19381 TCGv t0 = tcg_temp_new();
19382 TCGv v0_t = tcg_temp_new();
19384 gen_load_gpr(v0_t, rs);
19389 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19390 gen_store_gpr(v0_t, ret);
19394 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19395 gen_store_gpr(v0_t, ret);
19399 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19400 gen_store_gpr(v0_t, ret);
19402 case NM_PRECEQ_W_PHL:
19404 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19405 tcg_gen_ext32s_tl(v0_t, v0_t);
19406 gen_store_gpr(v0_t, ret);
19408 case NM_PRECEQ_W_PHR:
19410 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19411 tcg_gen_shli_tl(v0_t, v0_t, 16);
19412 tcg_gen_ext32s_tl(v0_t, v0_t);
19413 gen_store_gpr(v0_t, ret);
19415 case NM_PRECEQU_PH_QBL:
19417 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19418 gen_store_gpr(v0_t, ret);
19420 case NM_PRECEQU_PH_QBR:
19422 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19423 gen_store_gpr(v0_t, ret);
19425 case NM_PRECEQU_PH_QBLA:
19427 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19428 gen_store_gpr(v0_t, ret);
19430 case NM_PRECEQU_PH_QBRA:
19432 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19433 gen_store_gpr(v0_t, ret);
19435 case NM_PRECEU_PH_QBL:
19437 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19438 gen_store_gpr(v0_t, ret);
19440 case NM_PRECEU_PH_QBR:
19442 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19443 gen_store_gpr(v0_t, ret);
19445 case NM_PRECEU_PH_QBLA:
19447 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19448 gen_store_gpr(v0_t, ret);
19450 case NM_PRECEU_PH_QBRA:
19452 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19453 gen_store_gpr(v0_t, ret);
19457 tcg_gen_ext16u_tl(v0_t, v0_t);
19458 tcg_gen_shli_tl(t0, v0_t, 16);
19459 tcg_gen_or_tl(v0_t, v0_t, t0);
19460 tcg_gen_ext32s_tl(v0_t, v0_t);
19461 gen_store_gpr(v0_t, ret);
19465 tcg_gen_ext8u_tl(v0_t, v0_t);
19466 tcg_gen_shli_tl(t0, v0_t, 8);
19467 tcg_gen_or_tl(v0_t, v0_t, t0);
19468 tcg_gen_shli_tl(t0, v0_t, 16);
19469 tcg_gen_or_tl(v0_t, v0_t, t0);
19470 tcg_gen_ext32s_tl(v0_t, v0_t);
19471 gen_store_gpr(v0_t, ret);
19475 gen_helper_bitrev(v0_t, v0_t);
19476 gen_store_gpr(v0_t, ret);
19481 TCGv tv0 = tcg_temp_new();
19483 gen_load_gpr(tv0, rt);
19484 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19485 gen_store_gpr(v0_t, ret);
19486 tcg_temp_free(tv0);
19489 case NM_RADDU_W_QB:
19491 gen_helper_raddu_w_qb(v0_t, v0_t);
19492 gen_store_gpr(v0_t, ret);
19495 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19499 gen_cl(ctx, OPC_CLO, ret, rs);
19503 gen_cl(ctx, OPC_CLZ, ret, rs);
19506 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19509 generate_exception_end(ctx, EXCP_RI);
19513 tcg_temp_free(v0_t);
19517 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19518 int rt, int rs, int rd)
19520 TCGv t0 = tcg_temp_new();
19521 TCGv rs_t = tcg_temp_new();
19523 gen_load_gpr(rs_t, rs);
19528 tcg_gen_movi_tl(t0, rd >> 2);
19529 switch (extract32(ctx->opcode, 12, 1)) {
19532 gen_helper_shra_qb(t0, t0, rs_t);
19533 gen_store_gpr(t0, rt);
19537 gen_helper_shra_r_qb(t0, t0, rs_t);
19538 gen_store_gpr(t0, rt);
19544 tcg_gen_movi_tl(t0, rd >> 1);
19545 gen_helper_shrl_ph(t0, t0, rs_t);
19546 gen_store_gpr(t0, rt);
19552 target_long result;
19553 imm = extract32(ctx->opcode, 13, 8);
19554 result = (uint32_t)imm << 24 |
19555 (uint32_t)imm << 16 |
19556 (uint32_t)imm << 8 |
19558 result = (int32_t)result;
19559 tcg_gen_movi_tl(t0, result);
19560 gen_store_gpr(t0, rt);
19564 generate_exception_end(ctx, EXCP_RI);
19568 tcg_temp_free(rs_t);
19572 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19574 int rt = extract32(ctx->opcode, 21, 5);
19575 int rs = extract32(ctx->opcode, 16, 5);
19576 int rd = extract32(ctx->opcode, 11, 5);
19578 switch (extract32(ctx->opcode, 6, 3)) {
19579 case NM_POOL32AXF_1:
19581 int32_t op1 = extract32(ctx->opcode, 9, 3);
19582 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19585 case NM_POOL32AXF_2:
19587 int32_t op1 = extract32(ctx->opcode, 12, 2);
19588 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19591 case NM_POOL32AXF_4:
19593 int32_t op1 = extract32(ctx->opcode, 9, 7);
19594 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19597 case NM_POOL32AXF_5:
19598 switch (extract32(ctx->opcode, 9, 7)) {
19599 #ifndef CONFIG_USER_ONLY
19601 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19604 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19607 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19610 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19613 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19616 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19619 check_cp0_enabled(ctx);
19621 TCGv t0 = tcg_temp_new();
19623 save_cpu_state(ctx, 1);
19624 gen_helper_di(t0, cpu_env);
19625 gen_store_gpr(t0, rt);
19626 /* Stop translation as we may have switched the execution mode */
19627 ctx->base.is_jmp = DISAS_STOP;
19632 check_cp0_enabled(ctx);
19634 TCGv t0 = tcg_temp_new();
19636 save_cpu_state(ctx, 1);
19637 gen_helper_ei(t0, cpu_env);
19638 gen_store_gpr(t0, rt);
19639 /* Stop translation as we may have switched the execution mode */
19640 ctx->base.is_jmp = DISAS_STOP;
19645 gen_load_srsgpr(rs, rt);
19648 gen_store_srsgpr(rs, rt);
19651 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19654 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19657 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19661 generate_exception_end(ctx, EXCP_RI);
19665 case NM_POOL32AXF_7:
19667 int32_t op1 = extract32(ctx->opcode, 9, 3);
19668 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19672 generate_exception_end(ctx, EXCP_RI);
19677 /* Immediate Value Compact Branches */
19678 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19679 int rt, int32_t imm, int32_t offset)
19682 int bcond_compute = 0;
19683 TCGv t0 = tcg_temp_new();
19684 TCGv t1 = tcg_temp_new();
19686 gen_load_gpr(t0, rt);
19687 tcg_gen_movi_tl(t1, imm);
19688 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19690 /* Load needed operands and calculate btarget */
19693 if (rt == 0 && imm == 0) {
19694 /* Unconditional branch */
19695 } else if (rt == 0 && imm != 0) {
19700 cond = TCG_COND_EQ;
19706 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19707 generate_exception_end(ctx, EXCP_RI);
19709 } else if (rt == 0 && opc == NM_BBEQZC) {
19710 /* Unconditional branch */
19711 } else if (rt == 0 && opc == NM_BBNEZC) {
19715 tcg_gen_shri_tl(t0, t0, imm);
19716 tcg_gen_andi_tl(t0, t0, 1);
19717 tcg_gen_movi_tl(t1, 0);
19719 if (opc == NM_BBEQZC) {
19720 cond = TCG_COND_EQ;
19722 cond = TCG_COND_NE;
19727 if (rt == 0 && imm == 0) {
19730 } else if (rt == 0 && imm != 0) {
19731 /* Unconditional branch */
19734 cond = TCG_COND_NE;
19738 if (rt == 0 && imm == 0) {
19739 /* Unconditional branch */
19742 cond = TCG_COND_GE;
19747 cond = TCG_COND_LT;
19750 if (rt == 0 && imm == 0) {
19751 /* Unconditional branch */
19754 cond = TCG_COND_GEU;
19759 cond = TCG_COND_LTU;
19762 MIPS_INVAL("Immediate Value Compact branch");
19763 generate_exception_end(ctx, EXCP_RI);
19767 if (bcond_compute == 0) {
19768 /* Uncoditional compact branch */
19769 gen_goto_tb(ctx, 0, ctx->btarget);
19771 /* Conditional compact branch */
19772 TCGLabel *fs = gen_new_label();
19774 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19776 gen_goto_tb(ctx, 1, ctx->btarget);
19779 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19787 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19788 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19791 TCGv t0 = tcg_temp_new();
19792 TCGv t1 = tcg_temp_new();
19795 gen_load_gpr(t0, rs);
19799 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19802 /* calculate btarget */
19803 tcg_gen_shli_tl(t0, t0, 1);
19804 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19805 gen_op_addr_add(ctx, btarget, t1, t0);
19807 /* unconditional branch to register */
19808 tcg_gen_mov_tl(cpu_PC, btarget);
19809 tcg_gen_lookup_and_goto_ptr();
19815 /* nanoMIPS Branches */
19816 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19817 int rs, int rt, int32_t offset)
19819 int bcond_compute = 0;
19820 TCGv t0 = tcg_temp_new();
19821 TCGv t1 = tcg_temp_new();
19823 /* Load needed operands and calculate btarget */
19825 /* compact branch */
19828 gen_load_gpr(t0, rs);
19829 gen_load_gpr(t1, rt);
19831 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19835 if (rs == 0 || rs == rt) {
19836 /* OPC_BLEZALC, OPC_BGEZALC */
19837 /* OPC_BGTZALC, OPC_BLTZALC */
19838 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19840 gen_load_gpr(t0, rs);
19841 gen_load_gpr(t1, rt);
19843 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19846 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19850 /* OPC_BEQZC, OPC_BNEZC */
19851 gen_load_gpr(t0, rs);
19853 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19855 /* OPC_JIC, OPC_JIALC */
19856 TCGv tbase = tcg_temp_new();
19857 TCGv toffset = tcg_temp_new();
19859 gen_load_gpr(tbase, rt);
19860 tcg_gen_movi_tl(toffset, offset);
19861 gen_op_addr_add(ctx, btarget, tbase, toffset);
19862 tcg_temp_free(tbase);
19863 tcg_temp_free(toffset);
19867 MIPS_INVAL("Compact branch/jump");
19868 generate_exception_end(ctx, EXCP_RI);
19872 if (bcond_compute == 0) {
19873 /* Uncoditional compact branch */
19876 gen_goto_tb(ctx, 0, ctx->btarget);
19879 MIPS_INVAL("Compact branch/jump");
19880 generate_exception_end(ctx, EXCP_RI);
19884 /* Conditional compact branch */
19885 TCGLabel *fs = gen_new_label();
19889 if (rs == 0 && rt != 0) {
19891 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19892 } else if (rs != 0 && rt != 0 && rs == rt) {
19894 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19897 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19901 if (rs == 0 && rt != 0) {
19903 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19904 } else if (rs != 0 && rt != 0 && rs == rt) {
19906 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19909 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19913 if (rs == 0 && rt != 0) {
19915 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19916 } else if (rs != 0 && rt != 0 && rs == rt) {
19918 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19921 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19925 if (rs == 0 && rt != 0) {
19927 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19928 } else if (rs != 0 && rt != 0 && rs == rt) {
19930 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19933 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19937 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19940 MIPS_INVAL("Compact conditional branch/jump");
19941 generate_exception_end(ctx, EXCP_RI);
19945 /* Generating branch here as compact branches don't have delay slot */
19946 gen_goto_tb(ctx, 1, ctx->btarget);
19949 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19958 /* nanoMIPS CP1 Branches */
19959 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19960 int32_t ft, int32_t offset)
19962 target_ulong btarget;
19963 TCGv_i64 t0 = tcg_temp_new_i64();
19965 gen_load_fpr64(ctx, t0, ft);
19966 tcg_gen_andi_i64(t0, t0, 1);
19968 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19972 tcg_gen_xori_i64(t0, t0, 1);
19973 ctx->hflags |= MIPS_HFLAG_BC;
19976 /* t0 already set */
19977 ctx->hflags |= MIPS_HFLAG_BC;
19980 MIPS_INVAL("cp1 cond branch");
19981 generate_exception_end(ctx, EXCP_RI);
19985 tcg_gen_trunc_i64_tl(bcond, t0);
19987 ctx->btarget = btarget;
19990 tcg_temp_free_i64(t0);
19994 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19997 t0 = tcg_temp_new();
19998 t1 = tcg_temp_new();
20000 gen_load_gpr(t0, rs);
20001 gen_load_gpr(t1, rt);
20003 if ((extract32(ctx->opcode, 6, 1)) == 1) {
20004 /* PP.LSXS instructions require shifting */
20005 switch (extract32(ctx->opcode, 7, 4)) {
20010 tcg_gen_shli_tl(t0, t0, 1);
20017 tcg_gen_shli_tl(t0, t0, 2);
20021 tcg_gen_shli_tl(t0, t0, 3);
20025 gen_op_addr_add(ctx, t0, t0, t1);
20027 switch (extract32(ctx->opcode, 7, 4)) {
20029 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20031 gen_store_gpr(t0, rd);
20035 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20037 gen_store_gpr(t0, rd);
20041 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20043 gen_store_gpr(t0, rd);
20046 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20048 gen_store_gpr(t0, rd);
20052 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20054 gen_store_gpr(t0, rd);
20058 gen_load_gpr(t1, rd);
20059 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20065 gen_load_gpr(t1, rd);
20066 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20072 gen_load_gpr(t1, rd);
20073 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20077 /*case NM_LWC1XS:*/
20079 /*case NM_LDC1XS:*/
20081 /*case NM_SWC1XS:*/
20083 /*case NM_SDC1XS:*/
20084 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20085 check_cp1_enabled(ctx);
20086 switch (extract32(ctx->opcode, 7, 4)) {
20088 /*case NM_LWC1XS:*/
20089 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20092 /*case NM_LDC1XS:*/
20093 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20096 /*case NM_SWC1XS:*/
20097 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20100 /*case NM_SDC1XS:*/
20101 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20105 generate_exception_err(ctx, EXCP_CpU, 1);
20109 generate_exception_end(ctx, EXCP_RI);
20117 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20121 rt = extract32(ctx->opcode, 21, 5);
20122 rs = extract32(ctx->opcode, 16, 5);
20123 rd = extract32(ctx->opcode, 11, 5);
20125 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20126 generate_exception_end(ctx, EXCP_RI);
20129 check_cp1_enabled(ctx);
20130 switch (extract32(ctx->opcode, 0, 3)) {
20132 switch (extract32(ctx->opcode, 3, 7)) {
20134 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20137 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20140 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20143 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20146 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20149 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20152 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20155 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20158 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20161 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20164 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20167 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20170 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20173 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20176 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20179 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20182 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20185 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20188 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20191 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20194 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20197 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20200 generate_exception_end(ctx, EXCP_RI);
20205 switch (extract32(ctx->opcode, 3, 3)) {
20207 switch (extract32(ctx->opcode, 9, 1)) {
20209 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20212 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20217 switch (extract32(ctx->opcode, 9, 1)) {
20219 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20222 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20227 switch (extract32(ctx->opcode, 9, 1)) {
20229 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20232 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20237 switch (extract32(ctx->opcode, 9, 1)) {
20239 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20242 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20247 switch (extract32(ctx->opcode, 6, 8)) {
20249 gen_cp1(ctx, OPC_CFC1, rt, rs);
20252 gen_cp1(ctx, OPC_CTC1, rt, rs);
20255 gen_cp1(ctx, OPC_MFC1, rt, rs);
20258 gen_cp1(ctx, OPC_MTC1, rt, rs);
20261 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20264 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20267 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20270 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20273 switch (extract32(ctx->opcode, 6, 9)) {
20275 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20278 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20281 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20284 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20287 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20290 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20293 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20296 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20299 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20302 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20305 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20308 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20311 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20314 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20317 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20320 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20323 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20326 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20329 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20332 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20335 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20338 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20341 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20344 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20347 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20350 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20353 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20356 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20359 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20362 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20365 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20368 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20371 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20374 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20377 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20380 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20383 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20386 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20389 generate_exception_end(ctx, EXCP_RI);
20398 switch (extract32(ctx->opcode, 3, 3)) {
20399 case NM_CMP_CONDN_S:
20400 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20402 case NM_CMP_CONDN_D:
20403 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20406 generate_exception_end(ctx, EXCP_RI);
20411 generate_exception_end(ctx, EXCP_RI);
20416 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20417 int rd, int rs, int rt)
20420 TCGv t0 = tcg_temp_new();
20421 TCGv v1_t = tcg_temp_new();
20422 TCGv v2_t = tcg_temp_new();
20424 gen_load_gpr(v1_t, rs);
20425 gen_load_gpr(v2_t, rt);
20430 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20434 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20438 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20440 case NM_CMPU_EQ_QB:
20442 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20444 case NM_CMPU_LT_QB:
20446 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20448 case NM_CMPU_LE_QB:
20450 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20452 case NM_CMPGU_EQ_QB:
20454 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20455 gen_store_gpr(v1_t, ret);
20457 case NM_CMPGU_LT_QB:
20459 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20460 gen_store_gpr(v1_t, ret);
20462 case NM_CMPGU_LE_QB:
20464 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20465 gen_store_gpr(v1_t, ret);
20467 case NM_CMPGDU_EQ_QB:
20469 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20470 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20471 gen_store_gpr(v1_t, ret);
20473 case NM_CMPGDU_LT_QB:
20475 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20476 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20477 gen_store_gpr(v1_t, ret);
20479 case NM_CMPGDU_LE_QB:
20481 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20482 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20483 gen_store_gpr(v1_t, ret);
20487 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20488 gen_store_gpr(v1_t, ret);
20492 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20493 gen_store_gpr(v1_t, ret);
20497 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20498 gen_store_gpr(v1_t, ret);
20502 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20503 gen_store_gpr(v1_t, ret);
20507 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20508 gen_store_gpr(v1_t, ret);
20512 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20513 gen_store_gpr(v1_t, ret);
20517 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20518 gen_store_gpr(v1_t, ret);
20522 switch (extract32(ctx->opcode, 10, 1)) {
20525 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20526 gen_store_gpr(v1_t, ret);
20530 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20531 gen_store_gpr(v1_t, ret);
20535 case NM_ADDQH_R_PH:
20537 switch (extract32(ctx->opcode, 10, 1)) {
20540 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20541 gen_store_gpr(v1_t, ret);
20545 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20546 gen_store_gpr(v1_t, ret);
20552 switch (extract32(ctx->opcode, 10, 1)) {
20555 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20556 gen_store_gpr(v1_t, ret);
20560 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20561 gen_store_gpr(v1_t, ret);
20567 switch (extract32(ctx->opcode, 10, 1)) {
20570 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20571 gen_store_gpr(v1_t, ret);
20575 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20576 gen_store_gpr(v1_t, ret);
20582 switch (extract32(ctx->opcode, 10, 1)) {
20585 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20586 gen_store_gpr(v1_t, ret);
20590 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20591 gen_store_gpr(v1_t, ret);
20595 case NM_ADDUH_R_QB:
20597 switch (extract32(ctx->opcode, 10, 1)) {
20600 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20601 gen_store_gpr(v1_t, ret);
20605 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20606 gen_store_gpr(v1_t, ret);
20610 case NM_SHRAV_R_PH:
20612 switch (extract32(ctx->opcode, 10, 1)) {
20615 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20616 gen_store_gpr(v1_t, ret);
20620 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20621 gen_store_gpr(v1_t, ret);
20625 case NM_SHRAV_R_QB:
20627 switch (extract32(ctx->opcode, 10, 1)) {
20630 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20631 gen_store_gpr(v1_t, ret);
20635 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20636 gen_store_gpr(v1_t, ret);
20642 switch (extract32(ctx->opcode, 10, 1)) {
20645 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20646 gen_store_gpr(v1_t, ret);
20650 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20651 gen_store_gpr(v1_t, ret);
20655 case NM_SUBQH_R_PH:
20657 switch (extract32(ctx->opcode, 10, 1)) {
20660 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20661 gen_store_gpr(v1_t, ret);
20665 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20666 gen_store_gpr(v1_t, ret);
20672 switch (extract32(ctx->opcode, 10, 1)) {
20675 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20676 gen_store_gpr(v1_t, ret);
20680 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20681 gen_store_gpr(v1_t, ret);
20687 switch (extract32(ctx->opcode, 10, 1)) {
20690 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20691 gen_store_gpr(v1_t, ret);
20695 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20696 gen_store_gpr(v1_t, ret);
20702 switch (extract32(ctx->opcode, 10, 1)) {
20705 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20706 gen_store_gpr(v1_t, ret);
20710 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20711 gen_store_gpr(v1_t, ret);
20715 case NM_SUBUH_R_QB:
20717 switch (extract32(ctx->opcode, 10, 1)) {
20720 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20721 gen_store_gpr(v1_t, ret);
20725 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20726 gen_store_gpr(v1_t, ret);
20730 case NM_SHLLV_S_PH:
20732 switch (extract32(ctx->opcode, 10, 1)) {
20735 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20736 gen_store_gpr(v1_t, ret);
20740 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20741 gen_store_gpr(v1_t, ret);
20745 case NM_PRECR_SRA_R_PH_W:
20747 switch (extract32(ctx->opcode, 10, 1)) {
20749 /* PRECR_SRA_PH_W */
20751 TCGv_i32 sa_t = tcg_const_i32(rd);
20752 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20754 gen_store_gpr(v1_t, rt);
20755 tcg_temp_free_i32(sa_t);
20759 /* PRECR_SRA_R_PH_W */
20761 TCGv_i32 sa_t = tcg_const_i32(rd);
20762 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20764 gen_store_gpr(v1_t, rt);
20765 tcg_temp_free_i32(sa_t);
20770 case NM_MULEU_S_PH_QBL:
20772 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20773 gen_store_gpr(v1_t, ret);
20775 case NM_MULEU_S_PH_QBR:
20777 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20778 gen_store_gpr(v1_t, ret);
20780 case NM_MULQ_RS_PH:
20782 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20783 gen_store_gpr(v1_t, ret);
20787 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20788 gen_store_gpr(v1_t, ret);
20792 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20793 gen_store_gpr(v1_t, ret);
20797 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20798 gen_store_gpr(v1_t, ret);
20802 gen_load_gpr(t0, rs);
20804 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20806 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20810 gen_helper_modsub(v1_t, v1_t, v2_t);
20811 gen_store_gpr(v1_t, ret);
20815 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20816 gen_store_gpr(v1_t, ret);
20820 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20821 gen_store_gpr(v1_t, ret);
20825 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20826 gen_store_gpr(v1_t, ret);
20830 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20831 gen_store_gpr(v1_t, ret);
20835 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20836 gen_store_gpr(v1_t, ret);
20841 TCGv tv0 = tcg_temp_new();
20842 TCGv tv1 = tcg_temp_new();
20843 int16_t imm = extract32(ctx->opcode, 16, 7);
20845 tcg_gen_movi_tl(tv0, rd >> 3);
20846 tcg_gen_movi_tl(tv1, imm);
20847 gen_helper_shilo(tv0, tv1, cpu_env);
20850 case NM_MULEQ_S_W_PHL:
20852 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20853 gen_store_gpr(v1_t, ret);
20855 case NM_MULEQ_S_W_PHR:
20857 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20858 gen_store_gpr(v1_t, ret);
20862 switch (extract32(ctx->opcode, 10, 1)) {
20865 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20866 gen_store_gpr(v1_t, ret);
20870 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20871 gen_store_gpr(v1_t, ret);
20875 case NM_PRECR_QB_PH:
20877 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20878 gen_store_gpr(v1_t, ret);
20880 case NM_PRECRQ_QB_PH:
20882 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20883 gen_store_gpr(v1_t, ret);
20885 case NM_PRECRQ_PH_W:
20887 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20888 gen_store_gpr(v1_t, ret);
20890 case NM_PRECRQ_RS_PH_W:
20892 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20893 gen_store_gpr(v1_t, ret);
20895 case NM_PRECRQU_S_QB_PH:
20897 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20898 gen_store_gpr(v1_t, ret);
20902 tcg_gen_movi_tl(t0, rd);
20903 gen_helper_shra_r_w(v1_t, t0, v1_t);
20904 gen_store_gpr(v1_t, rt);
20908 tcg_gen_movi_tl(t0, rd >> 1);
20909 switch (extract32(ctx->opcode, 10, 1)) {
20912 gen_helper_shra_ph(v1_t, t0, v1_t);
20913 gen_store_gpr(v1_t, rt);
20917 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20918 gen_store_gpr(v1_t, rt);
20924 tcg_gen_movi_tl(t0, rd >> 1);
20925 switch (extract32(ctx->opcode, 10, 2)) {
20928 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20929 gen_store_gpr(v1_t, rt);
20933 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20934 gen_store_gpr(v1_t, rt);
20937 generate_exception_end(ctx, EXCP_RI);
20943 tcg_gen_movi_tl(t0, rd);
20944 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20945 gen_store_gpr(v1_t, rt);
20951 imm = sextract32(ctx->opcode, 11, 11);
20952 imm = (int16_t)(imm << 6) >> 6;
20954 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20959 generate_exception_end(ctx, EXCP_RI);
20964 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20972 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20973 ctx->opcode = (ctx->opcode << 16) | insn;
20975 rt = extract32(ctx->opcode, 21, 5);
20976 rs = extract32(ctx->opcode, 16, 5);
20977 rd = extract32(ctx->opcode, 11, 5);
20979 op = extract32(ctx->opcode, 26, 6);
20984 switch (extract32(ctx->opcode, 19, 2)) {
20987 generate_exception_end(ctx, EXCP_RI);
20990 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20991 generate_exception_end(ctx, EXCP_SYSCALL);
20993 generate_exception_end(ctx, EXCP_RI);
20997 generate_exception_end(ctx, EXCP_BREAK);
21000 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
21001 gen_helper_do_semihosting(cpu_env);
21003 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21004 generate_exception_end(ctx, EXCP_RI);
21006 generate_exception_end(ctx, EXCP_DBp);
21013 imm = extract32(ctx->opcode, 0, 16);
21015 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
21017 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21019 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21024 offset = sextract32(ctx->opcode, 0, 1) << 21 |
21025 extract32(ctx->opcode, 1, 20) << 1;
21026 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21027 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21031 switch (ctx->opcode & 0x07) {
21033 gen_pool32a0_nanomips_insn(env, ctx);
21037 int32_t op1 = extract32(ctx->opcode, 3, 7);
21038 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21042 switch (extract32(ctx->opcode, 3, 3)) {
21044 gen_p_lsx(ctx, rd, rs, rt);
21047 /* In nanoMIPS, the shift field directly encodes the shift
21048 * amount, meaning that the supported shift values are in
21049 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
21050 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21051 extract32(ctx->opcode, 9, 2) - 1);
21054 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21057 gen_pool32axf_nanomips_insn(env, ctx);
21060 generate_exception_end(ctx, EXCP_RI);
21065 generate_exception_end(ctx, EXCP_RI);
21070 switch (ctx->opcode & 0x03) {
21073 offset = extract32(ctx->opcode, 0, 21);
21074 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21078 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21081 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21084 generate_exception_end(ctx, EXCP_RI);
21090 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21091 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21092 switch (extract32(ctx->opcode, 16, 5)) {
21096 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21102 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21103 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21109 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21115 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21118 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21125 t0 = tcg_temp_new();
21127 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21130 tcg_gen_movi_tl(t0, addr);
21131 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21139 t0 = tcg_temp_new();
21140 t1 = tcg_temp_new();
21142 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21145 tcg_gen_movi_tl(t0, addr);
21146 gen_load_gpr(t1, rt);
21148 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21155 generate_exception_end(ctx, EXCP_RI);
21161 switch (extract32(ctx->opcode, 12, 4)) {
21163 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21166 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21169 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21172 switch (extract32(ctx->opcode, 20, 1)) {
21174 switch (ctx->opcode & 3) {
21176 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21177 extract32(ctx->opcode, 2, 1),
21178 extract32(ctx->opcode, 3, 9) << 3);
21181 case NM_RESTORE_JRC:
21182 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21183 extract32(ctx->opcode, 2, 1),
21184 extract32(ctx->opcode, 3, 9) << 3);
21185 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21186 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21190 generate_exception_end(ctx, EXCP_RI);
21195 generate_exception_end(ctx, EXCP_RI);
21200 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21203 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21207 TCGv t0 = tcg_temp_new();
21209 imm = extract32(ctx->opcode, 0, 12);
21210 gen_load_gpr(t0, rs);
21211 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21212 gen_store_gpr(t0, rt);
21218 imm = (int16_t) extract32(ctx->opcode, 0, 12);
21219 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21223 int shift = extract32(ctx->opcode, 0, 5);
21224 switch (extract32(ctx->opcode, 5, 4)) {
21226 if (rt == 0 && shift == 0) {
21228 } else if (rt == 0 && shift == 3) {
21229 /* EHB - treat as NOP */
21230 } else if (rt == 0 && shift == 5) {
21231 /* PAUSE - treat as NOP */
21232 } else if (rt == 0 && shift == 6) {
21234 gen_sync(extract32(ctx->opcode, 16, 5));
21237 gen_shift_imm(ctx, OPC_SLL, rt, rs,
21238 extract32(ctx->opcode, 0, 5));
21242 gen_shift_imm(ctx, OPC_SRL, rt, rs,
21243 extract32(ctx->opcode, 0, 5));
21246 gen_shift_imm(ctx, OPC_SRA, rt, rs,
21247 extract32(ctx->opcode, 0, 5));
21250 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21251 extract32(ctx->opcode, 0, 5));
21259 TCGv t0 = tcg_temp_new();
21260 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21261 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21263 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21265 gen_load_gpr(t0, rs);
21266 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21269 tcg_temp_free_i32(shift);
21270 tcg_temp_free_i32(shiftx);
21271 tcg_temp_free_i32(stripe);
21275 switch (((ctx->opcode >> 10) & 2) |
21276 (extract32(ctx->opcode, 5, 1))) {
21279 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21280 extract32(ctx->opcode, 6, 5));
21283 generate_exception_end(ctx, EXCP_RI);
21288 switch (((ctx->opcode >> 10) & 2) |
21289 (extract32(ctx->opcode, 5, 1))) {
21292 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21293 extract32(ctx->opcode, 6, 5));
21296 generate_exception_end(ctx, EXCP_RI);
21301 generate_exception_end(ctx, EXCP_RI);
21306 gen_pool32f_nanomips_insn(ctx);
21311 switch (extract32(ctx->opcode, 1, 1)) {
21314 tcg_gen_movi_tl(cpu_gpr[rt],
21315 sextract32(ctx->opcode, 0, 1) << 31 |
21316 extract32(ctx->opcode, 2, 10) << 21 |
21317 extract32(ctx->opcode, 12, 9) << 12);
21322 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21323 extract32(ctx->opcode, 2, 10) << 21 |
21324 extract32(ctx->opcode, 12, 9) << 12;
21326 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21327 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21334 uint32_t u = extract32(ctx->opcode, 0, 18);
21336 switch (extract32(ctx->opcode, 18, 3)) {
21338 gen_ld(ctx, OPC_LB, rt, 28, u);
21341 gen_st(ctx, OPC_SB, rt, 28, u);
21344 gen_ld(ctx, OPC_LBU, rt, 28, u);
21348 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21353 switch (ctx->opcode & 1) {
21355 gen_ld(ctx, OPC_LH, rt, 28, u);
21358 gen_ld(ctx, OPC_LHU, rt, 28, u);
21364 switch (ctx->opcode & 1) {
21366 gen_st(ctx, OPC_SH, rt, 28, u);
21369 generate_exception_end(ctx, EXCP_RI);
21375 switch (ctx->opcode & 0x3) {
21377 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21380 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21383 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21386 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21391 generate_exception_end(ctx, EXCP_RI);
21398 uint32_t u = extract32(ctx->opcode, 0, 12);
21400 switch (extract32(ctx->opcode, 12, 4)) {
21404 /* Break the TB to be able to sync copied instructions
21406 ctx->base.is_jmp = DISAS_STOP;
21409 /* Treat as NOP. */
21413 gen_ld(ctx, OPC_LB, rt, rs, u);
21416 gen_ld(ctx, OPC_LH, rt, rs, u);
21419 gen_ld(ctx, OPC_LW, rt, rs, u);
21422 gen_ld(ctx, OPC_LBU, rt, rs, u);
21425 gen_ld(ctx, OPC_LHU, rt, rs, u);
21428 gen_st(ctx, OPC_SB, rt, rs, u);
21431 gen_st(ctx, OPC_SH, rt, rs, u);
21434 gen_st(ctx, OPC_SW, rt, rs, u);
21437 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21440 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21443 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21446 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21449 generate_exception_end(ctx, EXCP_RI);
21456 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21457 extract32(ctx->opcode, 0, 8);
21459 switch (extract32(ctx->opcode, 8, 3)) {
21461 switch (extract32(ctx->opcode, 11, 4)) {
21463 gen_ld(ctx, OPC_LB, rt, rs, s);
21466 gen_ld(ctx, OPC_LH, rt, rs, s);
21469 gen_ld(ctx, OPC_LW, rt, rs, s);
21472 gen_ld(ctx, OPC_LBU, rt, rs, s);
21475 gen_ld(ctx, OPC_LHU, rt, rs, s);
21478 gen_st(ctx, OPC_SB, rt, rs, s);
21481 gen_st(ctx, OPC_SH, rt, rs, s);
21484 gen_st(ctx, OPC_SW, rt, rs, s);
21487 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21490 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21493 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21496 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21501 /* Break the TB to be able to sync copied instructions
21503 ctx->base.is_jmp = DISAS_STOP;
21506 /* Treat as NOP. */
21510 generate_exception_end(ctx, EXCP_RI);
21515 switch (extract32(ctx->opcode, 11, 4)) {
21520 TCGv t0 = tcg_temp_new();
21521 TCGv t1 = tcg_temp_new();
21523 gen_base_offset_addr(ctx, t0, rs, s);
21525 switch (extract32(ctx->opcode, 11, 4)) {
21527 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21529 gen_store_gpr(t0, rt);
21532 gen_load_gpr(t1, rt);
21533 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21542 switch (ctx->opcode & 0x03) {
21544 gen_ld(ctx, OPC_LL, rt, rs, s);
21548 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21553 switch (ctx->opcode & 0x03) {
21555 gen_st_cond(ctx, OPC_SC, rt, rs, s);
21559 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21564 check_cp0_enabled(ctx);
21565 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21566 gen_cache_operation(ctx, rt, rs, s);
21572 switch (extract32(ctx->opcode, 11, 4)) {
21575 check_cp0_enabled(ctx);
21576 gen_ld(ctx, OPC_LBE, rt, rs, s);
21580 check_cp0_enabled(ctx);
21581 gen_st(ctx, OPC_SBE, rt, rs, s);
21585 check_cp0_enabled(ctx);
21586 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21590 /* case NM_SYNCIE */
21592 check_cp0_enabled(ctx);
21593 /* Break the TB to be able to sync copied instructions
21595 ctx->base.is_jmp = DISAS_STOP;
21597 /* case NM_PREFE */
21599 check_cp0_enabled(ctx);
21600 /* Treat as NOP. */
21605 check_cp0_enabled(ctx);
21606 gen_ld(ctx, OPC_LHE, rt, rs, s);
21610 check_cp0_enabled(ctx);
21611 gen_st(ctx, OPC_SHE, rt, rs, s);
21615 check_cp0_enabled(ctx);
21616 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21619 check_nms_dl_il_sl_tl_l2c(ctx);
21620 gen_cache_operation(ctx, rt, rs, s);
21624 check_cp0_enabled(ctx);
21625 gen_ld(ctx, OPC_LWE, rt, rs, s);
21629 check_cp0_enabled(ctx);
21630 gen_st(ctx, OPC_SWE, rt, rs, s);
21633 switch (extract32(ctx->opcode, 2, 2)) {
21637 check_cp0_enabled(ctx);
21638 gen_ld(ctx, OPC_LLE, rt, rs, s);
21643 check_cp0_enabled(ctx);
21644 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21647 generate_exception_end(ctx, EXCP_RI);
21652 switch (extract32(ctx->opcode, 2, 2)) {
21656 check_cp0_enabled(ctx);
21657 gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21662 check_cp0_enabled(ctx);
21663 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21666 generate_exception_end(ctx, EXCP_RI);
21676 int count = extract32(ctx->opcode, 12, 3);
21679 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21680 extract32(ctx->opcode, 0, 8);
21681 TCGv va = tcg_temp_new();
21682 TCGv t1 = tcg_temp_new();
21683 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21684 NM_P_LS_UAWM ? MO_UNALN : 0;
21686 count = (count == 0) ? 8 : count;
21687 while (counter != count) {
21688 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21689 int this_offset = offset + (counter << 2);
21691 gen_base_offset_addr(ctx, va, rs, this_offset);
21693 switch (extract32(ctx->opcode, 11, 1)) {
21695 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21697 gen_store_gpr(t1, this_rt);
21698 if ((this_rt == rs) &&
21699 (counter != (count - 1))) {
21700 /* UNPREDICTABLE */
21704 this_rt = (rt == 0) ? 0 : this_rt;
21705 gen_load_gpr(t1, this_rt);
21706 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21717 generate_exception_end(ctx, EXCP_RI);
21725 TCGv t0 = tcg_temp_new();
21726 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21727 extract32(ctx->opcode, 1, 20) << 1;
21728 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21729 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21730 extract32(ctx->opcode, 21, 3));
21731 gen_load_gpr(t0, rt);
21732 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21733 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21739 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21740 extract32(ctx->opcode, 1, 24) << 1;
21742 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21744 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21747 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21752 switch (extract32(ctx->opcode, 12, 4)) {
21755 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21758 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21761 generate_exception_end(ctx, EXCP_RI);
21767 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21768 extract32(ctx->opcode, 1, 13) << 1;
21769 switch (extract32(ctx->opcode, 14, 2)) {
21772 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21775 s = sextract32(ctx->opcode, 0, 1) << 14 |
21776 extract32(ctx->opcode, 1, 13) << 1;
21777 check_cp1_enabled(ctx);
21778 switch (extract32(ctx->opcode, 16, 5)) {
21780 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21783 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21788 int32_t imm = extract32(ctx->opcode, 1, 13) |
21789 extract32(ctx->opcode, 0, 1) << 13;
21791 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21796 generate_exception_end(ctx, EXCP_RI);
21802 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21804 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21808 if (rs == rt || rt == 0) {
21809 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21810 } else if (rs == 0) {
21811 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21813 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21821 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21822 extract32(ctx->opcode, 1, 13) << 1;
21823 switch (extract32(ctx->opcode, 14, 2)) {
21826 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21829 if (rs != 0 && rt != 0 && rs == rt) {
21831 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21833 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21837 if (rs == 0 || rs == rt) {
21839 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21841 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21845 generate_exception_end(ctx, EXCP_RI);
21852 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21853 extract32(ctx->opcode, 1, 10) << 1;
21854 uint32_t u = extract32(ctx->opcode, 11, 7);
21856 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21861 generate_exception_end(ctx, EXCP_RI);
21867 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21870 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21871 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21872 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
21876 /* make sure instructions are on a halfword boundary */
21877 if (ctx->base.pc_next & 0x1) {
21878 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21879 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21880 tcg_temp_free(tmp);
21881 generate_exception_end(ctx, EXCP_AdEL);
21885 op = extract32(ctx->opcode, 10, 6);
21888 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21891 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21892 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21895 switch (extract32(ctx->opcode, 3, 2)) {
21896 case NM_P16_SYSCALL:
21897 if (extract32(ctx->opcode, 2, 1) == 0) {
21898 generate_exception_end(ctx, EXCP_SYSCALL);
21900 generate_exception_end(ctx, EXCP_RI);
21904 generate_exception_end(ctx, EXCP_BREAK);
21907 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21908 gen_helper_do_semihosting(cpu_env);
21910 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21911 generate_exception_end(ctx, EXCP_RI);
21913 generate_exception_end(ctx, EXCP_DBp);
21918 generate_exception_end(ctx, EXCP_RI);
21925 int shift = extract32(ctx->opcode, 0, 3);
21927 shift = (shift == 0) ? 8 : shift;
21929 switch (extract32(ctx->opcode, 3, 1)) {
21937 gen_shift_imm(ctx, opc, rt, rs, shift);
21941 switch (ctx->opcode & 1) {
21943 gen_pool16c_nanomips_insn(ctx);
21946 gen_ldxs(ctx, rt, rs, rd);
21951 switch (extract32(ctx->opcode, 6, 1)) {
21953 imm = extract32(ctx->opcode, 0, 6) << 2;
21954 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21957 generate_exception_end(ctx, EXCP_RI);
21962 switch (extract32(ctx->opcode, 3, 1)) {
21964 imm = extract32(ctx->opcode, 0, 3) << 2;
21965 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21967 case NM_P_ADDIURS5:
21968 rt = extract32(ctx->opcode, 5, 5);
21970 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21971 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21972 (extract32(ctx->opcode, 0, 3));
21973 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21979 switch (ctx->opcode & 0x1) {
21981 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21984 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21989 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21990 extract32(ctx->opcode, 5, 3);
21991 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21992 extract32(ctx->opcode, 0, 3);
21993 rt = decode_gpr_gpr4(rt);
21994 rs = decode_gpr_gpr4(rs);
21995 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21996 (extract32(ctx->opcode, 3, 1))) {
21999 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
22003 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
22006 generate_exception_end(ctx, EXCP_RI);
22012 int imm = extract32(ctx->opcode, 0, 7);
22013 imm = (imm == 0x7f ? -1 : imm);
22015 tcg_gen_movi_tl(cpu_gpr[rt], imm);
22021 uint32_t u = extract32(ctx->opcode, 0, 4);
22022 u = (u == 12) ? 0xff :
22023 (u == 13) ? 0xffff : u;
22024 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22028 offset = extract32(ctx->opcode, 0, 2);
22029 switch (extract32(ctx->opcode, 2, 2)) {
22031 gen_ld(ctx, OPC_LB, rt, rs, offset);
22034 rt = decode_gpr_gpr3_src_store(
22035 NANOMIPS_EXTRACT_RD(ctx->opcode));
22036 gen_st(ctx, OPC_SB, rt, rs, offset);
22039 gen_ld(ctx, OPC_LBU, rt, rs, offset);
22042 generate_exception_end(ctx, EXCP_RI);
22047 offset = extract32(ctx->opcode, 1, 2) << 1;
22048 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22050 gen_ld(ctx, OPC_LH, rt, rs, offset);
22053 rt = decode_gpr_gpr3_src_store(
22054 NANOMIPS_EXTRACT_RD(ctx->opcode));
22055 gen_st(ctx, OPC_SH, rt, rs, offset);
22058 gen_ld(ctx, OPC_LHU, rt, rs, offset);
22061 generate_exception_end(ctx, EXCP_RI);
22066 offset = extract32(ctx->opcode, 0, 4) << 2;
22067 gen_ld(ctx, OPC_LW, rt, rs, offset);
22070 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22071 offset = extract32(ctx->opcode, 0, 5) << 2;
22072 gen_ld(ctx, OPC_LW, rt, 29, offset);
22076 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22077 extract32(ctx->opcode, 5, 3);
22078 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22079 extract32(ctx->opcode, 0, 3);
22080 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22081 (extract32(ctx->opcode, 8, 1) << 2);
22082 rt = decode_gpr_gpr4(rt);
22083 rs = decode_gpr_gpr4(rs);
22084 gen_ld(ctx, OPC_LW, rt, rs, offset);
22088 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22089 extract32(ctx->opcode, 5, 3);
22090 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22091 extract32(ctx->opcode, 0, 3);
22092 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22093 (extract32(ctx->opcode, 8, 1) << 2);
22094 rt = decode_gpr_gpr4_zero(rt);
22095 rs = decode_gpr_gpr4(rs);
22096 gen_st(ctx, OPC_SW, rt, rs, offset);
22099 offset = extract32(ctx->opcode, 0, 7) << 2;
22100 gen_ld(ctx, OPC_LW, rt, 28, offset);
22103 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22104 offset = extract32(ctx->opcode, 0, 5) << 2;
22105 gen_st(ctx, OPC_SW, rt, 29, offset);
22108 rt = decode_gpr_gpr3_src_store(
22109 NANOMIPS_EXTRACT_RD(ctx->opcode));
22110 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
22111 offset = extract32(ctx->opcode, 0, 4) << 2;
22112 gen_st(ctx, OPC_SW, rt, rs, offset);
22115 rt = decode_gpr_gpr3_src_store(
22116 NANOMIPS_EXTRACT_RD(ctx->opcode));
22117 offset = extract32(ctx->opcode, 0, 7) << 2;
22118 gen_st(ctx, OPC_SW, rt, 28, offset);
22121 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22122 (sextract32(ctx->opcode, 0, 1) << 10) |
22123 (extract32(ctx->opcode, 1, 9) << 1));
22126 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22127 (sextract32(ctx->opcode, 0, 1) << 10) |
22128 (extract32(ctx->opcode, 1, 9) << 1));
22131 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22132 (sextract32(ctx->opcode, 0, 1) << 7) |
22133 (extract32(ctx->opcode, 1, 6) << 1));
22136 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22137 (sextract32(ctx->opcode, 0, 1) << 7) |
22138 (extract32(ctx->opcode, 1, 6) << 1));
22141 switch (ctx->opcode & 0xf) {
22144 switch (extract32(ctx->opcode, 4, 1)) {
22146 gen_compute_branch_nm(ctx, OPC_JR, 2,
22147 extract32(ctx->opcode, 5, 5), 0, 0);
22150 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22151 extract32(ctx->opcode, 5, 5), 31, 0);
22158 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22159 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22160 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22161 extract32(ctx->opcode, 0, 4) << 1);
22168 int count = extract32(ctx->opcode, 0, 4);
22169 int u = extract32(ctx->opcode, 4, 4) << 4;
22171 rt = 30 + extract32(ctx->opcode, 9, 1);
22172 switch (extract32(ctx->opcode, 8, 1)) {
22174 gen_save(ctx, rt, count, 0, u);
22176 case NM_RESTORE_JRC16:
22177 gen_restore(ctx, rt, count, 0, u);
22178 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22187 static const int gpr2reg1[] = {4, 5, 6, 7};
22188 static const int gpr2reg2[] = {5, 6, 7, 8};
22190 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22191 extract32(ctx->opcode, 8, 1);
22192 int r1 = gpr2reg1[rd2];
22193 int r2 = gpr2reg2[rd2];
22194 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22195 extract32(ctx->opcode, 0, 3);
22196 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22197 extract32(ctx->opcode, 5, 3);
22198 TCGv t0 = tcg_temp_new();
22199 TCGv t1 = tcg_temp_new();
22200 if (op == NM_MOVEP) {
22203 rs = decode_gpr_gpr4_zero(r3);
22204 rt = decode_gpr_gpr4_zero(r4);
22206 rd = decode_gpr_gpr4(r3);
22207 re = decode_gpr_gpr4(r4);
22211 gen_load_gpr(t0, rs);
22212 gen_load_gpr(t1, rt);
22213 tcg_gen_mov_tl(cpu_gpr[rd], t0);
22214 tcg_gen_mov_tl(cpu_gpr[re], t1);
22220 return decode_nanomips_32_48_opc(env, ctx);
22227 /* SmartMIPS extension to MIPS32 */
22229 #if defined(TARGET_MIPS64)
22231 /* MDMX extension to MIPS64 */
22235 /* MIPSDSP functions. */
22236 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22237 int rd, int base, int offset)
22242 t0 = tcg_temp_new();
22245 gen_load_gpr(t0, offset);
22246 } else if (offset == 0) {
22247 gen_load_gpr(t0, base);
22249 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22254 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22255 gen_store_gpr(t0, rd);
22258 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22259 gen_store_gpr(t0, rd);
22262 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22263 gen_store_gpr(t0, rd);
22265 #if defined(TARGET_MIPS64)
22267 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22268 gen_store_gpr(t0, rd);
22275 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22276 int ret, int v1, int v2)
22282 /* Treat as NOP. */
22286 v1_t = tcg_temp_new();
22287 v2_t = tcg_temp_new();
22289 gen_load_gpr(v1_t, v1);
22290 gen_load_gpr(v2_t, v2);
22293 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22294 case OPC_MULT_G_2E:
22298 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22300 case OPC_ADDUH_R_QB:
22301 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22304 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22306 case OPC_ADDQH_R_PH:
22307 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22310 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22312 case OPC_ADDQH_R_W:
22313 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22316 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22318 case OPC_SUBUH_R_QB:
22319 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22322 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22324 case OPC_SUBQH_R_PH:
22325 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22328 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22330 case OPC_SUBQH_R_W:
22331 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22335 case OPC_ABSQ_S_PH_DSP:
22337 case OPC_ABSQ_S_QB:
22339 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22341 case OPC_ABSQ_S_PH:
22343 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22347 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22349 case OPC_PRECEQ_W_PHL:
22351 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22352 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22354 case OPC_PRECEQ_W_PHR:
22356 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22357 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22358 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22360 case OPC_PRECEQU_PH_QBL:
22362 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22364 case OPC_PRECEQU_PH_QBR:
22366 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22368 case OPC_PRECEQU_PH_QBLA:
22370 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22372 case OPC_PRECEQU_PH_QBRA:
22374 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22376 case OPC_PRECEU_PH_QBL:
22378 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22380 case OPC_PRECEU_PH_QBR:
22382 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22384 case OPC_PRECEU_PH_QBLA:
22386 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22388 case OPC_PRECEU_PH_QBRA:
22390 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22394 case OPC_ADDU_QB_DSP:
22398 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22400 case OPC_ADDQ_S_PH:
22402 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22406 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22410 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22412 case OPC_ADDU_S_QB:
22414 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22418 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22420 case OPC_ADDU_S_PH:
22422 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22426 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22428 case OPC_SUBQ_S_PH:
22430 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22434 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22438 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22440 case OPC_SUBU_S_QB:
22442 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22446 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22448 case OPC_SUBU_S_PH:
22450 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22454 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22458 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22462 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22464 case OPC_RADDU_W_QB:
22466 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22470 case OPC_CMPU_EQ_QB_DSP:
22472 case OPC_PRECR_QB_PH:
22474 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22476 case OPC_PRECRQ_QB_PH:
22478 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22480 case OPC_PRECR_SRA_PH_W:
22483 TCGv_i32 sa_t = tcg_const_i32(v2);
22484 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22486 tcg_temp_free_i32(sa_t);
22489 case OPC_PRECR_SRA_R_PH_W:
22492 TCGv_i32 sa_t = tcg_const_i32(v2);
22493 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22495 tcg_temp_free_i32(sa_t);
22498 case OPC_PRECRQ_PH_W:
22500 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22502 case OPC_PRECRQ_RS_PH_W:
22504 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22506 case OPC_PRECRQU_S_QB_PH:
22508 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22512 #ifdef TARGET_MIPS64
22513 case OPC_ABSQ_S_QH_DSP:
22515 case OPC_PRECEQ_L_PWL:
22517 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22519 case OPC_PRECEQ_L_PWR:
22521 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22523 case OPC_PRECEQ_PW_QHL:
22525 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22527 case OPC_PRECEQ_PW_QHR:
22529 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22531 case OPC_PRECEQ_PW_QHLA:
22533 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22535 case OPC_PRECEQ_PW_QHRA:
22537 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22539 case OPC_PRECEQU_QH_OBL:
22541 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22543 case OPC_PRECEQU_QH_OBR:
22545 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22547 case OPC_PRECEQU_QH_OBLA:
22549 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22551 case OPC_PRECEQU_QH_OBRA:
22553 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22555 case OPC_PRECEU_QH_OBL:
22557 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22559 case OPC_PRECEU_QH_OBR:
22561 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22563 case OPC_PRECEU_QH_OBLA:
22565 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22567 case OPC_PRECEU_QH_OBRA:
22569 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22571 case OPC_ABSQ_S_OB:
22573 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22575 case OPC_ABSQ_S_PW:
22577 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22579 case OPC_ABSQ_S_QH:
22581 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22585 case OPC_ADDU_OB_DSP:
22587 case OPC_RADDU_L_OB:
22589 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22593 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22595 case OPC_SUBQ_S_PW:
22597 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22601 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22603 case OPC_SUBQ_S_QH:
22605 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22609 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22611 case OPC_SUBU_S_OB:
22613 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22617 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22619 case OPC_SUBU_S_QH:
22621 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22625 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22627 case OPC_SUBUH_R_OB:
22629 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22633 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22635 case OPC_ADDQ_S_PW:
22637 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22641 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22643 case OPC_ADDQ_S_QH:
22645 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22649 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22651 case OPC_ADDU_S_OB:
22653 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22657 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22659 case OPC_ADDU_S_QH:
22661 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22665 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22667 case OPC_ADDUH_R_OB:
22669 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22673 case OPC_CMPU_EQ_OB_DSP:
22675 case OPC_PRECR_OB_QH:
22677 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22679 case OPC_PRECR_SRA_QH_PW:
22682 TCGv_i32 ret_t = tcg_const_i32(ret);
22683 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22684 tcg_temp_free_i32(ret_t);
22687 case OPC_PRECR_SRA_R_QH_PW:
22690 TCGv_i32 sa_v = tcg_const_i32(ret);
22691 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22692 tcg_temp_free_i32(sa_v);
22695 case OPC_PRECRQ_OB_QH:
22697 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22699 case OPC_PRECRQ_PW_L:
22701 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22703 case OPC_PRECRQ_QH_PW:
22705 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22707 case OPC_PRECRQ_RS_QH_PW:
22709 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22711 case OPC_PRECRQU_S_OB_QH:
22713 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22720 tcg_temp_free(v1_t);
22721 tcg_temp_free(v2_t);
22724 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22725 int ret, int v1, int v2)
22733 /* Treat as NOP. */
22737 t0 = tcg_temp_new();
22738 v1_t = tcg_temp_new();
22739 v2_t = tcg_temp_new();
22741 tcg_gen_movi_tl(t0, v1);
22742 gen_load_gpr(v1_t, v1);
22743 gen_load_gpr(v2_t, v2);
22746 case OPC_SHLL_QB_DSP:
22748 op2 = MASK_SHLL_QB(ctx->opcode);
22752 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22756 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22760 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22764 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22766 case OPC_SHLL_S_PH:
22768 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22770 case OPC_SHLLV_S_PH:
22772 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22776 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22778 case OPC_SHLLV_S_W:
22780 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22784 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22788 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22792 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22796 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22800 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22802 case OPC_SHRA_R_QB:
22804 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22808 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22810 case OPC_SHRAV_R_QB:
22812 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22816 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22818 case OPC_SHRA_R_PH:
22820 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22824 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22826 case OPC_SHRAV_R_PH:
22828 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22832 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22834 case OPC_SHRAV_R_W:
22836 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22838 default: /* Invalid */
22839 MIPS_INVAL("MASK SHLL.QB");
22840 generate_exception_end(ctx, EXCP_RI);
22845 #ifdef TARGET_MIPS64
22846 case OPC_SHLL_OB_DSP:
22847 op2 = MASK_SHLL_OB(ctx->opcode);
22851 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22855 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22857 case OPC_SHLL_S_PW:
22859 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22861 case OPC_SHLLV_S_PW:
22863 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22867 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22871 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22875 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22879 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22881 case OPC_SHLL_S_QH:
22883 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22885 case OPC_SHLLV_S_QH:
22887 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22891 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22895 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22897 case OPC_SHRA_R_OB:
22899 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22901 case OPC_SHRAV_R_OB:
22903 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22907 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22911 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22913 case OPC_SHRA_R_PW:
22915 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22917 case OPC_SHRAV_R_PW:
22919 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22923 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22927 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22929 case OPC_SHRA_R_QH:
22931 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22933 case OPC_SHRAV_R_QH:
22935 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22939 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22943 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22947 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22951 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22953 default: /* Invalid */
22954 MIPS_INVAL("MASK SHLL.OB");
22955 generate_exception_end(ctx, EXCP_RI);
22963 tcg_temp_free(v1_t);
22964 tcg_temp_free(v2_t);
22967 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22968 int ret, int v1, int v2, int check_ret)
22974 if ((ret == 0) && (check_ret == 1)) {
22975 /* Treat as NOP. */
22979 t0 = tcg_temp_new_i32();
22980 v1_t = tcg_temp_new();
22981 v2_t = tcg_temp_new();
22983 tcg_gen_movi_i32(t0, ret);
22984 gen_load_gpr(v1_t, v1);
22985 gen_load_gpr(v2_t, v2);
22988 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22989 * the same mask and op1. */
22990 case OPC_MULT_G_2E:
22994 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22997 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23000 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23002 case OPC_MULQ_RS_W:
23003 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23007 case OPC_DPA_W_PH_DSP:
23009 case OPC_DPAU_H_QBL:
23011 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
23013 case OPC_DPAU_H_QBR:
23015 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
23017 case OPC_DPSU_H_QBL:
23019 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
23021 case OPC_DPSU_H_QBR:
23023 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23027 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23029 case OPC_DPAX_W_PH:
23031 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23033 case OPC_DPAQ_S_W_PH:
23035 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23037 case OPC_DPAQX_S_W_PH:
23039 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23041 case OPC_DPAQX_SA_W_PH:
23043 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23047 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23049 case OPC_DPSX_W_PH:
23051 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23053 case OPC_DPSQ_S_W_PH:
23055 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23057 case OPC_DPSQX_S_W_PH:
23059 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23061 case OPC_DPSQX_SA_W_PH:
23063 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23065 case OPC_MULSAQ_S_W_PH:
23067 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23069 case OPC_DPAQ_SA_L_W:
23071 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23073 case OPC_DPSQ_SA_L_W:
23075 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23077 case OPC_MAQ_S_W_PHL:
23079 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23081 case OPC_MAQ_S_W_PHR:
23083 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23085 case OPC_MAQ_SA_W_PHL:
23087 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23089 case OPC_MAQ_SA_W_PHR:
23091 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23093 case OPC_MULSA_W_PH:
23095 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23099 #ifdef TARGET_MIPS64
23100 case OPC_DPAQ_W_QH_DSP:
23102 int ac = ret & 0x03;
23103 tcg_gen_movi_i32(t0, ac);
23108 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23112 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23116 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23120 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23124 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23126 case OPC_DPAQ_S_W_QH:
23128 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23130 case OPC_DPAQ_SA_L_PW:
23132 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23134 case OPC_DPAU_H_OBL:
23136 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23138 case OPC_DPAU_H_OBR:
23140 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23144 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23146 case OPC_DPSQ_S_W_QH:
23148 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23150 case OPC_DPSQ_SA_L_PW:
23152 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23154 case OPC_DPSU_H_OBL:
23156 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23158 case OPC_DPSU_H_OBR:
23160 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23162 case OPC_MAQ_S_L_PWL:
23164 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23166 case OPC_MAQ_S_L_PWR:
23168 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23170 case OPC_MAQ_S_W_QHLL:
23172 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23174 case OPC_MAQ_SA_W_QHLL:
23176 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23178 case OPC_MAQ_S_W_QHLR:
23180 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23182 case OPC_MAQ_SA_W_QHLR:
23184 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23186 case OPC_MAQ_S_W_QHRL:
23188 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23190 case OPC_MAQ_SA_W_QHRL:
23192 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23194 case OPC_MAQ_S_W_QHRR:
23196 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23198 case OPC_MAQ_SA_W_QHRR:
23200 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23202 case OPC_MULSAQ_S_L_PW:
23204 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23206 case OPC_MULSAQ_S_W_QH:
23208 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23214 case OPC_ADDU_QB_DSP:
23216 case OPC_MULEU_S_PH_QBL:
23218 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23220 case OPC_MULEU_S_PH_QBR:
23222 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23224 case OPC_MULQ_RS_PH:
23226 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23228 case OPC_MULEQ_S_W_PHL:
23230 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23232 case OPC_MULEQ_S_W_PHR:
23234 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23236 case OPC_MULQ_S_PH:
23238 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23242 #ifdef TARGET_MIPS64
23243 case OPC_ADDU_OB_DSP:
23245 case OPC_MULEQ_S_PW_QHL:
23247 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23249 case OPC_MULEQ_S_PW_QHR:
23251 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23253 case OPC_MULEU_S_QH_OBL:
23255 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23257 case OPC_MULEU_S_QH_OBR:
23259 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23261 case OPC_MULQ_RS_QH:
23263 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23270 tcg_temp_free_i32(t0);
23271 tcg_temp_free(v1_t);
23272 tcg_temp_free(v2_t);
23275 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23283 /* Treat as NOP. */
23287 t0 = tcg_temp_new();
23288 val_t = tcg_temp_new();
23289 gen_load_gpr(val_t, val);
23292 case OPC_ABSQ_S_PH_DSP:
23296 gen_helper_bitrev(cpu_gpr[ret], val_t);
23301 target_long result;
23302 imm = (ctx->opcode >> 16) & 0xFF;
23303 result = (uint32_t)imm << 24 |
23304 (uint32_t)imm << 16 |
23305 (uint32_t)imm << 8 |
23307 result = (int32_t)result;
23308 tcg_gen_movi_tl(cpu_gpr[ret], result);
23313 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23314 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23315 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23316 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23317 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23318 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23323 imm = (ctx->opcode >> 16) & 0x03FF;
23324 imm = (int16_t)(imm << 6) >> 6;
23325 tcg_gen_movi_tl(cpu_gpr[ret], \
23326 (target_long)((int32_t)imm << 16 | \
23332 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23333 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23334 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23335 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23339 #ifdef TARGET_MIPS64
23340 case OPC_ABSQ_S_QH_DSP:
23347 imm = (ctx->opcode >> 16) & 0xFF;
23348 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23349 temp = (temp << 16) | temp;
23350 temp = (temp << 32) | temp;
23351 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23359 imm = (ctx->opcode >> 16) & 0x03FF;
23360 imm = (int16_t)(imm << 6) >> 6;
23361 temp = ((target_long)imm << 32) \
23362 | ((target_long)imm & 0xFFFFFFFF);
23363 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23371 imm = (ctx->opcode >> 16) & 0x03FF;
23372 imm = (int16_t)(imm << 6) >> 6;
23374 temp = ((uint64_t)(uint16_t)imm << 48) |
23375 ((uint64_t)(uint16_t)imm << 32) |
23376 ((uint64_t)(uint16_t)imm << 16) |
23377 (uint64_t)(uint16_t)imm;
23378 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23383 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23384 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23385 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23386 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23387 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23388 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23389 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23393 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23394 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23395 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23399 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23400 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23401 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23402 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23403 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23410 tcg_temp_free(val_t);
23413 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23414 uint32_t op1, uint32_t op2,
23415 int ret, int v1, int v2, int check_ret)
23421 if ((ret == 0) && (check_ret == 1)) {
23422 /* Treat as NOP. */
23426 t1 = tcg_temp_new();
23427 v1_t = tcg_temp_new();
23428 v2_t = tcg_temp_new();
23430 gen_load_gpr(v1_t, v1);
23431 gen_load_gpr(v2_t, v2);
23434 case OPC_CMPU_EQ_QB_DSP:
23436 case OPC_CMPU_EQ_QB:
23438 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23440 case OPC_CMPU_LT_QB:
23442 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23444 case OPC_CMPU_LE_QB:
23446 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23448 case OPC_CMPGU_EQ_QB:
23450 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23452 case OPC_CMPGU_LT_QB:
23454 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23456 case OPC_CMPGU_LE_QB:
23458 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23460 case OPC_CMPGDU_EQ_QB:
23462 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23463 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23464 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23465 tcg_gen_shli_tl(t1, t1, 24);
23466 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23468 case OPC_CMPGDU_LT_QB:
23470 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23471 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23472 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23473 tcg_gen_shli_tl(t1, t1, 24);
23474 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23476 case OPC_CMPGDU_LE_QB:
23478 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23479 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23480 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23481 tcg_gen_shli_tl(t1, t1, 24);
23482 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23484 case OPC_CMP_EQ_PH:
23486 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23488 case OPC_CMP_LT_PH:
23490 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23492 case OPC_CMP_LE_PH:
23494 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23498 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23502 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23504 case OPC_PACKRL_PH:
23506 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23510 #ifdef TARGET_MIPS64
23511 case OPC_CMPU_EQ_OB_DSP:
23513 case OPC_CMP_EQ_PW:
23515 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23517 case OPC_CMP_LT_PW:
23519 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23521 case OPC_CMP_LE_PW:
23523 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23525 case OPC_CMP_EQ_QH:
23527 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23529 case OPC_CMP_LT_QH:
23531 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23533 case OPC_CMP_LE_QH:
23535 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23537 case OPC_CMPGDU_EQ_OB:
23539 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23541 case OPC_CMPGDU_LT_OB:
23543 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23545 case OPC_CMPGDU_LE_OB:
23547 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23549 case OPC_CMPGU_EQ_OB:
23551 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23553 case OPC_CMPGU_LT_OB:
23555 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23557 case OPC_CMPGU_LE_OB:
23559 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23561 case OPC_CMPU_EQ_OB:
23563 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23565 case OPC_CMPU_LT_OB:
23567 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23569 case OPC_CMPU_LE_OB:
23571 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23573 case OPC_PACKRL_PW:
23575 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23579 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23583 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23587 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23595 tcg_temp_free(v1_t);
23596 tcg_temp_free(v2_t);
23599 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23600 uint32_t op1, int rt, int rs, int sa)
23607 /* Treat as NOP. */
23611 t0 = tcg_temp_new();
23612 gen_load_gpr(t0, rs);
23615 case OPC_APPEND_DSP:
23616 switch (MASK_APPEND(ctx->opcode)) {
23619 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23621 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23625 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23626 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23627 tcg_gen_shli_tl(t0, t0, 32 - sa);
23628 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23630 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23634 if (sa != 0 && sa != 2) {
23635 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23636 tcg_gen_ext32u_tl(t0, t0);
23637 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23638 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23640 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23642 default: /* Invalid */
23643 MIPS_INVAL("MASK APPEND");
23644 generate_exception_end(ctx, EXCP_RI);
23648 #ifdef TARGET_MIPS64
23649 case OPC_DAPPEND_DSP:
23650 switch (MASK_DAPPEND(ctx->opcode)) {
23653 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23657 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23658 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23659 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23663 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23664 tcg_gen_shli_tl(t0, t0, 64 - sa);
23665 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23670 if (sa != 0 && sa != 2 && sa != 4) {
23671 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23672 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23673 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23676 default: /* Invalid */
23677 MIPS_INVAL("MASK DAPPEND");
23678 generate_exception_end(ctx, EXCP_RI);
23687 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23688 int ret, int v1, int v2, int check_ret)
23697 if ((ret == 0) && (check_ret == 1)) {
23698 /* Treat as NOP. */
23702 t0 = tcg_temp_new();
23703 t1 = tcg_temp_new();
23704 v1_t = tcg_temp_new();
23705 v2_t = tcg_temp_new();
23707 gen_load_gpr(v1_t, v1);
23708 gen_load_gpr(v2_t, v2);
23711 case OPC_EXTR_W_DSP:
23715 tcg_gen_movi_tl(t0, v2);
23716 tcg_gen_movi_tl(t1, v1);
23717 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23720 tcg_gen_movi_tl(t0, v2);
23721 tcg_gen_movi_tl(t1, v1);
23722 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23724 case OPC_EXTR_RS_W:
23725 tcg_gen_movi_tl(t0, v2);
23726 tcg_gen_movi_tl(t1, v1);
23727 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23730 tcg_gen_movi_tl(t0, v2);
23731 tcg_gen_movi_tl(t1, v1);
23732 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23734 case OPC_EXTRV_S_H:
23735 tcg_gen_movi_tl(t0, v2);
23736 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23739 tcg_gen_movi_tl(t0, v2);
23740 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23742 case OPC_EXTRV_R_W:
23743 tcg_gen_movi_tl(t0, v2);
23744 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23746 case OPC_EXTRV_RS_W:
23747 tcg_gen_movi_tl(t0, v2);
23748 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23751 tcg_gen_movi_tl(t0, v2);
23752 tcg_gen_movi_tl(t1, v1);
23753 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23756 tcg_gen_movi_tl(t0, v2);
23757 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23760 tcg_gen_movi_tl(t0, v2);
23761 tcg_gen_movi_tl(t1, v1);
23762 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23765 tcg_gen_movi_tl(t0, v2);
23766 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23769 imm = (ctx->opcode >> 20) & 0x3F;
23770 tcg_gen_movi_tl(t0, ret);
23771 tcg_gen_movi_tl(t1, imm);
23772 gen_helper_shilo(t0, t1, cpu_env);
23775 tcg_gen_movi_tl(t0, ret);
23776 gen_helper_shilo(t0, v1_t, cpu_env);
23779 tcg_gen_movi_tl(t0, ret);
23780 gen_helper_mthlip(t0, v1_t, cpu_env);
23783 imm = (ctx->opcode >> 11) & 0x3FF;
23784 tcg_gen_movi_tl(t0, imm);
23785 gen_helper_wrdsp(v1_t, t0, cpu_env);
23788 imm = (ctx->opcode >> 16) & 0x03FF;
23789 tcg_gen_movi_tl(t0, imm);
23790 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23794 #ifdef TARGET_MIPS64
23795 case OPC_DEXTR_W_DSP:
23799 tcg_gen_movi_tl(t0, ret);
23800 gen_helper_dmthlip(v1_t, t0, cpu_env);
23804 int shift = (ctx->opcode >> 19) & 0x7F;
23805 int ac = (ctx->opcode >> 11) & 0x03;
23806 tcg_gen_movi_tl(t0, shift);
23807 tcg_gen_movi_tl(t1, ac);
23808 gen_helper_dshilo(t0, t1, cpu_env);
23813 int ac = (ctx->opcode >> 11) & 0x03;
23814 tcg_gen_movi_tl(t0, ac);
23815 gen_helper_dshilo(v1_t, t0, cpu_env);
23819 tcg_gen_movi_tl(t0, v2);
23820 tcg_gen_movi_tl(t1, v1);
23822 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23825 tcg_gen_movi_tl(t0, v2);
23826 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23829 tcg_gen_movi_tl(t0, v2);
23830 tcg_gen_movi_tl(t1, v1);
23831 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23834 tcg_gen_movi_tl(t0, v2);
23835 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23838 tcg_gen_movi_tl(t0, v2);
23839 tcg_gen_movi_tl(t1, v1);
23840 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23842 case OPC_DEXTR_R_L:
23843 tcg_gen_movi_tl(t0, v2);
23844 tcg_gen_movi_tl(t1, v1);
23845 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23847 case OPC_DEXTR_RS_L:
23848 tcg_gen_movi_tl(t0, v2);
23849 tcg_gen_movi_tl(t1, v1);
23850 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23853 tcg_gen_movi_tl(t0, v2);
23854 tcg_gen_movi_tl(t1, v1);
23855 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23857 case OPC_DEXTR_R_W:
23858 tcg_gen_movi_tl(t0, v2);
23859 tcg_gen_movi_tl(t1, v1);
23860 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23862 case OPC_DEXTR_RS_W:
23863 tcg_gen_movi_tl(t0, v2);
23864 tcg_gen_movi_tl(t1, v1);
23865 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23867 case OPC_DEXTR_S_H:
23868 tcg_gen_movi_tl(t0, v2);
23869 tcg_gen_movi_tl(t1, v1);
23870 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23872 case OPC_DEXTRV_S_H:
23873 tcg_gen_movi_tl(t0, v2);
23874 tcg_gen_movi_tl(t1, v1);
23875 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23878 tcg_gen_movi_tl(t0, v2);
23879 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23881 case OPC_DEXTRV_R_L:
23882 tcg_gen_movi_tl(t0, v2);
23883 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23885 case OPC_DEXTRV_RS_L:
23886 tcg_gen_movi_tl(t0, v2);
23887 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23890 tcg_gen_movi_tl(t0, v2);
23891 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23893 case OPC_DEXTRV_R_W:
23894 tcg_gen_movi_tl(t0, v2);
23895 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23897 case OPC_DEXTRV_RS_W:
23898 tcg_gen_movi_tl(t0, v2);
23899 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23908 tcg_temp_free(v1_t);
23909 tcg_temp_free(v2_t);
23912 /* End MIPSDSP functions. */
23914 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23916 int rs, rt, rd, sa;
23919 rs = (ctx->opcode >> 21) & 0x1f;
23920 rt = (ctx->opcode >> 16) & 0x1f;
23921 rd = (ctx->opcode >> 11) & 0x1f;
23922 sa = (ctx->opcode >> 6) & 0x1f;
23924 op1 = MASK_SPECIAL(ctx->opcode);
23927 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23933 op2 = MASK_R6_MULDIV(ctx->opcode);
23943 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23946 MIPS_INVAL("special_r6 muldiv");
23947 generate_exception_end(ctx, EXCP_RI);
23953 gen_cond_move(ctx, op1, rd, rs, rt);
23957 if (rt == 0 && sa == 1) {
23958 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23959 We need additionally to check other fields */
23960 gen_cl(ctx, op1, rd, rs);
23962 generate_exception_end(ctx, EXCP_RI);
23966 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23967 gen_helper_do_semihosting(cpu_env);
23969 if (ctx->hflags & MIPS_HFLAG_SBRI) {
23970 generate_exception_end(ctx, EXCP_RI);
23972 generate_exception_end(ctx, EXCP_DBp);
23976 #if defined(TARGET_MIPS64)
23978 check_mips_64(ctx);
23979 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23983 if (rt == 0 && sa == 1) {
23984 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23985 We need additionally to check other fields */
23986 check_mips_64(ctx);
23987 gen_cl(ctx, op1, rd, rs);
23989 generate_exception_end(ctx, EXCP_RI);
23997 op2 = MASK_R6_MULDIV(ctx->opcode);
24007 check_mips_64(ctx);
24008 gen_r6_muldiv(ctx, op2, rd, rs, rt);
24011 MIPS_INVAL("special_r6 muldiv");
24012 generate_exception_end(ctx, EXCP_RI);
24017 default: /* Invalid */
24018 MIPS_INVAL("special_r6");
24019 generate_exception_end(ctx, EXCP_RI);
24024 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24026 int rs = extract32(ctx->opcode, 21, 5);
24027 int rt = extract32(ctx->opcode, 16, 5);
24028 int rd = extract32(ctx->opcode, 11, 5);
24029 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24032 case OPC_MOVN: /* Conditional move */
24034 gen_cond_move(ctx, op1, rd, rs, rt);
24036 case OPC_MFHI: /* Move from HI/LO */
24038 gen_HILO(ctx, op1, 0, rd);
24041 case OPC_MTLO: /* Move to HI/LO */
24042 gen_HILO(ctx, op1, 0, rs);
24046 gen_mul_txx9(ctx, op1, rd, rs, rt);
24050 gen_muldiv(ctx, op1, 0, rs, rt);
24052 #if defined(TARGET_MIPS64)
24057 check_insn_opc_user_only(ctx, INSN_R5900);
24058 gen_muldiv(ctx, op1, 0, rs, rt);
24062 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24064 default: /* Invalid */
24065 MIPS_INVAL("special_tx79");
24066 generate_exception_end(ctx, EXCP_RI);
24071 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24073 int rs, rt, rd, sa;
24076 rs = (ctx->opcode >> 21) & 0x1f;
24077 rt = (ctx->opcode >> 16) & 0x1f;
24078 rd = (ctx->opcode >> 11) & 0x1f;
24079 sa = (ctx->opcode >> 6) & 0x1f;
24081 op1 = MASK_SPECIAL(ctx->opcode);
24083 case OPC_MOVN: /* Conditional move */
24085 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24086 INSN_LOONGSON2E | INSN_LOONGSON2F);
24087 gen_cond_move(ctx, op1, rd, rs, rt);
24089 case OPC_MFHI: /* Move from HI/LO */
24091 gen_HILO(ctx, op1, rs & 3, rd);
24094 case OPC_MTLO: /* Move to HI/LO */
24095 gen_HILO(ctx, op1, rd & 3, rs);
24098 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24099 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24100 check_cp1_enabled(ctx);
24101 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24102 (ctx->opcode >> 16) & 1);
24104 generate_exception_err(ctx, EXCP_CpU, 1);
24110 check_insn(ctx, INSN_VR54XX);
24111 op1 = MASK_MUL_VR54XX(ctx->opcode);
24112 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24114 gen_muldiv(ctx, op1, rd & 3, rs, rt);
24119 gen_muldiv(ctx, op1, 0, rs, rt);
24121 #if defined(TARGET_MIPS64)
24126 check_insn(ctx, ISA_MIPS3);
24127 check_mips_64(ctx);
24128 gen_muldiv(ctx, op1, 0, rs, rt);
24132 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24135 #ifdef MIPS_STRICT_STANDARD
24136 MIPS_INVAL("SPIM");
24137 generate_exception_end(ctx, EXCP_RI);
24139 /* Implemented as RI exception for now. */
24140 MIPS_INVAL("spim (unofficial)");
24141 generate_exception_end(ctx, EXCP_RI);
24144 default: /* Invalid */
24145 MIPS_INVAL("special_legacy");
24146 generate_exception_end(ctx, EXCP_RI);
24151 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24153 int rs, rt, rd, sa;
24156 rs = (ctx->opcode >> 21) & 0x1f;
24157 rt = (ctx->opcode >> 16) & 0x1f;
24158 rd = (ctx->opcode >> 11) & 0x1f;
24159 sa = (ctx->opcode >> 6) & 0x1f;
24161 op1 = MASK_SPECIAL(ctx->opcode);
24163 case OPC_SLL: /* Shift with immediate */
24164 if (sa == 5 && rd == 0 &&
24165 rs == 0 && rt == 0) { /* PAUSE */
24166 if ((ctx->insn_flags & ISA_MIPS32R6) &&
24167 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24168 generate_exception_end(ctx, EXCP_RI);
24174 gen_shift_imm(ctx, op1, rd, rt, sa);
24177 switch ((ctx->opcode >> 21) & 0x1f) {
24179 /* rotr is decoded as srl on non-R2 CPUs */
24180 if (ctx->insn_flags & ISA_MIPS32R2) {
24185 gen_shift_imm(ctx, op1, rd, rt, sa);
24188 generate_exception_end(ctx, EXCP_RI);
24196 gen_arith(ctx, op1, rd, rs, rt);
24198 case OPC_SLLV: /* Shifts */
24200 gen_shift(ctx, op1, rd, rs, rt);
24203 switch ((ctx->opcode >> 6) & 0x1f) {
24205 /* rotrv is decoded as srlv on non-R2 CPUs */
24206 if (ctx->insn_flags & ISA_MIPS32R2) {
24211 gen_shift(ctx, op1, rd, rs, rt);
24214 generate_exception_end(ctx, EXCP_RI);
24218 case OPC_SLT: /* Set on less than */
24220 gen_slt(ctx, op1, rd, rs, rt);
24222 case OPC_AND: /* Logic*/
24226 gen_logic(ctx, op1, rd, rs, rt);
24229 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24231 case OPC_TGE: /* Traps */
24237 check_insn(ctx, ISA_MIPS2);
24238 gen_trap(ctx, op1, rs, rt, -1);
24240 case OPC_LSA: /* OPC_PMON */
24241 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24242 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24243 decode_opc_special_r6(env, ctx);
24245 /* Pmon entry point, also R4010 selsl */
24246 #ifdef MIPS_STRICT_STANDARD
24247 MIPS_INVAL("PMON / selsl");
24248 generate_exception_end(ctx, EXCP_RI);
24250 gen_helper_0e0i(pmon, sa);
24255 generate_exception_end(ctx, EXCP_SYSCALL);
24258 generate_exception_end(ctx, EXCP_BREAK);
24261 check_insn(ctx, ISA_MIPS2);
24262 gen_sync(extract32(ctx->opcode, 6, 5));
24265 #if defined(TARGET_MIPS64)
24266 /* MIPS64 specific opcodes */
24271 check_insn(ctx, ISA_MIPS3);
24272 check_mips_64(ctx);
24273 gen_shift_imm(ctx, op1, rd, rt, sa);
24276 switch ((ctx->opcode >> 21) & 0x1f) {
24278 /* drotr is decoded as dsrl on non-R2 CPUs */
24279 if (ctx->insn_flags & ISA_MIPS32R2) {
24284 check_insn(ctx, ISA_MIPS3);
24285 check_mips_64(ctx);
24286 gen_shift_imm(ctx, op1, rd, rt, sa);
24289 generate_exception_end(ctx, EXCP_RI);
24294 switch ((ctx->opcode >> 21) & 0x1f) {
24296 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24297 if (ctx->insn_flags & ISA_MIPS32R2) {
24302 check_insn(ctx, ISA_MIPS3);
24303 check_mips_64(ctx);
24304 gen_shift_imm(ctx, op1, rd, rt, sa);
24307 generate_exception_end(ctx, EXCP_RI);
24315 check_insn(ctx, ISA_MIPS3);
24316 check_mips_64(ctx);
24317 gen_arith(ctx, op1, rd, rs, rt);
24321 check_insn(ctx, ISA_MIPS3);
24322 check_mips_64(ctx);
24323 gen_shift(ctx, op1, rd, rs, rt);
24326 switch ((ctx->opcode >> 6) & 0x1f) {
24328 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24329 if (ctx->insn_flags & ISA_MIPS32R2) {
24334 check_insn(ctx, ISA_MIPS3);
24335 check_mips_64(ctx);
24336 gen_shift(ctx, op1, rd, rs, rt);
24339 generate_exception_end(ctx, EXCP_RI);
24344 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24345 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24346 decode_opc_special_r6(env, ctx);
24351 if (ctx->insn_flags & ISA_MIPS32R6) {
24352 decode_opc_special_r6(env, ctx);
24353 } else if (ctx->insn_flags & INSN_R5900) {
24354 decode_opc_special_tx79(env, ctx);
24356 decode_opc_special_legacy(env, ctx);
24362 #if !defined(TARGET_MIPS64)
24364 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24365 #define MXU_APTN1_A 0
24366 #define MXU_APTN1_S 1
24368 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24369 #define MXU_APTN2_AA 0
24370 #define MXU_APTN2_AS 1
24371 #define MXU_APTN2_SA 2
24372 #define MXU_APTN2_SS 3
24374 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24375 #define MXU_EPTN2_AA 0
24376 #define MXU_EPTN2_AS 1
24377 #define MXU_EPTN2_SA 2
24378 #define MXU_EPTN2_SS 3
24380 /* MXU operand getting pattern 'optn2' */
24381 #define MXU_OPTN2_PTN0 0
24382 #define MXU_OPTN2_PTN1 1
24383 #define MXU_OPTN2_PTN2 2
24384 #define MXU_OPTN2_PTN3 3
24385 /* alternative naming scheme for 'optn2' */
24386 #define MXU_OPTN2_WW 0
24387 #define MXU_OPTN2_LW 1
24388 #define MXU_OPTN2_HW 2
24389 #define MXU_OPTN2_XW 3
24391 /* MXU operand getting pattern 'optn3' */
24392 #define MXU_OPTN3_PTN0 0
24393 #define MXU_OPTN3_PTN1 1
24394 #define MXU_OPTN3_PTN2 2
24395 #define MXU_OPTN3_PTN3 3
24396 #define MXU_OPTN3_PTN4 4
24397 #define MXU_OPTN3_PTN5 5
24398 #define MXU_OPTN3_PTN6 6
24399 #define MXU_OPTN3_PTN7 7
24403 * S32I2M XRa, rb - Register move from GRF to XRF
24405 static void gen_mxu_s32i2m(DisasContext *ctx)
24410 t0 = tcg_temp_new();
24412 XRa = extract32(ctx->opcode, 6, 5);
24413 Rb = extract32(ctx->opcode, 16, 5);
24415 gen_load_gpr(t0, Rb);
24417 gen_store_mxu_gpr(t0, XRa);
24418 } else if (XRa == 16) {
24419 gen_store_mxu_cr(t0);
24426 * S32M2I XRa, rb - Register move from XRF to GRF
24428 static void gen_mxu_s32m2i(DisasContext *ctx)
24433 t0 = tcg_temp_new();
24435 XRa = extract32(ctx->opcode, 6, 5);
24436 Rb = extract32(ctx->opcode, 16, 5);
24439 gen_load_mxu_gpr(t0, XRa);
24440 } else if (XRa == 16) {
24441 gen_load_mxu_cr(t0);
24444 gen_store_gpr(t0, Rb);
24450 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24452 static void gen_mxu_s8ldd(DisasContext *ctx)
24455 uint32_t XRa, Rb, s8, optn3;
24457 t0 = tcg_temp_new();
24458 t1 = tcg_temp_new();
24460 XRa = extract32(ctx->opcode, 6, 4);
24461 s8 = extract32(ctx->opcode, 10, 8);
24462 optn3 = extract32(ctx->opcode, 18, 3);
24463 Rb = extract32(ctx->opcode, 21, 5);
24465 gen_load_gpr(t0, Rb);
24466 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24469 /* XRa[7:0] = tmp8 */
24470 case MXU_OPTN3_PTN0:
24471 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24472 gen_load_mxu_gpr(t0, XRa);
24473 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24475 /* XRa[15:8] = tmp8 */
24476 case MXU_OPTN3_PTN1:
24477 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24478 gen_load_mxu_gpr(t0, XRa);
24479 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24481 /* XRa[23:16] = tmp8 */
24482 case MXU_OPTN3_PTN2:
24483 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24484 gen_load_mxu_gpr(t0, XRa);
24485 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24487 /* XRa[31:24] = tmp8 */
24488 case MXU_OPTN3_PTN3:
24489 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24490 gen_load_mxu_gpr(t0, XRa);
24491 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24493 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24494 case MXU_OPTN3_PTN4:
24495 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24496 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24498 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24499 case MXU_OPTN3_PTN5:
24500 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24501 tcg_gen_shli_tl(t1, t1, 8);
24502 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24504 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24505 case MXU_OPTN3_PTN6:
24506 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24507 tcg_gen_mov_tl(t0, t1);
24508 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24509 tcg_gen_shli_tl(t1, t1, 16);
24510 tcg_gen_or_tl(t0, t0, t1);
24512 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24513 case MXU_OPTN3_PTN7:
24514 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24515 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24516 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24520 gen_store_mxu_gpr(t0, XRa);
24527 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24529 static void gen_mxu_d16mul(DisasContext *ctx)
24531 TCGv t0, t1, t2, t3;
24532 uint32_t XRa, XRb, XRc, XRd, optn2;
24534 t0 = tcg_temp_new();
24535 t1 = tcg_temp_new();
24536 t2 = tcg_temp_new();
24537 t3 = tcg_temp_new();
24539 XRa = extract32(ctx->opcode, 6, 4);
24540 XRb = extract32(ctx->opcode, 10, 4);
24541 XRc = extract32(ctx->opcode, 14, 4);
24542 XRd = extract32(ctx->opcode, 18, 4);
24543 optn2 = extract32(ctx->opcode, 22, 2);
24545 gen_load_mxu_gpr(t1, XRb);
24546 tcg_gen_sextract_tl(t0, t1, 0, 16);
24547 tcg_gen_sextract_tl(t1, t1, 16, 16);
24548 gen_load_mxu_gpr(t3, XRc);
24549 tcg_gen_sextract_tl(t2, t3, 0, 16);
24550 tcg_gen_sextract_tl(t3, t3, 16, 16);
24553 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24554 tcg_gen_mul_tl(t3, t1, t3);
24555 tcg_gen_mul_tl(t2, t0, t2);
24557 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24558 tcg_gen_mul_tl(t3, t0, t3);
24559 tcg_gen_mul_tl(t2, t0, t2);
24561 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24562 tcg_gen_mul_tl(t3, t1, t3);
24563 tcg_gen_mul_tl(t2, t1, t2);
24565 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24566 tcg_gen_mul_tl(t3, t0, t3);
24567 tcg_gen_mul_tl(t2, t1, t2);
24570 gen_store_mxu_gpr(t3, XRa);
24571 gen_store_mxu_gpr(t2, XRd);
24580 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24583 static void gen_mxu_d16mac(DisasContext *ctx)
24585 TCGv t0, t1, t2, t3;
24586 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24588 t0 = tcg_temp_new();
24589 t1 = tcg_temp_new();
24590 t2 = tcg_temp_new();
24591 t3 = tcg_temp_new();
24593 XRa = extract32(ctx->opcode, 6, 4);
24594 XRb = extract32(ctx->opcode, 10, 4);
24595 XRc = extract32(ctx->opcode, 14, 4);
24596 XRd = extract32(ctx->opcode, 18, 4);
24597 optn2 = extract32(ctx->opcode, 22, 2);
24598 aptn2 = extract32(ctx->opcode, 24, 2);
24600 gen_load_mxu_gpr(t1, XRb);
24601 tcg_gen_sextract_tl(t0, t1, 0, 16);
24602 tcg_gen_sextract_tl(t1, t1, 16, 16);
24604 gen_load_mxu_gpr(t3, XRc);
24605 tcg_gen_sextract_tl(t2, t3, 0, 16);
24606 tcg_gen_sextract_tl(t3, t3, 16, 16);
24609 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24610 tcg_gen_mul_tl(t3, t1, t3);
24611 tcg_gen_mul_tl(t2, t0, t2);
24613 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24614 tcg_gen_mul_tl(t3, t0, t3);
24615 tcg_gen_mul_tl(t2, t0, t2);
24617 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24618 tcg_gen_mul_tl(t3, t1, t3);
24619 tcg_gen_mul_tl(t2, t1, t2);
24621 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24622 tcg_gen_mul_tl(t3, t0, t3);
24623 tcg_gen_mul_tl(t2, t1, t2);
24626 gen_load_mxu_gpr(t0, XRa);
24627 gen_load_mxu_gpr(t1, XRd);
24631 tcg_gen_add_tl(t3, t0, t3);
24632 tcg_gen_add_tl(t2, t1, t2);
24635 tcg_gen_add_tl(t3, t0, t3);
24636 tcg_gen_sub_tl(t2, t1, t2);
24639 tcg_gen_sub_tl(t3, t0, t3);
24640 tcg_gen_add_tl(t2, t1, t2);
24643 tcg_gen_sub_tl(t3, t0, t3);
24644 tcg_gen_sub_tl(t2, t1, t2);
24647 gen_store_mxu_gpr(t3, XRa);
24648 gen_store_mxu_gpr(t2, XRd);
24657 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24658 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24660 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24662 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24663 uint32_t XRa, XRb, XRc, XRd, sel;
24665 t0 = tcg_temp_new();
24666 t1 = tcg_temp_new();
24667 t2 = tcg_temp_new();
24668 t3 = tcg_temp_new();
24669 t4 = tcg_temp_new();
24670 t5 = tcg_temp_new();
24671 t6 = tcg_temp_new();
24672 t7 = tcg_temp_new();
24674 XRa = extract32(ctx->opcode, 6, 4);
24675 XRb = extract32(ctx->opcode, 10, 4);
24676 XRc = extract32(ctx->opcode, 14, 4);
24677 XRd = extract32(ctx->opcode, 18, 4);
24678 sel = extract32(ctx->opcode, 22, 2);
24680 gen_load_mxu_gpr(t3, XRb);
24681 gen_load_mxu_gpr(t7, XRc);
24685 tcg_gen_ext8s_tl(t0, t3);
24686 tcg_gen_shri_tl(t3, t3, 8);
24687 tcg_gen_ext8s_tl(t1, t3);
24688 tcg_gen_shri_tl(t3, t3, 8);
24689 tcg_gen_ext8s_tl(t2, t3);
24690 tcg_gen_shri_tl(t3, t3, 8);
24691 tcg_gen_ext8s_tl(t3, t3);
24694 tcg_gen_ext8u_tl(t0, t3);
24695 tcg_gen_shri_tl(t3, t3, 8);
24696 tcg_gen_ext8u_tl(t1, t3);
24697 tcg_gen_shri_tl(t3, t3, 8);
24698 tcg_gen_ext8u_tl(t2, t3);
24699 tcg_gen_shri_tl(t3, t3, 8);
24700 tcg_gen_ext8u_tl(t3, t3);
24703 tcg_gen_ext8u_tl(t4, t7);
24704 tcg_gen_shri_tl(t7, t7, 8);
24705 tcg_gen_ext8u_tl(t5, t7);
24706 tcg_gen_shri_tl(t7, t7, 8);
24707 tcg_gen_ext8u_tl(t6, t7);
24708 tcg_gen_shri_tl(t7, t7, 8);
24709 tcg_gen_ext8u_tl(t7, t7);
24711 tcg_gen_mul_tl(t0, t0, t4);
24712 tcg_gen_mul_tl(t1, t1, t5);
24713 tcg_gen_mul_tl(t2, t2, t6);
24714 tcg_gen_mul_tl(t3, t3, t7);
24716 tcg_gen_andi_tl(t0, t0, 0xFFFF);
24717 tcg_gen_andi_tl(t1, t1, 0xFFFF);
24718 tcg_gen_andi_tl(t2, t2, 0xFFFF);
24719 tcg_gen_andi_tl(t3, t3, 0xFFFF);
24721 tcg_gen_shli_tl(t1, t1, 16);
24722 tcg_gen_shli_tl(t3, t3, 16);
24724 tcg_gen_or_tl(t0, t0, t1);
24725 tcg_gen_or_tl(t1, t2, t3);
24727 gen_store_mxu_gpr(t0, XRd);
24728 gen_store_mxu_gpr(t1, XRa);
24741 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
24742 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24744 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24747 uint32_t XRa, Rb, s12, sel;
24749 t0 = tcg_temp_new();
24750 t1 = tcg_temp_new();
24752 XRa = extract32(ctx->opcode, 6, 4);
24753 s12 = extract32(ctx->opcode, 10, 10);
24754 sel = extract32(ctx->opcode, 20, 1);
24755 Rb = extract32(ctx->opcode, 21, 5);
24757 gen_load_gpr(t0, Rb);
24759 tcg_gen_movi_tl(t1, s12);
24760 tcg_gen_shli_tl(t1, t1, 2);
24762 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24764 tcg_gen_add_tl(t1, t0, t1);
24765 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24769 tcg_gen_bswap32_tl(t1, t1);
24771 gen_store_mxu_gpr(t1, XRa);
24779 * MXU instruction category: logic
24780 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24782 * S32NOR S32AND S32OR S32XOR
24786 * S32NOR XRa, XRb, XRc
24787 * Update XRa with the result of logical bitwise 'nor' operation
24788 * applied to the content of XRb and XRc.
24790 * 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
24791 * +-----------+---------+-----+-------+-------+-------+-----------+
24792 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24793 * +-----------+---------+-----+-------+-------+-------+-----------+
24795 static void gen_mxu_S32NOR(DisasContext *ctx)
24797 uint32_t pad, XRc, XRb, XRa;
24799 pad = extract32(ctx->opcode, 21, 5);
24800 XRc = extract32(ctx->opcode, 14, 4);
24801 XRb = extract32(ctx->opcode, 10, 4);
24802 XRa = extract32(ctx->opcode, 6, 4);
24804 if (unlikely(pad != 0)) {
24805 /* opcode padding incorrect -> do nothing */
24806 } else if (unlikely(XRa == 0)) {
24807 /* destination is zero register -> do nothing */
24808 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24809 /* both operands zero registers -> just set destination to all 1s */
24810 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
24811 } else if (unlikely(XRb == 0)) {
24812 /* XRb zero register -> just set destination to the negation of XRc */
24813 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24814 } else if (unlikely(XRc == 0)) {
24815 /* XRa zero register -> just set destination to the negation of XRb */
24816 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24817 } else if (unlikely(XRb == XRc)) {
24818 /* both operands same -> just set destination to the negation of XRb */
24819 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24821 /* the most general case */
24822 tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24827 * S32AND XRa, XRb, XRc
24828 * Update XRa with the result of logical bitwise 'and' operation
24829 * applied to the content of XRb and XRc.
24831 * 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
24832 * +-----------+---------+-----+-------+-------+-------+-----------+
24833 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24834 * +-----------+---------+-----+-------+-------+-------+-----------+
24836 static void gen_mxu_S32AND(DisasContext *ctx)
24838 uint32_t pad, XRc, XRb, XRa;
24840 pad = extract32(ctx->opcode, 21, 5);
24841 XRc = extract32(ctx->opcode, 14, 4);
24842 XRb = extract32(ctx->opcode, 10, 4);
24843 XRa = extract32(ctx->opcode, 6, 4);
24845 if (unlikely(pad != 0)) {
24846 /* opcode padding incorrect -> do nothing */
24847 } else if (unlikely(XRa == 0)) {
24848 /* destination is zero register -> do nothing */
24849 } else if (unlikely((XRb == 0) || (XRc == 0))) {
24850 /* one of operands zero register -> just set destination to all 0s */
24851 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24852 } else if (unlikely(XRb == XRc)) {
24853 /* both operands same -> just set destination to one of them */
24854 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24856 /* the most general case */
24857 tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24862 * S32OR XRa, XRb, XRc
24863 * Update XRa with the result of logical bitwise 'or' operation
24864 * applied to the content of XRb and XRc.
24866 * 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
24867 * +-----------+---------+-----+-------+-------+-------+-----------+
24868 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24869 * +-----------+---------+-----+-------+-------+-------+-----------+
24871 static void gen_mxu_S32OR(DisasContext *ctx)
24873 uint32_t pad, XRc, XRb, XRa;
24875 pad = extract32(ctx->opcode, 21, 5);
24876 XRc = extract32(ctx->opcode, 14, 4);
24877 XRb = extract32(ctx->opcode, 10, 4);
24878 XRa = extract32(ctx->opcode, 6, 4);
24880 if (unlikely(pad != 0)) {
24881 /* opcode padding incorrect -> do nothing */
24882 } else if (unlikely(XRa == 0)) {
24883 /* destination is zero register -> do nothing */
24884 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24885 /* both operands zero registers -> just set destination to all 0s */
24886 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24887 } else if (unlikely(XRb == 0)) {
24888 /* XRb zero register -> just set destination to the content of XRc */
24889 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24890 } else if (unlikely(XRc == 0)) {
24891 /* XRc zero register -> just set destination to the content of XRb */
24892 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24893 } else if (unlikely(XRb == XRc)) {
24894 /* both operands same -> just set destination to one of them */
24895 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24897 /* the most general case */
24898 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24903 * S32XOR XRa, XRb, XRc
24904 * Update XRa with the result of logical bitwise 'xor' operation
24905 * applied to the content of XRb and XRc.
24907 * 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
24908 * +-----------+---------+-----+-------+-------+-------+-----------+
24909 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24910 * +-----------+---------+-----+-------+-------+-------+-----------+
24912 static void gen_mxu_S32XOR(DisasContext *ctx)
24914 uint32_t pad, XRc, XRb, XRa;
24916 pad = extract32(ctx->opcode, 21, 5);
24917 XRc = extract32(ctx->opcode, 14, 4);
24918 XRb = extract32(ctx->opcode, 10, 4);
24919 XRa = extract32(ctx->opcode, 6, 4);
24921 if (unlikely(pad != 0)) {
24922 /* opcode padding incorrect -> do nothing */
24923 } else if (unlikely(XRa == 0)) {
24924 /* destination is zero register -> do nothing */
24925 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24926 /* both operands zero registers -> just set destination to all 0s */
24927 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24928 } else if (unlikely(XRb == 0)) {
24929 /* XRb zero register -> just set destination to the content of XRc */
24930 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24931 } else if (unlikely(XRc == 0)) {
24932 /* XRc zero register -> just set destination to the content of XRb */
24933 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24934 } else if (unlikely(XRb == XRc)) {
24935 /* both operands same -> just set destination to all 0s */
24936 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24938 /* the most general case */
24939 tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24945 * MXU instruction category max/min
24946 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24948 * S32MAX D16MAX Q8MAX
24949 * S32MIN D16MIN Q8MIN
24953 * S32MAX XRa, XRb, XRc
24954 * Update XRa with the maximum of signed 32-bit integers contained
24957 * S32MIN XRa, XRb, XRc
24958 * Update XRa with the minimum of signed 32-bit integers contained
24961 * 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
24962 * +-----------+---------+-----+-------+-------+-------+-----------+
24963 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
24964 * +-----------+---------+-----+-------+-------+-------+-----------+
24966 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
24968 uint32_t pad, opc, XRc, XRb, XRa;
24970 pad = extract32(ctx->opcode, 21, 5);
24971 opc = extract32(ctx->opcode, 18, 3);
24972 XRc = extract32(ctx->opcode, 14, 4);
24973 XRb = extract32(ctx->opcode, 10, 4);
24974 XRa = extract32(ctx->opcode, 6, 4);
24976 if (unlikely(pad != 0)) {
24977 /* opcode padding incorrect -> do nothing */
24978 } else if (unlikely(XRa == 0)) {
24979 /* destination is zero register -> do nothing */
24980 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24981 /* both operands zero registers -> just set destination to zero */
24982 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24983 } else if (unlikely((XRb == 0) || (XRc == 0))) {
24984 /* exactly one operand is zero register - find which one is not...*/
24985 uint32_t XRx = XRb ? XRb : XRc;
24986 /* ...and do max/min operation with one operand 0 */
24987 if (opc == OPC_MXU_S32MAX) {
24988 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24990 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24992 } else if (unlikely(XRb == XRc)) {
24993 /* both operands same -> just set destination to one of them */
24994 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24996 /* the most general case */
24997 if (opc == OPC_MXU_S32MAX) {
24998 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25001 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25009 * Update XRa with the 16-bit-wise maximums of signed integers
25010 * contained in XRb and XRc.
25013 * Update XRa with the 16-bit-wise minimums of signed integers
25014 * contained in XRb and XRc.
25016 * 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
25017 * +-----------+---------+-----+-------+-------+-------+-----------+
25018 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25019 * +-----------+---------+-----+-------+-------+-------+-----------+
25021 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25023 uint32_t pad, opc, XRc, XRb, XRa;
25025 pad = extract32(ctx->opcode, 21, 5);
25026 opc = extract32(ctx->opcode, 18, 3);
25027 XRc = extract32(ctx->opcode, 14, 4);
25028 XRb = extract32(ctx->opcode, 10, 4);
25029 XRa = extract32(ctx->opcode, 6, 4);
25031 if (unlikely(pad != 0)) {
25032 /* opcode padding incorrect -> do nothing */
25033 } else if (unlikely(XRc == 0)) {
25034 /* destination is zero register -> do nothing */
25035 } else if (unlikely((XRb == 0) && (XRa == 0))) {
25036 /* both operands zero registers -> just set destination to zero */
25037 tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25038 } else if (unlikely((XRb == 0) || (XRa == 0))) {
25039 /* exactly one operand is zero register - find which one is not...*/
25040 uint32_t XRx = XRb ? XRb : XRc;
25041 /* ...and do half-word-wise max/min with one operand 0 */
25042 TCGv_i32 t0 = tcg_temp_new();
25043 TCGv_i32 t1 = tcg_const_i32(0);
25045 /* the left half-word first */
25046 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25047 if (opc == OPC_MXU_D16MAX) {
25048 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25050 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25053 /* the right half-word */
25054 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25055 /* move half-words to the leftmost position */
25056 tcg_gen_shli_i32(t0, t0, 16);
25057 /* t0 will be max/min of t0 and t1 */
25058 if (opc == OPC_MXU_D16MAX) {
25059 tcg_gen_smax_i32(t0, t0, t1);
25061 tcg_gen_smin_i32(t0, t0, t1);
25063 /* return resulting half-words to its original position */
25064 tcg_gen_shri_i32(t0, t0, 16);
25065 /* finaly update the destination */
25066 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25070 } else if (unlikely(XRb == XRc)) {
25071 /* both operands same -> just set destination to one of them */
25072 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25074 /* the most general case */
25075 TCGv_i32 t0 = tcg_temp_new();
25076 TCGv_i32 t1 = tcg_temp_new();
25078 /* the left half-word first */
25079 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25080 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25081 if (opc == OPC_MXU_D16MAX) {
25082 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25084 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25087 /* the right half-word */
25088 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25089 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25090 /* move half-words to the leftmost position */
25091 tcg_gen_shli_i32(t0, t0, 16);
25092 tcg_gen_shli_i32(t1, t1, 16);
25093 /* t0 will be max/min of t0 and t1 */
25094 if (opc == OPC_MXU_D16MAX) {
25095 tcg_gen_smax_i32(t0, t0, t1);
25097 tcg_gen_smin_i32(t0, t0, t1);
25099 /* return resulting half-words to its original position */
25100 tcg_gen_shri_i32(t0, t0, 16);
25101 /* finaly update the destination */
25102 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25111 * Update XRa with the 8-bit-wise maximums of signed integers
25112 * contained in XRb and XRc.
25115 * Update XRa with the 8-bit-wise minimums of signed integers
25116 * contained in XRb and XRc.
25118 * 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
25119 * +-----------+---------+-----+-------+-------+-------+-----------+
25120 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25121 * +-----------+---------+-----+-------+-------+-------+-----------+
25123 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25125 uint32_t pad, opc, XRc, XRb, XRa;
25127 pad = extract32(ctx->opcode, 21, 5);
25128 opc = extract32(ctx->opcode, 18, 3);
25129 XRc = extract32(ctx->opcode, 14, 4);
25130 XRb = extract32(ctx->opcode, 10, 4);
25131 XRa = extract32(ctx->opcode, 6, 4);
25133 if (unlikely(pad != 0)) {
25134 /* opcode padding incorrect -> do nothing */
25135 } else if (unlikely(XRa == 0)) {
25136 /* destination is zero register -> do nothing */
25137 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25138 /* both operands zero registers -> just set destination to zero */
25139 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25140 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25141 /* exactly one operand is zero register - make it be the first...*/
25142 uint32_t XRx = XRb ? XRb : XRc;
25143 /* ...and do byte-wise max/min with one operand 0 */
25144 TCGv_i32 t0 = tcg_temp_new();
25145 TCGv_i32 t1 = tcg_const_i32(0);
25148 /* the leftmost byte (byte 3) first */
25149 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25150 if (opc == OPC_MXU_Q8MAX) {
25151 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25153 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25156 /* bytes 2, 1, 0 */
25157 for (i = 2; i >= 0; i--) {
25158 /* extract the byte */
25159 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25160 /* move the byte to the leftmost position */
25161 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25162 /* t0 will be max/min of t0 and t1 */
25163 if (opc == OPC_MXU_Q8MAX) {
25164 tcg_gen_smax_i32(t0, t0, t1);
25166 tcg_gen_smin_i32(t0, t0, t1);
25168 /* return resulting byte to its original position */
25169 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25170 /* finaly update the destination */
25171 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25176 } else if (unlikely(XRb == XRc)) {
25177 /* both operands same -> just set destination to one of them */
25178 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25180 /* the most general case */
25181 TCGv_i32 t0 = tcg_temp_new();
25182 TCGv_i32 t1 = tcg_temp_new();
25185 /* the leftmost bytes (bytes 3) first */
25186 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25187 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25188 if (opc == OPC_MXU_Q8MAX) {
25189 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25191 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25194 /* bytes 2, 1, 0 */
25195 for (i = 2; i >= 0; i--) {
25196 /* extract corresponding bytes */
25197 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25198 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25199 /* move the bytes to the leftmost position */
25200 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25201 tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25202 /* t0 will be max/min of t0 and t1 */
25203 if (opc == OPC_MXU_Q8MAX) {
25204 tcg_gen_smax_i32(t0, t0, t1);
25206 tcg_gen_smin_i32(t0, t0, t1);
25208 /* return resulting byte to its original position */
25209 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25210 /* finaly update the destination */
25211 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25221 * MXU instruction category: align
25222 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25228 * S32ALNI XRc, XRb, XRa, optn3
25229 * Arrange bytes from XRb and XRc according to one of five sets of
25230 * rules determined by optn3, and place the result in XRa.
25232 * 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
25233 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25234 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25235 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25238 static void gen_mxu_S32ALNI(DisasContext *ctx)
25240 uint32_t optn3, pad, XRc, XRb, XRa;
25242 optn3 = extract32(ctx->opcode, 23, 3);
25243 pad = extract32(ctx->opcode, 21, 2);
25244 XRc = extract32(ctx->opcode, 14, 4);
25245 XRb = extract32(ctx->opcode, 10, 4);
25246 XRa = extract32(ctx->opcode, 6, 4);
25248 if (unlikely(pad != 0)) {
25249 /* opcode padding incorrect -> do nothing */
25250 } else if (unlikely(XRa == 0)) {
25251 /* destination is zero register -> do nothing */
25252 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25253 /* both operands zero registers -> just set destination to all 0s */
25254 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25255 } else if (unlikely(XRb == 0)) {
25256 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25258 case MXU_OPTN3_PTN0:
25259 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25261 case MXU_OPTN3_PTN1:
25262 case MXU_OPTN3_PTN2:
25263 case MXU_OPTN3_PTN3:
25264 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25267 case MXU_OPTN3_PTN4:
25268 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25271 } else if (unlikely(XRc == 0)) {
25272 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25274 case MXU_OPTN3_PTN0:
25275 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25277 case MXU_OPTN3_PTN1:
25278 case MXU_OPTN3_PTN2:
25279 case MXU_OPTN3_PTN3:
25280 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25282 case MXU_OPTN3_PTN4:
25283 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25286 } else if (unlikely(XRb == XRc)) {
25287 /* both operands same -> just rotation or moving from any of them */
25289 case MXU_OPTN3_PTN0:
25290 case MXU_OPTN3_PTN4:
25291 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25293 case MXU_OPTN3_PTN1:
25294 case MXU_OPTN3_PTN2:
25295 case MXU_OPTN3_PTN3:
25296 tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25300 /* the most general case */
25302 case MXU_OPTN3_PTN0:
25306 /* +---------------+ */
25307 /* | A B C D | E F G H */
25308 /* +-------+-------+ */
25313 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25316 case MXU_OPTN3_PTN1:
25320 /* +-------------------+ */
25321 /* A | B C D E | F G H */
25322 /* +---------+---------+ */
25327 TCGv_i32 t0 = tcg_temp_new();
25328 TCGv_i32 t1 = tcg_temp_new();
25330 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25331 tcg_gen_shli_i32(t0, t0, 8);
25333 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25334 tcg_gen_shri_i32(t1, t1, 24);
25336 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25342 case MXU_OPTN3_PTN2:
25346 /* +-------------------+ */
25347 /* A B | C D E F | G H */
25348 /* +---------+---------+ */
25353 TCGv_i32 t0 = tcg_temp_new();
25354 TCGv_i32 t1 = tcg_temp_new();
25356 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25357 tcg_gen_shli_i32(t0, t0, 16);
25359 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25360 tcg_gen_shri_i32(t1, t1, 16);
25362 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25368 case MXU_OPTN3_PTN3:
25372 /* +-------------------+ */
25373 /* A B C | D E F G | H */
25374 /* +---------+---------+ */
25379 TCGv_i32 t0 = tcg_temp_new();
25380 TCGv_i32 t1 = tcg_temp_new();
25382 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25383 tcg_gen_shli_i32(t0, t0, 24);
25385 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25386 tcg_gen_shri_i32(t1, t1, 8);
25388 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25394 case MXU_OPTN3_PTN4:
25398 /* +---------------+ */
25399 /* A B C D | E F G H | */
25400 /* +-------+-------+ */
25405 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25414 * Decoding engine for MXU
25415 * =======================
25420 * Decode MXU pool00
25422 * 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
25423 * +-----------+---------+-----+-------+-------+-------+-----------+
25424 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25425 * +-----------+---------+-----+-------+-------+-------+-----------+
25428 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25430 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25433 case OPC_MXU_S32MAX:
25434 case OPC_MXU_S32MIN:
25435 gen_mxu_S32MAX_S32MIN(ctx);
25437 case OPC_MXU_D16MAX:
25438 case OPC_MXU_D16MIN:
25439 gen_mxu_D16MAX_D16MIN(ctx);
25441 case OPC_MXU_Q8MAX:
25442 case OPC_MXU_Q8MIN:
25443 gen_mxu_Q8MAX_Q8MIN(ctx);
25445 case OPC_MXU_Q8SLT:
25446 /* TODO: Implement emulation of Q8SLT instruction. */
25447 MIPS_INVAL("OPC_MXU_Q8SLT");
25448 generate_exception_end(ctx, EXCP_RI);
25450 case OPC_MXU_Q8SLTU:
25451 /* TODO: Implement emulation of Q8SLTU instruction. */
25452 MIPS_INVAL("OPC_MXU_Q8SLTU");
25453 generate_exception_end(ctx, EXCP_RI);
25456 MIPS_INVAL("decode_opc_mxu");
25457 generate_exception_end(ctx, EXCP_RI);
25464 * Decode MXU pool01
25466 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25467 * 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
25468 * +-----------+---------+-----+-------+-------+-------+-----------+
25469 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25470 * +-----------+---------+-----+-------+-------+-------+-----------+
25473 * 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
25474 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25475 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25476 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25479 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25481 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25484 case OPC_MXU_S32SLT:
25485 /* TODO: Implement emulation of S32SLT instruction. */
25486 MIPS_INVAL("OPC_MXU_S32SLT");
25487 generate_exception_end(ctx, EXCP_RI);
25489 case OPC_MXU_D16SLT:
25490 /* TODO: Implement emulation of D16SLT instruction. */
25491 MIPS_INVAL("OPC_MXU_D16SLT");
25492 generate_exception_end(ctx, EXCP_RI);
25494 case OPC_MXU_D16AVG:
25495 /* TODO: Implement emulation of D16AVG instruction. */
25496 MIPS_INVAL("OPC_MXU_D16AVG");
25497 generate_exception_end(ctx, EXCP_RI);
25499 case OPC_MXU_D16AVGR:
25500 /* TODO: Implement emulation of D16AVGR instruction. */
25501 MIPS_INVAL("OPC_MXU_D16AVGR");
25502 generate_exception_end(ctx, EXCP_RI);
25504 case OPC_MXU_Q8AVG:
25505 /* TODO: Implement emulation of Q8AVG instruction. */
25506 MIPS_INVAL("OPC_MXU_Q8AVG");
25507 generate_exception_end(ctx, EXCP_RI);
25509 case OPC_MXU_Q8AVGR:
25510 /* TODO: Implement emulation of Q8AVGR instruction. */
25511 MIPS_INVAL("OPC_MXU_Q8AVGR");
25512 generate_exception_end(ctx, EXCP_RI);
25514 case OPC_MXU_Q8ADD:
25515 /* TODO: Implement emulation of Q8ADD instruction. */
25516 MIPS_INVAL("OPC_MXU_Q8ADD");
25517 generate_exception_end(ctx, EXCP_RI);
25520 MIPS_INVAL("decode_opc_mxu");
25521 generate_exception_end(ctx, EXCP_RI);
25528 * Decode MXU pool02
25530 * 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
25531 * +-----------+---------+-----+-------+-------+-------+-----------+
25532 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
25533 * +-----------+---------+-----+-------+-------+-------+-----------+
25536 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25538 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25541 case OPC_MXU_S32CPS:
25542 /* TODO: Implement emulation of S32CPS instruction. */
25543 MIPS_INVAL("OPC_MXU_S32CPS");
25544 generate_exception_end(ctx, EXCP_RI);
25546 case OPC_MXU_D16CPS:
25547 /* TODO: Implement emulation of D16CPS instruction. */
25548 MIPS_INVAL("OPC_MXU_D16CPS");
25549 generate_exception_end(ctx, EXCP_RI);
25551 case OPC_MXU_Q8ABD:
25552 /* TODO: Implement emulation of Q8ABD instruction. */
25553 MIPS_INVAL("OPC_MXU_Q8ABD");
25554 generate_exception_end(ctx, EXCP_RI);
25556 case OPC_MXU_Q16SAT:
25557 /* TODO: Implement emulation of Q16SAT instruction. */
25558 MIPS_INVAL("OPC_MXU_Q16SAT");
25559 generate_exception_end(ctx, EXCP_RI);
25562 MIPS_INVAL("decode_opc_mxu");
25563 generate_exception_end(ctx, EXCP_RI);
25570 * Decode MXU pool03
25573 * 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
25574 * +-----------+---+---+-------+-------+-------+-------+-----------+
25575 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
25576 * +-----------+---+---+-------+-------+-------+-------+-----------+
25579 * 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
25580 * +-----------+---+---+-------+-------+-------+-------+-----------+
25581 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
25582 * +-----------+---+---+-------+-------+-------+-------+-----------+
25585 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25587 uint32_t opcode = extract32(ctx->opcode, 24, 2);
25590 case OPC_MXU_D16MULF:
25591 /* TODO: Implement emulation of D16MULF instruction. */
25592 MIPS_INVAL("OPC_MXU_D16MULF");
25593 generate_exception_end(ctx, EXCP_RI);
25595 case OPC_MXU_D16MULE:
25596 /* TODO: Implement emulation of D16MULE instruction. */
25597 MIPS_INVAL("OPC_MXU_D16MULE");
25598 generate_exception_end(ctx, EXCP_RI);
25601 MIPS_INVAL("decode_opc_mxu");
25602 generate_exception_end(ctx, EXCP_RI);
25609 * Decode MXU pool04
25611 * 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
25612 * +-----------+---------+-+-------------------+-------+-----------+
25613 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
25614 * +-----------+---------+-+-------------------+-------+-----------+
25617 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25619 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25622 case OPC_MXU_S32LDD:
25623 case OPC_MXU_S32LDDR:
25624 gen_mxu_s32ldd_s32lddr(ctx);
25627 MIPS_INVAL("decode_opc_mxu");
25628 generate_exception_end(ctx, EXCP_RI);
25635 * Decode MXU pool05
25637 * 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
25638 * +-----------+---------+-+-------------------+-------+-----------+
25639 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
25640 * +-----------+---------+-+-------------------+-------+-----------+
25643 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25645 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25648 case OPC_MXU_S32STD:
25649 /* TODO: Implement emulation of S32STD instruction. */
25650 MIPS_INVAL("OPC_MXU_S32STD");
25651 generate_exception_end(ctx, EXCP_RI);
25653 case OPC_MXU_S32STDR:
25654 /* TODO: Implement emulation of S32STDR instruction. */
25655 MIPS_INVAL("OPC_MXU_S32STDR");
25656 generate_exception_end(ctx, EXCP_RI);
25659 MIPS_INVAL("decode_opc_mxu");
25660 generate_exception_end(ctx, EXCP_RI);
25667 * Decode MXU pool06
25669 * 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
25670 * +-----------+---------+---------+---+-------+-------+-----------+
25671 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
25672 * +-----------+---------+---------+---+-------+-------+-----------+
25675 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25677 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25680 case OPC_MXU_S32LDDV:
25681 /* TODO: Implement emulation of S32LDDV instruction. */
25682 MIPS_INVAL("OPC_MXU_S32LDDV");
25683 generate_exception_end(ctx, EXCP_RI);
25685 case OPC_MXU_S32LDDVR:
25686 /* TODO: Implement emulation of S32LDDVR instruction. */
25687 MIPS_INVAL("OPC_MXU_S32LDDVR");
25688 generate_exception_end(ctx, EXCP_RI);
25691 MIPS_INVAL("decode_opc_mxu");
25692 generate_exception_end(ctx, EXCP_RI);
25699 * Decode MXU pool07
25701 * 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
25702 * +-----------+---------+---------+---+-------+-------+-----------+
25703 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
25704 * +-----------+---------+---------+---+-------+-------+-----------+
25707 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
25709 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25712 case OPC_MXU_S32STDV:
25713 /* TODO: Implement emulation of S32TDV instruction. */
25714 MIPS_INVAL("OPC_MXU_S32TDV");
25715 generate_exception_end(ctx, EXCP_RI);
25717 case OPC_MXU_S32STDVR:
25718 /* TODO: Implement emulation of S32TDVR instruction. */
25719 MIPS_INVAL("OPC_MXU_S32TDVR");
25720 generate_exception_end(ctx, EXCP_RI);
25723 MIPS_INVAL("decode_opc_mxu");
25724 generate_exception_end(ctx, EXCP_RI);
25731 * Decode MXU pool08
25733 * 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
25734 * +-----------+---------+-+-------------------+-------+-----------+
25735 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
25736 * +-----------+---------+-+-------------------+-------+-----------+
25739 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
25741 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25744 case OPC_MXU_S32LDI:
25745 /* TODO: Implement emulation of S32LDI instruction. */
25746 MIPS_INVAL("OPC_MXU_S32LDI");
25747 generate_exception_end(ctx, EXCP_RI);
25749 case OPC_MXU_S32LDIR:
25750 /* TODO: Implement emulation of S32LDIR instruction. */
25751 MIPS_INVAL("OPC_MXU_S32LDIR");
25752 generate_exception_end(ctx, EXCP_RI);
25755 MIPS_INVAL("decode_opc_mxu");
25756 generate_exception_end(ctx, EXCP_RI);
25763 * Decode MXU pool09
25765 * 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
25766 * +-----------+---------+-+-------------------+-------+-----------+
25767 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
25768 * +-----------+---------+-+-------------------+-------+-----------+
25771 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
25773 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25776 case OPC_MXU_S32SDI:
25777 /* TODO: Implement emulation of S32SDI instruction. */
25778 MIPS_INVAL("OPC_MXU_S32SDI");
25779 generate_exception_end(ctx, EXCP_RI);
25781 case OPC_MXU_S32SDIR:
25782 /* TODO: Implement emulation of S32SDIR instruction. */
25783 MIPS_INVAL("OPC_MXU_S32SDIR");
25784 generate_exception_end(ctx, EXCP_RI);
25787 MIPS_INVAL("decode_opc_mxu");
25788 generate_exception_end(ctx, EXCP_RI);
25795 * Decode MXU pool10
25797 * 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
25798 * +-----------+---------+---------+---+-------+-------+-----------+
25799 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
25800 * +-----------+---------+---------+---+-------+-------+-----------+
25803 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25805 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25808 case OPC_MXU_S32LDIV:
25809 /* TODO: Implement emulation of S32LDIV instruction. */
25810 MIPS_INVAL("OPC_MXU_S32LDIV");
25811 generate_exception_end(ctx, EXCP_RI);
25813 case OPC_MXU_S32LDIVR:
25814 /* TODO: Implement emulation of S32LDIVR instruction. */
25815 MIPS_INVAL("OPC_MXU_S32LDIVR");
25816 generate_exception_end(ctx, EXCP_RI);
25819 MIPS_INVAL("decode_opc_mxu");
25820 generate_exception_end(ctx, EXCP_RI);
25827 * Decode MXU pool11
25829 * 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
25830 * +-----------+---------+---------+---+-------+-------+-----------+
25831 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
25832 * +-----------+---------+---------+---+-------+-------+-----------+
25835 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25837 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25840 case OPC_MXU_S32SDIV:
25841 /* TODO: Implement emulation of S32SDIV instruction. */
25842 MIPS_INVAL("OPC_MXU_S32SDIV");
25843 generate_exception_end(ctx, EXCP_RI);
25845 case OPC_MXU_S32SDIVR:
25846 /* TODO: Implement emulation of S32SDIVR instruction. */
25847 MIPS_INVAL("OPC_MXU_S32SDIVR");
25848 generate_exception_end(ctx, EXCP_RI);
25851 MIPS_INVAL("decode_opc_mxu");
25852 generate_exception_end(ctx, EXCP_RI);
25859 * Decode MXU pool12
25861 * 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
25862 * +-----------+---+---+-------+-------+-------+-------+-----------+
25863 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
25864 * +-----------+---+---+-------+-------+-------+-------+-----------+
25867 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
25869 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25872 case OPC_MXU_D32ACC:
25873 /* TODO: Implement emulation of D32ACC instruction. */
25874 MIPS_INVAL("OPC_MXU_D32ACC");
25875 generate_exception_end(ctx, EXCP_RI);
25877 case OPC_MXU_D32ACCM:
25878 /* TODO: Implement emulation of D32ACCM instruction. */
25879 MIPS_INVAL("OPC_MXU_D32ACCM");
25880 generate_exception_end(ctx, EXCP_RI);
25882 case OPC_MXU_D32ASUM:
25883 /* TODO: Implement emulation of D32ASUM instruction. */
25884 MIPS_INVAL("OPC_MXU_D32ASUM");
25885 generate_exception_end(ctx, EXCP_RI);
25888 MIPS_INVAL("decode_opc_mxu");
25889 generate_exception_end(ctx, EXCP_RI);
25896 * Decode MXU pool13
25898 * 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
25899 * +-----------+---+---+-------+-------+-------+-------+-----------+
25900 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
25901 * +-----------+---+---+-------+-------+-------+-------+-----------+
25904 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
25906 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25909 case OPC_MXU_Q16ACC:
25910 /* TODO: Implement emulation of Q16ACC instruction. */
25911 MIPS_INVAL("OPC_MXU_Q16ACC");
25912 generate_exception_end(ctx, EXCP_RI);
25914 case OPC_MXU_Q16ACCM:
25915 /* TODO: Implement emulation of Q16ACCM instruction. */
25916 MIPS_INVAL("OPC_MXU_Q16ACCM");
25917 generate_exception_end(ctx, EXCP_RI);
25919 case OPC_MXU_Q16ASUM:
25920 /* TODO: Implement emulation of Q16ASUM instruction. */
25921 MIPS_INVAL("OPC_MXU_Q16ASUM");
25922 generate_exception_end(ctx, EXCP_RI);
25925 MIPS_INVAL("decode_opc_mxu");
25926 generate_exception_end(ctx, EXCP_RI);
25933 * Decode MXU pool14
25936 * 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
25937 * +-----------+---+---+-------+-------+-------+-------+-----------+
25938 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
25939 * +-----------+---+---+-------+-------+-------+-------+-----------+
25942 * 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
25943 * +-----------+---+---+-------+-------+-------+-------+-----------+
25944 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
25945 * +-----------+---+---+-------+-------+-------+-------+-----------+
25948 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
25950 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25953 case OPC_MXU_Q8ADDE:
25954 /* TODO: Implement emulation of Q8ADDE instruction. */
25955 MIPS_INVAL("OPC_MXU_Q8ADDE");
25956 generate_exception_end(ctx, EXCP_RI);
25958 case OPC_MXU_D8SUM:
25959 /* TODO: Implement emulation of D8SUM instruction. */
25960 MIPS_INVAL("OPC_MXU_D8SUM");
25961 generate_exception_end(ctx, EXCP_RI);
25963 case OPC_MXU_D8SUMC:
25964 /* TODO: Implement emulation of D8SUMC instruction. */
25965 MIPS_INVAL("OPC_MXU_D8SUMC");
25966 generate_exception_end(ctx, EXCP_RI);
25969 MIPS_INVAL("decode_opc_mxu");
25970 generate_exception_end(ctx, EXCP_RI);
25977 * Decode MXU pool15
25979 * S32MUL, S32MULU, S32EXTRV:
25980 * 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
25981 * +-----------+---------+---------+---+-------+-------+-----------+
25982 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
25983 * +-----------+---------+---------+---+-------+-------+-----------+
25986 * 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
25987 * +-----------+---------+---------+---+-------+-------+-----------+
25988 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
25989 * +-----------+---------+---------+---+-------+-------+-----------+
25992 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
25994 uint32_t opcode = extract32(ctx->opcode, 14, 2);
25997 case OPC_MXU_S32MUL:
25998 /* TODO: Implement emulation of S32MUL instruction. */
25999 MIPS_INVAL("OPC_MXU_S32MUL");
26000 generate_exception_end(ctx, EXCP_RI);
26002 case OPC_MXU_S32MULU:
26003 /* TODO: Implement emulation of S32MULU instruction. */
26004 MIPS_INVAL("OPC_MXU_S32MULU");
26005 generate_exception_end(ctx, EXCP_RI);
26007 case OPC_MXU_S32EXTR:
26008 /* TODO: Implement emulation of S32EXTR instruction. */
26009 MIPS_INVAL("OPC_MXU_S32EXTR");
26010 generate_exception_end(ctx, EXCP_RI);
26012 case OPC_MXU_S32EXTRV:
26013 /* TODO: Implement emulation of S32EXTRV instruction. */
26014 MIPS_INVAL("OPC_MXU_S32EXTRV");
26015 generate_exception_end(ctx, EXCP_RI);
26018 MIPS_INVAL("decode_opc_mxu");
26019 generate_exception_end(ctx, EXCP_RI);
26026 * Decode MXU pool16
26029 * 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
26030 * +-----------+---------+-----+-------+-------+-------+-----------+
26031 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26032 * +-----------+---------+-----+-------+-------+-------+-----------+
26035 * 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
26036 * +-----------+---------+-----+-------+-------+-------+-----------+
26037 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26038 * +-----------+---------+-----+-------+-------+-------+-----------+
26041 * 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
26042 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26043 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26044 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26047 * 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
26048 * +-----------+-----+---+-----+-------+---------------+-----------+
26049 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26050 * +-----------+-----+---+-----+-------+---------------+-----------+
26052 * S32NOR, S32AND, S32OR, S32XOR:
26053 * 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
26054 * +-----------+---------+-----+-------+-------+-------+-----------+
26055 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26056 * +-----------+---------+-----+-------+-------+-------+-----------+
26059 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26061 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26064 case OPC_MXU_D32SARW:
26065 /* TODO: Implement emulation of D32SARW instruction. */
26066 MIPS_INVAL("OPC_MXU_D32SARW");
26067 generate_exception_end(ctx, EXCP_RI);
26069 case OPC_MXU_S32ALN:
26070 /* TODO: Implement emulation of S32ALN instruction. */
26071 MIPS_INVAL("OPC_MXU_S32ALN");
26072 generate_exception_end(ctx, EXCP_RI);
26074 case OPC_MXU_S32ALNI:
26075 gen_mxu_S32ALNI(ctx);
26077 case OPC_MXU_S32LUI:
26078 /* TODO: Implement emulation of S32LUI instruction. */
26079 MIPS_INVAL("OPC_MXU_S32LUI");
26080 generate_exception_end(ctx, EXCP_RI);
26082 case OPC_MXU_S32NOR:
26083 gen_mxu_S32NOR(ctx);
26085 case OPC_MXU_S32AND:
26086 gen_mxu_S32AND(ctx);
26088 case OPC_MXU_S32OR:
26089 gen_mxu_S32OR(ctx);
26091 case OPC_MXU_S32XOR:
26092 gen_mxu_S32XOR(ctx);
26095 MIPS_INVAL("decode_opc_mxu");
26096 generate_exception_end(ctx, EXCP_RI);
26103 * Decode MXU pool17
26105 * 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
26106 * +-----------+---------+---------+---+---------+-----+-----------+
26107 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26108 * +-----------+---------+---------+---+---------+-----+-----------+
26111 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26113 uint32_t opcode = extract32(ctx->opcode, 6, 2);
26117 /* TODO: Implement emulation of LXW instruction. */
26118 MIPS_INVAL("OPC_MXU_LXW");
26119 generate_exception_end(ctx, EXCP_RI);
26122 /* TODO: Implement emulation of LXH instruction. */
26123 MIPS_INVAL("OPC_MXU_LXH");
26124 generate_exception_end(ctx, EXCP_RI);
26127 /* TODO: Implement emulation of LXHU instruction. */
26128 MIPS_INVAL("OPC_MXU_LXHU");
26129 generate_exception_end(ctx, EXCP_RI);
26132 /* TODO: Implement emulation of LXB instruction. */
26133 MIPS_INVAL("OPC_MXU_LXB");
26134 generate_exception_end(ctx, EXCP_RI);
26137 /* TODO: Implement emulation of LXBU instruction. */
26138 MIPS_INVAL("OPC_MXU_LXBU");
26139 generate_exception_end(ctx, EXCP_RI);
26142 MIPS_INVAL("decode_opc_mxu");
26143 generate_exception_end(ctx, EXCP_RI);
26149 * Decode MXU pool18
26151 * 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
26152 * +-----------+---------+-----+-------+-------+-------+-----------+
26153 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26154 * +-----------+---------+-----+-------+-------+-------+-----------+
26157 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26159 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26162 case OPC_MXU_D32SLLV:
26163 /* TODO: Implement emulation of D32SLLV instruction. */
26164 MIPS_INVAL("OPC_MXU_D32SLLV");
26165 generate_exception_end(ctx, EXCP_RI);
26167 case OPC_MXU_D32SLRV:
26168 /* TODO: Implement emulation of D32SLRV instruction. */
26169 MIPS_INVAL("OPC_MXU_D32SLRV");
26170 generate_exception_end(ctx, EXCP_RI);
26172 case OPC_MXU_D32SARV:
26173 /* TODO: Implement emulation of D32SARV instruction. */
26174 MIPS_INVAL("OPC_MXU_D32SARV");
26175 generate_exception_end(ctx, EXCP_RI);
26177 case OPC_MXU_Q16SLLV:
26178 /* TODO: Implement emulation of Q16SLLV instruction. */
26179 MIPS_INVAL("OPC_MXU_Q16SLLV");
26180 generate_exception_end(ctx, EXCP_RI);
26182 case OPC_MXU_Q16SLRV:
26183 /* TODO: Implement emulation of Q16SLRV instruction. */
26184 MIPS_INVAL("OPC_MXU_Q16SLRV");
26185 generate_exception_end(ctx, EXCP_RI);
26187 case OPC_MXU_Q16SARV:
26188 /* TODO: Implement emulation of Q16SARV instruction. */
26189 MIPS_INVAL("OPC_MXU_Q16SARV");
26190 generate_exception_end(ctx, EXCP_RI);
26193 MIPS_INVAL("decode_opc_mxu");
26194 generate_exception_end(ctx, EXCP_RI);
26201 * Decode MXU pool19
26203 * 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
26204 * +-----------+---+---+-------+-------+-------+-------+-----------+
26205 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
26206 * +-----------+---+---+-------+-------+-------+-------+-----------+
26209 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26211 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26214 case OPC_MXU_Q8MUL:
26215 case OPC_MXU_Q8MULSU:
26216 gen_mxu_q8mul_q8mulsu(ctx);
26219 MIPS_INVAL("decode_opc_mxu");
26220 generate_exception_end(ctx, EXCP_RI);
26227 * Decode MXU pool20
26229 * 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
26230 * +-----------+---------+-----+-------+-------+-------+-----------+
26231 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
26232 * +-----------+---------+-----+-------+-------+-------+-----------+
26235 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26237 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26240 case OPC_MXU_Q8MOVZ:
26241 /* TODO: Implement emulation of Q8MOVZ instruction. */
26242 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26243 generate_exception_end(ctx, EXCP_RI);
26245 case OPC_MXU_Q8MOVN:
26246 /* TODO: Implement emulation of Q8MOVN instruction. */
26247 MIPS_INVAL("OPC_MXU_Q8MOVN");
26248 generate_exception_end(ctx, EXCP_RI);
26250 case OPC_MXU_D16MOVZ:
26251 /* TODO: Implement emulation of D16MOVZ instruction. */
26252 MIPS_INVAL("OPC_MXU_D16MOVZ");
26253 generate_exception_end(ctx, EXCP_RI);
26255 case OPC_MXU_D16MOVN:
26256 /* TODO: Implement emulation of D16MOVN instruction. */
26257 MIPS_INVAL("OPC_MXU_D16MOVN");
26258 generate_exception_end(ctx, EXCP_RI);
26260 case OPC_MXU_S32MOVZ:
26261 /* TODO: Implement emulation of S32MOVZ instruction. */
26262 MIPS_INVAL("OPC_MXU_S32MOVZ");
26263 generate_exception_end(ctx, EXCP_RI);
26265 case OPC_MXU_S32MOVN:
26266 /* TODO: Implement emulation of S32MOVN instruction. */
26267 MIPS_INVAL("OPC_MXU_S32MOVN");
26268 generate_exception_end(ctx, EXCP_RI);
26271 MIPS_INVAL("decode_opc_mxu");
26272 generate_exception_end(ctx, EXCP_RI);
26279 * Decode MXU pool21
26281 * 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
26282 * +-----------+---+---+-------+-------+-------+-------+-----------+
26283 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
26284 * +-----------+---+---+-------+-------+-------+-------+-----------+
26287 static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26289 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26292 case OPC_MXU_Q8MAC:
26293 /* TODO: Implement emulation of Q8MAC instruction. */
26294 MIPS_INVAL("OPC_MXU_Q8MAC");
26295 generate_exception_end(ctx, EXCP_RI);
26297 case OPC_MXU_Q8MACSU:
26298 /* TODO: Implement emulation of Q8MACSU instruction. */
26299 MIPS_INVAL("OPC_MXU_Q8MACSU");
26300 generate_exception_end(ctx, EXCP_RI);
26303 MIPS_INVAL("decode_opc_mxu");
26304 generate_exception_end(ctx, EXCP_RI);
26311 * Main MXU decoding function
26313 * 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
26314 * +-----------+---------------------------------------+-----------+
26315 * | SPECIAL2 | |x x x x x x|
26316 * +-----------+---------------------------------------+-----------+
26319 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26322 * TODO: Investigate necessity of including handling of
26323 * CLZ, CLO, SDBB in this function, as they belong to
26324 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26326 uint32_t opcode = extract32(ctx->opcode, 0, 6);
26328 if (opcode == OPC__MXU_MUL) {
26329 uint32_t rs, rt, rd, op1;
26331 rs = extract32(ctx->opcode, 21, 5);
26332 rt = extract32(ctx->opcode, 16, 5);
26333 rd = extract32(ctx->opcode, 11, 5);
26334 op1 = MASK_SPECIAL2(ctx->opcode);
26336 gen_arith(ctx, op1, rd, rs, rt);
26341 if (opcode == OPC_MXU_S32M2I) {
26342 gen_mxu_s32m2i(ctx);
26346 if (opcode == OPC_MXU_S32I2M) {
26347 gen_mxu_s32i2m(ctx);
26352 TCGv t_mxu_cr = tcg_temp_new();
26353 TCGLabel *l_exit = gen_new_label();
26355 gen_load_mxu_cr(t_mxu_cr);
26356 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26357 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26360 case OPC_MXU_S32MADD:
26361 /* TODO: Implement emulation of S32MADD instruction. */
26362 MIPS_INVAL("OPC_MXU_S32MADD");
26363 generate_exception_end(ctx, EXCP_RI);
26365 case OPC_MXU_S32MADDU:
26366 /* TODO: Implement emulation of S32MADDU instruction. */
26367 MIPS_INVAL("OPC_MXU_S32MADDU");
26368 generate_exception_end(ctx, EXCP_RI);
26370 case OPC_MXU__POOL00:
26371 decode_opc_mxu__pool00(env, ctx);
26373 case OPC_MXU_S32MSUB:
26374 /* TODO: Implement emulation of S32MSUB instruction. */
26375 MIPS_INVAL("OPC_MXU_S32MSUB");
26376 generate_exception_end(ctx, EXCP_RI);
26378 case OPC_MXU_S32MSUBU:
26379 /* TODO: Implement emulation of S32MSUBU instruction. */
26380 MIPS_INVAL("OPC_MXU_S32MSUBU");
26381 generate_exception_end(ctx, EXCP_RI);
26383 case OPC_MXU__POOL01:
26384 decode_opc_mxu__pool01(env, ctx);
26386 case OPC_MXU__POOL02:
26387 decode_opc_mxu__pool02(env, ctx);
26389 case OPC_MXU_D16MUL:
26390 gen_mxu_d16mul(ctx);
26392 case OPC_MXU__POOL03:
26393 decode_opc_mxu__pool03(env, ctx);
26395 case OPC_MXU_D16MAC:
26396 gen_mxu_d16mac(ctx);
26398 case OPC_MXU_D16MACF:
26399 /* TODO: Implement emulation of D16MACF instruction. */
26400 MIPS_INVAL("OPC_MXU_D16MACF");
26401 generate_exception_end(ctx, EXCP_RI);
26403 case OPC_MXU_D16MADL:
26404 /* TODO: Implement emulation of D16MADL instruction. */
26405 MIPS_INVAL("OPC_MXU_D16MADL");
26406 generate_exception_end(ctx, EXCP_RI);
26408 case OPC_MXU_S16MAD:
26409 /* TODO: Implement emulation of S16MAD instruction. */
26410 MIPS_INVAL("OPC_MXU_S16MAD");
26411 generate_exception_end(ctx, EXCP_RI);
26413 case OPC_MXU_Q16ADD:
26414 /* TODO: Implement emulation of Q16ADD instruction. */
26415 MIPS_INVAL("OPC_MXU_Q16ADD");
26416 generate_exception_end(ctx, EXCP_RI);
26418 case OPC_MXU_D16MACE:
26419 /* TODO: Implement emulation of D16MACE instruction. */
26420 MIPS_INVAL("OPC_MXU_D16MACE");
26421 generate_exception_end(ctx, EXCP_RI);
26423 case OPC_MXU__POOL04:
26424 decode_opc_mxu__pool04(env, ctx);
26426 case OPC_MXU__POOL05:
26427 decode_opc_mxu__pool05(env, ctx);
26429 case OPC_MXU__POOL06:
26430 decode_opc_mxu__pool06(env, ctx);
26432 case OPC_MXU__POOL07:
26433 decode_opc_mxu__pool07(env, ctx);
26435 case OPC_MXU__POOL08:
26436 decode_opc_mxu__pool08(env, ctx);
26438 case OPC_MXU__POOL09:
26439 decode_opc_mxu__pool09(env, ctx);
26441 case OPC_MXU__POOL10:
26442 decode_opc_mxu__pool10(env, ctx);
26444 case OPC_MXU__POOL11:
26445 decode_opc_mxu__pool11(env, ctx);
26447 case OPC_MXU_D32ADD:
26448 /* TODO: Implement emulation of D32ADD instruction. */
26449 MIPS_INVAL("OPC_MXU_D32ADD");
26450 generate_exception_end(ctx, EXCP_RI);
26452 case OPC_MXU__POOL12:
26453 decode_opc_mxu__pool12(env, ctx);
26455 case OPC_MXU__POOL13:
26456 decode_opc_mxu__pool13(env, ctx);
26458 case OPC_MXU__POOL14:
26459 decode_opc_mxu__pool14(env, ctx);
26461 case OPC_MXU_Q8ACCE:
26462 /* TODO: Implement emulation of Q8ACCE instruction. */
26463 MIPS_INVAL("OPC_MXU_Q8ACCE");
26464 generate_exception_end(ctx, EXCP_RI);
26466 case OPC_MXU_S8LDD:
26467 gen_mxu_s8ldd(ctx);
26469 case OPC_MXU_S8STD:
26470 /* TODO: Implement emulation of S8STD instruction. */
26471 MIPS_INVAL("OPC_MXU_S8STD");
26472 generate_exception_end(ctx, EXCP_RI);
26474 case OPC_MXU_S8LDI:
26475 /* TODO: Implement emulation of S8LDI instruction. */
26476 MIPS_INVAL("OPC_MXU_S8LDI");
26477 generate_exception_end(ctx, EXCP_RI);
26479 case OPC_MXU_S8SDI:
26480 /* TODO: Implement emulation of S8SDI instruction. */
26481 MIPS_INVAL("OPC_MXU_S8SDI");
26482 generate_exception_end(ctx, EXCP_RI);
26484 case OPC_MXU__POOL15:
26485 decode_opc_mxu__pool15(env, ctx);
26487 case OPC_MXU__POOL16:
26488 decode_opc_mxu__pool16(env, ctx);
26490 case OPC_MXU__POOL17:
26491 decode_opc_mxu__pool17(env, ctx);
26493 case OPC_MXU_S16LDD:
26494 /* TODO: Implement emulation of S16LDD instruction. */
26495 MIPS_INVAL("OPC_MXU_S16LDD");
26496 generate_exception_end(ctx, EXCP_RI);
26498 case OPC_MXU_S16STD:
26499 /* TODO: Implement emulation of S16STD instruction. */
26500 MIPS_INVAL("OPC_MXU_S16STD");
26501 generate_exception_end(ctx, EXCP_RI);
26503 case OPC_MXU_S16LDI:
26504 /* TODO: Implement emulation of S16LDI instruction. */
26505 MIPS_INVAL("OPC_MXU_S16LDI");
26506 generate_exception_end(ctx, EXCP_RI);
26508 case OPC_MXU_S16SDI:
26509 /* TODO: Implement emulation of S16SDI instruction. */
26510 MIPS_INVAL("OPC_MXU_S16SDI");
26511 generate_exception_end(ctx, EXCP_RI);
26513 case OPC_MXU_D32SLL:
26514 /* TODO: Implement emulation of D32SLL instruction. */
26515 MIPS_INVAL("OPC_MXU_D32SLL");
26516 generate_exception_end(ctx, EXCP_RI);
26518 case OPC_MXU_D32SLR:
26519 /* TODO: Implement emulation of D32SLR instruction. */
26520 MIPS_INVAL("OPC_MXU_D32SLR");
26521 generate_exception_end(ctx, EXCP_RI);
26523 case OPC_MXU_D32SARL:
26524 /* TODO: Implement emulation of D32SARL instruction. */
26525 MIPS_INVAL("OPC_MXU_D32SARL");
26526 generate_exception_end(ctx, EXCP_RI);
26528 case OPC_MXU_D32SAR:
26529 /* TODO: Implement emulation of D32SAR instruction. */
26530 MIPS_INVAL("OPC_MXU_D32SAR");
26531 generate_exception_end(ctx, EXCP_RI);
26533 case OPC_MXU_Q16SLL:
26534 /* TODO: Implement emulation of Q16SLL instruction. */
26535 MIPS_INVAL("OPC_MXU_Q16SLL");
26536 generate_exception_end(ctx, EXCP_RI);
26538 case OPC_MXU_Q16SLR:
26539 /* TODO: Implement emulation of Q16SLR instruction. */
26540 MIPS_INVAL("OPC_MXU_Q16SLR");
26541 generate_exception_end(ctx, EXCP_RI);
26543 case OPC_MXU__POOL18:
26544 decode_opc_mxu__pool18(env, ctx);
26546 case OPC_MXU_Q16SAR:
26547 /* TODO: Implement emulation of Q16SAR instruction. */
26548 MIPS_INVAL("OPC_MXU_Q16SAR");
26549 generate_exception_end(ctx, EXCP_RI);
26551 case OPC_MXU__POOL19:
26552 decode_opc_mxu__pool19(env, ctx);
26554 case OPC_MXU__POOL20:
26555 decode_opc_mxu__pool20(env, ctx);
26557 case OPC_MXU__POOL21:
26558 decode_opc_mxu__pool21(env, ctx);
26560 case OPC_MXU_Q16SCOP:
26561 /* TODO: Implement emulation of Q16SCOP instruction. */
26562 MIPS_INVAL("OPC_MXU_Q16SCOP");
26563 generate_exception_end(ctx, EXCP_RI);
26565 case OPC_MXU_Q8MADL:
26566 /* TODO: Implement emulation of Q8MADL instruction. */
26567 MIPS_INVAL("OPC_MXU_Q8MADL");
26568 generate_exception_end(ctx, EXCP_RI);
26570 case OPC_MXU_S32SFL:
26571 /* TODO: Implement emulation of S32SFL instruction. */
26572 MIPS_INVAL("OPC_MXU_S32SFL");
26573 generate_exception_end(ctx, EXCP_RI);
26575 case OPC_MXU_Q8SAD:
26576 /* TODO: Implement emulation of Q8SAD instruction. */
26577 MIPS_INVAL("OPC_MXU_Q8SAD");
26578 generate_exception_end(ctx, EXCP_RI);
26581 MIPS_INVAL("decode_opc_mxu");
26582 generate_exception_end(ctx, EXCP_RI);
26585 gen_set_label(l_exit);
26586 tcg_temp_free(t_mxu_cr);
26590 #endif /* !defined(TARGET_MIPS64) */
26593 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26598 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26600 rs = (ctx->opcode >> 21) & 0x1f;
26601 rt = (ctx->opcode >> 16) & 0x1f;
26602 rd = (ctx->opcode >> 11) & 0x1f;
26604 op1 = MASK_SPECIAL2(ctx->opcode);
26606 case OPC_MADD: /* Multiply and add/sub */
26610 check_insn(ctx, ISA_MIPS32);
26611 gen_muldiv(ctx, op1, rd & 3, rs, rt);
26614 gen_arith(ctx, op1, rd, rs, rt);
26617 case OPC_DIVU_G_2F:
26618 case OPC_MULT_G_2F:
26619 case OPC_MULTU_G_2F:
26621 case OPC_MODU_G_2F:
26622 check_insn(ctx, INSN_LOONGSON2F);
26623 gen_loongson_integer(ctx, op1, rd, rs, rt);
26627 check_insn(ctx, ISA_MIPS32);
26628 gen_cl(ctx, op1, rd, rs);
26631 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26632 gen_helper_do_semihosting(cpu_env);
26634 /* XXX: not clear which exception should be raised
26635 * when in debug mode...
26637 check_insn(ctx, ISA_MIPS32);
26638 generate_exception_end(ctx, EXCP_DBp);
26641 #if defined(TARGET_MIPS64)
26644 check_insn(ctx, ISA_MIPS64);
26645 check_mips_64(ctx);
26646 gen_cl(ctx, op1, rd, rs);
26648 case OPC_DMULT_G_2F:
26649 case OPC_DMULTU_G_2F:
26650 case OPC_DDIV_G_2F:
26651 case OPC_DDIVU_G_2F:
26652 case OPC_DMOD_G_2F:
26653 case OPC_DMODU_G_2F:
26654 check_insn(ctx, INSN_LOONGSON2F);
26655 gen_loongson_integer(ctx, op1, rd, rs, rt);
26658 default: /* Invalid */
26659 MIPS_INVAL("special2_legacy");
26660 generate_exception_end(ctx, EXCP_RI);
26665 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26667 int rs, rt, rd, sa;
26671 rs = (ctx->opcode >> 21) & 0x1f;
26672 rt = (ctx->opcode >> 16) & 0x1f;
26673 rd = (ctx->opcode >> 11) & 0x1f;
26674 sa = (ctx->opcode >> 6) & 0x1f;
26675 imm = (int16_t)ctx->opcode >> 7;
26677 op1 = MASK_SPECIAL3(ctx->opcode);
26681 /* hint codes 24-31 are reserved and signal RI */
26682 generate_exception_end(ctx, EXCP_RI);
26684 /* Treat as NOP. */
26687 check_cp0_enabled(ctx);
26688 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26689 gen_cache_operation(ctx, rt, rs, imm);
26693 gen_st_cond(ctx, op1, rt, rs, imm);
26696 gen_ld(ctx, op1, rt, rs, imm);
26701 /* Treat as NOP. */
26704 op2 = MASK_BSHFL(ctx->opcode);
26710 gen_align(ctx, 32, rd, rs, rt, sa & 3);
26713 gen_bitswap(ctx, op2, rd, rt);
26718 #if defined(TARGET_MIPS64)
26720 gen_st_cond(ctx, op1, rt, rs, imm);
26723 gen_ld(ctx, op1, rt, rs, imm);
26726 check_mips_64(ctx);
26729 /* Treat as NOP. */
26732 op2 = MASK_DBSHFL(ctx->opcode);
26742 gen_align(ctx, 64, rd, rs, rt, sa & 7);
26745 gen_bitswap(ctx, op2, rd, rt);
26752 default: /* Invalid */
26753 MIPS_INVAL("special3_r6");
26754 generate_exception_end(ctx, EXCP_RI);
26759 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
26764 rs = (ctx->opcode >> 21) & 0x1f;
26765 rt = (ctx->opcode >> 16) & 0x1f;
26766 rd = (ctx->opcode >> 11) & 0x1f;
26768 op1 = MASK_SPECIAL3(ctx->opcode);
26771 case OPC_DIVU_G_2E:
26773 case OPC_MODU_G_2E:
26774 case OPC_MULT_G_2E:
26775 case OPC_MULTU_G_2E:
26776 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26777 * the same mask and op1. */
26778 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
26779 op2 = MASK_ADDUH_QB(ctx->opcode);
26782 case OPC_ADDUH_R_QB:
26784 case OPC_ADDQH_R_PH:
26786 case OPC_ADDQH_R_W:
26788 case OPC_SUBUH_R_QB:
26790 case OPC_SUBQH_R_PH:
26792 case OPC_SUBQH_R_W:
26793 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26798 case OPC_MULQ_RS_W:
26799 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26802 MIPS_INVAL("MASK ADDUH.QB");
26803 generate_exception_end(ctx, EXCP_RI);
26806 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
26807 gen_loongson_integer(ctx, op1, rd, rs, rt);
26809 generate_exception_end(ctx, EXCP_RI);
26813 op2 = MASK_LX(ctx->opcode);
26815 #if defined(TARGET_MIPS64)
26821 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26823 default: /* Invalid */
26824 MIPS_INVAL("MASK LX");
26825 generate_exception_end(ctx, EXCP_RI);
26829 case OPC_ABSQ_S_PH_DSP:
26830 op2 = MASK_ABSQ_S_PH(ctx->opcode);
26832 case OPC_ABSQ_S_QB:
26833 case OPC_ABSQ_S_PH:
26835 case OPC_PRECEQ_W_PHL:
26836 case OPC_PRECEQ_W_PHR:
26837 case OPC_PRECEQU_PH_QBL:
26838 case OPC_PRECEQU_PH_QBR:
26839 case OPC_PRECEQU_PH_QBLA:
26840 case OPC_PRECEQU_PH_QBRA:
26841 case OPC_PRECEU_PH_QBL:
26842 case OPC_PRECEU_PH_QBR:
26843 case OPC_PRECEU_PH_QBLA:
26844 case OPC_PRECEU_PH_QBRA:
26845 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26852 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26855 MIPS_INVAL("MASK ABSQ_S.PH");
26856 generate_exception_end(ctx, EXCP_RI);
26860 case OPC_ADDU_QB_DSP:
26861 op2 = MASK_ADDU_QB(ctx->opcode);
26864 case OPC_ADDQ_S_PH:
26867 case OPC_ADDU_S_QB:
26869 case OPC_ADDU_S_PH:
26871 case OPC_SUBQ_S_PH:
26874 case OPC_SUBU_S_QB:
26876 case OPC_SUBU_S_PH:
26880 case OPC_RADDU_W_QB:
26881 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26883 case OPC_MULEU_S_PH_QBL:
26884 case OPC_MULEU_S_PH_QBR:
26885 case OPC_MULQ_RS_PH:
26886 case OPC_MULEQ_S_W_PHL:
26887 case OPC_MULEQ_S_W_PHR:
26888 case OPC_MULQ_S_PH:
26889 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26891 default: /* Invalid */
26892 MIPS_INVAL("MASK ADDU.QB");
26893 generate_exception_end(ctx, EXCP_RI);
26898 case OPC_CMPU_EQ_QB_DSP:
26899 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
26901 case OPC_PRECR_SRA_PH_W:
26902 case OPC_PRECR_SRA_R_PH_W:
26903 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
26905 case OPC_PRECR_QB_PH:
26906 case OPC_PRECRQ_QB_PH:
26907 case OPC_PRECRQ_PH_W:
26908 case OPC_PRECRQ_RS_PH_W:
26909 case OPC_PRECRQU_S_QB_PH:
26910 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26912 case OPC_CMPU_EQ_QB:
26913 case OPC_CMPU_LT_QB:
26914 case OPC_CMPU_LE_QB:
26915 case OPC_CMP_EQ_PH:
26916 case OPC_CMP_LT_PH:
26917 case OPC_CMP_LE_PH:
26918 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
26920 case OPC_CMPGU_EQ_QB:
26921 case OPC_CMPGU_LT_QB:
26922 case OPC_CMPGU_LE_QB:
26923 case OPC_CMPGDU_EQ_QB:
26924 case OPC_CMPGDU_LT_QB:
26925 case OPC_CMPGDU_LE_QB:
26928 case OPC_PACKRL_PH:
26929 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26931 default: /* Invalid */
26932 MIPS_INVAL("MASK CMPU.EQ.QB");
26933 generate_exception_end(ctx, EXCP_RI);
26937 case OPC_SHLL_QB_DSP:
26938 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26940 case OPC_DPA_W_PH_DSP:
26941 op2 = MASK_DPA_W_PH(ctx->opcode);
26943 case OPC_DPAU_H_QBL:
26944 case OPC_DPAU_H_QBR:
26945 case OPC_DPSU_H_QBL:
26946 case OPC_DPSU_H_QBR:
26948 case OPC_DPAX_W_PH:
26949 case OPC_DPAQ_S_W_PH:
26950 case OPC_DPAQX_S_W_PH:
26951 case OPC_DPAQX_SA_W_PH:
26953 case OPC_DPSX_W_PH:
26954 case OPC_DPSQ_S_W_PH:
26955 case OPC_DPSQX_S_W_PH:
26956 case OPC_DPSQX_SA_W_PH:
26957 case OPC_MULSAQ_S_W_PH:
26958 case OPC_DPAQ_SA_L_W:
26959 case OPC_DPSQ_SA_L_W:
26960 case OPC_MAQ_S_W_PHL:
26961 case OPC_MAQ_S_W_PHR:
26962 case OPC_MAQ_SA_W_PHL:
26963 case OPC_MAQ_SA_W_PHR:
26964 case OPC_MULSA_W_PH:
26965 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26967 default: /* Invalid */
26968 MIPS_INVAL("MASK DPAW.PH");
26969 generate_exception_end(ctx, EXCP_RI);
26974 op2 = MASK_INSV(ctx->opcode);
26985 t0 = tcg_temp_new();
26986 t1 = tcg_temp_new();
26988 gen_load_gpr(t0, rt);
26989 gen_load_gpr(t1, rs);
26991 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
26997 default: /* Invalid */
26998 MIPS_INVAL("MASK INSV");
26999 generate_exception_end(ctx, EXCP_RI);
27003 case OPC_APPEND_DSP:
27004 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27006 case OPC_EXTR_W_DSP:
27007 op2 = MASK_EXTR_W(ctx->opcode);
27011 case OPC_EXTR_RS_W:
27013 case OPC_EXTRV_S_H:
27015 case OPC_EXTRV_R_W:
27016 case OPC_EXTRV_RS_W:
27021 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27024 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27030 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27032 default: /* Invalid */
27033 MIPS_INVAL("MASK EXTR.W");
27034 generate_exception_end(ctx, EXCP_RI);
27038 #if defined(TARGET_MIPS64)
27039 case OPC_DDIV_G_2E:
27040 case OPC_DDIVU_G_2E:
27041 case OPC_DMULT_G_2E:
27042 case OPC_DMULTU_G_2E:
27043 case OPC_DMOD_G_2E:
27044 case OPC_DMODU_G_2E:
27045 check_insn(ctx, INSN_LOONGSON2E);
27046 gen_loongson_integer(ctx, op1, rd, rs, rt);
27048 case OPC_ABSQ_S_QH_DSP:
27049 op2 = MASK_ABSQ_S_QH(ctx->opcode);
27051 case OPC_PRECEQ_L_PWL:
27052 case OPC_PRECEQ_L_PWR:
27053 case OPC_PRECEQ_PW_QHL:
27054 case OPC_PRECEQ_PW_QHR:
27055 case OPC_PRECEQ_PW_QHLA:
27056 case OPC_PRECEQ_PW_QHRA:
27057 case OPC_PRECEQU_QH_OBL:
27058 case OPC_PRECEQU_QH_OBR:
27059 case OPC_PRECEQU_QH_OBLA:
27060 case OPC_PRECEQU_QH_OBRA:
27061 case OPC_PRECEU_QH_OBL:
27062 case OPC_PRECEU_QH_OBR:
27063 case OPC_PRECEU_QH_OBLA:
27064 case OPC_PRECEU_QH_OBRA:
27065 case OPC_ABSQ_S_OB:
27066 case OPC_ABSQ_S_PW:
27067 case OPC_ABSQ_S_QH:
27068 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27076 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27078 default: /* Invalid */
27079 MIPS_INVAL("MASK ABSQ_S.QH");
27080 generate_exception_end(ctx, EXCP_RI);
27084 case OPC_ADDU_OB_DSP:
27085 op2 = MASK_ADDU_OB(ctx->opcode);
27087 case OPC_RADDU_L_OB:
27089 case OPC_SUBQ_S_PW:
27091 case OPC_SUBQ_S_QH:
27093 case OPC_SUBU_S_OB:
27095 case OPC_SUBU_S_QH:
27097 case OPC_SUBUH_R_OB:
27099 case OPC_ADDQ_S_PW:
27101 case OPC_ADDQ_S_QH:
27103 case OPC_ADDU_S_OB:
27105 case OPC_ADDU_S_QH:
27107 case OPC_ADDUH_R_OB:
27108 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27110 case OPC_MULEQ_S_PW_QHL:
27111 case OPC_MULEQ_S_PW_QHR:
27112 case OPC_MULEU_S_QH_OBL:
27113 case OPC_MULEU_S_QH_OBR:
27114 case OPC_MULQ_RS_QH:
27115 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27117 default: /* Invalid */
27118 MIPS_INVAL("MASK ADDU.OB");
27119 generate_exception_end(ctx, EXCP_RI);
27123 case OPC_CMPU_EQ_OB_DSP:
27124 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27126 case OPC_PRECR_SRA_QH_PW:
27127 case OPC_PRECR_SRA_R_QH_PW:
27128 /* Return value is rt. */
27129 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27131 case OPC_PRECR_OB_QH:
27132 case OPC_PRECRQ_OB_QH:
27133 case OPC_PRECRQ_PW_L:
27134 case OPC_PRECRQ_QH_PW:
27135 case OPC_PRECRQ_RS_QH_PW:
27136 case OPC_PRECRQU_S_OB_QH:
27137 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27139 case OPC_CMPU_EQ_OB:
27140 case OPC_CMPU_LT_OB:
27141 case OPC_CMPU_LE_OB:
27142 case OPC_CMP_EQ_QH:
27143 case OPC_CMP_LT_QH:
27144 case OPC_CMP_LE_QH:
27145 case OPC_CMP_EQ_PW:
27146 case OPC_CMP_LT_PW:
27147 case OPC_CMP_LE_PW:
27148 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27150 case OPC_CMPGDU_EQ_OB:
27151 case OPC_CMPGDU_LT_OB:
27152 case OPC_CMPGDU_LE_OB:
27153 case OPC_CMPGU_EQ_OB:
27154 case OPC_CMPGU_LT_OB:
27155 case OPC_CMPGU_LE_OB:
27156 case OPC_PACKRL_PW:
27160 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27162 default: /* Invalid */
27163 MIPS_INVAL("MASK CMPU_EQ.OB");
27164 generate_exception_end(ctx, EXCP_RI);
27168 case OPC_DAPPEND_DSP:
27169 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27171 case OPC_DEXTR_W_DSP:
27172 op2 = MASK_DEXTR_W(ctx->opcode);
27179 case OPC_DEXTR_R_L:
27180 case OPC_DEXTR_RS_L:
27182 case OPC_DEXTR_R_W:
27183 case OPC_DEXTR_RS_W:
27184 case OPC_DEXTR_S_H:
27186 case OPC_DEXTRV_R_L:
27187 case OPC_DEXTRV_RS_L:
27188 case OPC_DEXTRV_S_H:
27190 case OPC_DEXTRV_R_W:
27191 case OPC_DEXTRV_RS_W:
27192 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27197 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27199 default: /* Invalid */
27200 MIPS_INVAL("MASK EXTR.W");
27201 generate_exception_end(ctx, EXCP_RI);
27205 case OPC_DPAQ_W_QH_DSP:
27206 op2 = MASK_DPAQ_W_QH(ctx->opcode);
27208 case OPC_DPAU_H_OBL:
27209 case OPC_DPAU_H_OBR:
27210 case OPC_DPSU_H_OBL:
27211 case OPC_DPSU_H_OBR:
27213 case OPC_DPAQ_S_W_QH:
27215 case OPC_DPSQ_S_W_QH:
27216 case OPC_MULSAQ_S_W_QH:
27217 case OPC_DPAQ_SA_L_PW:
27218 case OPC_DPSQ_SA_L_PW:
27219 case OPC_MULSAQ_S_L_PW:
27220 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27222 case OPC_MAQ_S_W_QHLL:
27223 case OPC_MAQ_S_W_QHLR:
27224 case OPC_MAQ_S_W_QHRL:
27225 case OPC_MAQ_S_W_QHRR:
27226 case OPC_MAQ_SA_W_QHLL:
27227 case OPC_MAQ_SA_W_QHLR:
27228 case OPC_MAQ_SA_W_QHRL:
27229 case OPC_MAQ_SA_W_QHRR:
27230 case OPC_MAQ_S_L_PWL:
27231 case OPC_MAQ_S_L_PWR:
27236 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27238 default: /* Invalid */
27239 MIPS_INVAL("MASK DPAQ.W.QH");
27240 generate_exception_end(ctx, EXCP_RI);
27244 case OPC_DINSV_DSP:
27245 op2 = MASK_INSV(ctx->opcode);
27256 t0 = tcg_temp_new();
27257 t1 = tcg_temp_new();
27259 gen_load_gpr(t0, rt);
27260 gen_load_gpr(t1, rs);
27262 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27268 default: /* Invalid */
27269 MIPS_INVAL("MASK DINSV");
27270 generate_exception_end(ctx, EXCP_RI);
27274 case OPC_SHLL_OB_DSP:
27275 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27278 default: /* Invalid */
27279 MIPS_INVAL("special3_legacy");
27280 generate_exception_end(ctx, EXCP_RI);
27285 static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27287 uint32_t opc = MASK_MMI0(ctx->opcode);
27290 case MMI_OPC_0_PADDW: /* TODO: MMI_OPC_0_PADDW */
27291 case MMI_OPC_0_PSUBW: /* TODO: MMI_OPC_0_PSUBW */
27292 case MMI_OPC_0_PCGTW: /* TODO: MMI_OPC_0_PCGTW */
27293 case MMI_OPC_0_PMAXW: /* TODO: MMI_OPC_0_PMAXW */
27294 case MMI_OPC_0_PADDH: /* TODO: MMI_OPC_0_PADDH */
27295 case MMI_OPC_0_PSUBH: /* TODO: MMI_OPC_0_PSUBH */
27296 case MMI_OPC_0_PCGTH: /* TODO: MMI_OPC_0_PCGTH */
27297 case MMI_OPC_0_PMAXH: /* TODO: MMI_OPC_0_PMAXH */
27298 case MMI_OPC_0_PADDB: /* TODO: MMI_OPC_0_PADDB */
27299 case MMI_OPC_0_PSUBB: /* TODO: MMI_OPC_0_PSUBB */
27300 case MMI_OPC_0_PCGTB: /* TODO: MMI_OPC_0_PCGTB */
27301 case MMI_OPC_0_PADDSW: /* TODO: MMI_OPC_0_PADDSW */
27302 case MMI_OPC_0_PSUBSW: /* TODO: MMI_OPC_0_PSUBSW */
27303 case MMI_OPC_0_PEXTLW: /* TODO: MMI_OPC_0_PEXTLW */
27304 case MMI_OPC_0_PPACW: /* TODO: MMI_OPC_0_PPACW */
27305 case MMI_OPC_0_PADDSH: /* TODO: MMI_OPC_0_PADDSH */
27306 case MMI_OPC_0_PSUBSH: /* TODO: MMI_OPC_0_PSUBSH */
27307 case MMI_OPC_0_PEXTLH: /* TODO: MMI_OPC_0_PEXTLH */
27308 case MMI_OPC_0_PPACH: /* TODO: MMI_OPC_0_PPACH */
27309 case MMI_OPC_0_PADDSB: /* TODO: MMI_OPC_0_PADDSB */
27310 case MMI_OPC_0_PSUBSB: /* TODO: MMI_OPC_0_PSUBSB */
27311 case MMI_OPC_0_PEXTLB: /* TODO: MMI_OPC_0_PEXTLB */
27312 case MMI_OPC_0_PPACB: /* TODO: MMI_OPC_0_PPACB */
27313 case MMI_OPC_0_PEXT5: /* TODO: MMI_OPC_0_PEXT5 */
27314 case MMI_OPC_0_PPAC5: /* TODO: MMI_OPC_0_PPAC5 */
27315 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27318 MIPS_INVAL("TX79 MMI class MMI0");
27319 generate_exception_end(ctx, EXCP_RI);
27324 static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27326 uint32_t opc = MASK_MMI1(ctx->opcode);
27329 case MMI_OPC_1_PABSW: /* TODO: MMI_OPC_1_PABSW */
27330 case MMI_OPC_1_PCEQW: /* TODO: MMI_OPC_1_PCEQW */
27331 case MMI_OPC_1_PMINW: /* TODO: MMI_OPC_1_PMINW */
27332 case MMI_OPC_1_PADSBH: /* TODO: MMI_OPC_1_PADSBH */
27333 case MMI_OPC_1_PABSH: /* TODO: MMI_OPC_1_PABSH */
27334 case MMI_OPC_1_PCEQH: /* TODO: MMI_OPC_1_PCEQH */
27335 case MMI_OPC_1_PMINH: /* TODO: MMI_OPC_1_PMINH */
27336 case MMI_OPC_1_PCEQB: /* TODO: MMI_OPC_1_PCEQB */
27337 case MMI_OPC_1_PADDUW: /* TODO: MMI_OPC_1_PADDUW */
27338 case MMI_OPC_1_PSUBUW: /* TODO: MMI_OPC_1_PSUBUW */
27339 case MMI_OPC_1_PEXTUW: /* TODO: MMI_OPC_1_PEXTUW */
27340 case MMI_OPC_1_PADDUH: /* TODO: MMI_OPC_1_PADDUH */
27341 case MMI_OPC_1_PSUBUH: /* TODO: MMI_OPC_1_PSUBUH */
27342 case MMI_OPC_1_PEXTUH: /* TODO: MMI_OPC_1_PEXTUH */
27343 case MMI_OPC_1_PADDUB: /* TODO: MMI_OPC_1_PADDUB */
27344 case MMI_OPC_1_PSUBUB: /* TODO: MMI_OPC_1_PSUBUB */
27345 case MMI_OPC_1_PEXTUB: /* TODO: MMI_OPC_1_PEXTUB */
27346 case MMI_OPC_1_QFSRV: /* TODO: MMI_OPC_1_QFSRV */
27347 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27350 MIPS_INVAL("TX79 MMI class MMI1");
27351 generate_exception_end(ctx, EXCP_RI);
27356 static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27358 uint32_t opc = MASK_MMI2(ctx->opcode);
27361 case MMI_OPC_2_PMADDW: /* TODO: MMI_OPC_2_PMADDW */
27362 case MMI_OPC_2_PSLLVW: /* TODO: MMI_OPC_2_PSLLVW */
27363 case MMI_OPC_2_PSRLVW: /* TODO: MMI_OPC_2_PSRLVW */
27364 case MMI_OPC_2_PMSUBW: /* TODO: MMI_OPC_2_PMSUBW */
27365 case MMI_OPC_2_PMFHI: /* TODO: MMI_OPC_2_PMFHI */
27366 case MMI_OPC_2_PMFLO: /* TODO: MMI_OPC_2_PMFLO */
27367 case MMI_OPC_2_PINTH: /* TODO: MMI_OPC_2_PINTH */
27368 case MMI_OPC_2_PMULTW: /* TODO: MMI_OPC_2_PMULTW */
27369 case MMI_OPC_2_PDIVW: /* TODO: MMI_OPC_2_PDIVW */
27370 case MMI_OPC_2_PCPYLD: /* TODO: MMI_OPC_2_PCPYLD */
27371 case MMI_OPC_2_PMADDH: /* TODO: MMI_OPC_2_PMADDH */
27372 case MMI_OPC_2_PHMADH: /* TODO: MMI_OPC_2_PHMADH */
27373 case MMI_OPC_2_PAND: /* TODO: MMI_OPC_2_PAND */
27374 case MMI_OPC_2_PXOR: /* TODO: MMI_OPC_2_PXOR */
27375 case MMI_OPC_2_PMSUBH: /* TODO: MMI_OPC_2_PMSUBH */
27376 case MMI_OPC_2_PHMSBH: /* TODO: MMI_OPC_2_PHMSBH */
27377 case MMI_OPC_2_PEXEH: /* TODO: MMI_OPC_2_PEXEH */
27378 case MMI_OPC_2_PREVH: /* TODO: MMI_OPC_2_PREVH */
27379 case MMI_OPC_2_PMULTH: /* TODO: MMI_OPC_2_PMULTH */
27380 case MMI_OPC_2_PDIVBW: /* TODO: MMI_OPC_2_PDIVBW */
27381 case MMI_OPC_2_PEXEW: /* TODO: MMI_OPC_2_PEXEW */
27382 case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */
27383 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27386 MIPS_INVAL("TX79 MMI class MMI2");
27387 generate_exception_end(ctx, EXCP_RI);
27392 static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27394 uint32_t opc = MASK_MMI3(ctx->opcode);
27397 case MMI_OPC_3_PMADDUW: /* TODO: MMI_OPC_3_PMADDUW */
27398 case MMI_OPC_3_PSRAVW: /* TODO: MMI_OPC_3_PSRAVW */
27399 case MMI_OPC_3_PMTHI: /* TODO: MMI_OPC_3_PMTHI */
27400 case MMI_OPC_3_PMTLO: /* TODO: MMI_OPC_3_PMTLO */
27401 case MMI_OPC_3_PINTEH: /* TODO: MMI_OPC_3_PINTEH */
27402 case MMI_OPC_3_PMULTUW: /* TODO: MMI_OPC_3_PMULTUW */
27403 case MMI_OPC_3_PDIVUW: /* TODO: MMI_OPC_3_PDIVUW */
27404 case MMI_OPC_3_PCPYUD: /* TODO: MMI_OPC_3_PCPYUD */
27405 case MMI_OPC_3_POR: /* TODO: MMI_OPC_3_POR */
27406 case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */
27407 case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */
27408 case MMI_OPC_3_PCPYH: /* TODO: MMI_OPC_3_PCPYH */
27409 case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */
27410 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27413 MIPS_INVAL("TX79 MMI class MMI3");
27414 generate_exception_end(ctx, EXCP_RI);
27419 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27421 uint32_t opc = MASK_MMI(ctx->opcode);
27422 int rs = extract32(ctx->opcode, 21, 5);
27423 int rt = extract32(ctx->opcode, 16, 5);
27424 int rd = extract32(ctx->opcode, 11, 5);
27427 case MMI_OPC_CLASS_MMI0:
27428 decode_mmi0(env, ctx);
27430 case MMI_OPC_CLASS_MMI1:
27431 decode_mmi1(env, ctx);
27433 case MMI_OPC_CLASS_MMI2:
27434 decode_mmi2(env, ctx);
27436 case MMI_OPC_CLASS_MMI3:
27437 decode_mmi3(env, ctx);
27439 case MMI_OPC_MULT1:
27440 case MMI_OPC_MULTU1:
27442 case MMI_OPC_MADDU:
27443 case MMI_OPC_MADD1:
27444 case MMI_OPC_MADDU1:
27445 gen_mul_txx9(ctx, opc, rd, rs, rt);
27448 case MMI_OPC_DIVU1:
27449 gen_div1_tx79(ctx, opc, rs, rt);
27451 case MMI_OPC_MTLO1:
27452 case MMI_OPC_MTHI1:
27453 gen_HILO1_tx79(ctx, opc, rs);
27455 case MMI_OPC_MFLO1:
27456 case MMI_OPC_MFHI1:
27457 gen_HILO1_tx79(ctx, opc, rd);
27459 case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */
27460 case MMI_OPC_PMFHL: /* TODO: MMI_OPC_PMFHL */
27461 case MMI_OPC_PMTHL: /* TODO: MMI_OPC_PMTHL */
27462 case MMI_OPC_PSLLH: /* TODO: MMI_OPC_PSLLH */
27463 case MMI_OPC_PSRLH: /* TODO: MMI_OPC_PSRLH */
27464 case MMI_OPC_PSRAH: /* TODO: MMI_OPC_PSRAH */
27465 case MMI_OPC_PSLLW: /* TODO: MMI_OPC_PSLLW */
27466 case MMI_OPC_PSRLW: /* TODO: MMI_OPC_PSRLW */
27467 case MMI_OPC_PSRAW: /* TODO: MMI_OPC_PSRAW */
27468 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI */
27471 MIPS_INVAL("TX79 MMI class");
27472 generate_exception_end(ctx, EXCP_RI);
27477 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27479 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_LQ */
27482 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27484 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_SQ */
27488 * The TX79-specific instruction Store Quadword
27490 * +--------+-------+-------+------------------------+
27491 * | 011111 | base | rt | offset | SQ
27492 * +--------+-------+-------+------------------------+
27495 * has the same opcode as the Read Hardware Register instruction
27497 * +--------+-------+-------+-------+-------+--------+
27498 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
27499 * +--------+-------+-------+-------+-------+--------+
27502 * that is required, trapped and emulated by the Linux kernel. However, all
27503 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27504 * offset is odd. Therefore all valid SQ instructions can execute normally.
27505 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27506 * between SQ and RDHWR, as the Linux kernel does.
27508 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27510 int base = extract32(ctx->opcode, 21, 5);
27511 int rt = extract32(ctx->opcode, 16, 5);
27512 int offset = extract32(ctx->opcode, 0, 16);
27514 #ifdef CONFIG_USER_ONLY
27515 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27516 uint32_t op2 = extract32(ctx->opcode, 6, 5);
27518 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27519 int rd = extract32(ctx->opcode, 11, 5);
27521 gen_rdhwr(ctx, rt, rd, 0);
27526 gen_mmi_sq(ctx, base, rt, offset);
27529 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27531 int rs, rt, rd, sa;
27535 rs = (ctx->opcode >> 21) & 0x1f;
27536 rt = (ctx->opcode >> 16) & 0x1f;
27537 rd = (ctx->opcode >> 11) & 0x1f;
27538 sa = (ctx->opcode >> 6) & 0x1f;
27539 imm = sextract32(ctx->opcode, 7, 9);
27541 op1 = MASK_SPECIAL3(ctx->opcode);
27544 * EVA loads and stores overlap Loongson 2E instructions decoded by
27545 * decode_opc_special3_legacy(), so be careful to allow their decoding when
27552 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27560 check_cp0_enabled(ctx);
27561 gen_ld(ctx, op1, rt, rs, imm);
27565 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27570 check_cp0_enabled(ctx);
27571 gen_st(ctx, op1, rt, rs, imm);
27574 check_cp0_enabled(ctx);
27575 gen_st_cond(ctx, op1, rt, rs, imm);
27578 check_cp0_enabled(ctx);
27579 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27580 gen_cache_operation(ctx, rt, rs, imm);
27582 /* Treat as NOP. */
27585 check_cp0_enabled(ctx);
27586 /* Treat as NOP. */
27594 check_insn(ctx, ISA_MIPS32R2);
27595 gen_bitops(ctx, op1, rt, rs, sa, rd);
27598 op2 = MASK_BSHFL(ctx->opcode);
27605 check_insn(ctx, ISA_MIPS32R6);
27606 decode_opc_special3_r6(env, ctx);
27609 check_insn(ctx, ISA_MIPS32R2);
27610 gen_bshfl(ctx, op2, rt, rd);
27614 #if defined(TARGET_MIPS64)
27621 check_insn(ctx, ISA_MIPS64R2);
27622 check_mips_64(ctx);
27623 gen_bitops(ctx, op1, rt, rs, sa, rd);
27626 op2 = MASK_DBSHFL(ctx->opcode);
27637 check_insn(ctx, ISA_MIPS32R6);
27638 decode_opc_special3_r6(env, ctx);
27641 check_insn(ctx, ISA_MIPS64R2);
27642 check_mips_64(ctx);
27643 op2 = MASK_DBSHFL(ctx->opcode);
27644 gen_bshfl(ctx, op2, rt, rd);
27650 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27655 TCGv t0 = tcg_temp_new();
27656 TCGv t1 = tcg_temp_new();
27658 gen_load_gpr(t0, rt);
27659 gen_load_gpr(t1, rs);
27660 gen_helper_fork(t0, t1);
27668 TCGv t0 = tcg_temp_new();
27670 gen_load_gpr(t0, rs);
27671 gen_helper_yield(t0, cpu_env, t0);
27672 gen_store_gpr(t0, rd);
27677 if (ctx->insn_flags & ISA_MIPS32R6) {
27678 decode_opc_special3_r6(env, ctx);
27680 decode_opc_special3_legacy(env, ctx);
27685 /* MIPS SIMD Architecture (MSA) */
27686 static inline int check_msa_access(DisasContext *ctx)
27688 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
27689 !(ctx->hflags & MIPS_HFLAG_F64))) {
27690 generate_exception_end(ctx, EXCP_RI);
27694 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
27695 if (ctx->insn_flags & ASE_MSA) {
27696 generate_exception_end(ctx, EXCP_MSADIS);
27699 generate_exception_end(ctx, EXCP_RI);
27706 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
27708 /* generates tcg ops to check if any element is 0 */
27709 /* Note this function only works with MSA_WRLEN = 128 */
27710 uint64_t eval_zero_or_big = 0;
27711 uint64_t eval_big = 0;
27712 TCGv_i64 t0 = tcg_temp_new_i64();
27713 TCGv_i64 t1 = tcg_temp_new_i64();
27716 eval_zero_or_big = 0x0101010101010101ULL;
27717 eval_big = 0x8080808080808080ULL;
27720 eval_zero_or_big = 0x0001000100010001ULL;
27721 eval_big = 0x8000800080008000ULL;
27724 eval_zero_or_big = 0x0000000100000001ULL;
27725 eval_big = 0x8000000080000000ULL;
27728 eval_zero_or_big = 0x0000000000000001ULL;
27729 eval_big = 0x8000000000000000ULL;
27732 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
27733 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
27734 tcg_gen_andi_i64(t0, t0, eval_big);
27735 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
27736 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
27737 tcg_gen_andi_i64(t1, t1, eval_big);
27738 tcg_gen_or_i64(t0, t0, t1);
27739 /* if all bits are zero then all elements are not zero */
27740 /* if some bit is non-zero then some element is zero */
27741 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
27742 tcg_gen_trunc_i64_tl(tresult, t0);
27743 tcg_temp_free_i64(t0);
27744 tcg_temp_free_i64(t1);
27747 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
27749 uint8_t df = (ctx->opcode >> 21) & 0x3;
27750 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27751 int64_t s16 = (int16_t)ctx->opcode;
27753 check_msa_access(ctx);
27755 if (ctx->hflags & MIPS_HFLAG_BMASK) {
27756 generate_exception_end(ctx, EXCP_RI);
27763 TCGv_i64 t0 = tcg_temp_new_i64();
27764 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
27765 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
27766 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
27767 tcg_gen_trunc_i64_tl(bcond, t0);
27768 tcg_temp_free_i64(t0);
27775 gen_check_zero_element(bcond, df, wt);
27781 gen_check_zero_element(bcond, df, wt);
27782 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
27786 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
27788 ctx->hflags |= MIPS_HFLAG_BC;
27789 ctx->hflags |= MIPS_HFLAG_BDS32;
27792 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
27794 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
27795 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
27796 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27797 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27799 TCGv_i32 twd = tcg_const_i32(wd);
27800 TCGv_i32 tws = tcg_const_i32(ws);
27801 TCGv_i32 ti8 = tcg_const_i32(i8);
27803 switch (MASK_MSA_I8(ctx->opcode)) {
27805 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
27808 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
27811 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
27814 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
27817 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27820 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27823 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27829 uint8_t df = (ctx->opcode >> 24) & 0x3;
27830 if (df == DF_DOUBLE) {
27831 generate_exception_end(ctx, EXCP_RI);
27833 TCGv_i32 tdf = tcg_const_i32(df);
27834 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27835 tcg_temp_free_i32(tdf);
27840 MIPS_INVAL("MSA instruction");
27841 generate_exception_end(ctx, EXCP_RI);
27845 tcg_temp_free_i32(twd);
27846 tcg_temp_free_i32(tws);
27847 tcg_temp_free_i32(ti8);
27850 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
27852 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27853 uint8_t df = (ctx->opcode >> 21) & 0x3;
27854 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
27855 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
27856 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27857 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27859 TCGv_i32 tdf = tcg_const_i32(df);
27860 TCGv_i32 twd = tcg_const_i32(wd);
27861 TCGv_i32 tws = tcg_const_i32(ws);
27862 TCGv_i32 timm = tcg_temp_new_i32();
27863 tcg_gen_movi_i32(timm, u5);
27865 switch (MASK_MSA_I5(ctx->opcode)) {
27867 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
27870 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
27872 case OPC_MAXI_S_df:
27873 tcg_gen_movi_i32(timm, s5);
27874 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
27876 case OPC_MAXI_U_df:
27877 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
27879 case OPC_MINI_S_df:
27880 tcg_gen_movi_i32(timm, s5);
27881 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
27883 case OPC_MINI_U_df:
27884 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
27887 tcg_gen_movi_i32(timm, s5);
27888 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
27890 case OPC_CLTI_S_df:
27891 tcg_gen_movi_i32(timm, s5);
27892 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
27894 case OPC_CLTI_U_df:
27895 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
27897 case OPC_CLEI_S_df:
27898 tcg_gen_movi_i32(timm, s5);
27899 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
27901 case OPC_CLEI_U_df:
27902 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
27906 int32_t s10 = sextract32(ctx->opcode, 11, 10);
27907 tcg_gen_movi_i32(timm, s10);
27908 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
27912 MIPS_INVAL("MSA instruction");
27913 generate_exception_end(ctx, EXCP_RI);
27917 tcg_temp_free_i32(tdf);
27918 tcg_temp_free_i32(twd);
27919 tcg_temp_free_i32(tws);
27920 tcg_temp_free_i32(timm);
27923 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
27925 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27926 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
27927 uint32_t df = 0, m = 0;
27928 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27929 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27936 if ((dfm & 0x40) == 0x00) {
27939 } else if ((dfm & 0x60) == 0x40) {
27942 } else if ((dfm & 0x70) == 0x60) {
27945 } else if ((dfm & 0x78) == 0x70) {
27949 generate_exception_end(ctx, EXCP_RI);
27953 tdf = tcg_const_i32(df);
27954 tm = tcg_const_i32(m);
27955 twd = tcg_const_i32(wd);
27956 tws = tcg_const_i32(ws);
27958 switch (MASK_MSA_BIT(ctx->opcode)) {
27960 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
27963 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
27966 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
27969 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
27972 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
27975 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
27977 case OPC_BINSLI_df:
27978 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
27980 case OPC_BINSRI_df:
27981 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
27984 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
27987 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
27990 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
27993 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
27996 MIPS_INVAL("MSA instruction");
27997 generate_exception_end(ctx, EXCP_RI);
28001 tcg_temp_free_i32(tdf);
28002 tcg_temp_free_i32(tm);
28003 tcg_temp_free_i32(twd);
28004 tcg_temp_free_i32(tws);
28007 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28009 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28010 uint8_t df = (ctx->opcode >> 21) & 0x3;
28011 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28012 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28013 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28015 TCGv_i32 tdf = tcg_const_i32(df);
28016 TCGv_i32 twd = tcg_const_i32(wd);
28017 TCGv_i32 tws = tcg_const_i32(ws);
28018 TCGv_i32 twt = tcg_const_i32(wt);
28020 switch (MASK_MSA_3R(ctx->opcode)) {
28022 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28025 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28028 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28031 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28033 case OPC_SUBS_S_df:
28034 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28037 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28040 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28043 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28046 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28049 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28051 case OPC_ADDS_A_df:
28052 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28054 case OPC_SUBS_U_df:
28055 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28058 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28061 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28064 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28067 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28070 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28073 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28075 case OPC_ADDS_S_df:
28076 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28078 case OPC_SUBSUS_U_df:
28079 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28082 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28085 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28088 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28091 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28094 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28097 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28099 case OPC_ADDS_U_df:
28100 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28102 case OPC_SUBSUU_S_df:
28103 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28106 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28109 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28112 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28115 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28118 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28120 case OPC_ASUB_S_df:
28121 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28124 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28127 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28130 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28133 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28136 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28139 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28141 case OPC_ASUB_U_df:
28142 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28145 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28148 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28151 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28154 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28156 case OPC_AVER_S_df:
28157 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28160 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28163 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28166 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28169 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28171 case OPC_AVER_U_df:
28172 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28175 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28178 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28181 case OPC_DOTP_S_df:
28182 case OPC_DOTP_U_df:
28183 case OPC_DPADD_S_df:
28184 case OPC_DPADD_U_df:
28185 case OPC_DPSUB_S_df:
28186 case OPC_HADD_S_df:
28187 case OPC_DPSUB_U_df:
28188 case OPC_HADD_U_df:
28189 case OPC_HSUB_S_df:
28190 case OPC_HSUB_U_df:
28191 if (df == DF_BYTE) {
28192 generate_exception_end(ctx, EXCP_RI);
28195 switch (MASK_MSA_3R(ctx->opcode)) {
28196 case OPC_DOTP_S_df:
28197 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28199 case OPC_DOTP_U_df:
28200 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28202 case OPC_DPADD_S_df:
28203 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28205 case OPC_DPADD_U_df:
28206 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28208 case OPC_DPSUB_S_df:
28209 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28211 case OPC_HADD_S_df:
28212 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28214 case OPC_DPSUB_U_df:
28215 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28217 case OPC_HADD_U_df:
28218 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28220 case OPC_HSUB_S_df:
28221 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28223 case OPC_HSUB_U_df:
28224 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28229 MIPS_INVAL("MSA instruction");
28230 generate_exception_end(ctx, EXCP_RI);
28233 tcg_temp_free_i32(twd);
28234 tcg_temp_free_i32(tws);
28235 tcg_temp_free_i32(twt);
28236 tcg_temp_free_i32(tdf);
28239 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28241 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28242 uint8_t source = (ctx->opcode >> 11) & 0x1f;
28243 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28244 TCGv telm = tcg_temp_new();
28245 TCGv_i32 tsr = tcg_const_i32(source);
28246 TCGv_i32 tdt = tcg_const_i32(dest);
28248 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28250 gen_load_gpr(telm, source);
28251 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28254 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28255 gen_store_gpr(telm, dest);
28258 gen_helper_msa_move_v(cpu_env, tdt, tsr);
28261 MIPS_INVAL("MSA instruction");
28262 generate_exception_end(ctx, EXCP_RI);
28266 tcg_temp_free(telm);
28267 tcg_temp_free_i32(tdt);
28268 tcg_temp_free_i32(tsr);
28271 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28274 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28275 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28276 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28278 TCGv_i32 tws = tcg_const_i32(ws);
28279 TCGv_i32 twd = tcg_const_i32(wd);
28280 TCGv_i32 tn = tcg_const_i32(n);
28281 TCGv_i32 tdf = tcg_const_i32(df);
28283 switch (MASK_MSA_ELM(ctx->opcode)) {
28285 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28287 case OPC_SPLATI_df:
28288 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28291 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28293 case OPC_COPY_S_df:
28294 case OPC_COPY_U_df:
28295 case OPC_INSERT_df:
28296 #if !defined(TARGET_MIPS64)
28297 /* Double format valid only for MIPS64 */
28298 if (df == DF_DOUBLE) {
28299 generate_exception_end(ctx, EXCP_RI);
28303 switch (MASK_MSA_ELM(ctx->opcode)) {
28304 case OPC_COPY_S_df:
28305 if (likely(wd != 0)) {
28306 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
28309 case OPC_COPY_U_df:
28310 if (likely(wd != 0)) {
28311 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
28314 case OPC_INSERT_df:
28315 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
28320 MIPS_INVAL("MSA instruction");
28321 generate_exception_end(ctx, EXCP_RI);
28323 tcg_temp_free_i32(twd);
28324 tcg_temp_free_i32(tws);
28325 tcg_temp_free_i32(tn);
28326 tcg_temp_free_i32(tdf);
28329 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28331 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28332 uint32_t df = 0, n = 0;
28334 if ((dfn & 0x30) == 0x00) {
28337 } else if ((dfn & 0x38) == 0x20) {
28340 } else if ((dfn & 0x3c) == 0x30) {
28343 } else if ((dfn & 0x3e) == 0x38) {
28346 } else if (dfn == 0x3E) {
28347 /* CTCMSA, CFCMSA, MOVE.V */
28348 gen_msa_elm_3e(env, ctx);
28351 generate_exception_end(ctx, EXCP_RI);
28355 gen_msa_elm_df(env, ctx, df, n);
28358 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28360 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28361 uint8_t df = (ctx->opcode >> 21) & 0x1;
28362 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28363 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28364 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28366 TCGv_i32 twd = tcg_const_i32(wd);
28367 TCGv_i32 tws = tcg_const_i32(ws);
28368 TCGv_i32 twt = tcg_const_i32(wt);
28369 TCGv_i32 tdf = tcg_temp_new_i32();
28371 /* adjust df value for floating-point instruction */
28372 tcg_gen_movi_i32(tdf, df + 2);
28374 switch (MASK_MSA_3RF(ctx->opcode)) {
28376 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28379 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28382 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28385 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28388 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28391 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28394 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28397 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28400 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28403 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28406 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28409 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28412 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28415 tcg_gen_movi_i32(tdf, df + 1);
28416 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28419 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28422 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28424 case OPC_MADD_Q_df:
28425 tcg_gen_movi_i32(tdf, df + 1);
28426 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28429 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28431 case OPC_MSUB_Q_df:
28432 tcg_gen_movi_i32(tdf, df + 1);
28433 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28436 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28439 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28442 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28445 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28448 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28451 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28454 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28457 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28460 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28463 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28466 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28469 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28472 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28474 case OPC_MULR_Q_df:
28475 tcg_gen_movi_i32(tdf, df + 1);
28476 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28479 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28481 case OPC_FMIN_A_df:
28482 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28484 case OPC_MADDR_Q_df:
28485 tcg_gen_movi_i32(tdf, df + 1);
28486 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28489 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28492 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28494 case OPC_MSUBR_Q_df:
28495 tcg_gen_movi_i32(tdf, df + 1);
28496 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28499 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28501 case OPC_FMAX_A_df:
28502 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28505 MIPS_INVAL("MSA instruction");
28506 generate_exception_end(ctx, EXCP_RI);
28510 tcg_temp_free_i32(twd);
28511 tcg_temp_free_i32(tws);
28512 tcg_temp_free_i32(twt);
28513 tcg_temp_free_i32(tdf);
28516 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28518 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28519 (op & (0x7 << 18)))
28520 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28521 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28522 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28523 uint8_t df = (ctx->opcode >> 16) & 0x3;
28524 TCGv_i32 twd = tcg_const_i32(wd);
28525 TCGv_i32 tws = tcg_const_i32(ws);
28526 TCGv_i32 twt = tcg_const_i32(wt);
28527 TCGv_i32 tdf = tcg_const_i32(df);
28529 switch (MASK_MSA_2R(ctx->opcode)) {
28531 #if !defined(TARGET_MIPS64)
28532 /* Double format valid only for MIPS64 */
28533 if (df == DF_DOUBLE) {
28534 generate_exception_end(ctx, EXCP_RI);
28538 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28541 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28544 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28547 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28550 MIPS_INVAL("MSA instruction");
28551 generate_exception_end(ctx, EXCP_RI);
28555 tcg_temp_free_i32(twd);
28556 tcg_temp_free_i32(tws);
28557 tcg_temp_free_i32(twt);
28558 tcg_temp_free_i32(tdf);
28561 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28563 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28564 (op & (0xf << 17)))
28565 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28566 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28567 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28568 uint8_t df = (ctx->opcode >> 16) & 0x1;
28569 TCGv_i32 twd = tcg_const_i32(wd);
28570 TCGv_i32 tws = tcg_const_i32(ws);
28571 TCGv_i32 twt = tcg_const_i32(wt);
28572 /* adjust df value for floating-point instruction */
28573 TCGv_i32 tdf = tcg_const_i32(df + 2);
28575 switch (MASK_MSA_2RF(ctx->opcode)) {
28576 case OPC_FCLASS_df:
28577 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28579 case OPC_FTRUNC_S_df:
28580 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28582 case OPC_FTRUNC_U_df:
28583 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28586 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28588 case OPC_FRSQRT_df:
28589 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28592 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28595 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28598 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28600 case OPC_FEXUPL_df:
28601 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28603 case OPC_FEXUPR_df:
28604 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28607 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28610 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28612 case OPC_FTINT_S_df:
28613 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28615 case OPC_FTINT_U_df:
28616 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
28618 case OPC_FFINT_S_df:
28619 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
28621 case OPC_FFINT_U_df:
28622 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
28626 tcg_temp_free_i32(twd);
28627 tcg_temp_free_i32(tws);
28628 tcg_temp_free_i32(twt);
28629 tcg_temp_free_i32(tdf);
28632 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
28634 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
28635 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28636 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28637 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28638 TCGv_i32 twd = tcg_const_i32(wd);
28639 TCGv_i32 tws = tcg_const_i32(ws);
28640 TCGv_i32 twt = tcg_const_i32(wt);
28642 switch (MASK_MSA_VEC(ctx->opcode)) {
28644 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
28647 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
28650 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
28653 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
28656 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
28659 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
28662 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
28665 MIPS_INVAL("MSA instruction");
28666 generate_exception_end(ctx, EXCP_RI);
28670 tcg_temp_free_i32(twd);
28671 tcg_temp_free_i32(tws);
28672 tcg_temp_free_i32(twt);
28675 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
28677 switch (MASK_MSA_VEC(ctx->opcode)) {
28685 gen_msa_vec_v(env, ctx);
28688 gen_msa_2r(env, ctx);
28691 gen_msa_2rf(env, ctx);
28694 MIPS_INVAL("MSA instruction");
28695 generate_exception_end(ctx, EXCP_RI);
28700 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
28702 uint32_t opcode = ctx->opcode;
28703 check_insn(ctx, ASE_MSA);
28704 check_msa_access(ctx);
28706 switch (MASK_MSA_MINOR(opcode)) {
28707 case OPC_MSA_I8_00:
28708 case OPC_MSA_I8_01:
28709 case OPC_MSA_I8_02:
28710 gen_msa_i8(env, ctx);
28712 case OPC_MSA_I5_06:
28713 case OPC_MSA_I5_07:
28714 gen_msa_i5(env, ctx);
28716 case OPC_MSA_BIT_09:
28717 case OPC_MSA_BIT_0A:
28718 gen_msa_bit(env, ctx);
28720 case OPC_MSA_3R_0D:
28721 case OPC_MSA_3R_0E:
28722 case OPC_MSA_3R_0F:
28723 case OPC_MSA_3R_10:
28724 case OPC_MSA_3R_11:
28725 case OPC_MSA_3R_12:
28726 case OPC_MSA_3R_13:
28727 case OPC_MSA_3R_14:
28728 case OPC_MSA_3R_15:
28729 gen_msa_3r(env, ctx);
28732 gen_msa_elm(env, ctx);
28734 case OPC_MSA_3RF_1A:
28735 case OPC_MSA_3RF_1B:
28736 case OPC_MSA_3RF_1C:
28737 gen_msa_3rf(env, ctx);
28740 gen_msa_vec(env, ctx);
28751 int32_t s10 = sextract32(ctx->opcode, 16, 10);
28752 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
28753 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28754 uint8_t df = (ctx->opcode >> 0) & 0x3;
28756 TCGv_i32 twd = tcg_const_i32(wd);
28757 TCGv taddr = tcg_temp_new();
28758 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
28760 switch (MASK_MSA_MINOR(opcode)) {
28762 gen_helper_msa_ld_b(cpu_env, twd, taddr);
28765 gen_helper_msa_ld_h(cpu_env, twd, taddr);
28768 gen_helper_msa_ld_w(cpu_env, twd, taddr);
28771 gen_helper_msa_ld_d(cpu_env, twd, taddr);
28774 gen_helper_msa_st_b(cpu_env, twd, taddr);
28777 gen_helper_msa_st_h(cpu_env, twd, taddr);
28780 gen_helper_msa_st_w(cpu_env, twd, taddr);
28783 gen_helper_msa_st_d(cpu_env, twd, taddr);
28787 tcg_temp_free_i32(twd);
28788 tcg_temp_free(taddr);
28792 MIPS_INVAL("MSA instruction");
28793 generate_exception_end(ctx, EXCP_RI);
28799 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
28802 int rs, rt, rd, sa;
28806 /* make sure instructions are on a word boundary */
28807 if (ctx->base.pc_next & 0x3) {
28808 env->CP0_BadVAddr = ctx->base.pc_next;
28809 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
28813 /* Handle blikely not taken case */
28814 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
28815 TCGLabel *l1 = gen_new_label();
28817 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
28818 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
28819 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
28823 op = MASK_OP_MAJOR(ctx->opcode);
28824 rs = (ctx->opcode >> 21) & 0x1f;
28825 rt = (ctx->opcode >> 16) & 0x1f;
28826 rd = (ctx->opcode >> 11) & 0x1f;
28827 sa = (ctx->opcode >> 6) & 0x1f;
28828 imm = (int16_t)ctx->opcode;
28831 decode_opc_special(env, ctx);
28834 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
28835 decode_mmi(env, ctx);
28836 #if !defined(TARGET_MIPS64)
28837 } else if (ctx->insn_flags & ASE_MXU) {
28838 decode_opc_mxu(env, ctx);
28841 decode_opc_special2_legacy(env, ctx);
28845 if (ctx->insn_flags & INSN_R5900) {
28846 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
28848 decode_opc_special3(env, ctx);
28852 op1 = MASK_REGIMM(ctx->opcode);
28854 case OPC_BLTZL: /* REGIMM branches */
28858 check_insn(ctx, ISA_MIPS2);
28859 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28863 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28867 if (ctx->insn_flags & ISA_MIPS32R6) {
28869 /* OPC_NAL, OPC_BAL */
28870 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
28872 generate_exception_end(ctx, EXCP_RI);
28875 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28878 case OPC_TGEI: /* REGIMM traps */
28885 check_insn(ctx, ISA_MIPS2);
28886 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28887 gen_trap(ctx, op1, rs, -1, imm);
28890 check_insn(ctx, ISA_MIPS32R6);
28891 generate_exception_end(ctx, EXCP_RI);
28894 check_insn(ctx, ISA_MIPS32R2);
28895 /* Break the TB to be able to sync copied instructions
28897 ctx->base.is_jmp = DISAS_STOP;
28899 case OPC_BPOSGE32: /* MIPS DSP branch */
28900 #if defined(TARGET_MIPS64)
28904 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
28906 #if defined(TARGET_MIPS64)
28908 check_insn(ctx, ISA_MIPS32R6);
28909 check_mips_64(ctx);
28911 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28915 check_insn(ctx, ISA_MIPS32R6);
28916 check_mips_64(ctx);
28918 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28922 default: /* Invalid */
28923 MIPS_INVAL("regimm");
28924 generate_exception_end(ctx, EXCP_RI);
28929 check_cp0_enabled(ctx);
28930 op1 = MASK_CP0(ctx->opcode);
28938 #if defined(TARGET_MIPS64)
28942 #ifndef CONFIG_USER_ONLY
28943 gen_cp0(env, ctx, op1, rt, rd);
28944 #endif /* !CONFIG_USER_ONLY */
28962 #ifndef CONFIG_USER_ONLY
28963 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
28964 #endif /* !CONFIG_USER_ONLY */
28967 #ifndef CONFIG_USER_ONLY
28970 TCGv t0 = tcg_temp_new();
28972 op2 = MASK_MFMC0(ctx->opcode);
28976 gen_helper_dmt(t0);
28977 gen_store_gpr(t0, rt);
28981 gen_helper_emt(t0);
28982 gen_store_gpr(t0, rt);
28986 gen_helper_dvpe(t0, cpu_env);
28987 gen_store_gpr(t0, rt);
28991 gen_helper_evpe(t0, cpu_env);
28992 gen_store_gpr(t0, rt);
28995 check_insn(ctx, ISA_MIPS32R6);
28997 gen_helper_dvp(t0, cpu_env);
28998 gen_store_gpr(t0, rt);
29002 check_insn(ctx, ISA_MIPS32R6);
29004 gen_helper_evp(t0, cpu_env);
29005 gen_store_gpr(t0, rt);
29009 check_insn(ctx, ISA_MIPS32R2);
29010 save_cpu_state(ctx, 1);
29011 gen_helper_di(t0, cpu_env);
29012 gen_store_gpr(t0, rt);
29013 /* Stop translation as we may have switched
29014 the execution mode. */
29015 ctx->base.is_jmp = DISAS_STOP;
29018 check_insn(ctx, ISA_MIPS32R2);
29019 save_cpu_state(ctx, 1);
29020 gen_helper_ei(t0, cpu_env);
29021 gen_store_gpr(t0, rt);
29022 /* DISAS_STOP isn't sufficient, we need to ensure we break
29023 out of translated code to check for pending interrupts */
29024 gen_save_pc(ctx->base.pc_next + 4);
29025 ctx->base.is_jmp = DISAS_EXIT;
29027 default: /* Invalid */
29028 MIPS_INVAL("mfmc0");
29029 generate_exception_end(ctx, EXCP_RI);
29034 #endif /* !CONFIG_USER_ONLY */
29037 check_insn(ctx, ISA_MIPS32R2);
29038 gen_load_srsgpr(rt, rd);
29041 check_insn(ctx, ISA_MIPS32R2);
29042 gen_store_srsgpr(rt, rd);
29046 generate_exception_end(ctx, EXCP_RI);
29050 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29051 if (ctx->insn_flags & ISA_MIPS32R6) {
29052 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29053 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29056 /* Arithmetic with immediate opcode */
29057 gen_arith_imm(ctx, op, rt, rs, imm);
29061 gen_arith_imm(ctx, op, rt, rs, imm);
29063 case OPC_SLTI: /* Set on less than with immediate opcode */
29065 gen_slt_imm(ctx, op, rt, rs, imm);
29067 case OPC_ANDI: /* Arithmetic with immediate opcode */
29068 case OPC_LUI: /* OPC_AUI */
29071 gen_logic_imm(ctx, op, rt, rs, imm);
29073 case OPC_J: /* Jump */
29075 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29076 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29079 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29080 if (ctx->insn_flags & ISA_MIPS32R6) {
29082 generate_exception_end(ctx, EXCP_RI);
29085 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29086 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29089 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29092 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29093 if (ctx->insn_flags & ISA_MIPS32R6) {
29095 generate_exception_end(ctx, EXCP_RI);
29098 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29099 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29102 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29105 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29108 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29110 check_insn(ctx, ISA_MIPS32R6);
29111 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29112 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29115 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29118 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29120 check_insn(ctx, ISA_MIPS32R6);
29121 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29122 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29127 check_insn(ctx, ISA_MIPS2);
29128 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29132 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29134 case OPC_LL: /* Load and stores */
29135 check_insn(ctx, ISA_MIPS2);
29136 if (ctx->insn_flags & INSN_R5900) {
29137 check_insn_opc_user_only(ctx, INSN_R5900);
29142 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29150 gen_ld(ctx, op, rt, rs, imm);
29154 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29159 gen_st(ctx, op, rt, rs, imm);
29162 check_insn(ctx, ISA_MIPS2);
29163 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29164 if (ctx->insn_flags & INSN_R5900) {
29165 check_insn_opc_user_only(ctx, INSN_R5900);
29167 gen_st_cond(ctx, op, rt, rs, imm);
29170 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29171 check_cp0_enabled(ctx);
29172 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29173 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29174 gen_cache_operation(ctx, rt, rs, imm);
29176 /* Treat as NOP. */
29179 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29180 if (ctx->insn_flags & INSN_R5900) {
29181 /* Treat as NOP. */
29183 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29184 /* Treat as NOP. */
29188 /* Floating point (COP1). */
29193 gen_cop1_ldst(ctx, op, rt, rs, imm);
29197 op1 = MASK_CP1(ctx->opcode);
29202 check_cp1_enabled(ctx);
29203 check_insn(ctx, ISA_MIPS32R2);
29209 check_cp1_enabled(ctx);
29210 gen_cp1(ctx, op1, rt, rd);
29212 #if defined(TARGET_MIPS64)
29215 check_cp1_enabled(ctx);
29216 check_insn(ctx, ISA_MIPS3);
29217 check_mips_64(ctx);
29218 gen_cp1(ctx, op1, rt, rd);
29221 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29222 check_cp1_enabled(ctx);
29223 if (ctx->insn_flags & ISA_MIPS32R6) {
29225 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29230 check_insn(ctx, ASE_MIPS3D);
29231 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29232 (rt >> 2) & 0x7, imm << 2);
29236 check_cp1_enabled(ctx);
29237 check_insn(ctx, ISA_MIPS32R6);
29238 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29242 check_cp1_enabled(ctx);
29243 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29245 check_insn(ctx, ASE_MIPS3D);
29248 check_cp1_enabled(ctx);
29249 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29250 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29251 (rt >> 2) & 0x7, imm << 2);
29258 check_cp1_enabled(ctx);
29259 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29265 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29266 check_cp1_enabled(ctx);
29267 if (ctx->insn_flags & ISA_MIPS32R6) {
29269 case R6_OPC_CMP_AF_S:
29270 case R6_OPC_CMP_UN_S:
29271 case R6_OPC_CMP_EQ_S:
29272 case R6_OPC_CMP_UEQ_S:
29273 case R6_OPC_CMP_LT_S:
29274 case R6_OPC_CMP_ULT_S:
29275 case R6_OPC_CMP_LE_S:
29276 case R6_OPC_CMP_ULE_S:
29277 case R6_OPC_CMP_SAF_S:
29278 case R6_OPC_CMP_SUN_S:
29279 case R6_OPC_CMP_SEQ_S:
29280 case R6_OPC_CMP_SEUQ_S:
29281 case R6_OPC_CMP_SLT_S:
29282 case R6_OPC_CMP_SULT_S:
29283 case R6_OPC_CMP_SLE_S:
29284 case R6_OPC_CMP_SULE_S:
29285 case R6_OPC_CMP_OR_S:
29286 case R6_OPC_CMP_UNE_S:
29287 case R6_OPC_CMP_NE_S:
29288 case R6_OPC_CMP_SOR_S:
29289 case R6_OPC_CMP_SUNE_S:
29290 case R6_OPC_CMP_SNE_S:
29291 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29293 case R6_OPC_CMP_AF_D:
29294 case R6_OPC_CMP_UN_D:
29295 case R6_OPC_CMP_EQ_D:
29296 case R6_OPC_CMP_UEQ_D:
29297 case R6_OPC_CMP_LT_D:
29298 case R6_OPC_CMP_ULT_D:
29299 case R6_OPC_CMP_LE_D:
29300 case R6_OPC_CMP_ULE_D:
29301 case R6_OPC_CMP_SAF_D:
29302 case R6_OPC_CMP_SUN_D:
29303 case R6_OPC_CMP_SEQ_D:
29304 case R6_OPC_CMP_SEUQ_D:
29305 case R6_OPC_CMP_SLT_D:
29306 case R6_OPC_CMP_SULT_D:
29307 case R6_OPC_CMP_SLE_D:
29308 case R6_OPC_CMP_SULE_D:
29309 case R6_OPC_CMP_OR_D:
29310 case R6_OPC_CMP_UNE_D:
29311 case R6_OPC_CMP_NE_D:
29312 case R6_OPC_CMP_SOR_D:
29313 case R6_OPC_CMP_SUNE_D:
29314 case R6_OPC_CMP_SNE_D:
29315 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29318 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29319 rt, rd, sa, (imm >> 8) & 0x7);
29324 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29339 check_insn(ctx, ASE_MSA);
29340 gen_msa_branch(env, ctx, op1);
29344 generate_exception_end(ctx, EXCP_RI);
29349 /* Compact branches [R6] and COP2 [non-R6] */
29350 case OPC_BC: /* OPC_LWC2 */
29351 case OPC_BALC: /* OPC_SWC2 */
29352 if (ctx->insn_flags & ISA_MIPS32R6) {
29353 /* OPC_BC, OPC_BALC */
29354 gen_compute_compact_branch(ctx, op, 0, 0,
29355 sextract32(ctx->opcode << 2, 0, 28));
29357 /* OPC_LWC2, OPC_SWC2 */
29358 /* COP2: Not implemented. */
29359 generate_exception_err(ctx, EXCP_CpU, 2);
29362 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29363 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29364 if (ctx->insn_flags & ISA_MIPS32R6) {
29366 /* OPC_BEQZC, OPC_BNEZC */
29367 gen_compute_compact_branch(ctx, op, rs, 0,
29368 sextract32(ctx->opcode << 2, 0, 23));
29370 /* OPC_JIC, OPC_JIALC */
29371 gen_compute_compact_branch(ctx, op, 0, rt, imm);
29374 /* OPC_LWC2, OPC_SWC2 */
29375 /* COP2: Not implemented. */
29376 generate_exception_err(ctx, EXCP_CpU, 2);
29380 check_insn(ctx, INSN_LOONGSON2F);
29381 /* Note that these instructions use different fields. */
29382 gen_loongson_multimedia(ctx, sa, rd, rt);
29386 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29387 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29388 check_cp1_enabled(ctx);
29389 op1 = MASK_CP3(ctx->opcode);
29393 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29399 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29400 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29403 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29404 /* Treat as NOP. */
29407 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29421 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29422 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29426 generate_exception_end(ctx, EXCP_RI);
29430 generate_exception_err(ctx, EXCP_CpU, 1);
29434 #if defined(TARGET_MIPS64)
29435 /* MIPS64 opcodes */
29437 if (ctx->insn_flags & INSN_R5900) {
29438 check_insn_opc_user_only(ctx, INSN_R5900);
29443 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29447 check_insn(ctx, ISA_MIPS3);
29448 check_mips_64(ctx);
29449 gen_ld(ctx, op, rt, rs, imm);
29453 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29456 check_insn(ctx, ISA_MIPS3);
29457 check_mips_64(ctx);
29458 gen_st(ctx, op, rt, rs, imm);
29461 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29462 check_insn(ctx, ISA_MIPS3);
29463 if (ctx->insn_flags & INSN_R5900) {
29464 check_insn_opc_user_only(ctx, INSN_R5900);
29466 check_mips_64(ctx);
29467 gen_st_cond(ctx, op, rt, rs, imm);
29469 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29470 if (ctx->insn_flags & ISA_MIPS32R6) {
29471 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29472 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29475 check_insn(ctx, ISA_MIPS3);
29476 check_mips_64(ctx);
29477 gen_arith_imm(ctx, op, rt, rs, imm);
29481 check_insn(ctx, ISA_MIPS3);
29482 check_mips_64(ctx);
29483 gen_arith_imm(ctx, op, rt, rs, imm);
29486 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29487 if (ctx->insn_flags & ISA_MIPS32R6) {
29488 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29490 MIPS_INVAL("major opcode");
29491 generate_exception_end(ctx, EXCP_RI);
29495 case OPC_DAUI: /* OPC_JALX */
29496 if (ctx->insn_flags & ISA_MIPS32R6) {
29497 #if defined(TARGET_MIPS64)
29499 check_mips_64(ctx);
29501 generate_exception(ctx, EXCP_RI);
29502 } else if (rt != 0) {
29503 TCGv t0 = tcg_temp_new();
29504 gen_load_gpr(t0, rs);
29505 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29509 generate_exception_end(ctx, EXCP_RI);
29510 MIPS_INVAL("major opcode");
29514 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29515 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29516 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29519 case OPC_MSA: /* OPC_MDMX */
29520 if (ctx->insn_flags & INSN_R5900) {
29521 gen_mmi_lq(env, ctx); /* MMI_OPC_LQ */
29523 /* MDMX: Not implemented. */
29528 check_insn(ctx, ISA_MIPS32R6);
29529 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29531 default: /* Invalid */
29532 MIPS_INVAL("major opcode");
29533 generate_exception_end(ctx, EXCP_RI);
29538 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29540 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29541 CPUMIPSState *env = cs->env_ptr;
29543 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29544 ctx->saved_pc = -1;
29545 ctx->insn_flags = env->insn_flags;
29546 ctx->CP0_Config1 = env->CP0_Config1;
29547 ctx->CP0_Config2 = env->CP0_Config2;
29548 ctx->CP0_Config3 = env->CP0_Config3;
29549 ctx->CP0_Config5 = env->CP0_Config5;
29551 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29552 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29553 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29554 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29555 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29556 ctx->PAMask = env->PAMask;
29557 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29558 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29559 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29560 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29561 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29562 /* Restore delay slot state from the tb context. */
29563 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29564 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29565 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29566 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29567 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29568 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29569 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29570 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29571 restore_cpu_state(env, ctx);
29572 #ifdef CONFIG_USER_ONLY
29573 ctx->mem_idx = MIPS_HFLAG_UM;
29575 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29577 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29578 MO_UNALN : MO_ALIGN;
29580 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29584 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29588 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29590 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29592 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29596 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29597 const CPUBreakpoint *bp)
29599 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29601 save_cpu_state(ctx, 1);
29602 ctx->base.is_jmp = DISAS_NORETURN;
29603 gen_helper_raise_exception_debug(cpu_env);
29604 /* The address covered by the breakpoint must be included in
29605 [tb->pc, tb->pc + tb->size) in order to for it to be
29606 properly cleared -- thus we increment the PC here so that
29607 the logic setting tb->size below does the right thing. */
29608 ctx->base.pc_next += 4;
29612 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
29614 CPUMIPSState *env = cs->env_ptr;
29615 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29619 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
29620 if (ctx->insn_flags & ISA_NANOMIPS32) {
29621 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29622 insn_bytes = decode_nanomips_opc(env, ctx);
29623 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
29624 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
29626 decode_opc(env, ctx);
29627 } else if (ctx->insn_flags & ASE_MICROMIPS) {
29628 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29629 insn_bytes = decode_micromips_opc(env, ctx);
29630 } else if (ctx->insn_flags & ASE_MIPS16) {
29631 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29632 insn_bytes = decode_mips16_opc(env, ctx);
29634 generate_exception_end(ctx, EXCP_RI);
29635 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
29639 if (ctx->hflags & MIPS_HFLAG_BMASK) {
29640 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
29641 MIPS_HFLAG_FBNSLOT))) {
29642 /* force to generate branch as there is neither delay nor
29646 if ((ctx->hflags & MIPS_HFLAG_M16) &&
29647 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
29648 /* Force to generate branch as microMIPS R6 doesn't restrict
29649 branches in the forbidden slot. */
29654 gen_branch(ctx, insn_bytes);
29656 ctx->base.pc_next += insn_bytes;
29658 if (ctx->base.is_jmp != DISAS_NEXT) {
29661 /* Execute a branch and its delay slot as a single instruction.
29662 This is what GDB expects and is consistent with what the
29663 hardware does (e.g. if a delay slot instruction faults, the
29664 reported PC is the PC of the branch). */
29665 if (ctx->base.singlestep_enabled &&
29666 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
29667 ctx->base.is_jmp = DISAS_TOO_MANY;
29669 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
29670 ctx->base.is_jmp = DISAS_TOO_MANY;
29674 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29676 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29678 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
29679 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
29680 gen_helper_raise_exception_debug(cpu_env);
29682 switch (ctx->base.is_jmp) {
29684 gen_save_pc(ctx->base.pc_next);
29685 tcg_gen_lookup_and_goto_ptr();
29688 case DISAS_TOO_MANY:
29689 save_cpu_state(ctx, 0);
29690 gen_goto_tb(ctx, 0, ctx->base.pc_next);
29693 tcg_gen_exit_tb(NULL, 0);
29695 case DISAS_NORETURN:
29698 g_assert_not_reached();
29703 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
29705 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
29706 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
29709 static const TranslatorOps mips_tr_ops = {
29710 .init_disas_context = mips_tr_init_disas_context,
29711 .tb_start = mips_tr_tb_start,
29712 .insn_start = mips_tr_insn_start,
29713 .breakpoint_check = mips_tr_breakpoint_check,
29714 .translate_insn = mips_tr_translate_insn,
29715 .tb_stop = mips_tr_tb_stop,
29716 .disas_log = mips_tr_disas_log,
29719 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
29723 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
29726 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
29730 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
29732 #define printfpr(fp) \
29735 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
29736 " fd:%13g fs:%13g psu: %13g\n", \
29737 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
29738 (double)(fp)->fd, \
29739 (double)(fp)->fs[FP_ENDIAN_IDX], \
29740 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
29743 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
29744 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
29745 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
29746 " fd:%13g fs:%13g psu:%13g\n", \
29747 tmp.w[FP_ENDIAN_IDX], tmp.d, \
29749 (double)tmp.fs[FP_ENDIAN_IDX], \
29750 (double)tmp.fs[!FP_ENDIAN_IDX]); \
29755 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
29756 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
29757 get_float_exception_flags(&env->active_fpu.fp_status));
29758 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
29759 fpu_fprintf(f, "%3s: ", fregnames[i]);
29760 printfpr(&env->active_fpu.fpr[i]);
29766 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
29769 MIPSCPU *cpu = MIPS_CPU(cs);
29770 CPUMIPSState *env = &cpu->env;
29773 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29774 " LO=0x" TARGET_FMT_lx " ds %04x "
29775 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
29776 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29777 env->hflags, env->btarget, env->bcond);
29778 for (i = 0; i < 32; i++) {
29780 cpu_fprintf(f, "GPR%02d:", i);
29781 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
29783 cpu_fprintf(f, "\n");
29786 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
29787 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
29788 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29790 env->CP0_Config0, env->CP0_Config1, env->lladdr);
29791 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
29792 env->CP0_Config2, env->CP0_Config3);
29793 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
29794 env->CP0_Config4, env->CP0_Config5);
29795 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
29796 fpu_dump_state(env, f, cpu_fprintf, flags);
29800 void mips_tcg_init(void)
29805 for (i = 1; i < 32; i++)
29806 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
29807 offsetof(CPUMIPSState, active_tc.gpr[i]),
29810 for (i = 0; i < 32; i++) {
29811 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
29813 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
29814 /* The scalar floating-point unit (FPU) registers are mapped on
29815 * the MSA vector registers. */
29816 fpu_f64[i] = msa_wr_d[i * 2];
29817 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
29818 msa_wr_d[i * 2 + 1] =
29819 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
29822 cpu_PC = tcg_global_mem_new(cpu_env,
29823 offsetof(CPUMIPSState, active_tc.PC), "PC");
29824 for (i = 0; i < MIPS_DSP_ACC; i++) {
29825 cpu_HI[i] = tcg_global_mem_new(cpu_env,
29826 offsetof(CPUMIPSState, active_tc.HI[i]),
29828 cpu_LO[i] = tcg_global_mem_new(cpu_env,
29829 offsetof(CPUMIPSState, active_tc.LO[i]),
29832 cpu_dspctrl = tcg_global_mem_new(cpu_env,
29833 offsetof(CPUMIPSState, active_tc.DSPControl),
29835 bcond = tcg_global_mem_new(cpu_env,
29836 offsetof(CPUMIPSState, bcond), "bcond");
29837 btarget = tcg_global_mem_new(cpu_env,
29838 offsetof(CPUMIPSState, btarget), "btarget");
29839 hflags = tcg_global_mem_new_i32(cpu_env,
29840 offsetof(CPUMIPSState, hflags), "hflags");
29842 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
29843 offsetof(CPUMIPSState, active_fpu.fcr0),
29845 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
29846 offsetof(CPUMIPSState, active_fpu.fcr31),
29848 #if !defined(TARGET_MIPS64)
29849 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29850 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29851 offsetof(CPUMIPSState,
29852 active_tc.mxu_gpr[i]),
29856 mxu_CR = tcg_global_mem_new(cpu_env,
29857 offsetof(CPUMIPSState, active_tc.mxu_cr),
29858 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
29862 #include "translate_init.inc.c"
29864 void cpu_mips_realize_env(CPUMIPSState *env)
29866 env->exception_base = (int32_t)0xBFC00000;
29868 #ifndef CONFIG_USER_ONLY
29869 mmu_init(env, env->cpu_model);
29871 fpu_init(env, env->cpu_model);
29872 mvp_init(env, env->cpu_model);
29875 bool cpu_supports_cps_smp(const char *cpu_type)
29877 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29878 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
29881 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
29883 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29884 return (mcc->cpu_def->insn_flags & isa) != 0;
29887 void cpu_set_exception_base(int vp_index, target_ulong address)
29889 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
29890 vp->env.exception_base = address;
29893 void cpu_state_reset(CPUMIPSState *env)
29895 MIPSCPU *cpu = mips_env_get_cpu(env);
29896 CPUState *cs = CPU(cpu);
29898 /* Reset registers to their default values */
29899 env->CP0_PRid = env->cpu_model->CP0_PRid;
29900 env->CP0_Config0 = env->cpu_model->CP0_Config0;
29901 #ifdef TARGET_WORDS_BIGENDIAN
29902 env->CP0_Config0 |= (1 << CP0C0_BE);
29904 env->CP0_Config1 = env->cpu_model->CP0_Config1;
29905 env->CP0_Config2 = env->cpu_model->CP0_Config2;
29906 env->CP0_Config3 = env->cpu_model->CP0_Config3;
29907 env->CP0_Config4 = env->cpu_model->CP0_Config4;
29908 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
29909 env->CP0_Config5 = env->cpu_model->CP0_Config5;
29910 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
29911 env->CP0_Config6 = env->cpu_model->CP0_Config6;
29912 env->CP0_Config7 = env->cpu_model->CP0_Config7;
29913 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
29914 << env->cpu_model->CP0_LLAddr_shift;
29915 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
29916 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
29917 env->CCRes = env->cpu_model->CCRes;
29918 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
29919 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
29920 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
29921 env->current_tc = 0;
29922 env->SEGBITS = env->cpu_model->SEGBITS;
29923 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
29924 #if defined(TARGET_MIPS64)
29925 if (env->cpu_model->insn_flags & ISA_MIPS3) {
29926 env->SEGMask |= 3ULL << 62;
29929 env->PABITS = env->cpu_model->PABITS;
29930 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
29931 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
29932 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
29933 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
29934 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
29935 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
29936 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
29937 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
29938 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
29939 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
29940 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
29941 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
29942 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
29943 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
29944 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
29945 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
29946 env->msair = env->cpu_model->MSAIR;
29947 env->insn_flags = env->cpu_model->insn_flags;
29949 #if defined(CONFIG_USER_ONLY)
29950 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
29951 # ifdef TARGET_MIPS64
29952 /* Enable 64-bit register mode. */
29953 env->CP0_Status |= (1 << CP0St_PX);
29955 # ifdef TARGET_ABI_MIPSN64
29956 /* Enable 64-bit address mode. */
29957 env->CP0_Status |= (1 << CP0St_UX);
29959 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
29960 hardware registers. */
29961 env->CP0_HWREna |= 0x0000000F;
29962 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
29963 env->CP0_Status |= (1 << CP0St_CU1);
29965 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
29966 env->CP0_Status |= (1 << CP0St_MX);
29968 # if defined(TARGET_MIPS64)
29969 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
29970 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
29971 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
29972 env->CP0_Status |= (1 << CP0St_FR);
29976 if (env->hflags & MIPS_HFLAG_BMASK) {
29977 /* If the exception was raised from a delay slot,
29978 come back to the jump. */
29979 env->CP0_ErrorEPC = (env->active_tc.PC
29980 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
29982 env->CP0_ErrorEPC = env->active_tc.PC;
29984 env->active_tc.PC = env->exception_base;
29985 env->CP0_Random = env->tlb->nb_tlb - 1;
29986 env->tlb->tlb_in_use = env->tlb->nb_tlb;
29987 env->CP0_Wired = 0;
29988 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
29989 env->CP0_EBase = (cs->cpu_index & 0x3FF);
29990 if (mips_um_ksegs_enabled()) {
29991 env->CP0_EBase |= 0x40000000;
29993 env->CP0_EBase |= (int32_t)0x80000000;
29995 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
29996 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
29998 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
30000 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30001 /* vectored interrupts not implemented, timer on int 7,
30002 no performance counters. */
30003 env->CP0_IntCtl = 0xe0000000;
30007 for (i = 0; i < 7; i++) {
30008 env->CP0_WatchLo[i] = 0;
30009 env->CP0_WatchHi[i] = 0x80000000;
30011 env->CP0_WatchLo[7] = 0;
30012 env->CP0_WatchHi[7] = 0;
30014 /* Count register increments in debug mode, EJTAG version 1 */
30015 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30017 cpu_mips_store_count(env, 1);
30019 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30022 /* Only TC0 on VPE 0 starts as active. */
30023 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30024 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30025 env->tcs[i].CP0_TCHalt = 1;
30027 env->active_tc.CP0_TCHalt = 1;
30030 if (cs->cpu_index == 0) {
30031 /* VPE0 starts up enabled. */
30032 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30033 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30035 /* TC0 starts up unhalted. */
30037 env->active_tc.CP0_TCHalt = 0;
30038 env->tcs[0].CP0_TCHalt = 0;
30039 /* With thread 0 active. */
30040 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30041 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30046 * Configure default legacy segmentation control. We use this regardless of
30047 * whether segmentation control is presented to the guest.
30049 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30050 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
30051 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30052 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30053 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30054 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30056 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30057 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30058 (3 << CP0SC_C)) << 16;
30059 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30060 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30061 (1 << CP0SC_EU) | (2 << CP0SC_C);
30062 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30063 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30064 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30065 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30066 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30068 if ((env->insn_flags & ISA_MIPS32R6) &&
30069 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30070 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30071 env->CP0_Status |= (1 << CP0St_FR);
30074 if (env->insn_flags & ISA_MIPS32R6) {
30076 env->CP0_PWSize = 0x40;
30082 env->CP0_PWField = 0x0C30C302;
30089 env->CP0_PWField = 0x02;
30092 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30093 /* microMIPS on reset when Config3.ISA is 3 */
30094 env->hflags |= MIPS_HFLAG_M16;
30098 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30102 compute_hflags(env);
30103 restore_fp_status(env);
30104 restore_pamask(env);
30105 cs->exception_index = EXCP_NONE;
30107 if (semihosting_get_argc()) {
30108 /* UHI interface can be used to obtain argc and argv */
30109 env->active_tc.gpr[4] = -1;
30113 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30114 target_ulong *data)
30116 env->active_tc.PC = data[0];
30117 env->hflags &= ~MIPS_HFLAG_BMASK;
30118 env->hflags |= data[1];
30119 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30120 case MIPS_HFLAG_BR:
30122 case MIPS_HFLAG_BC:
30123 case MIPS_HFLAG_BL:
30125 env->btarget = data[2];