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 "hw/semihosting/semihost.h"
37 #include "target/mips/trace.h"
38 #include "trace-tcg.h"
39 #include "exec/translator.h"
41 #include "qemu/qemu-print.h"
43 #define MIPS_DEBUG_DISAS 0
45 /* MIPS major opcodes */
46 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
49 /* indirect opcode tables */
50 OPC_SPECIAL = (0x00 << 26),
51 OPC_REGIMM = (0x01 << 26),
52 OPC_CP0 = (0x10 << 26),
53 OPC_CP1 = (0x11 << 26),
54 OPC_CP2 = (0x12 << 26),
55 OPC_CP3 = (0x13 << 26),
56 OPC_SPECIAL2 = (0x1C << 26),
57 OPC_SPECIAL3 = (0x1F << 26),
58 /* arithmetic with immediate */
59 OPC_ADDI = (0x08 << 26),
60 OPC_ADDIU = (0x09 << 26),
61 OPC_SLTI = (0x0A << 26),
62 OPC_SLTIU = (0x0B << 26),
63 /* logic with immediate */
64 OPC_ANDI = (0x0C << 26),
65 OPC_ORI = (0x0D << 26),
66 OPC_XORI = (0x0E << 26),
67 OPC_LUI = (0x0F << 26),
68 /* arithmetic with immediate */
69 OPC_DADDI = (0x18 << 26),
70 OPC_DADDIU = (0x19 << 26),
71 /* Jump and branches */
73 OPC_JAL = (0x03 << 26),
74 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
75 OPC_BEQL = (0x14 << 26),
76 OPC_BNE = (0x05 << 26),
77 OPC_BNEL = (0x15 << 26),
78 OPC_BLEZ = (0x06 << 26),
79 OPC_BLEZL = (0x16 << 26),
80 OPC_BGTZ = (0x07 << 26),
81 OPC_BGTZL = (0x17 << 26),
82 OPC_JALX = (0x1D << 26),
83 OPC_DAUI = (0x1D << 26),
85 OPC_LDL = (0x1A << 26),
86 OPC_LDR = (0x1B << 26),
87 OPC_LB = (0x20 << 26),
88 OPC_LH = (0x21 << 26),
89 OPC_LWL = (0x22 << 26),
90 OPC_LW = (0x23 << 26),
91 OPC_LWPC = OPC_LW | 0x5,
92 OPC_LBU = (0x24 << 26),
93 OPC_LHU = (0x25 << 26),
94 OPC_LWR = (0x26 << 26),
95 OPC_LWU = (0x27 << 26),
96 OPC_SB = (0x28 << 26),
97 OPC_SH = (0x29 << 26),
98 OPC_SWL = (0x2A << 26),
99 OPC_SW = (0x2B << 26),
100 OPC_SDL = (0x2C << 26),
101 OPC_SDR = (0x2D << 26),
102 OPC_SWR = (0x2E << 26),
103 OPC_LL = (0x30 << 26),
104 OPC_LLD = (0x34 << 26),
105 OPC_LD = (0x37 << 26),
106 OPC_LDPC = OPC_LD | 0x5,
107 OPC_SC = (0x38 << 26),
108 OPC_SCD = (0x3C << 26),
109 OPC_SD = (0x3F << 26),
110 /* Floating point load/store */
111 OPC_LWC1 = (0x31 << 26),
112 OPC_LWC2 = (0x32 << 26),
113 OPC_LDC1 = (0x35 << 26),
114 OPC_LDC2 = (0x36 << 26),
115 OPC_SWC1 = (0x39 << 26),
116 OPC_SWC2 = (0x3A << 26),
117 OPC_SDC1 = (0x3D << 26),
118 OPC_SDC2 = (0x3E << 26),
119 /* Compact Branches */
120 OPC_BLEZALC = (0x06 << 26),
121 OPC_BGEZALC = (0x06 << 26),
122 OPC_BGEUC = (0x06 << 26),
123 OPC_BGTZALC = (0x07 << 26),
124 OPC_BLTZALC = (0x07 << 26),
125 OPC_BLTUC = (0x07 << 26),
126 OPC_BOVC = (0x08 << 26),
127 OPC_BEQZALC = (0x08 << 26),
128 OPC_BEQC = (0x08 << 26),
129 OPC_BLEZC = (0x16 << 26),
130 OPC_BGEZC = (0x16 << 26),
131 OPC_BGEC = (0x16 << 26),
132 OPC_BGTZC = (0x17 << 26),
133 OPC_BLTZC = (0x17 << 26),
134 OPC_BLTC = (0x17 << 26),
135 OPC_BNVC = (0x18 << 26),
136 OPC_BNEZALC = (0x18 << 26),
137 OPC_BNEC = (0x18 << 26),
138 OPC_BC = (0x32 << 26),
139 OPC_BEQZC = (0x36 << 26),
140 OPC_JIC = (0x36 << 26),
141 OPC_BALC = (0x3A << 26),
142 OPC_BNEZC = (0x3E << 26),
143 OPC_JIALC = (0x3E << 26),
144 /* MDMX ASE specific */
145 OPC_MDMX = (0x1E << 26),
146 /* MSA ASE, same as MDMX */
148 /* Cache and prefetch */
149 OPC_CACHE = (0x2F << 26),
150 OPC_PREF = (0x33 << 26),
151 /* PC-relative address computation / loads */
152 OPC_PCREL = (0x3B << 26),
155 /* PC-relative address computation / loads */
156 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
157 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
159 /* Instructions determined by bits 19 and 20 */
160 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
161 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
162 OPC_LWUPC = OPC_PCREL | (2 << 19),
164 /* Instructions determined by bits 16 ... 20 */
165 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
166 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
169 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
172 /* MIPS special opcodes */
173 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
177 OPC_SLL = 0x00 | OPC_SPECIAL,
178 /* NOP is SLL r0, r0, 0 */
179 /* SSNOP is SLL r0, r0, 1 */
180 /* EHB is SLL r0, r0, 3 */
181 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
182 OPC_ROTR = OPC_SRL | (1 << 21),
183 OPC_SRA = 0x03 | OPC_SPECIAL,
184 OPC_SLLV = 0x04 | OPC_SPECIAL,
185 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
186 OPC_ROTRV = OPC_SRLV | (1 << 6),
187 OPC_SRAV = 0x07 | OPC_SPECIAL,
188 OPC_DSLLV = 0x14 | OPC_SPECIAL,
189 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
190 OPC_DROTRV = OPC_DSRLV | (1 << 6),
191 OPC_DSRAV = 0x17 | OPC_SPECIAL,
192 OPC_DSLL = 0x38 | OPC_SPECIAL,
193 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
194 OPC_DROTR = OPC_DSRL | (1 << 21),
195 OPC_DSRA = 0x3B | OPC_SPECIAL,
196 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
197 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
198 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
199 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
200 /* Multiplication / division */
201 OPC_MULT = 0x18 | OPC_SPECIAL,
202 OPC_MULTU = 0x19 | OPC_SPECIAL,
203 OPC_DIV = 0x1A | OPC_SPECIAL,
204 OPC_DIVU = 0x1B | OPC_SPECIAL,
205 OPC_DMULT = 0x1C | OPC_SPECIAL,
206 OPC_DMULTU = 0x1D | OPC_SPECIAL,
207 OPC_DDIV = 0x1E | OPC_SPECIAL,
208 OPC_DDIVU = 0x1F | OPC_SPECIAL,
210 /* 2 registers arithmetic / logic */
211 OPC_ADD = 0x20 | OPC_SPECIAL,
212 OPC_ADDU = 0x21 | OPC_SPECIAL,
213 OPC_SUB = 0x22 | OPC_SPECIAL,
214 OPC_SUBU = 0x23 | OPC_SPECIAL,
215 OPC_AND = 0x24 | OPC_SPECIAL,
216 OPC_OR = 0x25 | OPC_SPECIAL,
217 OPC_XOR = 0x26 | OPC_SPECIAL,
218 OPC_NOR = 0x27 | OPC_SPECIAL,
219 OPC_SLT = 0x2A | OPC_SPECIAL,
220 OPC_SLTU = 0x2B | OPC_SPECIAL,
221 OPC_DADD = 0x2C | OPC_SPECIAL,
222 OPC_DADDU = 0x2D | OPC_SPECIAL,
223 OPC_DSUB = 0x2E | OPC_SPECIAL,
224 OPC_DSUBU = 0x2F | OPC_SPECIAL,
226 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
227 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
229 OPC_TGE = 0x30 | OPC_SPECIAL,
230 OPC_TGEU = 0x31 | OPC_SPECIAL,
231 OPC_TLT = 0x32 | OPC_SPECIAL,
232 OPC_TLTU = 0x33 | OPC_SPECIAL,
233 OPC_TEQ = 0x34 | OPC_SPECIAL,
234 OPC_TNE = 0x36 | OPC_SPECIAL,
235 /* HI / LO registers load & stores */
236 OPC_MFHI = 0x10 | OPC_SPECIAL,
237 OPC_MTHI = 0x11 | OPC_SPECIAL,
238 OPC_MFLO = 0x12 | OPC_SPECIAL,
239 OPC_MTLO = 0x13 | OPC_SPECIAL,
240 /* Conditional moves */
241 OPC_MOVZ = 0x0A | OPC_SPECIAL,
242 OPC_MOVN = 0x0B | OPC_SPECIAL,
244 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
245 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
247 OPC_MOVCI = 0x01 | OPC_SPECIAL,
250 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
251 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
252 OPC_BREAK = 0x0D | OPC_SPECIAL,
253 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
254 OPC_SYNC = 0x0F | OPC_SPECIAL,
256 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
257 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
258 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
259 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
262 /* R6 Multiply and Divide instructions have the same Opcode
263 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
264 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
267 R6_OPC_MUL = OPC_MULT | (2 << 6),
268 R6_OPC_MUH = OPC_MULT | (3 << 6),
269 R6_OPC_MULU = OPC_MULTU | (2 << 6),
270 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
271 R6_OPC_DIV = OPC_DIV | (2 << 6),
272 R6_OPC_MOD = OPC_DIV | (3 << 6),
273 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
274 R6_OPC_MODU = OPC_DIVU | (3 << 6),
276 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
277 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
278 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
279 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
280 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
281 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
282 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
283 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
285 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
286 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
287 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
288 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
289 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
291 OPC_LSA = 0x05 | OPC_SPECIAL,
292 OPC_DLSA = 0x15 | OPC_SPECIAL,
295 /* Multiplication variants of the vr54xx. */
296 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
299 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
300 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
301 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
302 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
303 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
304 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
305 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
306 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
307 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
308 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
309 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
310 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
311 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
312 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
315 /* REGIMM (rt field) opcodes */
316 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
319 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
320 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
321 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
322 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
323 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
324 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
325 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
326 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
327 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
328 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
329 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
330 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
331 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
332 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
333 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
334 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
336 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
337 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
340 /* Special2 opcodes */
341 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
344 /* Multiply & xxx operations */
345 OPC_MADD = 0x00 | OPC_SPECIAL2,
346 OPC_MADDU = 0x01 | OPC_SPECIAL2,
347 OPC_MUL = 0x02 | OPC_SPECIAL2,
348 OPC_MSUB = 0x04 | OPC_SPECIAL2,
349 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
351 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
352 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
353 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
354 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
355 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
356 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
357 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
358 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
359 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
360 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
361 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
362 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
364 OPC_CLZ = 0x20 | OPC_SPECIAL2,
365 OPC_CLO = 0x21 | OPC_SPECIAL2,
366 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
367 OPC_DCLO = 0x25 | OPC_SPECIAL2,
369 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
372 /* Special3 opcodes */
373 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
376 OPC_EXT = 0x00 | OPC_SPECIAL3,
377 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
378 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
379 OPC_DEXT = 0x03 | OPC_SPECIAL3,
380 OPC_INS = 0x04 | OPC_SPECIAL3,
381 OPC_DINSM = 0x05 | OPC_SPECIAL3,
382 OPC_DINSU = 0x06 | OPC_SPECIAL3,
383 OPC_DINS = 0x07 | OPC_SPECIAL3,
384 OPC_FORK = 0x08 | OPC_SPECIAL3,
385 OPC_YIELD = 0x09 | OPC_SPECIAL3,
386 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
387 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
388 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
391 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
392 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
393 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
394 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
395 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
396 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
397 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
398 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
399 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
400 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
401 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
402 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
405 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
406 /* MIPS DSP Arithmetic */
407 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
408 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
409 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
410 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
411 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
412 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
413 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
414 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
415 /* MIPS DSP GPR-Based Shift Sub-class */
416 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
417 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
418 /* MIPS DSP Multiply Sub-class insns */
419 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
420 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
421 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
422 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
423 /* DSP Bit/Manipulation Sub-class */
424 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
425 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
426 /* MIPS DSP Append Sub-class */
427 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
428 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
429 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
430 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
431 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
434 OPC_LWLE = 0x19 | OPC_SPECIAL3,
435 OPC_LWRE = 0x1A | OPC_SPECIAL3,
436 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
437 OPC_SBE = 0x1C | OPC_SPECIAL3,
438 OPC_SHE = 0x1D | OPC_SPECIAL3,
439 OPC_SCE = 0x1E | OPC_SPECIAL3,
440 OPC_SWE = 0x1F | OPC_SPECIAL3,
441 OPC_SWLE = 0x21 | OPC_SPECIAL3,
442 OPC_SWRE = 0x22 | OPC_SPECIAL3,
443 OPC_PREFE = 0x23 | OPC_SPECIAL3,
444 OPC_LBUE = 0x28 | OPC_SPECIAL3,
445 OPC_LHUE = 0x29 | OPC_SPECIAL3,
446 OPC_LBE = 0x2C | OPC_SPECIAL3,
447 OPC_LHE = 0x2D | OPC_SPECIAL3,
448 OPC_LLE = 0x2E | OPC_SPECIAL3,
449 OPC_LWE = 0x2F | OPC_SPECIAL3,
452 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
453 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
454 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
455 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
456 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
457 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
461 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
464 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
465 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
466 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
467 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
468 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
469 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
470 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
471 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
475 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
478 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
479 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
480 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
481 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
482 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
483 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
484 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
485 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
486 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
487 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
488 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
491 /* MIPS DSP REGIMM opcodes */
493 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
494 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
497 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
500 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
501 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
502 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
503 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
506 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
508 /* MIPS DSP Arithmetic Sub-class */
509 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
510 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
511 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
512 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
513 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
515 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
516 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
517 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
518 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
519 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
520 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
521 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
522 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
523 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
524 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
525 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
526 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
527 /* MIPS DSP Multiply Sub-class insns */
528 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
529 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
530 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
531 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
532 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
533 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
536 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
537 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539 /* MIPS DSP Arithmetic Sub-class */
540 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
541 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
542 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
543 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
544 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
545 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
546 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
548 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
549 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
550 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
551 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
552 /* MIPS DSP Multiply Sub-class insns */
553 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
554 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
555 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
556 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
559 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
561 /* MIPS DSP Arithmetic Sub-class */
562 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
564 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
566 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
567 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
572 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
573 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
574 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
575 /* DSP Bit/Manipulation Sub-class */
576 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
577 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
578 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
579 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
580 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
583 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
585 /* MIPS DSP Arithmetic Sub-class */
586 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
592 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
593 /* DSP Compare-Pick Sub-class */
594 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
600 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
601 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
602 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
603 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
604 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
605 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
606 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
607 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
608 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
611 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
613 /* MIPS DSP GPR-Based Shift Sub-class */
614 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
627 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
628 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
629 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
630 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
631 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
632 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
633 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
634 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
635 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
638 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
640 /* MIPS DSP Multiply Sub-class insns */
641 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
646 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
649 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
650 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
652 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
654 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
655 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
656 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
657 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
658 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
659 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
660 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
661 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
662 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
665 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
667 /* DSP Bit/Manipulation Sub-class */
668 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
671 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673 /* MIPS DSP Append Sub-class */
674 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
675 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
676 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
679 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
681 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
682 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
683 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
684 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
685 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
686 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
687 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
688 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
689 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
690 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
691 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
692 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
693 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
694 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
695 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
696 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
697 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
698 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
701 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
703 /* MIPS DSP Arithmetic Sub-class */
704 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
712 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
713 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
719 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
720 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
721 /* DSP Bit/Manipulation Sub-class */
722 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
723 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
724 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
725 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
726 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
727 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
730 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
732 /* MIPS DSP Multiply Sub-class insns */
733 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
734 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
735 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
736 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
737 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
738 /* MIPS DSP Arithmetic Sub-class */
739 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
740 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
741 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
742 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
743 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
744 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
745 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
746 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
747 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
748 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
749 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
750 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
751 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
752 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
753 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
754 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
755 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
756 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
757 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
758 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
759 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
762 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
764 /* DSP Compare-Pick Sub-class */
765 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
775 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
776 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
783 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
784 /* MIPS DSP Arithmetic Sub-class */
785 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
786 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
787 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
788 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
789 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
790 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
792 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
795 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
797 /* DSP Append Sub-class */
798 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
799 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
800 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
801 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
804 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
806 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
807 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
808 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
819 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
820 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
821 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
822 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
823 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
824 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
825 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
826 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
827 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
830 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
832 /* DSP Bit/Manipulation Sub-class */
833 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
836 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
838 /* MIPS DSP Multiply Sub-class insns */
839 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
856 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
857 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
858 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
859 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
860 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
861 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
862 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
863 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
864 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
867 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
869 /* MIPS DSP GPR-Based Shift Sub-class */
870 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
887 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
888 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
889 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
890 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
891 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
892 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
893 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
894 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
895 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
898 /* Coprocessor 0 (rs field) */
899 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
902 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
903 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
904 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
905 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
906 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
907 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
908 OPC_MFTR = (0x08 << 21) | OPC_CP0,
909 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
910 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
911 OPC_MTTR = (0x0C << 21) | OPC_CP0,
912 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
913 OPC_C0 = (0x10 << 21) | OPC_CP0,
914 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
915 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
916 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
917 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
918 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
919 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
920 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
921 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
922 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
923 OPC_C0_A = (0x1A << 21) | OPC_CP0,
924 OPC_C0_B = (0x1B << 21) | OPC_CP0,
925 OPC_C0_C = (0x1C << 21) | OPC_CP0,
926 OPC_C0_D = (0x1D << 21) | OPC_CP0,
927 OPC_C0_E = (0x1E << 21) | OPC_CP0,
928 OPC_C0_F = (0x1F << 21) | OPC_CP0,
932 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
935 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
936 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
937 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
938 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
939 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
940 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
941 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
942 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
945 /* Coprocessor 0 (with rs == C0) */
946 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
949 OPC_TLBR = 0x01 | OPC_C0,
950 OPC_TLBWI = 0x02 | OPC_C0,
951 OPC_TLBINV = 0x03 | OPC_C0,
952 OPC_TLBINVF = 0x04 | OPC_C0,
953 OPC_TLBWR = 0x06 | OPC_C0,
954 OPC_TLBP = 0x08 | OPC_C0,
955 OPC_RFE = 0x10 | OPC_C0,
956 OPC_ERET = 0x18 | OPC_C0,
957 OPC_DERET = 0x1F | OPC_C0,
958 OPC_WAIT = 0x20 | OPC_C0,
961 /* Coprocessor 1 (rs field) */
962 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
964 /* Values for the fmt field in FP instructions */
966 /* 0 - 15 are reserved */
967 FMT_S = 16, /* single fp */
968 FMT_D = 17, /* double fp */
969 FMT_E = 18, /* extended fp */
970 FMT_Q = 19, /* quad fp */
971 FMT_W = 20, /* 32-bit fixed */
972 FMT_L = 21, /* 64-bit fixed */
973 FMT_PS = 22, /* paired single fp */
974 /* 23 - 31 are reserved */
978 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
979 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
980 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
981 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
982 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
983 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
984 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
985 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
986 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
987 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
988 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
989 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
990 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
991 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
992 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
993 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
994 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
995 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
996 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
997 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
998 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
999 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
1000 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
1001 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
1002 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
1003 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
1004 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
1005 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
1006 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
1007 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
1010 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1011 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1014 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1015 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1016 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1017 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1021 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1022 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1026 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1027 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1030 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1033 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1034 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1035 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1036 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1037 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1038 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1039 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1040 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1041 OPC_BC2 = (0x08 << 21) | OPC_CP2,
1042 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1043 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1046 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1049 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1050 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1051 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1052 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1053 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1054 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1055 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1056 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1058 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1059 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1060 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1061 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1062 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1063 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1064 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1065 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1067 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1068 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1069 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1070 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1071 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1072 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1073 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1074 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1076 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1077 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1078 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1079 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1080 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1081 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1082 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1083 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1085 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1086 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1087 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1088 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1089 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1090 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1092 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1093 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1094 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1095 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1096 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1097 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1099 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1100 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1101 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1102 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1103 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1104 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1106 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1107 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1108 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1109 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1110 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1111 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1113 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1114 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1115 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1116 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1117 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1118 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1120 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1121 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1122 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1123 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1124 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1125 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1127 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1128 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1129 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1130 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1131 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1132 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1134 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1135 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1136 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1137 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1138 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1139 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1143 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1146 OPC_LWXC1 = 0x00 | OPC_CP3,
1147 OPC_LDXC1 = 0x01 | OPC_CP3,
1148 OPC_LUXC1 = 0x05 | OPC_CP3,
1149 OPC_SWXC1 = 0x08 | OPC_CP3,
1150 OPC_SDXC1 = 0x09 | OPC_CP3,
1151 OPC_SUXC1 = 0x0D | OPC_CP3,
1152 OPC_PREFX = 0x0F | OPC_CP3,
1153 OPC_ALNV_PS = 0x1E | OPC_CP3,
1154 OPC_MADD_S = 0x20 | OPC_CP3,
1155 OPC_MADD_D = 0x21 | OPC_CP3,
1156 OPC_MADD_PS = 0x26 | OPC_CP3,
1157 OPC_MSUB_S = 0x28 | OPC_CP3,
1158 OPC_MSUB_D = 0x29 | OPC_CP3,
1159 OPC_MSUB_PS = 0x2E | OPC_CP3,
1160 OPC_NMADD_S = 0x30 | OPC_CP3,
1161 OPC_NMADD_D = 0x31 | OPC_CP3,
1162 OPC_NMADD_PS= 0x36 | OPC_CP3,
1163 OPC_NMSUB_S = 0x38 | OPC_CP3,
1164 OPC_NMSUB_D = 0x39 | OPC_CP3,
1165 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1169 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1171 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1172 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1173 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1174 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1175 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1176 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1177 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1178 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1179 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1180 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1181 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1182 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1183 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1184 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1185 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1186 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1187 OPC_MSA_ELM = 0x19 | OPC_MSA,
1188 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1189 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1190 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1191 OPC_MSA_VEC = 0x1E | OPC_MSA,
1193 /* MI10 instruction */
1194 OPC_LD_B = (0x20) | OPC_MSA,
1195 OPC_LD_H = (0x21) | OPC_MSA,
1196 OPC_LD_W = (0x22) | OPC_MSA,
1197 OPC_LD_D = (0x23) | OPC_MSA,
1198 OPC_ST_B = (0x24) | OPC_MSA,
1199 OPC_ST_H = (0x25) | OPC_MSA,
1200 OPC_ST_W = (0x26) | OPC_MSA,
1201 OPC_ST_D = (0x27) | OPC_MSA,
1205 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1206 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1207 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1208 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1209 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1210 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1211 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1212 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1213 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1214 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1215 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1216 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1217 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1219 /* I8 instruction */
1220 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1221 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1222 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1223 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1224 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1225 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1226 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1227 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1228 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1229 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1231 /* VEC/2R/2RF instruction */
1232 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1233 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1234 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1235 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1236 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1237 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1238 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1240 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1241 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1243 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1244 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1245 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1246 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1247 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1249 /* 2RF instruction df(bit 16) = _w, _d */
1250 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1251 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1252 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1253 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1254 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1255 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1256 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1257 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1258 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1259 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1260 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1261 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1262 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1263 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1264 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1265 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1267 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1268 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1269 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1270 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1271 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1272 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1273 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1274 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1275 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1276 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1277 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1278 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1279 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1280 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1281 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1282 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1283 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1284 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1285 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1286 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1287 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1288 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1289 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1290 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1291 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1292 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1293 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1294 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1295 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1296 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1297 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1298 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1299 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1300 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1301 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1302 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1303 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1304 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1305 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1306 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1307 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1308 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1309 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1310 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1311 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1312 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1313 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1314 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1315 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1316 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1317 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1318 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1319 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1320 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1321 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1322 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1323 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1324 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1325 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1326 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1327 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1328 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1329 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1330 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1332 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1333 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1334 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1335 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1336 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1337 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1338 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1339 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1341 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1343 /* 3RF instruction _df(bit 21) = _w, _d */
1344 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1345 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1346 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1347 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1348 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1349 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1350 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1351 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1352 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1353 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1354 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1355 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1356 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1357 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1358 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1359 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1360 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1361 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1362 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1363 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1364 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1365 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1366 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1367 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1368 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1369 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1370 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1371 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1372 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1373 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1374 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1375 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1376 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1377 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1378 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1379 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1380 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1381 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1382 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1383 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1384 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1386 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1387 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1388 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1389 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1390 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1391 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1392 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1393 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1394 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1395 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1396 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1397 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1398 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1404 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1405 * ============================================
1408 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1409 * instructions set. It is designed to fit the needs of signal, graphical and
1410 * video processing applications. MXU instruction set is used in Xburst family
1411 * of microprocessors by Ingenic.
1413 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1414 * the control register.
1417 * The notation used in MXU assembler mnemonics
1418 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1420 * Register operands:
1422 * XRa, XRb, XRc, XRd - MXU registers
1423 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1425 * Non-register operands:
1427 * aptn1 - 1-bit accumulate add/subtract pattern
1428 * aptn2 - 2-bit accumulate add/subtract pattern
1429 * eptn2 - 2-bit execute add/subtract pattern
1430 * optn2 - 2-bit operand pattern
1431 * optn3 - 3-bit operand pattern
1432 * sft4 - 4-bit shift amount
1433 * strd2 - 2-bit stride amount
1437 * Level of parallelism: Operand size:
1438 * S - single operation at a time 32 - word
1439 * D - two operations in parallel 16 - half word
1440 * Q - four operations in parallel 8 - byte
1444 * ADD - Add or subtract
1445 * ADDC - Add with carry-in
1447 * ASUM - Sum together then accumulate (add or subtract)
1448 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1449 * AVG - Average between 2 operands
1450 * ABD - Absolute difference
1452 * AND - Logical bitwise 'and' operation
1454 * EXTR - Extract bits
1455 * I2M - Move from GPR register to MXU register
1456 * LDD - Load data from memory to XRF
1457 * LDI - Load data from memory to XRF (and increase the address base)
1458 * LUI - Load unsigned immediate
1460 * MULU - Unsigned multiply
1461 * MADD - 64-bit operand add 32x32 product
1462 * MSUB - 64-bit operand subtract 32x32 product
1463 * MAC - Multiply and accumulate (add or subtract)
1464 * MAD - Multiply and add or subtract
1465 * MAX - Maximum between 2 operands
1466 * MIN - Minimum between 2 operands
1467 * M2I - Move from MXU register to GPR register
1468 * MOVZ - Move if zero
1469 * MOVN - Move if non-zero
1470 * NOR - Logical bitwise 'nor' operation
1471 * OR - Logical bitwise 'or' operation
1472 * STD - Store data from XRF to memory
1473 * SDI - Store data from XRF to memory (and increase the address base)
1474 * SLT - Set of less than comparison
1475 * SAD - Sum of absolute differences
1476 * SLL - Logical shift left
1477 * SLR - Logical shift right
1478 * SAR - Arithmetic shift right
1481 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1482 * XOR - Logical bitwise 'exclusive or' operation
1486 * E - Expand results
1487 * F - Fixed point multiplication
1488 * L - Low part result
1489 * R - Doing rounding
1490 * V - Variable instead of immediate
1491 * W - Combine above L and V
1494 * The list of MXU instructions grouped by functionality
1495 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1497 * Load/Store instructions Multiplication instructions
1498 * ----------------------- ---------------------------
1500 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1501 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1502 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1503 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1504 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1505 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1506 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1507 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1508 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1509 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1510 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1511 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1512 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1513 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1514 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1515 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1516 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1517 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1518 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1519 * S16SDI XRa, Rb, s10, eptn2
1520 * S8LDD XRa, Rb, s8, eptn3
1521 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1522 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1523 * S8SDI XRa, Rb, s8, eptn3
1524 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1525 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1526 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1527 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1528 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1529 * S32CPS XRa, XRb, XRc
1530 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1531 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1532 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1533 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1534 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1535 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1536 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1537 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1538 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1539 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1540 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1541 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1542 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1543 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1544 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1545 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1546 * Q8SLT XRa, XRb, XRc
1547 * Q8SLTU XRa, XRb, XRc
1548 * Q8MOVZ XRa, XRb, XRc Shift instructions
1549 * Q8MOVN XRa, XRb, XRc ------------------
1551 * D32SLL XRa, XRb, XRc, XRd, sft4
1552 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1553 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1554 * D32SARL XRa, XRb, XRc, sft4
1555 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1556 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1557 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1558 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1559 * Q16SLL XRa, XRb, XRc, XRd, sft4
1560 * Q16SLR XRa, XRb, XRc, XRd, sft4
1561 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1562 * ------------------------- Q16SLLV XRa, XRb, Rb
1563 * Q16SLRV XRa, XRb, Rb
1564 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1565 * S32ALN XRa, XRb, XRc, Rb
1566 * S32ALNI XRa, XRb, XRc, s3
1567 * S32LUI XRa, s8, optn3 Move instructions
1568 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1569 * S32EXTRV XRa, XRb, Rs, Rt
1570 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1571 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1574 * The opcode organization of MXU instructions
1575 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1577 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1578 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1579 * other bits up to the instruction level is as follows:
1584 * ┌─ 000000 ─ OPC_MXU_S32MADD
1585 * ├─ 000001 ─ OPC_MXU_S32MADDU
1586 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1589 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1590 * │ ├─ 001 ─ OPC_MXU_S32MIN
1591 * │ ├─ 010 ─ OPC_MXU_D16MAX
1592 * │ ├─ 011 ─ OPC_MXU_D16MIN
1593 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1594 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1595 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1596 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1597 * ├─ 000100 ─ OPC_MXU_S32MSUB
1598 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1599 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1600 * │ ├─ 001 ─ OPC_MXU_D16SLT
1601 * │ ├─ 010 ─ OPC_MXU_D16AVG
1602 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1603 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1604 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1605 * │ └─ 111 ─ OPC_MXU_Q8ADD
1608 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1609 * │ ├─ 010 ─ OPC_MXU_D16CPS
1610 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1611 * │ └─ 110 ─ OPC_MXU_Q16SAT
1612 * ├─ 001000 ─ OPC_MXU_D16MUL
1614 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1615 * │ └─ 01 ─ OPC_MXU_D16MULE
1616 * ├─ 001010 ─ OPC_MXU_D16MAC
1617 * ├─ 001011 ─ OPC_MXU_D16MACF
1618 * ├─ 001100 ─ OPC_MXU_D16MADL
1619 * ├─ 001101 ─ OPC_MXU_S16MAD
1620 * ├─ 001110 ─ OPC_MXU_Q16ADD
1621 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1622 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1623 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1626 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1627 * │ └─ 1 ─ OPC_MXU_S32STDR
1630 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1631 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1634 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1635 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1638 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1639 * │ └─ 1 ─ OPC_MXU_S32LDIR
1642 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1643 * │ └─ 1 ─ OPC_MXU_S32SDIR
1646 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1647 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1650 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1651 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1652 * ├─ 011000 ─ OPC_MXU_D32ADD
1654 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1655 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1656 * │ └─ 10 ─ OPC_MXU_D32ASUM
1657 * ├─ 011010 ─ <not assigned>
1659 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1660 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1661 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1664 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1665 * │ ├─ 01 ─ OPC_MXU_D8SUM
1666 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1667 * ├─ 011110 ─ <not assigned>
1668 * ├─ 011111 ─ <not assigned>
1669 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1670 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1671 * ├─ 100010 ─ OPC_MXU_S8LDD
1672 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1673 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1674 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1675 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1676 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1679 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1680 * │ ├─ 001 ─ OPC_MXU_S32ALN
1681 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1682 * │ ├─ 011 ─ OPC_MXU_S32LUI
1683 * │ ├─ 100 ─ OPC_MXU_S32NOR
1684 * │ ├─ 101 ─ OPC_MXU_S32AND
1685 * │ ├─ 110 ─ OPC_MXU_S32OR
1686 * │ └─ 111 ─ OPC_MXU_S32XOR
1689 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1690 * │ ├─ 001 ─ OPC_MXU_LXH
1691 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1692 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1693 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1694 * ├─ 101100 ─ OPC_MXU_S16LDI
1695 * ├─ 101101 ─ OPC_MXU_S16SDI
1696 * ├─ 101110 ─ OPC_MXU_S32M2I
1697 * ├─ 101111 ─ OPC_MXU_S32I2M
1698 * ├─ 110000 ─ OPC_MXU_D32SLL
1699 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1700 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1701 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1702 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1703 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1704 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1705 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1707 * ├─ 110111 ─ OPC_MXU_Q16SAR
1709 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1710 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1713 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1714 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1715 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1716 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1717 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1718 * │ └─ 101 ─ OPC_MXU_S32MOVN
1721 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1722 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1723 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1724 * ├─ 111100 ─ OPC_MXU_Q8MADL
1725 * ├─ 111101 ─ OPC_MXU_S32SFL
1726 * ├─ 111110 ─ OPC_MXU_Q8SAD
1727 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1732 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1733 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1737 OPC_MXU_S32MADD = 0x00,
1738 OPC_MXU_S32MADDU = 0x01,
1739 OPC__MXU_MUL = 0x02,
1740 OPC_MXU__POOL00 = 0x03,
1741 OPC_MXU_S32MSUB = 0x04,
1742 OPC_MXU_S32MSUBU = 0x05,
1743 OPC_MXU__POOL01 = 0x06,
1744 OPC_MXU__POOL02 = 0x07,
1745 OPC_MXU_D16MUL = 0x08,
1746 OPC_MXU__POOL03 = 0x09,
1747 OPC_MXU_D16MAC = 0x0A,
1748 OPC_MXU_D16MACF = 0x0B,
1749 OPC_MXU_D16MADL = 0x0C,
1750 OPC_MXU_S16MAD = 0x0D,
1751 OPC_MXU_Q16ADD = 0x0E,
1752 OPC_MXU_D16MACE = 0x0F,
1753 OPC_MXU__POOL04 = 0x10,
1754 OPC_MXU__POOL05 = 0x11,
1755 OPC_MXU__POOL06 = 0x12,
1756 OPC_MXU__POOL07 = 0x13,
1757 OPC_MXU__POOL08 = 0x14,
1758 OPC_MXU__POOL09 = 0x15,
1759 OPC_MXU__POOL10 = 0x16,
1760 OPC_MXU__POOL11 = 0x17,
1761 OPC_MXU_D32ADD = 0x18,
1762 OPC_MXU__POOL12 = 0x19,
1763 /* not assigned 0x1A */
1764 OPC_MXU__POOL13 = 0x1B,
1765 OPC_MXU__POOL14 = 0x1C,
1766 OPC_MXU_Q8ACCE = 0x1D,
1767 /* not assigned 0x1E */
1768 /* not assigned 0x1F */
1769 /* not assigned 0x20 */
1770 /* not assigned 0x21 */
1771 OPC_MXU_S8LDD = 0x22,
1772 OPC_MXU_S8STD = 0x23,
1773 OPC_MXU_S8LDI = 0x24,
1774 OPC_MXU_S8SDI = 0x25,
1775 OPC_MXU__POOL15 = 0x26,
1776 OPC_MXU__POOL16 = 0x27,
1777 OPC_MXU__POOL17 = 0x28,
1778 /* not assigned 0x29 */
1779 OPC_MXU_S16LDD = 0x2A,
1780 OPC_MXU_S16STD = 0x2B,
1781 OPC_MXU_S16LDI = 0x2C,
1782 OPC_MXU_S16SDI = 0x2D,
1783 OPC_MXU_S32M2I = 0x2E,
1784 OPC_MXU_S32I2M = 0x2F,
1785 OPC_MXU_D32SLL = 0x30,
1786 OPC_MXU_D32SLR = 0x31,
1787 OPC_MXU_D32SARL = 0x32,
1788 OPC_MXU_D32SAR = 0x33,
1789 OPC_MXU_Q16SLL = 0x34,
1790 OPC_MXU_Q16SLR = 0x35,
1791 OPC_MXU__POOL18 = 0x36,
1792 OPC_MXU_Q16SAR = 0x37,
1793 OPC_MXU__POOL19 = 0x38,
1794 OPC_MXU__POOL20 = 0x39,
1795 OPC_MXU__POOL21 = 0x3A,
1796 OPC_MXU_Q16SCOP = 0x3B,
1797 OPC_MXU_Q8MADL = 0x3C,
1798 OPC_MXU_S32SFL = 0x3D,
1799 OPC_MXU_Q8SAD = 0x3E,
1800 /* not assigned 0x3F */
1808 OPC_MXU_S32MAX = 0x00,
1809 OPC_MXU_S32MIN = 0x01,
1810 OPC_MXU_D16MAX = 0x02,
1811 OPC_MXU_D16MIN = 0x03,
1812 OPC_MXU_Q8MAX = 0x04,
1813 OPC_MXU_Q8MIN = 0x05,
1814 OPC_MXU_Q8SLT = 0x06,
1815 OPC_MXU_Q8SLTU = 0x07,
1822 OPC_MXU_S32SLT = 0x00,
1823 OPC_MXU_D16SLT = 0x01,
1824 OPC_MXU_D16AVG = 0x02,
1825 OPC_MXU_D16AVGR = 0x03,
1826 OPC_MXU_Q8AVG = 0x04,
1827 OPC_MXU_Q8AVGR = 0x05,
1828 OPC_MXU_Q8ADD = 0x07,
1835 OPC_MXU_S32CPS = 0x00,
1836 OPC_MXU_D16CPS = 0x02,
1837 OPC_MXU_Q8ABD = 0x04,
1838 OPC_MXU_Q16SAT = 0x06,
1845 OPC_MXU_D16MULF = 0x00,
1846 OPC_MXU_D16MULE = 0x01,
1853 OPC_MXU_S32LDD = 0x00,
1854 OPC_MXU_S32LDDR = 0x01,
1861 OPC_MXU_S32STD = 0x00,
1862 OPC_MXU_S32STDR = 0x01,
1869 OPC_MXU_S32LDDV = 0x00,
1870 OPC_MXU_S32LDDVR = 0x01,
1877 OPC_MXU_S32STDV = 0x00,
1878 OPC_MXU_S32STDVR = 0x01,
1885 OPC_MXU_S32LDI = 0x00,
1886 OPC_MXU_S32LDIR = 0x01,
1893 OPC_MXU_S32SDI = 0x00,
1894 OPC_MXU_S32SDIR = 0x01,
1901 OPC_MXU_S32LDIV = 0x00,
1902 OPC_MXU_S32LDIVR = 0x01,
1909 OPC_MXU_S32SDIV = 0x00,
1910 OPC_MXU_S32SDIVR = 0x01,
1917 OPC_MXU_D32ACC = 0x00,
1918 OPC_MXU_D32ACCM = 0x01,
1919 OPC_MXU_D32ASUM = 0x02,
1926 OPC_MXU_Q16ACC = 0x00,
1927 OPC_MXU_Q16ACCM = 0x01,
1928 OPC_MXU_Q16ASUM = 0x02,
1935 OPC_MXU_Q8ADDE = 0x00,
1936 OPC_MXU_D8SUM = 0x01,
1937 OPC_MXU_D8SUMC = 0x02,
1944 OPC_MXU_S32MUL = 0x00,
1945 OPC_MXU_S32MULU = 0x01,
1946 OPC_MXU_S32EXTR = 0x02,
1947 OPC_MXU_S32EXTRV = 0x03,
1954 OPC_MXU_D32SARW = 0x00,
1955 OPC_MXU_S32ALN = 0x01,
1956 OPC_MXU_S32ALNI = 0x02,
1957 OPC_MXU_S32LUI = 0x03,
1958 OPC_MXU_S32NOR = 0x04,
1959 OPC_MXU_S32AND = 0x05,
1960 OPC_MXU_S32OR = 0x06,
1961 OPC_MXU_S32XOR = 0x07,
1971 OPC_MXU_LXBU = 0x04,
1972 OPC_MXU_LXHU = 0x05,
1979 OPC_MXU_D32SLLV = 0x00,
1980 OPC_MXU_D32SLRV = 0x01,
1981 OPC_MXU_D32SARV = 0x03,
1982 OPC_MXU_Q16SLLV = 0x04,
1983 OPC_MXU_Q16SLRV = 0x05,
1984 OPC_MXU_Q16SARV = 0x07,
1991 OPC_MXU_Q8MUL = 0x00,
1992 OPC_MXU_Q8MULSU = 0x01,
1999 OPC_MXU_Q8MOVZ = 0x00,
2000 OPC_MXU_Q8MOVN = 0x01,
2001 OPC_MXU_D16MOVZ = 0x02,
2002 OPC_MXU_D16MOVN = 0x03,
2003 OPC_MXU_S32MOVZ = 0x04,
2004 OPC_MXU_S32MOVN = 0x05,
2011 OPC_MXU_Q8MAC = 0x00,
2012 OPC_MXU_Q8MACSU = 0x01,
2016 * Overview of the TX79-specific instruction set
2017 * =============================================
2019 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2020 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2021 * instructions and certain multimedia instructions (MMIs). These MMIs
2022 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2023 * or sixteen 8-bit paths.
2027 * The Toshiba TX System RISC TX79 Core Architecture manual,
2028 * https://wiki.qemu.org/File:C790.pdf
2030 * Three-Operand Multiply and Multiply-Add (4 instructions)
2031 * --------------------------------------------------------
2032 * MADD [rd,] rs, rt Multiply/Add
2033 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2034 * MULT [rd,] rs, rt Multiply (3-operand)
2035 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2037 * Multiply Instructions for Pipeline 1 (10 instructions)
2038 * ------------------------------------------------------
2039 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2040 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2041 * DIV1 rs, rt Divide Pipeline 1
2042 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2043 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2044 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2045 * MFHI1 rd Move From HI1 Register
2046 * MFLO1 rd Move From LO1 Register
2047 * MTHI1 rs Move To HI1 Register
2048 * MTLO1 rs Move To LO1 Register
2050 * Arithmetic (19 instructions)
2051 * ----------------------------
2052 * PADDB rd, rs, rt Parallel Add Byte
2053 * PSUBB rd, rs, rt Parallel Subtract Byte
2054 * PADDH rd, rs, rt Parallel Add Halfword
2055 * PSUBH rd, rs, rt Parallel Subtract Halfword
2056 * PADDW rd, rs, rt Parallel Add Word
2057 * PSUBW rd, rs, rt Parallel Subtract Word
2058 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2059 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2060 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2061 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2062 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2063 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2064 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2065 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2066 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2067 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2068 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2069 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2070 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2072 * Min/Max (4 instructions)
2073 * ------------------------
2074 * PMAXH rd, rs, rt Parallel Maximum Halfword
2075 * PMINH rd, rs, rt Parallel Minimum Halfword
2076 * PMAXW rd, rs, rt Parallel Maximum Word
2077 * PMINW rd, rs, rt Parallel Minimum Word
2079 * Absolute (2 instructions)
2080 * -------------------------
2081 * PABSH rd, rt Parallel Absolute Halfword
2082 * PABSW rd, rt Parallel Absolute Word
2084 * Logical (4 instructions)
2085 * ------------------------
2086 * PAND rd, rs, rt Parallel AND
2087 * POR rd, rs, rt Parallel OR
2088 * PXOR rd, rs, rt Parallel XOR
2089 * PNOR rd, rs, rt Parallel NOR
2091 * Shift (9 instructions)
2092 * ----------------------
2093 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2094 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2095 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2096 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2097 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2098 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2099 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2100 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2101 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2103 * Compare (6 instructions)
2104 * ------------------------
2105 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2106 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2107 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2108 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2109 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2110 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2112 * LZC (1 instruction)
2113 * -------------------
2114 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2116 * Quadword Load and Store (2 instructions)
2117 * ----------------------------------------
2118 * LQ rt, offset(base) Load Quadword
2119 * SQ rt, offset(base) Store Quadword
2121 * Multiply and Divide (19 instructions)
2122 * -------------------------------------
2123 * PMULTW rd, rs, rt Parallel Multiply Word
2124 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2125 * PDIVW rs, rt Parallel Divide Word
2126 * PDIVUW rs, rt Parallel Divide Unsigned Word
2127 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2128 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2129 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2130 * PMULTH rd, rs, rt Parallel Multiply Halfword
2131 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2132 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2133 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2134 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2135 * PDIVBW rs, rt Parallel Divide Broadcast Word
2136 * PMFHI rd Parallel Move From HI Register
2137 * PMFLO rd Parallel Move From LO Register
2138 * PMTHI rs Parallel Move To HI Register
2139 * PMTLO rs Parallel Move To LO Register
2140 * PMFHL rd Parallel Move From HI/LO Register
2141 * PMTHL rs Parallel Move To HI/LO Register
2143 * Pack/Extend (11 instructions)
2144 * -----------------------------
2145 * PPAC5 rd, rt Parallel Pack to 5 bits
2146 * PPACB rd, rs, rt Parallel Pack to Byte
2147 * PPACH rd, rs, rt Parallel Pack to Halfword
2148 * PPACW rd, rs, rt Parallel Pack to Word
2149 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2150 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2151 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2152 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2153 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2154 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2155 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2157 * Others (16 instructions)
2158 * ------------------------
2159 * PCPYH rd, rt Parallel Copy Halfword
2160 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2161 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2162 * PREVH rd, rt Parallel Reverse Halfword
2163 * PINTH rd, rs, rt Parallel Interleave Halfword
2164 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2165 * PEXEH rd, rt Parallel Exchange Even Halfword
2166 * PEXCH rd, rt Parallel Exchange Center Halfword
2167 * PEXEW rd, rt Parallel Exchange Even Word
2168 * PEXCW rd, rt Parallel Exchange Center Word
2169 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2170 * MFSA rd Move from Shift Amount Register
2171 * MTSA rs Move to Shift Amount Register
2172 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2173 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2174 * PROT3W rd, rt Parallel Rotate 3 Words
2176 * MMI (MultiMedia Instruction) encodings
2177 * ======================================
2179 * MMI instructions encoding table keys:
2181 * * This code is reserved for future use. An attempt to execute it
2182 * causes a Reserved Instruction exception.
2183 * % This code indicates an instruction class. The instruction word
2184 * must be further decoded by examining additional tables that show
2185 * the values for other instruction fields.
2186 * # This code is reserved for the unsupported instructions DMULT,
2187 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2188 * to execute it causes a Reserved Instruction exception.
2190 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2193 * +--------+----------------------------------------+
2195 * +--------+----------------------------------------+
2197 * opcode bits 28..26
2198 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2199 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2200 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2201 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2202 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2203 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2204 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2205 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2206 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2207 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2208 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2212 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2213 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */
2214 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
2218 * MMI instructions with opcode field = MMI:
2221 * +--------+-------------------------------+--------+
2222 * | MMI | |function|
2223 * +--------+-------------------------------+--------+
2225 * function bits 2..0
2226 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2227 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2228 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2229 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2230 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2231 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2232 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2233 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2234 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2235 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2236 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2239 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2241 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2242 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2243 MMI_OPC_PLZCW = 0x04 | MMI_OPC_CLASS_MMI,
2244 MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2245 MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2246 MMI_OPC_MFHI1 = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2247 MMI_OPC_MTHI1 = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2248 MMI_OPC_MFLO1 = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2249 MMI_OPC_MTLO1 = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2250 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2251 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2252 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
2253 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2254 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
2255 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
2256 MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2257 MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2258 MMI_OPC_PMFHL = 0x30 | MMI_OPC_CLASS_MMI,
2259 MMI_OPC_PMTHL = 0x31 | MMI_OPC_CLASS_MMI,
2260 MMI_OPC_PSLLH = 0x34 | MMI_OPC_CLASS_MMI,
2261 MMI_OPC_PSRLH = 0x36 | MMI_OPC_CLASS_MMI,
2262 MMI_OPC_PSRAH = 0x37 | MMI_OPC_CLASS_MMI,
2263 MMI_OPC_PSLLW = 0x3C | MMI_OPC_CLASS_MMI,
2264 MMI_OPC_PSRLW = 0x3E | MMI_OPC_CLASS_MMI,
2265 MMI_OPC_PSRAW = 0x3F | MMI_OPC_CLASS_MMI,
2269 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2272 * +--------+----------------------+--------+--------+
2273 * | MMI | |function| MMI0 |
2274 * +--------+----------------------+--------+--------+
2276 * function bits 7..6
2277 * bits | 0 | 1 | 2 | 3
2278 * 10..8 | 00 | 01 | 10 | 11
2279 * -------+-------+-------+-------+-------
2280 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2281 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2282 * 2 010 | PADDB | PSUBB | PCGTB | *
2283 * 3 011 | * | * | * | *
2284 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2285 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2286 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2287 * 7 111 | * | * | PEXT5 | PPAC5
2290 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2292 MMI_OPC_0_PADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2293 MMI_OPC_0_PSUBW = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2294 MMI_OPC_0_PCGTW = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2295 MMI_OPC_0_PMAXW = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2296 MMI_OPC_0_PADDH = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2297 MMI_OPC_0_PSUBH = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2298 MMI_OPC_0_PCGTH = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2299 MMI_OPC_0_PMAXH = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2300 MMI_OPC_0_PADDB = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2301 MMI_OPC_0_PSUBB = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2302 MMI_OPC_0_PCGTB = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2303 MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2304 MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2305 MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2306 MMI_OPC_0_PPACW = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2307 MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2308 MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2309 MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2310 MMI_OPC_0_PPACH = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2311 MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2312 MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2313 MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2314 MMI_OPC_0_PPACB = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2315 MMI_OPC_0_PEXT5 = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2316 MMI_OPC_0_PPAC5 = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2320 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2323 * +--------+----------------------+--------+--------+
2324 * | MMI | |function| MMI1 |
2325 * +--------+----------------------+--------+--------+
2327 * function bits 7..6
2328 * bits | 0 | 1 | 2 | 3
2329 * 10..8 | 00 | 01 | 10 | 11
2330 * -------+-------+-------+-------+-------
2331 * 0 000 | * | PABSW | PCEQW | PMINW
2332 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2333 * 2 010 | * | * | PCEQB | *
2334 * 3 011 | * | * | * | *
2335 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2336 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2337 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2338 * 7 111 | * | * | * | *
2341 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2343 MMI_OPC_1_PABSW = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2344 MMI_OPC_1_PCEQW = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2345 MMI_OPC_1_PMINW = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2346 MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2347 MMI_OPC_1_PABSH = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2348 MMI_OPC_1_PCEQH = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2349 MMI_OPC_1_PMINH = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2350 MMI_OPC_1_PCEQB = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2351 MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2352 MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2353 MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2354 MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2355 MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2356 MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2357 MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2358 MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2359 MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2360 MMI_OPC_1_QFSRV = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2364 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2367 * +--------+----------------------+--------+--------+
2368 * | MMI | |function| MMI2 |
2369 * +--------+----------------------+--------+--------+
2371 * function bits 7..6
2372 * bits | 0 | 1 | 2 | 3
2373 * 10..8 | 00 | 01 | 10 | 11
2374 * -------+-------+-------+-------+-------
2375 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2376 * 1 001 | PMSUBW| * | * | *
2377 * 2 010 | PMFHI | PMFLO | PINTH | *
2378 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2379 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2380 * 5 101 | PMSUBH| PHMSBH| * | *
2381 * 6 110 | * | * | PEXEH | PREVH
2382 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2385 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2387 MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2388 MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2389 MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2390 MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2391 MMI_OPC_2_PMFHI = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2392 MMI_OPC_2_PMFLO = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2393 MMI_OPC_2_PINTH = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2394 MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2395 MMI_OPC_2_PDIVW = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2396 MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2397 MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2398 MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2399 MMI_OPC_2_PAND = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2400 MMI_OPC_2_PXOR = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2401 MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2402 MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2403 MMI_OPC_2_PEXEH = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2404 MMI_OPC_2_PREVH = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2405 MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2406 MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2407 MMI_OPC_2_PEXEW = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2408 MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2412 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2415 * +--------+----------------------+--------+--------+
2416 * | MMI | |function| MMI3 |
2417 * +--------+----------------------+--------+--------+
2419 * function bits 7..6
2420 * bits | 0 | 1 | 2 | 3
2421 * 10..8 | 00 | 01 | 10 | 11
2422 * -------+-------+-------+-------+-------
2423 * 0 000 |PMADDUW| * | * | PSRAVW
2424 * 1 001 | * | * | * | *
2425 * 2 010 | PMTHI | PMTLO | PINTEH| *
2426 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2427 * 4 100 | * | * | POR | PNOR
2428 * 5 101 | * | * | * | *
2429 * 6 110 | * | * | PEXCH | PCPYH
2430 * 7 111 | * | * | PEXCW | *
2433 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2435 MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2436 MMI_OPC_3_PSRAVW = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2437 MMI_OPC_3_PMTHI = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2438 MMI_OPC_3_PMTLO = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2439 MMI_OPC_3_PINTEH = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2440 MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2441 MMI_OPC_3_PDIVUW = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2442 MMI_OPC_3_PCPYUD = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2443 MMI_OPC_3_POR = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2444 MMI_OPC_3_PNOR = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2445 MMI_OPC_3_PEXCH = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2446 MMI_OPC_3_PCPYH = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2447 MMI_OPC_3_PEXCW = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2450 /* global register indices */
2451 static TCGv cpu_gpr[32], cpu_PC;
2452 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2453 static TCGv cpu_dspctrl, btarget, bcond;
2454 static TCGv cpu_lladdr, cpu_llval;
2455 static TCGv_i32 hflags;
2456 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2457 static TCGv_i64 fpu_f64[32];
2458 static TCGv_i64 msa_wr_d[64];
2460 #if defined(TARGET_MIPS64)
2461 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2462 static TCGv_i64 cpu_mmr[32];
2465 #if !defined(TARGET_MIPS64)
2467 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2471 #include "exec/gen-icount.h"
2473 #define gen_helper_0e0i(name, arg) do { \
2474 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2475 gen_helper_##name(cpu_env, helper_tmp); \
2476 tcg_temp_free_i32(helper_tmp); \
2479 #define gen_helper_0e1i(name, arg1, arg2) do { \
2480 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2481 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2482 tcg_temp_free_i32(helper_tmp); \
2485 #define gen_helper_1e0i(name, ret, arg1) do { \
2486 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2487 gen_helper_##name(ret, cpu_env, helper_tmp); \
2488 tcg_temp_free_i32(helper_tmp); \
2491 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2492 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2493 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2494 tcg_temp_free_i32(helper_tmp); \
2497 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2498 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2499 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2500 tcg_temp_free_i32(helper_tmp); \
2503 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2504 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2505 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2506 tcg_temp_free_i32(helper_tmp); \
2509 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2510 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2511 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2512 tcg_temp_free_i32(helper_tmp); \
2515 typedef struct DisasContext {
2516 DisasContextBase base;
2517 target_ulong saved_pc;
2518 target_ulong page_start;
2520 uint64_t insn_flags;
2521 int32_t CP0_Config1;
2522 int32_t CP0_Config2;
2523 int32_t CP0_Config3;
2524 int32_t CP0_Config5;
2525 /* Routine used to access memory */
2527 TCGMemOp default_tcg_memop_mask;
2528 uint32_t hflags, saved_hflags;
2529 target_ulong btarget;
2540 int CP0_LLAddr_shift;
2550 #define DISAS_STOP DISAS_TARGET_0
2551 #define DISAS_EXIT DISAS_TARGET_1
2553 static const char * const regnames[] = {
2554 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2555 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2556 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2557 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2560 static const char * const regnames_HI[] = {
2561 "HI0", "HI1", "HI2", "HI3",
2564 static const char * const regnames_LO[] = {
2565 "LO0", "LO1", "LO2", "LO3",
2568 static const char * const fregnames[] = {
2569 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2570 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2571 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2572 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2575 static const char * const msaregnames[] = {
2576 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2577 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2578 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2579 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2580 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2581 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2582 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2583 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2584 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2585 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2586 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2587 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2588 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2589 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2590 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2591 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2594 #if !defined(TARGET_MIPS64)
2595 static const char * const mxuregnames[] = {
2596 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2597 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2601 #define LOG_DISAS(...) \
2603 if (MIPS_DEBUG_DISAS) { \
2604 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2608 #define MIPS_INVAL(op) \
2610 if (MIPS_DEBUG_DISAS) { \
2611 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2612 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2613 ctx->base.pc_next, ctx->opcode, op, \
2614 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2615 ((ctx->opcode >> 16) & 0x1F)); \
2619 /* General purpose registers moves. */
2620 static inline void gen_load_gpr (TCGv t, int reg)
2623 tcg_gen_movi_tl(t, 0);
2625 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2628 static inline void gen_store_gpr (TCGv t, int reg)
2631 tcg_gen_mov_tl(cpu_gpr[reg], t);
2634 /* Moves to/from shadow registers. */
2635 static inline void gen_load_srsgpr (int from, int to)
2637 TCGv t0 = tcg_temp_new();
2640 tcg_gen_movi_tl(t0, 0);
2642 TCGv_i32 t2 = tcg_temp_new_i32();
2643 TCGv_ptr addr = tcg_temp_new_ptr();
2645 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2646 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2647 tcg_gen_andi_i32(t2, t2, 0xf);
2648 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2649 tcg_gen_ext_i32_ptr(addr, t2);
2650 tcg_gen_add_ptr(addr, cpu_env, addr);
2652 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2653 tcg_temp_free_ptr(addr);
2654 tcg_temp_free_i32(t2);
2656 gen_store_gpr(t0, to);
2660 static inline void gen_store_srsgpr (int from, int to)
2663 TCGv t0 = tcg_temp_new();
2664 TCGv_i32 t2 = tcg_temp_new_i32();
2665 TCGv_ptr addr = tcg_temp_new_ptr();
2667 gen_load_gpr(t0, from);
2668 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2669 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2670 tcg_gen_andi_i32(t2, t2, 0xf);
2671 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2672 tcg_gen_ext_i32_ptr(addr, t2);
2673 tcg_gen_add_ptr(addr, cpu_env, addr);
2675 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2676 tcg_temp_free_ptr(addr);
2677 tcg_temp_free_i32(t2);
2682 #if !defined(TARGET_MIPS64)
2683 /* MXU General purpose registers moves. */
2684 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2687 tcg_gen_movi_tl(t, 0);
2688 } else if (reg <= 15) {
2689 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2693 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2695 if (reg > 0 && reg <= 15) {
2696 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2700 /* MXU control register moves. */
2701 static inline void gen_load_mxu_cr(TCGv t)
2703 tcg_gen_mov_tl(t, mxu_CR);
2706 static inline void gen_store_mxu_cr(TCGv t)
2708 /* TODO: Add handling of RW rules for MXU_CR. */
2709 tcg_gen_mov_tl(mxu_CR, t);
2715 static inline void gen_save_pc(target_ulong pc)
2717 tcg_gen_movi_tl(cpu_PC, pc);
2720 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2722 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2723 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2724 gen_save_pc(ctx->base.pc_next);
2725 ctx->saved_pc = ctx->base.pc_next;
2727 if (ctx->hflags != ctx->saved_hflags) {
2728 tcg_gen_movi_i32(hflags, ctx->hflags);
2729 ctx->saved_hflags = ctx->hflags;
2730 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2736 tcg_gen_movi_tl(btarget, ctx->btarget);
2742 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2744 ctx->saved_hflags = ctx->hflags;
2745 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2751 ctx->btarget = env->btarget;
2756 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2758 TCGv_i32 texcp = tcg_const_i32(excp);
2759 TCGv_i32 terr = tcg_const_i32(err);
2760 save_cpu_state(ctx, 1);
2761 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2762 tcg_temp_free_i32(terr);
2763 tcg_temp_free_i32(texcp);
2764 ctx->base.is_jmp = DISAS_NORETURN;
2767 static inline void generate_exception(DisasContext *ctx, int excp)
2769 gen_helper_0e0i(raise_exception, excp);
2772 static inline void generate_exception_end(DisasContext *ctx, int excp)
2774 generate_exception_err(ctx, excp, 0);
2777 /* Floating point register moves. */
2778 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2780 if (ctx->hflags & MIPS_HFLAG_FRE) {
2781 generate_exception(ctx, EXCP_RI);
2783 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2786 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2789 if (ctx->hflags & MIPS_HFLAG_FRE) {
2790 generate_exception(ctx, EXCP_RI);
2792 t64 = tcg_temp_new_i64();
2793 tcg_gen_extu_i32_i64(t64, t);
2794 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2795 tcg_temp_free_i64(t64);
2798 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2800 if (ctx->hflags & MIPS_HFLAG_F64) {
2801 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2803 gen_load_fpr32(ctx, t, reg | 1);
2807 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2809 if (ctx->hflags & MIPS_HFLAG_F64) {
2810 TCGv_i64 t64 = tcg_temp_new_i64();
2811 tcg_gen_extu_i32_i64(t64, t);
2812 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2813 tcg_temp_free_i64(t64);
2815 gen_store_fpr32(ctx, t, reg | 1);
2819 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2821 if (ctx->hflags & MIPS_HFLAG_F64) {
2822 tcg_gen_mov_i64(t, fpu_f64[reg]);
2824 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2828 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2830 if (ctx->hflags & MIPS_HFLAG_F64) {
2831 tcg_gen_mov_i64(fpu_f64[reg], t);
2834 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2835 t0 = tcg_temp_new_i64();
2836 tcg_gen_shri_i64(t0, t, 32);
2837 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2838 tcg_temp_free_i64(t0);
2842 static inline int get_fp_bit (int cc)
2850 /* Addresses computation */
2851 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2853 tcg_gen_add_tl(ret, arg0, arg1);
2855 #if defined(TARGET_MIPS64)
2856 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2857 tcg_gen_ext32s_i64(ret, ret);
2862 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2865 tcg_gen_addi_tl(ret, base, ofs);
2867 #if defined(TARGET_MIPS64)
2868 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2869 tcg_gen_ext32s_i64(ret, ret);
2874 /* Addresses computation (translation time) */
2875 static target_long addr_add(DisasContext *ctx, target_long base,
2878 target_long sum = base + offset;
2880 #if defined(TARGET_MIPS64)
2881 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2888 /* Sign-extract the low 32-bits to a target_long. */
2889 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2891 #if defined(TARGET_MIPS64)
2892 tcg_gen_ext32s_i64(ret, arg);
2894 tcg_gen_extrl_i64_i32(ret, arg);
2898 /* Sign-extract the high 32-bits to a target_long. */
2899 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2901 #if defined(TARGET_MIPS64)
2902 tcg_gen_sari_i64(ret, arg, 32);
2904 tcg_gen_extrh_i64_i32(ret, arg);
2908 static inline void check_cp0_enabled(DisasContext *ctx)
2910 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2911 generate_exception_err(ctx, EXCP_CpU, 0);
2914 static inline void check_cp1_enabled(DisasContext *ctx)
2916 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2917 generate_exception_err(ctx, EXCP_CpU, 1);
2920 /* Verify that the processor is running with COP1X instructions enabled.
2921 This is associated with the nabla symbol in the MIPS32 and MIPS64
2924 static inline void check_cop1x(DisasContext *ctx)
2926 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2927 generate_exception_end(ctx, EXCP_RI);
2930 /* Verify that the processor is running with 64-bit floating-point
2931 operations enabled. */
2933 static inline void check_cp1_64bitmode(DisasContext *ctx)
2935 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2936 generate_exception_end(ctx, EXCP_RI);
2940 * Verify if floating point register is valid; an operation is not defined
2941 * if bit 0 of any register specification is set and the FR bit in the
2942 * Status register equals zero, since the register numbers specify an
2943 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2944 * in the Status register equals one, both even and odd register numbers
2945 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2947 * Multiple 64 bit wide registers can be checked by calling
2948 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2950 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2952 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2953 generate_exception_end(ctx, EXCP_RI);
2956 /* Verify that the processor is running with DSP instructions enabled.
2957 This is enabled by CP0 Status register MX(24) bit.
2960 static inline void check_dsp(DisasContext *ctx)
2962 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2963 if (ctx->insn_flags & ASE_DSP) {
2964 generate_exception_end(ctx, EXCP_DSPDIS);
2966 generate_exception_end(ctx, EXCP_RI);
2971 static inline void check_dsp_r2(DisasContext *ctx)
2973 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2974 if (ctx->insn_flags & ASE_DSP) {
2975 generate_exception_end(ctx, EXCP_DSPDIS);
2977 generate_exception_end(ctx, EXCP_RI);
2982 static inline void check_dsp_r3(DisasContext *ctx)
2984 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2985 if (ctx->insn_flags & ASE_DSP) {
2986 generate_exception_end(ctx, EXCP_DSPDIS);
2988 generate_exception_end(ctx, EXCP_RI);
2993 /* This code generates a "reserved instruction" exception if the
2994 CPU does not support the instruction set corresponding to flags. */
2995 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2997 if (unlikely(!(ctx->insn_flags & flags))) {
2998 generate_exception_end(ctx, EXCP_RI);
3002 /* This code generates a "reserved instruction" exception if the
3003 CPU has corresponding flag set which indicates that the instruction
3004 has been removed. */
3005 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3007 if (unlikely(ctx->insn_flags & flags)) {
3008 generate_exception_end(ctx, EXCP_RI);
3013 * The Linux kernel traps certain reserved instruction exceptions to
3014 * emulate the corresponding instructions. QEMU is the kernel in user
3015 * mode, so those traps are emulated by accepting the instructions.
3017 * A reserved instruction exception is generated for flagged CPUs if
3018 * QEMU runs in system mode.
3020 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3022 #ifndef CONFIG_USER_ONLY
3023 check_insn_opc_removed(ctx, flags);
3027 /* This code generates a "reserved instruction" exception if the
3028 CPU does not support 64-bit paired-single (PS) floating point data type */
3029 static inline void check_ps(DisasContext *ctx)
3031 if (unlikely(!ctx->ps)) {
3032 generate_exception(ctx, EXCP_RI);
3034 check_cp1_64bitmode(ctx);
3037 #ifdef TARGET_MIPS64
3038 /* This code generates a "reserved instruction" exception if 64-bit
3039 instructions are not enabled. */
3040 static inline void check_mips_64(DisasContext *ctx)
3042 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
3043 generate_exception_end(ctx, EXCP_RI);
3047 #ifndef CONFIG_USER_ONLY
3048 static inline void check_mvh(DisasContext *ctx)
3050 if (unlikely(!ctx->mvh)) {
3051 generate_exception(ctx, EXCP_RI);
3057 * This code generates a "reserved instruction" exception if the
3058 * Config5 XNP bit is set.
3060 static inline void check_xnp(DisasContext *ctx)
3062 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3063 generate_exception_end(ctx, EXCP_RI);
3067 #ifndef CONFIG_USER_ONLY
3069 * This code generates a "reserved instruction" exception if the
3070 * Config3 PW bit is NOT set.
3072 static inline void check_pw(DisasContext *ctx)
3074 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3075 generate_exception_end(ctx, EXCP_RI);
3081 * This code generates a "reserved instruction" exception if the
3082 * Config3 MT bit is NOT set.
3084 static inline void check_mt(DisasContext *ctx)
3086 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3087 generate_exception_end(ctx, EXCP_RI);
3091 #ifndef CONFIG_USER_ONLY
3093 * This code generates a "coprocessor unusable" exception if CP0 is not
3094 * available, and, if that is not the case, generates a "reserved instruction"
3095 * exception if the Config5 MT bit is NOT set. This is needed for availability
3096 * control of some of MT ASE instructions.
3098 static inline void check_cp0_mt(DisasContext *ctx)
3100 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3101 generate_exception_err(ctx, EXCP_CpU, 0);
3103 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3104 generate_exception_err(ctx, EXCP_RI, 0);
3111 * This code generates a "reserved instruction" exception if the
3112 * Config5 NMS bit is set.
3114 static inline void check_nms(DisasContext *ctx)
3116 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3117 generate_exception_end(ctx, EXCP_RI);
3122 * This code generates a "reserved instruction" exception if the
3123 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3124 * Config2 TL, and Config5 L2C are unset.
3126 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3128 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3129 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3130 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3131 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3132 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3133 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3135 generate_exception_end(ctx, EXCP_RI);
3140 * This code generates a "reserved instruction" exception if the
3141 * Config5 EVA bit is NOT set.
3143 static inline void check_eva(DisasContext *ctx)
3145 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3146 generate_exception_end(ctx, EXCP_RI);
3151 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3152 calling interface for 32 and 64-bit FPRs. No sense in changing
3153 all callers for gen_load_fpr32 when we need the CTX parameter for
3155 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3156 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3157 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3158 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3159 int ft, int fs, int cc) \
3161 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3162 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3171 check_cp1_registers(ctx, fs | ft); \
3179 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3180 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3182 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3183 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3184 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3185 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3186 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3187 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3188 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3189 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3190 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3191 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3192 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3193 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3194 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3195 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3196 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3197 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
3200 tcg_temp_free_i##bits (fp0); \
3201 tcg_temp_free_i##bits (fp1); \
3204 FOP_CONDS(, 0, d, FMT_D, 64)
3205 FOP_CONDS(abs, 1, d, FMT_D, 64)
3206 FOP_CONDS(, 0, s, FMT_S, 32)
3207 FOP_CONDS(abs, 1, s, FMT_S, 32)
3208 FOP_CONDS(, 0, ps, FMT_PS, 64)
3209 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3212 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3213 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3214 int ft, int fs, int fd) \
3216 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3217 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3218 if (ifmt == FMT_D) { \
3219 check_cp1_registers(ctx, fs | ft | fd); \
3221 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3222 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3225 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3228 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3231 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3234 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3237 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3240 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3243 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3246 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3249 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3252 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3255 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3258 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3261 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3264 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3267 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3270 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3273 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3276 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3279 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3282 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3285 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3288 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3294 tcg_temp_free_i ## bits (fp0); \
3295 tcg_temp_free_i ## bits (fp1); \
3298 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3299 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3301 #undef gen_ldcmp_fpr32
3302 #undef gen_ldcmp_fpr64
3304 /* load/store instructions. */
3305 #ifdef CONFIG_USER_ONLY
3306 #define OP_LD_ATOMIC(insn,fname) \
3307 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3308 DisasContext *ctx) \
3310 TCGv t0 = tcg_temp_new(); \
3311 tcg_gen_mov_tl(t0, arg1); \
3312 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3313 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3314 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3315 tcg_temp_free(t0); \
3318 #define OP_LD_ATOMIC(insn,fname) \
3319 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3320 DisasContext *ctx) \
3322 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3325 OP_LD_ATOMIC(ll,ld32s);
3326 #if defined(TARGET_MIPS64)
3327 OP_LD_ATOMIC(lld,ld64);
3331 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3332 int base, int offset)
3335 tcg_gen_movi_tl(addr, offset);
3336 } else if (offset == 0) {
3337 gen_load_gpr(addr, base);
3339 tcg_gen_movi_tl(addr, offset);
3340 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3344 static target_ulong pc_relative_pc (DisasContext *ctx)
3346 target_ulong pc = ctx->base.pc_next;
3348 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3349 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3354 pc &= ~(target_ulong)3;
3359 static void gen_ld(DisasContext *ctx, uint32_t opc,
3360 int rt, int base, int offset)
3363 int mem_idx = ctx->mem_idx;
3365 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3366 /* Loongson CPU uses a load to zero register for prefetch.
3367 We emulate it as a NOP. On other CPU we must perform the
3368 actual memory access. */
3372 t0 = tcg_temp_new();
3373 gen_base_offset_addr(ctx, t0, base, offset);
3376 #if defined(TARGET_MIPS64)
3378 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3379 ctx->default_tcg_memop_mask);
3380 gen_store_gpr(t0, rt);
3383 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3384 ctx->default_tcg_memop_mask);
3385 gen_store_gpr(t0, rt);
3389 op_ld_lld(t0, t0, mem_idx, ctx);
3390 gen_store_gpr(t0, rt);
3393 t1 = tcg_temp_new();
3394 /* Do a byte access to possibly trigger a page
3395 fault with the unaligned address. */
3396 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3397 tcg_gen_andi_tl(t1, t0, 7);
3398 #ifndef TARGET_WORDS_BIGENDIAN
3399 tcg_gen_xori_tl(t1, t1, 7);
3401 tcg_gen_shli_tl(t1, t1, 3);
3402 tcg_gen_andi_tl(t0, t0, ~7);
3403 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3404 tcg_gen_shl_tl(t0, t0, t1);
3405 t2 = tcg_const_tl(-1);
3406 tcg_gen_shl_tl(t2, t2, t1);
3407 gen_load_gpr(t1, rt);
3408 tcg_gen_andc_tl(t1, t1, t2);
3410 tcg_gen_or_tl(t0, t0, t1);
3412 gen_store_gpr(t0, rt);
3415 t1 = tcg_temp_new();
3416 /* Do a byte access to possibly trigger a page
3417 fault with the unaligned address. */
3418 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3419 tcg_gen_andi_tl(t1, t0, 7);
3420 #ifdef TARGET_WORDS_BIGENDIAN
3421 tcg_gen_xori_tl(t1, t1, 7);
3423 tcg_gen_shli_tl(t1, t1, 3);
3424 tcg_gen_andi_tl(t0, t0, ~7);
3425 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3426 tcg_gen_shr_tl(t0, t0, t1);
3427 tcg_gen_xori_tl(t1, t1, 63);
3428 t2 = tcg_const_tl(0xfffffffffffffffeull);
3429 tcg_gen_shl_tl(t2, t2, t1);
3430 gen_load_gpr(t1, rt);
3431 tcg_gen_and_tl(t1, t1, t2);
3433 tcg_gen_or_tl(t0, t0, t1);
3435 gen_store_gpr(t0, rt);
3438 t1 = tcg_const_tl(pc_relative_pc(ctx));
3439 gen_op_addr_add(ctx, t0, t0, t1);
3441 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3442 gen_store_gpr(t0, rt);
3446 t1 = tcg_const_tl(pc_relative_pc(ctx));
3447 gen_op_addr_add(ctx, t0, t0, t1);
3449 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3450 gen_store_gpr(t0, rt);
3453 mem_idx = MIPS_HFLAG_UM;
3456 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3457 ctx->default_tcg_memop_mask);
3458 gen_store_gpr(t0, rt);
3461 mem_idx = MIPS_HFLAG_UM;
3464 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3465 ctx->default_tcg_memop_mask);
3466 gen_store_gpr(t0, rt);
3469 mem_idx = MIPS_HFLAG_UM;
3472 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3473 ctx->default_tcg_memop_mask);
3474 gen_store_gpr(t0, rt);
3477 mem_idx = MIPS_HFLAG_UM;
3480 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3481 gen_store_gpr(t0, rt);
3484 mem_idx = MIPS_HFLAG_UM;
3487 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3488 gen_store_gpr(t0, rt);
3491 mem_idx = MIPS_HFLAG_UM;
3494 t1 = tcg_temp_new();
3495 /* Do a byte access to possibly trigger a page
3496 fault with the unaligned address. */
3497 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3498 tcg_gen_andi_tl(t1, t0, 3);
3499 #ifndef TARGET_WORDS_BIGENDIAN
3500 tcg_gen_xori_tl(t1, t1, 3);
3502 tcg_gen_shli_tl(t1, t1, 3);
3503 tcg_gen_andi_tl(t0, t0, ~3);
3504 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3505 tcg_gen_shl_tl(t0, t0, t1);
3506 t2 = tcg_const_tl(-1);
3507 tcg_gen_shl_tl(t2, t2, t1);
3508 gen_load_gpr(t1, rt);
3509 tcg_gen_andc_tl(t1, t1, t2);
3511 tcg_gen_or_tl(t0, t0, t1);
3513 tcg_gen_ext32s_tl(t0, t0);
3514 gen_store_gpr(t0, rt);
3517 mem_idx = MIPS_HFLAG_UM;
3520 t1 = tcg_temp_new();
3521 /* Do a byte access to possibly trigger a page
3522 fault with the unaligned address. */
3523 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3524 tcg_gen_andi_tl(t1, t0, 3);
3525 #ifdef TARGET_WORDS_BIGENDIAN
3526 tcg_gen_xori_tl(t1, t1, 3);
3528 tcg_gen_shli_tl(t1, t1, 3);
3529 tcg_gen_andi_tl(t0, t0, ~3);
3530 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3531 tcg_gen_shr_tl(t0, t0, t1);
3532 tcg_gen_xori_tl(t1, t1, 31);
3533 t2 = tcg_const_tl(0xfffffffeull);
3534 tcg_gen_shl_tl(t2, t2, t1);
3535 gen_load_gpr(t1, rt);
3536 tcg_gen_and_tl(t1, t1, t2);
3538 tcg_gen_or_tl(t0, t0, t1);
3540 tcg_gen_ext32s_tl(t0, t0);
3541 gen_store_gpr(t0, rt);
3544 mem_idx = MIPS_HFLAG_UM;
3548 op_ld_ll(t0, t0, mem_idx, ctx);
3549 gen_store_gpr(t0, rt);
3555 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3556 uint32_t reg1, uint32_t reg2)
3558 TCGv taddr = tcg_temp_new();
3559 TCGv_i64 tval = tcg_temp_new_i64();
3560 TCGv tmp1 = tcg_temp_new();
3561 TCGv tmp2 = tcg_temp_new();
3563 gen_base_offset_addr(ctx, taddr, base, offset);
3564 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3565 #ifdef TARGET_WORDS_BIGENDIAN
3566 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3568 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3570 gen_store_gpr(tmp1, reg1);
3571 tcg_temp_free(tmp1);
3572 gen_store_gpr(tmp2, reg2);
3573 tcg_temp_free(tmp2);
3574 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3575 tcg_temp_free_i64(tval);
3576 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3577 tcg_temp_free(taddr);
3581 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3582 int base, int offset)
3584 TCGv t0 = tcg_temp_new();
3585 TCGv t1 = tcg_temp_new();
3586 int mem_idx = ctx->mem_idx;
3588 gen_base_offset_addr(ctx, t0, base, offset);
3589 gen_load_gpr(t1, rt);
3591 #if defined(TARGET_MIPS64)
3593 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3594 ctx->default_tcg_memop_mask);
3597 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3600 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3604 mem_idx = MIPS_HFLAG_UM;
3607 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3608 ctx->default_tcg_memop_mask);
3611 mem_idx = MIPS_HFLAG_UM;
3614 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3615 ctx->default_tcg_memop_mask);
3618 mem_idx = MIPS_HFLAG_UM;
3621 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3624 mem_idx = MIPS_HFLAG_UM;
3627 gen_helper_0e2i(swl, t1, t0, mem_idx);
3630 mem_idx = MIPS_HFLAG_UM;
3633 gen_helper_0e2i(swr, t1, t0, mem_idx);
3641 /* Store conditional */
3642 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3643 TCGMemOp tcg_mo, bool eva)
3646 TCGLabel *l1 = gen_new_label();
3647 TCGLabel *done = gen_new_label();
3649 t0 = tcg_temp_new();
3650 addr = tcg_temp_new();
3651 /* compare the address against that of the preceeding LL */
3652 gen_base_offset_addr(ctx, addr, base, offset);
3653 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3654 tcg_temp_free(addr);
3655 tcg_gen_movi_tl(t0, 0);
3656 gen_store_gpr(t0, rt);
3660 /* generate cmpxchg */
3661 val = tcg_temp_new();
3662 gen_load_gpr(val, rt);
3663 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3664 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3665 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3666 gen_store_gpr(t0, rt);
3669 gen_set_label(done);
3674 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3675 uint32_t reg1, uint32_t reg2, bool eva)
3677 TCGv taddr = tcg_temp_local_new();
3678 TCGv lladdr = tcg_temp_local_new();
3679 TCGv_i64 tval = tcg_temp_new_i64();
3680 TCGv_i64 llval = tcg_temp_new_i64();
3681 TCGv_i64 val = tcg_temp_new_i64();
3682 TCGv tmp1 = tcg_temp_new();
3683 TCGv tmp2 = tcg_temp_new();
3684 TCGLabel *lab_fail = gen_new_label();
3685 TCGLabel *lab_done = gen_new_label();
3687 gen_base_offset_addr(ctx, taddr, base, offset);
3689 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3690 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3692 gen_load_gpr(tmp1, reg1);
3693 gen_load_gpr(tmp2, reg2);
3695 #ifdef TARGET_WORDS_BIGENDIAN
3696 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3698 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3701 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3702 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3703 eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3705 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3707 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3709 gen_set_label(lab_fail);
3712 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3714 gen_set_label(lab_done);
3715 tcg_gen_movi_tl(lladdr, -1);
3716 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3719 /* Load and store */
3720 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3723 /* Don't do NOP if destination is zero: we must perform the actual
3728 TCGv_i32 fp0 = tcg_temp_new_i32();
3729 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3730 ctx->default_tcg_memop_mask);
3731 gen_store_fpr32(ctx, fp0, ft);
3732 tcg_temp_free_i32(fp0);
3737 TCGv_i32 fp0 = tcg_temp_new_i32();
3738 gen_load_fpr32(ctx, fp0, ft);
3739 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3740 ctx->default_tcg_memop_mask);
3741 tcg_temp_free_i32(fp0);
3746 TCGv_i64 fp0 = tcg_temp_new_i64();
3747 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3748 ctx->default_tcg_memop_mask);
3749 gen_store_fpr64(ctx, fp0, ft);
3750 tcg_temp_free_i64(fp0);
3755 TCGv_i64 fp0 = tcg_temp_new_i64();
3756 gen_load_fpr64(ctx, fp0, ft);
3757 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3758 ctx->default_tcg_memop_mask);
3759 tcg_temp_free_i64(fp0);
3763 MIPS_INVAL("flt_ldst");
3764 generate_exception_end(ctx, EXCP_RI);
3769 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3770 int rs, int16_t imm)
3772 TCGv t0 = tcg_temp_new();
3774 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3775 check_cp1_enabled(ctx);
3779 check_insn(ctx, ISA_MIPS2);
3782 gen_base_offset_addr(ctx, t0, rs, imm);
3783 gen_flt_ldst(ctx, op, rt, t0);
3786 generate_exception_err(ctx, EXCP_CpU, 1);
3791 /* Arithmetic with immediate operand */
3792 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3793 int rt, int rs, int imm)
3795 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3797 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3798 /* If no destination, treat it as a NOP.
3799 For addi, we must generate the overflow exception when needed. */
3805 TCGv t0 = tcg_temp_local_new();
3806 TCGv t1 = tcg_temp_new();
3807 TCGv t2 = tcg_temp_new();
3808 TCGLabel *l1 = gen_new_label();
3810 gen_load_gpr(t1, rs);
3811 tcg_gen_addi_tl(t0, t1, uimm);
3812 tcg_gen_ext32s_tl(t0, t0);
3814 tcg_gen_xori_tl(t1, t1, ~uimm);
3815 tcg_gen_xori_tl(t2, t0, uimm);
3816 tcg_gen_and_tl(t1, t1, t2);
3818 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3820 /* operands of same sign, result different sign */
3821 generate_exception(ctx, EXCP_OVERFLOW);
3823 tcg_gen_ext32s_tl(t0, t0);
3824 gen_store_gpr(t0, rt);
3830 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3831 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3833 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3836 #if defined(TARGET_MIPS64)
3839 TCGv t0 = tcg_temp_local_new();
3840 TCGv t1 = tcg_temp_new();
3841 TCGv t2 = tcg_temp_new();
3842 TCGLabel *l1 = gen_new_label();
3844 gen_load_gpr(t1, rs);
3845 tcg_gen_addi_tl(t0, t1, uimm);
3847 tcg_gen_xori_tl(t1, t1, ~uimm);
3848 tcg_gen_xori_tl(t2, t0, uimm);
3849 tcg_gen_and_tl(t1, t1, t2);
3851 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3853 /* operands of same sign, result different sign */
3854 generate_exception(ctx, EXCP_OVERFLOW);
3856 gen_store_gpr(t0, rt);
3862 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3864 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3871 /* Logic with immediate operand */
3872 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3873 int rt, int rs, int16_t imm)
3878 /* If no destination, treat it as a NOP. */
3881 uimm = (uint16_t)imm;
3884 if (likely(rs != 0))
3885 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3887 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3891 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3893 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3896 if (likely(rs != 0))
3897 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3899 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3902 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3904 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3905 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3907 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3916 /* Set on less than with immediate operand */
3917 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3918 int rt, int rs, int16_t imm)
3920 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3924 /* If no destination, treat it as a NOP. */
3927 t0 = tcg_temp_new();
3928 gen_load_gpr(t0, rs);
3931 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3934 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3940 /* Shifts with immediate operand */
3941 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3942 int rt, int rs, int16_t imm)
3944 target_ulong uimm = ((uint16_t)imm) & 0x1f;
3948 /* If no destination, treat it as a NOP. */
3952 t0 = tcg_temp_new();
3953 gen_load_gpr(t0, rs);
3956 tcg_gen_shli_tl(t0, t0, uimm);
3957 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3960 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3964 tcg_gen_ext32u_tl(t0, t0);
3965 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3967 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3972 TCGv_i32 t1 = tcg_temp_new_i32();
3974 tcg_gen_trunc_tl_i32(t1, t0);
3975 tcg_gen_rotri_i32(t1, t1, uimm);
3976 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3977 tcg_temp_free_i32(t1);
3979 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3982 #if defined(TARGET_MIPS64)
3984 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3987 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3990 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3994 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3996 tcg_gen_mov_tl(cpu_gpr[rt], t0);
4000 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4003 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4006 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4009 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4017 static void gen_arith(DisasContext *ctx, uint32_t opc,
4018 int rd, int rs, int rt)
4020 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4021 && opc != OPC_DADD && opc != OPC_DSUB) {
4022 /* If no destination, treat it as a NOP.
4023 For add & sub, we must generate the overflow exception when needed. */
4030 TCGv t0 = tcg_temp_local_new();
4031 TCGv t1 = tcg_temp_new();
4032 TCGv t2 = tcg_temp_new();
4033 TCGLabel *l1 = gen_new_label();
4035 gen_load_gpr(t1, rs);
4036 gen_load_gpr(t2, rt);
4037 tcg_gen_add_tl(t0, t1, t2);
4038 tcg_gen_ext32s_tl(t0, t0);
4039 tcg_gen_xor_tl(t1, t1, t2);
4040 tcg_gen_xor_tl(t2, t0, t2);
4041 tcg_gen_andc_tl(t1, t2, t1);
4043 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4045 /* operands of same sign, result different sign */
4046 generate_exception(ctx, EXCP_OVERFLOW);
4048 gen_store_gpr(t0, rd);
4053 if (rs != 0 && rt != 0) {
4054 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4055 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4056 } else if (rs == 0 && rt != 0) {
4057 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4058 } else if (rs != 0 && rt == 0) {
4059 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4061 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4066 TCGv t0 = tcg_temp_local_new();
4067 TCGv t1 = tcg_temp_new();
4068 TCGv t2 = tcg_temp_new();
4069 TCGLabel *l1 = gen_new_label();
4071 gen_load_gpr(t1, rs);
4072 gen_load_gpr(t2, rt);
4073 tcg_gen_sub_tl(t0, t1, t2);
4074 tcg_gen_ext32s_tl(t0, t0);
4075 tcg_gen_xor_tl(t2, t1, t2);
4076 tcg_gen_xor_tl(t1, t0, t1);
4077 tcg_gen_and_tl(t1, t1, t2);
4079 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4081 /* operands of different sign, first operand and result different sign */
4082 generate_exception(ctx, EXCP_OVERFLOW);
4084 gen_store_gpr(t0, rd);
4089 if (rs != 0 && rt != 0) {
4090 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4091 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4092 } else if (rs == 0 && rt != 0) {
4093 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4094 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
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);
4101 #if defined(TARGET_MIPS64)
4104 TCGv t0 = tcg_temp_local_new();
4105 TCGv t1 = tcg_temp_new();
4106 TCGv t2 = tcg_temp_new();
4107 TCGLabel *l1 = gen_new_label();
4109 gen_load_gpr(t1, rs);
4110 gen_load_gpr(t2, rt);
4111 tcg_gen_add_tl(t0, t1, t2);
4112 tcg_gen_xor_tl(t1, t1, t2);
4113 tcg_gen_xor_tl(t2, t0, t2);
4114 tcg_gen_andc_tl(t1, t2, t1);
4116 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4118 /* operands of same sign, result different sign */
4119 generate_exception(ctx, EXCP_OVERFLOW);
4121 gen_store_gpr(t0, rd);
4126 if (rs != 0 && rt != 0) {
4127 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4128 } else if (rs == 0 && rt != 0) {
4129 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4130 } else if (rs != 0 && rt == 0) {
4131 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4133 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4138 TCGv t0 = tcg_temp_local_new();
4139 TCGv t1 = tcg_temp_new();
4140 TCGv t2 = tcg_temp_new();
4141 TCGLabel *l1 = gen_new_label();
4143 gen_load_gpr(t1, rs);
4144 gen_load_gpr(t2, rt);
4145 tcg_gen_sub_tl(t0, t1, t2);
4146 tcg_gen_xor_tl(t2, t1, t2);
4147 tcg_gen_xor_tl(t1, t0, t1);
4148 tcg_gen_and_tl(t1, t1, t2);
4150 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4152 /* operands of different sign, first operand and result different sign */
4153 generate_exception(ctx, EXCP_OVERFLOW);
4155 gen_store_gpr(t0, rd);
4160 if (rs != 0 && rt != 0) {
4161 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4162 } else if (rs == 0 && rt != 0) {
4163 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4164 } else if (rs != 0 && rt == 0) {
4165 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4167 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4172 if (likely(rs != 0 && rt != 0)) {
4173 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4174 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4176 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4182 /* Conditional move */
4183 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4184 int rd, int rs, int rt)
4189 /* If no destination, treat it as a NOP. */
4193 t0 = tcg_temp_new();
4194 gen_load_gpr(t0, rt);
4195 t1 = tcg_const_tl(0);
4196 t2 = tcg_temp_new();
4197 gen_load_gpr(t2, rs);
4200 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4203 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4206 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4209 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4218 static void gen_logic(DisasContext *ctx, uint32_t opc,
4219 int rd, int rs, int rt)
4222 /* If no destination, treat it as a NOP. */
4228 if (likely(rs != 0 && rt != 0)) {
4229 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4231 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4235 if (rs != 0 && rt != 0) {
4236 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4237 } else if (rs == 0 && rt != 0) {
4238 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4239 } else if (rs != 0 && rt == 0) {
4240 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4242 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4246 if (likely(rs != 0 && rt != 0)) {
4247 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4248 } else if (rs == 0 && rt != 0) {
4249 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4250 } else if (rs != 0 && rt == 0) {
4251 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4253 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4257 if (likely(rs != 0 && rt != 0)) {
4258 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4259 } else if (rs == 0 && rt != 0) {
4260 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4261 } else if (rs != 0 && rt == 0) {
4262 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4264 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4270 /* Set on lower than */
4271 static void gen_slt(DisasContext *ctx, uint32_t opc,
4272 int rd, int rs, int rt)
4277 /* If no destination, treat it as a NOP. */
4281 t0 = tcg_temp_new();
4282 t1 = tcg_temp_new();
4283 gen_load_gpr(t0, rs);
4284 gen_load_gpr(t1, rt);
4287 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4290 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4298 static void gen_shift(DisasContext *ctx, uint32_t opc,
4299 int rd, int rs, int rt)
4304 /* If no destination, treat it as a NOP.
4305 For add & sub, we must generate the overflow exception when needed. */
4309 t0 = tcg_temp_new();
4310 t1 = tcg_temp_new();
4311 gen_load_gpr(t0, rs);
4312 gen_load_gpr(t1, rt);
4315 tcg_gen_andi_tl(t0, t0, 0x1f);
4316 tcg_gen_shl_tl(t0, t1, t0);
4317 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4320 tcg_gen_andi_tl(t0, t0, 0x1f);
4321 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4324 tcg_gen_ext32u_tl(t1, t1);
4325 tcg_gen_andi_tl(t0, t0, 0x1f);
4326 tcg_gen_shr_tl(t0, t1, t0);
4327 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4331 TCGv_i32 t2 = tcg_temp_new_i32();
4332 TCGv_i32 t3 = tcg_temp_new_i32();
4334 tcg_gen_trunc_tl_i32(t2, t0);
4335 tcg_gen_trunc_tl_i32(t3, t1);
4336 tcg_gen_andi_i32(t2, t2, 0x1f);
4337 tcg_gen_rotr_i32(t2, t3, t2);
4338 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4339 tcg_temp_free_i32(t2);
4340 tcg_temp_free_i32(t3);
4343 #if defined(TARGET_MIPS64)
4345 tcg_gen_andi_tl(t0, t0, 0x3f);
4346 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4349 tcg_gen_andi_tl(t0, t0, 0x3f);
4350 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4353 tcg_gen_andi_tl(t0, t0, 0x3f);
4354 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4357 tcg_gen_andi_tl(t0, t0, 0x3f);
4358 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4366 #if defined(TARGET_MIPS64)
4367 /* Copy GPR to and from TX79 HI1/LO1 register. */
4368 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4370 if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4377 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4380 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4384 tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4386 tcg_gen_movi_tl(cpu_HI[1], 0);
4391 tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4393 tcg_gen_movi_tl(cpu_LO[1], 0);
4397 MIPS_INVAL("mfthilo1 TX79");
4398 generate_exception_end(ctx, EXCP_RI);
4404 /* Arithmetic on HI/LO registers */
4405 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4407 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4418 #if defined(TARGET_MIPS64)
4420 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4424 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4428 #if defined(TARGET_MIPS64)
4430 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4434 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4439 #if defined(TARGET_MIPS64)
4441 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4445 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4448 tcg_gen_movi_tl(cpu_HI[acc], 0);
4453 #if defined(TARGET_MIPS64)
4455 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4459 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4462 tcg_gen_movi_tl(cpu_LO[acc], 0);
4468 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4471 TCGv t0 = tcg_const_tl(addr);
4472 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4473 gen_store_gpr(t0, reg);
4477 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4483 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4486 offset = sextract32(ctx->opcode << 2, 0, 21);
4487 addr = addr_add(ctx, pc, offset);
4488 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4492 offset = sextract32(ctx->opcode << 2, 0, 21);
4493 addr = addr_add(ctx, pc, offset);
4494 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4496 #if defined(TARGET_MIPS64)
4499 offset = sextract32(ctx->opcode << 2, 0, 21);
4500 addr = addr_add(ctx, pc, offset);
4501 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4505 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4508 offset = sextract32(ctx->opcode, 0, 16) << 16;
4509 addr = addr_add(ctx, pc, offset);
4510 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4515 offset = sextract32(ctx->opcode, 0, 16) << 16;
4516 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4517 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4520 #if defined(TARGET_MIPS64)
4521 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4522 case R6_OPC_LDPC + (1 << 16):
4523 case R6_OPC_LDPC + (2 << 16):
4524 case R6_OPC_LDPC + (3 << 16):
4526 offset = sextract32(ctx->opcode << 3, 0, 21);
4527 addr = addr_add(ctx, (pc & ~0x7), offset);
4528 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4532 MIPS_INVAL("OPC_PCREL");
4533 generate_exception_end(ctx, EXCP_RI);
4540 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4549 t0 = tcg_temp_new();
4550 t1 = tcg_temp_new();
4552 gen_load_gpr(t0, rs);
4553 gen_load_gpr(t1, rt);
4558 TCGv t2 = tcg_temp_new();
4559 TCGv t3 = tcg_temp_new();
4560 tcg_gen_ext32s_tl(t0, t0);
4561 tcg_gen_ext32s_tl(t1, t1);
4562 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4563 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4564 tcg_gen_and_tl(t2, t2, t3);
4565 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4566 tcg_gen_or_tl(t2, t2, t3);
4567 tcg_gen_movi_tl(t3, 0);
4568 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4569 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4570 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4577 TCGv t2 = tcg_temp_new();
4578 TCGv t3 = tcg_temp_new();
4579 tcg_gen_ext32s_tl(t0, t0);
4580 tcg_gen_ext32s_tl(t1, t1);
4581 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4582 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4583 tcg_gen_and_tl(t2, t2, t3);
4584 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4585 tcg_gen_or_tl(t2, t2, t3);
4586 tcg_gen_movi_tl(t3, 0);
4587 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4588 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4589 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4596 TCGv t2 = tcg_const_tl(0);
4597 TCGv t3 = tcg_const_tl(1);
4598 tcg_gen_ext32u_tl(t0, t0);
4599 tcg_gen_ext32u_tl(t1, t1);
4600 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4601 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4602 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4609 TCGv t2 = tcg_const_tl(0);
4610 TCGv t3 = tcg_const_tl(1);
4611 tcg_gen_ext32u_tl(t0, t0);
4612 tcg_gen_ext32u_tl(t1, t1);
4613 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4614 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4615 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4622 TCGv_i32 t2 = tcg_temp_new_i32();
4623 TCGv_i32 t3 = tcg_temp_new_i32();
4624 tcg_gen_trunc_tl_i32(t2, t0);
4625 tcg_gen_trunc_tl_i32(t3, t1);
4626 tcg_gen_mul_i32(t2, t2, t3);
4627 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4628 tcg_temp_free_i32(t2);
4629 tcg_temp_free_i32(t3);
4634 TCGv_i32 t2 = tcg_temp_new_i32();
4635 TCGv_i32 t3 = tcg_temp_new_i32();
4636 tcg_gen_trunc_tl_i32(t2, t0);
4637 tcg_gen_trunc_tl_i32(t3, t1);
4638 tcg_gen_muls2_i32(t2, t3, t2, t3);
4639 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4640 tcg_temp_free_i32(t2);
4641 tcg_temp_free_i32(t3);
4646 TCGv_i32 t2 = tcg_temp_new_i32();
4647 TCGv_i32 t3 = tcg_temp_new_i32();
4648 tcg_gen_trunc_tl_i32(t2, t0);
4649 tcg_gen_trunc_tl_i32(t3, t1);
4650 tcg_gen_mul_i32(t2, t2, t3);
4651 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4652 tcg_temp_free_i32(t2);
4653 tcg_temp_free_i32(t3);
4658 TCGv_i32 t2 = tcg_temp_new_i32();
4659 TCGv_i32 t3 = tcg_temp_new_i32();
4660 tcg_gen_trunc_tl_i32(t2, t0);
4661 tcg_gen_trunc_tl_i32(t3, t1);
4662 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4663 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4664 tcg_temp_free_i32(t2);
4665 tcg_temp_free_i32(t3);
4668 #if defined(TARGET_MIPS64)
4671 TCGv t2 = tcg_temp_new();
4672 TCGv t3 = tcg_temp_new();
4673 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4674 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4675 tcg_gen_and_tl(t2, t2, t3);
4676 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4677 tcg_gen_or_tl(t2, t2, t3);
4678 tcg_gen_movi_tl(t3, 0);
4679 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4680 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4687 TCGv t2 = tcg_temp_new();
4688 TCGv t3 = tcg_temp_new();
4689 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4690 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4691 tcg_gen_and_tl(t2, t2, t3);
4692 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4693 tcg_gen_or_tl(t2, t2, t3);
4694 tcg_gen_movi_tl(t3, 0);
4695 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4696 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4703 TCGv t2 = tcg_const_tl(0);
4704 TCGv t3 = tcg_const_tl(1);
4705 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4706 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4713 TCGv t2 = tcg_const_tl(0);
4714 TCGv t3 = tcg_const_tl(1);
4715 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4716 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4722 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4726 TCGv t2 = tcg_temp_new();
4727 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4732 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4736 TCGv t2 = tcg_temp_new();
4737 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4743 MIPS_INVAL("r6 mul/div");
4744 generate_exception_end(ctx, EXCP_RI);
4752 #if defined(TARGET_MIPS64)
4753 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4757 t0 = tcg_temp_new();
4758 t1 = tcg_temp_new();
4760 gen_load_gpr(t0, rs);
4761 gen_load_gpr(t1, rt);
4766 TCGv t2 = tcg_temp_new();
4767 TCGv t3 = tcg_temp_new();
4768 tcg_gen_ext32s_tl(t0, t0);
4769 tcg_gen_ext32s_tl(t1, t1);
4770 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4771 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4772 tcg_gen_and_tl(t2, t2, t3);
4773 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4774 tcg_gen_or_tl(t2, t2, t3);
4775 tcg_gen_movi_tl(t3, 0);
4776 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4777 tcg_gen_div_tl(cpu_LO[1], t0, t1);
4778 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4779 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4780 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4787 TCGv t2 = tcg_const_tl(0);
4788 TCGv t3 = tcg_const_tl(1);
4789 tcg_gen_ext32u_tl(t0, t0);
4790 tcg_gen_ext32u_tl(t1, t1);
4791 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4792 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4793 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4794 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4795 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4801 MIPS_INVAL("div1 TX79");
4802 generate_exception_end(ctx, EXCP_RI);
4811 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4812 int acc, int rs, int rt)
4816 t0 = tcg_temp_new();
4817 t1 = tcg_temp_new();
4819 gen_load_gpr(t0, rs);
4820 gen_load_gpr(t1, rt);
4829 TCGv t2 = tcg_temp_new();
4830 TCGv t3 = tcg_temp_new();
4831 tcg_gen_ext32s_tl(t0, t0);
4832 tcg_gen_ext32s_tl(t1, t1);
4833 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4834 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4835 tcg_gen_and_tl(t2, t2, t3);
4836 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4837 tcg_gen_or_tl(t2, t2, t3);
4838 tcg_gen_movi_tl(t3, 0);
4839 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4840 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4841 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4842 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4843 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4850 TCGv t2 = tcg_const_tl(0);
4851 TCGv t3 = tcg_const_tl(1);
4852 tcg_gen_ext32u_tl(t0, t0);
4853 tcg_gen_ext32u_tl(t1, t1);
4854 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4855 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4856 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4857 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4858 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4865 TCGv_i32 t2 = tcg_temp_new_i32();
4866 TCGv_i32 t3 = tcg_temp_new_i32();
4867 tcg_gen_trunc_tl_i32(t2, t0);
4868 tcg_gen_trunc_tl_i32(t3, t1);
4869 tcg_gen_muls2_i32(t2, t3, t2, t3);
4870 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4871 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4872 tcg_temp_free_i32(t2);
4873 tcg_temp_free_i32(t3);
4878 TCGv_i32 t2 = tcg_temp_new_i32();
4879 TCGv_i32 t3 = tcg_temp_new_i32();
4880 tcg_gen_trunc_tl_i32(t2, t0);
4881 tcg_gen_trunc_tl_i32(t3, t1);
4882 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4883 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4884 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4885 tcg_temp_free_i32(t2);
4886 tcg_temp_free_i32(t3);
4889 #if defined(TARGET_MIPS64)
4892 TCGv t2 = tcg_temp_new();
4893 TCGv t3 = tcg_temp_new();
4894 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4895 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4896 tcg_gen_and_tl(t2, t2, t3);
4897 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4898 tcg_gen_or_tl(t2, t2, t3);
4899 tcg_gen_movi_tl(t3, 0);
4900 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4901 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4902 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4909 TCGv t2 = tcg_const_tl(0);
4910 TCGv t3 = tcg_const_tl(1);
4911 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4912 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4913 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4919 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4922 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4927 TCGv_i64 t2 = tcg_temp_new_i64();
4928 TCGv_i64 t3 = tcg_temp_new_i64();
4930 tcg_gen_ext_tl_i64(t2, t0);
4931 tcg_gen_ext_tl_i64(t3, t1);
4932 tcg_gen_mul_i64(t2, t2, t3);
4933 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4934 tcg_gen_add_i64(t2, t2, t3);
4935 tcg_temp_free_i64(t3);
4936 gen_move_low32(cpu_LO[acc], t2);
4937 gen_move_high32(cpu_HI[acc], t2);
4938 tcg_temp_free_i64(t2);
4943 TCGv_i64 t2 = tcg_temp_new_i64();
4944 TCGv_i64 t3 = tcg_temp_new_i64();
4946 tcg_gen_ext32u_tl(t0, t0);
4947 tcg_gen_ext32u_tl(t1, t1);
4948 tcg_gen_extu_tl_i64(t2, t0);
4949 tcg_gen_extu_tl_i64(t3, t1);
4950 tcg_gen_mul_i64(t2, t2, t3);
4951 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4952 tcg_gen_add_i64(t2, t2, t3);
4953 tcg_temp_free_i64(t3);
4954 gen_move_low32(cpu_LO[acc], t2);
4955 gen_move_high32(cpu_HI[acc], t2);
4956 tcg_temp_free_i64(t2);
4961 TCGv_i64 t2 = tcg_temp_new_i64();
4962 TCGv_i64 t3 = tcg_temp_new_i64();
4964 tcg_gen_ext_tl_i64(t2, t0);
4965 tcg_gen_ext_tl_i64(t3, t1);
4966 tcg_gen_mul_i64(t2, t2, t3);
4967 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4968 tcg_gen_sub_i64(t2, t3, t2);
4969 tcg_temp_free_i64(t3);
4970 gen_move_low32(cpu_LO[acc], t2);
4971 gen_move_high32(cpu_HI[acc], t2);
4972 tcg_temp_free_i64(t2);
4977 TCGv_i64 t2 = tcg_temp_new_i64();
4978 TCGv_i64 t3 = tcg_temp_new_i64();
4980 tcg_gen_ext32u_tl(t0, t0);
4981 tcg_gen_ext32u_tl(t1, t1);
4982 tcg_gen_extu_tl_i64(t2, t0);
4983 tcg_gen_extu_tl_i64(t3, t1);
4984 tcg_gen_mul_i64(t2, t2, t3);
4985 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4986 tcg_gen_sub_i64(t2, t3, t2);
4987 tcg_temp_free_i64(t3);
4988 gen_move_low32(cpu_LO[acc], t2);
4989 gen_move_high32(cpu_HI[acc], t2);
4990 tcg_temp_free_i64(t2);
4994 MIPS_INVAL("mul/div");
4995 generate_exception_end(ctx, EXCP_RI);
5004 * These MULT[U] and MADD[U] instructions implemented in for example
5005 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5006 * architectures are special three-operand variants with the syntax
5008 * MULT[U][1] rd, rs, rt
5012 * (rd, LO, HI) <- rs * rt
5016 * MADD[U][1] rd, rs, rt
5020 * (rd, LO, HI) <- (LO, HI) + rs * rt
5022 * where the low-order 32-bits of the result is placed into both the
5023 * GPR rd and the special register LO. The high-order 32-bits of the
5024 * result is placed into the special register HI.
5026 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5027 * which is the zero register that always reads as 0.
5029 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5030 int rd, int rs, int rt)
5032 TCGv t0 = tcg_temp_new();
5033 TCGv t1 = tcg_temp_new();
5036 gen_load_gpr(t0, rs);
5037 gen_load_gpr(t1, rt);
5045 TCGv_i32 t2 = tcg_temp_new_i32();
5046 TCGv_i32 t3 = tcg_temp_new_i32();
5047 tcg_gen_trunc_tl_i32(t2, t0);
5048 tcg_gen_trunc_tl_i32(t3, t1);
5049 tcg_gen_muls2_i32(t2, t3, t2, t3);
5051 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5053 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5054 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5055 tcg_temp_free_i32(t2);
5056 tcg_temp_free_i32(t3);
5059 case MMI_OPC_MULTU1:
5064 TCGv_i32 t2 = tcg_temp_new_i32();
5065 TCGv_i32 t3 = tcg_temp_new_i32();
5066 tcg_gen_trunc_tl_i32(t2, t0);
5067 tcg_gen_trunc_tl_i32(t3, t1);
5068 tcg_gen_mulu2_i32(t2, t3, t2, t3);
5070 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5072 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5073 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5074 tcg_temp_free_i32(t2);
5075 tcg_temp_free_i32(t3);
5083 TCGv_i64 t2 = tcg_temp_new_i64();
5084 TCGv_i64 t3 = tcg_temp_new_i64();
5086 tcg_gen_ext_tl_i64(t2, t0);
5087 tcg_gen_ext_tl_i64(t3, t1);
5088 tcg_gen_mul_i64(t2, t2, t3);
5089 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5090 tcg_gen_add_i64(t2, t2, t3);
5091 tcg_temp_free_i64(t3);
5092 gen_move_low32(cpu_LO[acc], t2);
5093 gen_move_high32(cpu_HI[acc], t2);
5095 gen_move_low32(cpu_gpr[rd], t2);
5097 tcg_temp_free_i64(t2);
5100 case MMI_OPC_MADDU1:
5105 TCGv_i64 t2 = tcg_temp_new_i64();
5106 TCGv_i64 t3 = tcg_temp_new_i64();
5108 tcg_gen_ext32u_tl(t0, t0);
5109 tcg_gen_ext32u_tl(t1, t1);
5110 tcg_gen_extu_tl_i64(t2, t0);
5111 tcg_gen_extu_tl_i64(t3, t1);
5112 tcg_gen_mul_i64(t2, t2, t3);
5113 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5114 tcg_gen_add_i64(t2, t2, t3);
5115 tcg_temp_free_i64(t3);
5116 gen_move_low32(cpu_LO[acc], t2);
5117 gen_move_high32(cpu_HI[acc], t2);
5119 gen_move_low32(cpu_gpr[rd], t2);
5121 tcg_temp_free_i64(t2);
5125 MIPS_INVAL("mul/madd TXx9");
5126 generate_exception_end(ctx, EXCP_RI);
5135 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5136 int rd, int rs, int rt)
5138 TCGv t0 = tcg_temp_new();
5139 TCGv t1 = tcg_temp_new();
5141 gen_load_gpr(t0, rs);
5142 gen_load_gpr(t1, rt);
5145 case OPC_VR54XX_MULS:
5146 gen_helper_muls(t0, cpu_env, t0, t1);
5148 case OPC_VR54XX_MULSU:
5149 gen_helper_mulsu(t0, cpu_env, t0, t1);
5151 case OPC_VR54XX_MACC:
5152 gen_helper_macc(t0, cpu_env, t0, t1);
5154 case OPC_VR54XX_MACCU:
5155 gen_helper_maccu(t0, cpu_env, t0, t1);
5157 case OPC_VR54XX_MSAC:
5158 gen_helper_msac(t0, cpu_env, t0, t1);
5160 case OPC_VR54XX_MSACU:
5161 gen_helper_msacu(t0, cpu_env, t0, t1);
5163 case OPC_VR54XX_MULHI:
5164 gen_helper_mulhi(t0, cpu_env, t0, t1);
5166 case OPC_VR54XX_MULHIU:
5167 gen_helper_mulhiu(t0, cpu_env, t0, t1);
5169 case OPC_VR54XX_MULSHI:
5170 gen_helper_mulshi(t0, cpu_env, t0, t1);
5172 case OPC_VR54XX_MULSHIU:
5173 gen_helper_mulshiu(t0, cpu_env, t0, t1);
5175 case OPC_VR54XX_MACCHI:
5176 gen_helper_macchi(t0, cpu_env, t0, t1);
5178 case OPC_VR54XX_MACCHIU:
5179 gen_helper_macchiu(t0, cpu_env, t0, t1);
5181 case OPC_VR54XX_MSACHI:
5182 gen_helper_msachi(t0, cpu_env, t0, t1);
5184 case OPC_VR54XX_MSACHIU:
5185 gen_helper_msachiu(t0, cpu_env, t0, t1);
5188 MIPS_INVAL("mul vr54xx");
5189 generate_exception_end(ctx, EXCP_RI);
5192 gen_store_gpr(t0, rd);
5199 static void gen_cl (DisasContext *ctx, uint32_t opc,
5209 gen_load_gpr(t0, rs);
5214 #if defined(TARGET_MIPS64)
5218 tcg_gen_not_tl(t0, t0);
5227 tcg_gen_ext32u_tl(t0, t0);
5228 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5229 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5231 #if defined(TARGET_MIPS64)
5236 tcg_gen_clzi_i64(t0, t0, 64);
5242 /* Godson integer instructions */
5243 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5244 int rd, int rs, int rt)
5256 case OPC_MULTU_G_2E:
5257 case OPC_MULTU_G_2F:
5258 #if defined(TARGET_MIPS64)
5259 case OPC_DMULT_G_2E:
5260 case OPC_DMULT_G_2F:
5261 case OPC_DMULTU_G_2E:
5262 case OPC_DMULTU_G_2F:
5264 t0 = tcg_temp_new();
5265 t1 = tcg_temp_new();
5268 t0 = tcg_temp_local_new();
5269 t1 = tcg_temp_local_new();
5273 gen_load_gpr(t0, rs);
5274 gen_load_gpr(t1, rt);
5279 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5280 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5282 case OPC_MULTU_G_2E:
5283 case OPC_MULTU_G_2F:
5284 tcg_gen_ext32u_tl(t0, t0);
5285 tcg_gen_ext32u_tl(t1, t1);
5286 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5287 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5292 TCGLabel *l1 = gen_new_label();
5293 TCGLabel *l2 = gen_new_label();
5294 TCGLabel *l3 = gen_new_label();
5295 tcg_gen_ext32s_tl(t0, t0);
5296 tcg_gen_ext32s_tl(t1, t1);
5297 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5298 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5301 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5302 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5303 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5306 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5307 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5314 TCGLabel *l1 = gen_new_label();
5315 TCGLabel *l2 = gen_new_label();
5316 tcg_gen_ext32u_tl(t0, t0);
5317 tcg_gen_ext32u_tl(t1, t1);
5318 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5319 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5322 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5323 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5330 TCGLabel *l1 = gen_new_label();
5331 TCGLabel *l2 = gen_new_label();
5332 TCGLabel *l3 = gen_new_label();
5333 tcg_gen_ext32u_tl(t0, t0);
5334 tcg_gen_ext32u_tl(t1, t1);
5335 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5336 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5337 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5339 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5342 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5343 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5350 TCGLabel *l1 = gen_new_label();
5351 TCGLabel *l2 = gen_new_label();
5352 tcg_gen_ext32u_tl(t0, t0);
5353 tcg_gen_ext32u_tl(t1, t1);
5354 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5355 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5358 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5359 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5363 #if defined(TARGET_MIPS64)
5364 case OPC_DMULT_G_2E:
5365 case OPC_DMULT_G_2F:
5366 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5368 case OPC_DMULTU_G_2E:
5369 case OPC_DMULTU_G_2F:
5370 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5375 TCGLabel *l1 = gen_new_label();
5376 TCGLabel *l2 = gen_new_label();
5377 TCGLabel *l3 = gen_new_label();
5378 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5379 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5382 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5383 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5384 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5387 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5391 case OPC_DDIVU_G_2E:
5392 case OPC_DDIVU_G_2F:
5394 TCGLabel *l1 = gen_new_label();
5395 TCGLabel *l2 = gen_new_label();
5396 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5397 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5400 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5407 TCGLabel *l1 = gen_new_label();
5408 TCGLabel *l2 = gen_new_label();
5409 TCGLabel *l3 = gen_new_label();
5410 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5411 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5412 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5414 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5417 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5421 case OPC_DMODU_G_2E:
5422 case OPC_DMODU_G_2F:
5424 TCGLabel *l1 = gen_new_label();
5425 TCGLabel *l2 = gen_new_label();
5426 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5427 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5430 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5441 /* Loongson multimedia instructions */
5442 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5444 uint32_t opc, shift_max;
5447 opc = MASK_LMI(ctx->opcode);
5453 t0 = tcg_temp_local_new_i64();
5454 t1 = tcg_temp_local_new_i64();
5457 t0 = tcg_temp_new_i64();
5458 t1 = tcg_temp_new_i64();
5462 check_cp1_enabled(ctx);
5463 gen_load_fpr64(ctx, t0, rs);
5464 gen_load_fpr64(ctx, t1, rt);
5466 #define LMI_HELPER(UP, LO) \
5467 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5468 #define LMI_HELPER_1(UP, LO) \
5469 case OPC_##UP: gen_helper_##LO(t0, t0); break
5470 #define LMI_DIRECT(UP, LO, OP) \
5471 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5474 LMI_HELPER(PADDSH, paddsh);
5475 LMI_HELPER(PADDUSH, paddush);
5476 LMI_HELPER(PADDH, paddh);
5477 LMI_HELPER(PADDW, paddw);
5478 LMI_HELPER(PADDSB, paddsb);
5479 LMI_HELPER(PADDUSB, paddusb);
5480 LMI_HELPER(PADDB, paddb);
5482 LMI_HELPER(PSUBSH, psubsh);
5483 LMI_HELPER(PSUBUSH, psubush);
5484 LMI_HELPER(PSUBH, psubh);
5485 LMI_HELPER(PSUBW, psubw);
5486 LMI_HELPER(PSUBSB, psubsb);
5487 LMI_HELPER(PSUBUSB, psubusb);
5488 LMI_HELPER(PSUBB, psubb);
5490 LMI_HELPER(PSHUFH, pshufh);
5491 LMI_HELPER(PACKSSWH, packsswh);
5492 LMI_HELPER(PACKSSHB, packsshb);
5493 LMI_HELPER(PACKUSHB, packushb);
5495 LMI_HELPER(PUNPCKLHW, punpcklhw);
5496 LMI_HELPER(PUNPCKHHW, punpckhhw);
5497 LMI_HELPER(PUNPCKLBH, punpcklbh);
5498 LMI_HELPER(PUNPCKHBH, punpckhbh);
5499 LMI_HELPER(PUNPCKLWD, punpcklwd);
5500 LMI_HELPER(PUNPCKHWD, punpckhwd);
5502 LMI_HELPER(PAVGH, pavgh);
5503 LMI_HELPER(PAVGB, pavgb);
5504 LMI_HELPER(PMAXSH, pmaxsh);
5505 LMI_HELPER(PMINSH, pminsh);
5506 LMI_HELPER(PMAXUB, pmaxub);
5507 LMI_HELPER(PMINUB, pminub);
5509 LMI_HELPER(PCMPEQW, pcmpeqw);
5510 LMI_HELPER(PCMPGTW, pcmpgtw);
5511 LMI_HELPER(PCMPEQH, pcmpeqh);
5512 LMI_HELPER(PCMPGTH, pcmpgth);
5513 LMI_HELPER(PCMPEQB, pcmpeqb);
5514 LMI_HELPER(PCMPGTB, pcmpgtb);
5516 LMI_HELPER(PSLLW, psllw);
5517 LMI_HELPER(PSLLH, psllh);
5518 LMI_HELPER(PSRLW, psrlw);
5519 LMI_HELPER(PSRLH, psrlh);
5520 LMI_HELPER(PSRAW, psraw);
5521 LMI_HELPER(PSRAH, psrah);
5523 LMI_HELPER(PMULLH, pmullh);
5524 LMI_HELPER(PMULHH, pmulhh);
5525 LMI_HELPER(PMULHUH, pmulhuh);
5526 LMI_HELPER(PMADDHW, pmaddhw);
5528 LMI_HELPER(PASUBUB, pasubub);
5529 LMI_HELPER_1(BIADD, biadd);
5530 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5532 LMI_DIRECT(PADDD, paddd, add);
5533 LMI_DIRECT(PSUBD, psubd, sub);
5534 LMI_DIRECT(XOR_CP2, xor, xor);
5535 LMI_DIRECT(NOR_CP2, nor, nor);
5536 LMI_DIRECT(AND_CP2, and, and);
5537 LMI_DIRECT(OR_CP2, or, or);
5540 tcg_gen_andc_i64(t0, t1, t0);
5544 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5547 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5550 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5553 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5557 tcg_gen_andi_i64(t1, t1, 3);
5558 tcg_gen_shli_i64(t1, t1, 4);
5559 tcg_gen_shr_i64(t0, t0, t1);
5560 tcg_gen_ext16u_i64(t0, t0);
5564 tcg_gen_add_i64(t0, t0, t1);
5565 tcg_gen_ext32s_i64(t0, t0);
5568 tcg_gen_sub_i64(t0, t0, t1);
5569 tcg_gen_ext32s_i64(t0, t0);
5591 /* Make sure shift count isn't TCG undefined behaviour. */
5592 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5597 tcg_gen_shl_i64(t0, t0, t1);
5601 /* Since SRA is UndefinedResult without sign-extended inputs,
5602 we can treat SRA and DSRA the same. */
5603 tcg_gen_sar_i64(t0, t0, t1);
5606 /* We want to shift in zeros for SRL; zero-extend first. */
5607 tcg_gen_ext32u_i64(t0, t0);
5610 tcg_gen_shr_i64(t0, t0, t1);
5614 if (shift_max == 32) {
5615 tcg_gen_ext32s_i64(t0, t0);
5618 /* Shifts larger than MAX produce zero. */
5619 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5620 tcg_gen_neg_i64(t1, t1);
5621 tcg_gen_and_i64(t0, t0, t1);
5627 TCGv_i64 t2 = tcg_temp_new_i64();
5628 TCGLabel *lab = gen_new_label();
5630 tcg_gen_mov_i64(t2, t0);
5631 tcg_gen_add_i64(t0, t1, t2);
5632 if (opc == OPC_ADD_CP2) {
5633 tcg_gen_ext32s_i64(t0, t0);
5635 tcg_gen_xor_i64(t1, t1, t2);
5636 tcg_gen_xor_i64(t2, t2, t0);
5637 tcg_gen_andc_i64(t1, t2, t1);
5638 tcg_temp_free_i64(t2);
5639 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5640 generate_exception(ctx, EXCP_OVERFLOW);
5648 TCGv_i64 t2 = tcg_temp_new_i64();
5649 TCGLabel *lab = gen_new_label();
5651 tcg_gen_mov_i64(t2, t0);
5652 tcg_gen_sub_i64(t0, t1, t2);
5653 if (opc == OPC_SUB_CP2) {
5654 tcg_gen_ext32s_i64(t0, t0);
5656 tcg_gen_xor_i64(t1, t1, t2);
5657 tcg_gen_xor_i64(t2, t2, t0);
5658 tcg_gen_and_i64(t1, t1, t2);
5659 tcg_temp_free_i64(t2);
5660 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5661 generate_exception(ctx, EXCP_OVERFLOW);
5667 tcg_gen_ext32u_i64(t0, t0);
5668 tcg_gen_ext32u_i64(t1, t1);
5669 tcg_gen_mul_i64(t0, t0, t1);
5678 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5679 FD field is the CC field? */
5681 MIPS_INVAL("loongson_cp2");
5682 generate_exception_end(ctx, EXCP_RI);
5689 gen_store_fpr64(ctx, t0, rd);
5691 tcg_temp_free_i64(t0);
5692 tcg_temp_free_i64(t1);
5696 static void gen_trap (DisasContext *ctx, uint32_t opc,
5697 int rs, int rt, int16_t imm)
5700 TCGv t0 = tcg_temp_new();
5701 TCGv t1 = tcg_temp_new();
5704 /* Load needed operands */
5712 /* Compare two registers */
5714 gen_load_gpr(t0, rs);
5715 gen_load_gpr(t1, rt);
5725 /* Compare register to immediate */
5726 if (rs != 0 || imm != 0) {
5727 gen_load_gpr(t0, rs);
5728 tcg_gen_movi_tl(t1, (int32_t)imm);
5735 case OPC_TEQ: /* rs == rs */
5736 case OPC_TEQI: /* r0 == 0 */
5737 case OPC_TGE: /* rs >= rs */
5738 case OPC_TGEI: /* r0 >= 0 */
5739 case OPC_TGEU: /* rs >= rs unsigned */
5740 case OPC_TGEIU: /* r0 >= 0 unsigned */
5742 generate_exception_end(ctx, EXCP_TRAP);
5744 case OPC_TLT: /* rs < rs */
5745 case OPC_TLTI: /* r0 < 0 */
5746 case OPC_TLTU: /* rs < rs unsigned */
5747 case OPC_TLTIU: /* r0 < 0 unsigned */
5748 case OPC_TNE: /* rs != rs */
5749 case OPC_TNEI: /* r0 != 0 */
5750 /* Never trap: treat as NOP. */
5754 TCGLabel *l1 = gen_new_label();
5759 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5763 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5767 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5771 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5775 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5779 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5782 generate_exception(ctx, EXCP_TRAP);
5789 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5791 if (unlikely(ctx->base.singlestep_enabled)) {
5795 #ifndef CONFIG_USER_ONLY
5796 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5802 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5804 if (use_goto_tb(ctx, dest)) {
5807 tcg_gen_exit_tb(ctx->base.tb, n);
5810 if (ctx->base.singlestep_enabled) {
5811 save_cpu_state(ctx, 0);
5812 gen_helper_raise_exception_debug(cpu_env);
5814 tcg_gen_lookup_and_goto_ptr();
5818 /* Branches (before delay slot) */
5819 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5821 int rs, int rt, int32_t offset,
5824 target_ulong btgt = -1;
5826 int bcond_compute = 0;
5827 TCGv t0 = tcg_temp_new();
5828 TCGv t1 = tcg_temp_new();
5830 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5831 #ifdef MIPS_DEBUG_DISAS
5832 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5833 TARGET_FMT_lx "\n", ctx->base.pc_next);
5835 generate_exception_end(ctx, EXCP_RI);
5839 /* Load needed operands */
5845 /* Compare two registers */
5847 gen_load_gpr(t0, rs);
5848 gen_load_gpr(t1, rt);
5851 btgt = ctx->base.pc_next + insn_bytes + offset;
5865 /* Compare to zero */
5867 gen_load_gpr(t0, rs);
5870 btgt = ctx->base.pc_next + insn_bytes + offset;
5873 #if defined(TARGET_MIPS64)
5875 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5877 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5880 btgt = ctx->base.pc_next + insn_bytes + offset;
5885 /* Jump to immediate */
5886 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5891 /* Jump to register */
5892 if (offset != 0 && offset != 16) {
5893 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5894 others are reserved. */
5895 MIPS_INVAL("jump hint");
5896 generate_exception_end(ctx, EXCP_RI);
5899 gen_load_gpr(btarget, rs);
5902 MIPS_INVAL("branch/jump");
5903 generate_exception_end(ctx, EXCP_RI);
5906 if (bcond_compute == 0) {
5907 /* No condition to be computed */
5909 case OPC_BEQ: /* rx == rx */
5910 case OPC_BEQL: /* rx == rx likely */
5911 case OPC_BGEZ: /* 0 >= 0 */
5912 case OPC_BGEZL: /* 0 >= 0 likely */
5913 case OPC_BLEZ: /* 0 <= 0 */
5914 case OPC_BLEZL: /* 0 <= 0 likely */
5916 ctx->hflags |= MIPS_HFLAG_B;
5918 case OPC_BGEZAL: /* 0 >= 0 */
5919 case OPC_BGEZALL: /* 0 >= 0 likely */
5920 /* Always take and link */
5922 ctx->hflags |= MIPS_HFLAG_B;
5924 case OPC_BNE: /* rx != rx */
5925 case OPC_BGTZ: /* 0 > 0 */
5926 case OPC_BLTZ: /* 0 < 0 */
5929 case OPC_BLTZAL: /* 0 < 0 */
5930 /* Handle as an unconditional branch to get correct delay
5933 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5934 ctx->hflags |= MIPS_HFLAG_B;
5936 case OPC_BLTZALL: /* 0 < 0 likely */
5937 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5938 /* Skip the instruction in the delay slot */
5939 ctx->base.pc_next += 4;
5941 case OPC_BNEL: /* rx != rx likely */
5942 case OPC_BGTZL: /* 0 > 0 likely */
5943 case OPC_BLTZL: /* 0 < 0 likely */
5944 /* Skip the instruction in the delay slot */
5945 ctx->base.pc_next += 4;
5948 ctx->hflags |= MIPS_HFLAG_B;
5951 ctx->hflags |= MIPS_HFLAG_BX;
5955 ctx->hflags |= MIPS_HFLAG_B;
5958 ctx->hflags |= MIPS_HFLAG_BR;
5962 ctx->hflags |= MIPS_HFLAG_BR;
5965 MIPS_INVAL("branch/jump");
5966 generate_exception_end(ctx, EXCP_RI);
5972 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5975 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5978 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5981 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5984 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5987 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5990 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5994 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5998 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6001 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6004 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6007 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6010 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6013 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6016 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6018 #if defined(TARGET_MIPS64)
6020 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6024 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6027 ctx->hflags |= MIPS_HFLAG_BC;
6030 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6033 ctx->hflags |= MIPS_HFLAG_BL;
6036 MIPS_INVAL("conditional branch/jump");
6037 generate_exception_end(ctx, EXCP_RI);
6042 ctx->btarget = btgt;
6044 switch (delayslot_size) {
6046 ctx->hflags |= MIPS_HFLAG_BDS16;
6049 ctx->hflags |= MIPS_HFLAG_BDS32;
6054 int post_delay = insn_bytes + delayslot_size;
6055 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6057 tcg_gen_movi_tl(cpu_gpr[blink],
6058 ctx->base.pc_next + post_delay + lowbit);
6062 if (insn_bytes == 2)
6063 ctx->hflags |= MIPS_HFLAG_B16;
6069 /* nanoMIPS Branches */
6070 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6072 int rs, int rt, int32_t offset)
6074 target_ulong btgt = -1;
6075 int bcond_compute = 0;
6076 TCGv t0 = tcg_temp_new();
6077 TCGv t1 = tcg_temp_new();
6079 /* Load needed operands */
6083 /* Compare two registers */
6085 gen_load_gpr(t0, rs);
6086 gen_load_gpr(t1, rt);
6089 btgt = ctx->base.pc_next + insn_bytes + offset;
6092 /* Compare to zero */
6094 gen_load_gpr(t0, rs);
6097 btgt = ctx->base.pc_next + insn_bytes + offset;
6100 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6102 btgt = ctx->base.pc_next + insn_bytes + offset;
6106 /* Jump to register */
6107 if (offset != 0 && offset != 16) {
6108 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6109 others are reserved. */
6110 MIPS_INVAL("jump hint");
6111 generate_exception_end(ctx, EXCP_RI);
6114 gen_load_gpr(btarget, rs);
6117 MIPS_INVAL("branch/jump");
6118 generate_exception_end(ctx, EXCP_RI);
6121 if (bcond_compute == 0) {
6122 /* No condition to be computed */
6124 case OPC_BEQ: /* rx == rx */
6126 ctx->hflags |= MIPS_HFLAG_B;
6128 case OPC_BGEZAL: /* 0 >= 0 */
6129 /* Always take and link */
6130 tcg_gen_movi_tl(cpu_gpr[31],
6131 ctx->base.pc_next + insn_bytes);
6132 ctx->hflags |= MIPS_HFLAG_B;
6134 case OPC_BNE: /* rx != rx */
6135 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6136 /* Skip the instruction in the delay slot */
6137 ctx->base.pc_next += 4;
6140 ctx->hflags |= MIPS_HFLAG_BR;
6144 tcg_gen_movi_tl(cpu_gpr[rt],
6145 ctx->base.pc_next + insn_bytes);
6147 ctx->hflags |= MIPS_HFLAG_BR;
6150 MIPS_INVAL("branch/jump");
6151 generate_exception_end(ctx, EXCP_RI);
6157 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6160 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6163 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6164 tcg_gen_movi_tl(cpu_gpr[31],
6165 ctx->base.pc_next + insn_bytes);
6168 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6170 ctx->hflags |= MIPS_HFLAG_BC;
6173 MIPS_INVAL("conditional branch/jump");
6174 generate_exception_end(ctx, EXCP_RI);
6179 ctx->btarget = btgt;
6182 if (insn_bytes == 2) {
6183 ctx->hflags |= MIPS_HFLAG_B16;
6190 /* special3 bitfield operations */
6191 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
6192 int rs, int lsb, int msb)
6194 TCGv t0 = tcg_temp_new();
6195 TCGv t1 = tcg_temp_new();
6197 gen_load_gpr(t1, rs);
6200 if (lsb + msb > 31) {
6204 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6206 /* The two checks together imply that lsb == 0,
6207 so this is a simple sign-extension. */
6208 tcg_gen_ext32s_tl(t0, t1);
6211 #if defined(TARGET_MIPS64)
6220 if (lsb + msb > 63) {
6223 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6230 gen_load_gpr(t0, rt);
6231 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6232 tcg_gen_ext32s_tl(t0, t0);
6234 #if defined(TARGET_MIPS64)
6245 gen_load_gpr(t0, rt);
6246 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6251 MIPS_INVAL("bitops");
6252 generate_exception_end(ctx, EXCP_RI);
6257 gen_store_gpr(t0, rt);
6262 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6267 /* If no destination, treat it as a NOP. */
6271 t0 = tcg_temp_new();
6272 gen_load_gpr(t0, rt);
6276 TCGv t1 = tcg_temp_new();
6277 TCGv t2 = tcg_const_tl(0x00FF00FF);
6279 tcg_gen_shri_tl(t1, t0, 8);
6280 tcg_gen_and_tl(t1, t1, t2);
6281 tcg_gen_and_tl(t0, t0, t2);
6282 tcg_gen_shli_tl(t0, t0, 8);
6283 tcg_gen_or_tl(t0, t0, t1);
6286 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6290 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6293 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6295 #if defined(TARGET_MIPS64)
6298 TCGv t1 = tcg_temp_new();
6299 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6301 tcg_gen_shri_tl(t1, t0, 8);
6302 tcg_gen_and_tl(t1, t1, t2);
6303 tcg_gen_and_tl(t0, t0, t2);
6304 tcg_gen_shli_tl(t0, t0, 8);
6305 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6312 TCGv t1 = tcg_temp_new();
6313 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6315 tcg_gen_shri_tl(t1, t0, 16);
6316 tcg_gen_and_tl(t1, t1, t2);
6317 tcg_gen_and_tl(t0, t0, t2);
6318 tcg_gen_shli_tl(t0, t0, 16);
6319 tcg_gen_or_tl(t0, t0, t1);
6320 tcg_gen_shri_tl(t1, t0, 32);
6321 tcg_gen_shli_tl(t0, t0, 32);
6322 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6329 MIPS_INVAL("bsfhl");
6330 generate_exception_end(ctx, EXCP_RI);
6337 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6346 t0 = tcg_temp_new();
6347 t1 = tcg_temp_new();
6348 gen_load_gpr(t0, rs);
6349 gen_load_gpr(t1, rt);
6350 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6351 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6352 if (opc == OPC_LSA) {
6353 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6362 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6370 t0 = tcg_temp_new();
6371 if (bits == 0 || bits == wordsz) {
6373 gen_load_gpr(t0, rt);
6375 gen_load_gpr(t0, rs);
6379 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6381 #if defined(TARGET_MIPS64)
6383 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6388 TCGv t1 = tcg_temp_new();
6389 gen_load_gpr(t0, rt);
6390 gen_load_gpr(t1, rs);
6394 TCGv_i64 t2 = tcg_temp_new_i64();
6395 tcg_gen_concat_tl_i64(t2, t1, t0);
6396 tcg_gen_shri_i64(t2, t2, 32 - bits);
6397 gen_move_low32(cpu_gpr[rd], t2);
6398 tcg_temp_free_i64(t2);
6401 #if defined(TARGET_MIPS64)
6403 tcg_gen_shli_tl(t0, t0, bits);
6404 tcg_gen_shri_tl(t1, t1, 64 - bits);
6405 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6415 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6418 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6421 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6424 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6427 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6434 t0 = tcg_temp_new();
6435 gen_load_gpr(t0, rt);
6438 gen_helper_bitswap(cpu_gpr[rd], t0);
6440 #if defined(TARGET_MIPS64)
6442 gen_helper_dbitswap(cpu_gpr[rd], t0);
6449 #ifndef CONFIG_USER_ONLY
6450 /* CP0 (MMU and control) */
6451 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6453 TCGv_i64 t0 = tcg_temp_new_i64();
6454 TCGv_i64 t1 = tcg_temp_new_i64();
6456 tcg_gen_ext_tl_i64(t0, arg);
6457 tcg_gen_ld_i64(t1, cpu_env, off);
6458 #if defined(TARGET_MIPS64)
6459 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6461 tcg_gen_concat32_i64(t1, t1, t0);
6463 tcg_gen_st_i64(t1, cpu_env, off);
6464 tcg_temp_free_i64(t1);
6465 tcg_temp_free_i64(t0);
6468 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6470 TCGv_i64 t0 = tcg_temp_new_i64();
6471 TCGv_i64 t1 = tcg_temp_new_i64();
6473 tcg_gen_ext_tl_i64(t0, arg);
6474 tcg_gen_ld_i64(t1, cpu_env, off);
6475 tcg_gen_concat32_i64(t1, t1, t0);
6476 tcg_gen_st_i64(t1, cpu_env, off);
6477 tcg_temp_free_i64(t1);
6478 tcg_temp_free_i64(t0);
6481 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6483 TCGv_i64 t0 = tcg_temp_new_i64();
6485 tcg_gen_ld_i64(t0, cpu_env, off);
6486 #if defined(TARGET_MIPS64)
6487 tcg_gen_shri_i64(t0, t0, 30);
6489 tcg_gen_shri_i64(t0, t0, 32);
6491 gen_move_low32(arg, t0);
6492 tcg_temp_free_i64(t0);
6495 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6497 TCGv_i64 t0 = tcg_temp_new_i64();
6499 tcg_gen_ld_i64(t0, cpu_env, off);
6500 tcg_gen_shri_i64(t0, t0, 32 + shift);
6501 gen_move_low32(arg, t0);
6502 tcg_temp_free_i64(t0);
6505 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6507 TCGv_i32 t0 = tcg_temp_new_i32();
6509 tcg_gen_ld_i32(t0, cpu_env, off);
6510 tcg_gen_ext_i32_tl(arg, t0);
6511 tcg_temp_free_i32(t0);
6514 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6516 tcg_gen_ld_tl(arg, cpu_env, off);
6517 tcg_gen_ext32s_tl(arg, arg);
6520 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6522 TCGv_i32 t0 = tcg_temp_new_i32();
6524 tcg_gen_trunc_tl_i32(t0, arg);
6525 tcg_gen_st_i32(t0, cpu_env, off);
6526 tcg_temp_free_i32(t0);
6529 #define CP0_CHECK(c) \
6532 goto cp0_unimplemented; \
6536 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6538 const char *register_name = "invalid";
6541 case CP0_REGISTER_02:
6544 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6545 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6546 register_name = "EntryLo0";
6549 goto cp0_unimplemented;
6552 case CP0_REGISTER_03:
6555 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6556 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6557 register_name = "EntryLo1";
6560 goto cp0_unimplemented;
6563 case CP0_REGISTER_09:
6566 CP0_CHECK(ctx->saar);
6567 gen_helper_mfhc0_saar(arg, cpu_env);
6568 register_name = "SAAR";
6571 goto cp0_unimplemented;
6574 case CP0_REGISTER_17:
6577 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
6578 ctx->CP0_LLAddr_shift);
6579 register_name = "LLAddr";
6582 CP0_CHECK(ctx->mrp);
6583 gen_helper_mfhc0_maar(arg, cpu_env);
6584 register_name = "MAAR";
6587 goto cp0_unimplemented;
6590 case CP0_REGISTER_28:
6596 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6597 register_name = "TagLo";
6600 goto cp0_unimplemented;
6604 goto cp0_unimplemented;
6606 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6610 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6611 register_name, reg, sel);
6612 tcg_gen_movi_tl(arg, 0);
6615 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6617 const char *register_name = "invalid";
6618 uint64_t mask = ctx->PAMask >> 36;
6621 case CP0_REGISTER_02:
6624 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6625 tcg_gen_andi_tl(arg, arg, mask);
6626 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6627 register_name = "EntryLo0";
6630 goto cp0_unimplemented;
6633 case CP0_REGISTER_03:
6636 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6637 tcg_gen_andi_tl(arg, arg, mask);
6638 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6639 register_name = "EntryLo1";
6642 goto cp0_unimplemented;
6645 case CP0_REGISTER_09:
6648 CP0_CHECK(ctx->saar);
6649 gen_helper_mthc0_saar(cpu_env, arg);
6650 register_name = "SAAR";
6653 goto cp0_unimplemented;
6655 case CP0_REGISTER_17:
6658 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6659 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6660 relevant for modern MIPS cores supporting MTHC0, therefore
6661 treating MTHC0 to LLAddr as NOP. */
6662 register_name = "LLAddr";
6665 CP0_CHECK(ctx->mrp);
6666 gen_helper_mthc0_maar(cpu_env, arg);
6667 register_name = "MAAR";
6670 goto cp0_unimplemented;
6673 case CP0_REGISTER_28:
6679 tcg_gen_andi_tl(arg, arg, mask);
6680 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6681 register_name = "TagLo";
6684 goto cp0_unimplemented;
6688 goto cp0_unimplemented;
6690 trace_mips_translate_c0("mthc0", register_name, reg, sel);
6693 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6694 register_name, reg, sel);
6697 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6699 if (ctx->insn_flags & ISA_MIPS32R6) {
6700 tcg_gen_movi_tl(arg, 0);
6702 tcg_gen_movi_tl(arg, ~0);
6706 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6708 const char *register_name = "invalid";
6711 check_insn(ctx, ISA_MIPS32);
6714 case CP0_REGISTER_00:
6717 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6718 register_name = "Index";
6721 CP0_CHECK(ctx->insn_flags & ASE_MT);
6722 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6723 register_name = "MVPControl";
6726 CP0_CHECK(ctx->insn_flags & ASE_MT);
6727 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6728 register_name = "MVPConf0";
6731 CP0_CHECK(ctx->insn_flags & ASE_MT);
6732 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6733 register_name = "MVPConf1";
6737 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6738 register_name = "VPControl";
6741 goto cp0_unimplemented;
6744 case CP0_REGISTER_01:
6747 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6748 gen_helper_mfc0_random(arg, cpu_env);
6749 register_name = "Random";
6752 CP0_CHECK(ctx->insn_flags & ASE_MT);
6753 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6754 register_name = "VPEControl";
6757 CP0_CHECK(ctx->insn_flags & ASE_MT);
6758 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6759 register_name = "VPEConf0";
6762 CP0_CHECK(ctx->insn_flags & ASE_MT);
6763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6764 register_name = "VPEConf1";
6767 CP0_CHECK(ctx->insn_flags & ASE_MT);
6768 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6769 register_name = "YQMask";
6772 CP0_CHECK(ctx->insn_flags & ASE_MT);
6773 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6774 register_name = "VPESchedule";
6777 CP0_CHECK(ctx->insn_flags & ASE_MT);
6778 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6779 register_name = "VPEScheFBack";
6782 CP0_CHECK(ctx->insn_flags & ASE_MT);
6783 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6784 register_name = "VPEOpt";
6787 goto cp0_unimplemented;
6790 case CP0_REGISTER_02:
6794 TCGv_i64 tmp = tcg_temp_new_i64();
6795 tcg_gen_ld_i64(tmp, cpu_env,
6796 offsetof(CPUMIPSState, CP0_EntryLo0));
6797 #if defined(TARGET_MIPS64)
6799 /* Move RI/XI fields to bits 31:30 */
6800 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6801 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6804 gen_move_low32(arg, tmp);
6805 tcg_temp_free_i64(tmp);
6807 register_name = "EntryLo0";
6810 CP0_CHECK(ctx->insn_flags & ASE_MT);
6811 gen_helper_mfc0_tcstatus(arg, cpu_env);
6812 register_name = "TCStatus";
6815 CP0_CHECK(ctx->insn_flags & ASE_MT);
6816 gen_helper_mfc0_tcbind(arg, cpu_env);
6817 register_name = "TCBind";
6820 CP0_CHECK(ctx->insn_flags & ASE_MT);
6821 gen_helper_mfc0_tcrestart(arg, cpu_env);
6822 register_name = "TCRestart";
6825 CP0_CHECK(ctx->insn_flags & ASE_MT);
6826 gen_helper_mfc0_tchalt(arg, cpu_env);
6827 register_name = "TCHalt";
6830 CP0_CHECK(ctx->insn_flags & ASE_MT);
6831 gen_helper_mfc0_tccontext(arg, cpu_env);
6832 register_name = "TCContext";
6835 CP0_CHECK(ctx->insn_flags & ASE_MT);
6836 gen_helper_mfc0_tcschedule(arg, cpu_env);
6837 register_name = "TCSchedule";
6840 CP0_CHECK(ctx->insn_flags & ASE_MT);
6841 gen_helper_mfc0_tcschefback(arg, cpu_env);
6842 register_name = "TCScheFBack";
6845 goto cp0_unimplemented;
6848 case CP0_REGISTER_03:
6852 TCGv_i64 tmp = tcg_temp_new_i64();
6853 tcg_gen_ld_i64(tmp, cpu_env,
6854 offsetof(CPUMIPSState, CP0_EntryLo1));
6855 #if defined(TARGET_MIPS64)
6857 /* Move RI/XI fields to bits 31:30 */
6858 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6859 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6862 gen_move_low32(arg, tmp);
6863 tcg_temp_free_i64(tmp);
6865 register_name = "EntryLo1";
6869 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6870 register_name = "GlobalNumber";
6873 goto cp0_unimplemented;
6876 case CP0_REGISTER_04:
6879 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6880 tcg_gen_ext32s_tl(arg, arg);
6881 register_name = "Context";
6884 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6885 register_name = "ContextConfig";
6886 goto cp0_unimplemented;
6888 CP0_CHECK(ctx->ulri);
6889 tcg_gen_ld_tl(arg, cpu_env,
6890 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6891 tcg_gen_ext32s_tl(arg, arg);
6892 register_name = "UserLocal";
6895 goto cp0_unimplemented;
6898 case CP0_REGISTER_05:
6901 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6902 register_name = "PageMask";
6905 check_insn(ctx, ISA_MIPS32R2);
6906 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6907 register_name = "PageGrain";
6911 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6912 tcg_gen_ext32s_tl(arg, arg);
6913 register_name = "SegCtl0";
6917 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6918 tcg_gen_ext32s_tl(arg, arg);
6919 register_name = "SegCtl1";
6923 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6924 tcg_gen_ext32s_tl(arg, arg);
6925 register_name = "SegCtl2";
6929 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6930 register_name = "PWBase";
6934 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6935 register_name = "PWField";
6939 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6940 register_name = "PWSize";
6943 goto cp0_unimplemented;
6946 case CP0_REGISTER_06:
6949 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6950 register_name = "Wired";
6953 check_insn(ctx, ISA_MIPS32R2);
6954 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6955 register_name = "SRSConf0";
6958 check_insn(ctx, ISA_MIPS32R2);
6959 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6960 register_name = "SRSConf1";
6963 check_insn(ctx, ISA_MIPS32R2);
6964 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6965 register_name = "SRSConf2";
6968 check_insn(ctx, ISA_MIPS32R2);
6969 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6970 register_name = "SRSConf3";
6973 check_insn(ctx, ISA_MIPS32R2);
6974 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6975 register_name = "SRSConf4";
6979 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6980 register_name = "PWCtl";
6983 goto cp0_unimplemented;
6986 case CP0_REGISTER_07:
6989 check_insn(ctx, ISA_MIPS32R2);
6990 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6991 register_name = "HWREna";
6994 goto cp0_unimplemented;
6997 case CP0_REGISTER_08:
7000 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7001 tcg_gen_ext32s_tl(arg, arg);
7002 register_name = "BadVAddr";
7006 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7007 register_name = "BadInstr";
7011 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7012 register_name = "BadInstrP";
7016 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7017 tcg_gen_andi_tl(arg, arg, ~0xffff);
7018 register_name = "BadInstrX";
7021 goto cp0_unimplemented;
7024 case CP0_REGISTER_09:
7027 /* Mark as an IO operation because we read the time. */
7028 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7031 gen_helper_mfc0_count(arg, cpu_env);
7032 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7035 /* Break the TB to be able to take timer interrupts immediately
7036 after reading count. DISAS_STOP isn't sufficient, we need to
7037 ensure we break completely out of translated code. */
7038 gen_save_pc(ctx->base.pc_next + 4);
7039 ctx->base.is_jmp = DISAS_EXIT;
7040 register_name = "Count";
7043 CP0_CHECK(ctx->saar);
7044 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7045 register_name = "SAARI";
7048 CP0_CHECK(ctx->saar);
7049 gen_helper_mfc0_saar(arg, cpu_env);
7050 register_name = "SAAR";
7053 goto cp0_unimplemented;
7056 case CP0_REGISTER_10:
7059 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7060 tcg_gen_ext32s_tl(arg, arg);
7061 register_name = "EntryHi";
7064 goto cp0_unimplemented;
7067 case CP0_REGISTER_11:
7070 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7071 register_name = "Compare";
7073 /* 6,7 are implementation dependent */
7075 goto cp0_unimplemented;
7078 case CP0_REGISTER_12:
7081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7082 register_name = "Status";
7085 check_insn(ctx, ISA_MIPS32R2);
7086 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7087 register_name = "IntCtl";
7090 check_insn(ctx, ISA_MIPS32R2);
7091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7092 register_name = "SRSCtl";
7095 check_insn(ctx, ISA_MIPS32R2);
7096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7097 register_name = "SRSMap";
7100 goto cp0_unimplemented;
7103 case CP0_REGISTER_13:
7106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7107 register_name = "Cause";
7110 goto cp0_unimplemented;
7113 case CP0_REGISTER_14:
7116 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7117 tcg_gen_ext32s_tl(arg, arg);
7118 register_name = "EPC";
7121 goto cp0_unimplemented;
7124 case CP0_REGISTER_15:
7127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7128 register_name = "PRid";
7131 check_insn(ctx, ISA_MIPS32R2);
7132 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7133 tcg_gen_ext32s_tl(arg, arg);
7134 register_name = "EBase";
7137 check_insn(ctx, ISA_MIPS32R2);
7138 CP0_CHECK(ctx->cmgcr);
7139 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7140 tcg_gen_ext32s_tl(arg, arg);
7141 register_name = "CMGCRBase";
7144 goto cp0_unimplemented;
7147 case CP0_REGISTER_16:
7150 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7151 register_name = "Config";
7154 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7155 register_name = "Config1";
7158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7159 register_name = "Config2";
7162 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7163 register_name = "Config3";
7166 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7167 register_name = "Config4";
7170 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7171 register_name = "Config5";
7173 /* 6,7 are implementation dependent */
7175 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7176 register_name = "Config6";
7179 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7180 register_name = "Config7";
7183 goto cp0_unimplemented;
7186 case CP0_REGISTER_17:
7189 gen_helper_mfc0_lladdr(arg, cpu_env);
7190 register_name = "LLAddr";
7193 CP0_CHECK(ctx->mrp);
7194 gen_helper_mfc0_maar(arg, cpu_env);
7195 register_name = "MAAR";
7198 CP0_CHECK(ctx->mrp);
7199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7200 register_name = "MAARI";
7203 goto cp0_unimplemented;
7206 case CP0_REGISTER_18:
7216 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7217 gen_helper_1e0i(mfc0_watchlo, arg, sel);
7218 register_name = "WatchLo";
7221 goto cp0_unimplemented;
7224 case CP0_REGISTER_19:
7234 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7235 gen_helper_1e0i(mfc0_watchhi, arg, sel);
7236 register_name = "WatchHi";
7239 goto cp0_unimplemented;
7242 case CP0_REGISTER_20:
7245 #if defined(TARGET_MIPS64)
7246 check_insn(ctx, ISA_MIPS3);
7247 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7248 tcg_gen_ext32s_tl(arg, arg);
7249 register_name = "XContext";
7253 goto cp0_unimplemented;
7256 case CP0_REGISTER_21:
7257 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7258 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7262 register_name = "Framemask";
7265 goto cp0_unimplemented;
7268 case CP0_REGISTER_22:
7269 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7270 register_name = "'Diagnostic"; /* implementation dependent */
7272 case CP0_REGISTER_23:
7275 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7276 register_name = "Debug";
7279 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7280 register_name = "TraceControl";
7281 goto cp0_unimplemented;
7283 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7284 register_name = "TraceControl2";
7285 goto cp0_unimplemented;
7287 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7288 register_name = "UserTraceData";
7289 goto cp0_unimplemented;
7291 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7292 register_name = "TraceBPC";
7293 goto cp0_unimplemented;
7295 goto cp0_unimplemented;
7298 case CP0_REGISTER_24:
7302 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7303 tcg_gen_ext32s_tl(arg, arg);
7304 register_name = "DEPC";
7307 goto cp0_unimplemented;
7310 case CP0_REGISTER_25:
7313 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7314 register_name = "Performance0";
7317 // gen_helper_mfc0_performance1(arg);
7318 register_name = "Performance1";
7319 goto cp0_unimplemented;
7321 // gen_helper_mfc0_performance2(arg);
7322 register_name = "Performance2";
7323 goto cp0_unimplemented;
7325 // gen_helper_mfc0_performance3(arg);
7326 register_name = "Performance3";
7327 goto cp0_unimplemented;
7329 // gen_helper_mfc0_performance4(arg);
7330 register_name = "Performance4";
7331 goto cp0_unimplemented;
7333 // gen_helper_mfc0_performance5(arg);
7334 register_name = "Performance5";
7335 goto cp0_unimplemented;
7337 // gen_helper_mfc0_performance6(arg);
7338 register_name = "Performance6";
7339 goto cp0_unimplemented;
7341 // gen_helper_mfc0_performance7(arg);
7342 register_name = "Performance7";
7343 goto cp0_unimplemented;
7345 goto cp0_unimplemented;
7348 case CP0_REGISTER_26:
7351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7352 register_name = "ErrCtl";
7355 goto cp0_unimplemented;
7358 case CP0_REGISTER_27:
7364 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7365 register_name = "CacheErr";
7368 goto cp0_unimplemented;
7371 case CP0_REGISTER_28:
7378 TCGv_i64 tmp = tcg_temp_new_i64();
7379 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7380 gen_move_low32(arg, tmp);
7381 tcg_temp_free_i64(tmp);
7383 register_name = "TagLo";
7389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7390 register_name = "DataLo";
7393 goto cp0_unimplemented;
7396 case CP0_REGISTER_29:
7402 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7403 register_name = "TagHi";
7409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7410 register_name = "DataHi";
7413 goto cp0_unimplemented;
7416 case CP0_REGISTER_30:
7419 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7420 tcg_gen_ext32s_tl(arg, arg);
7421 register_name = "ErrorEPC";
7424 goto cp0_unimplemented;
7427 case CP0_REGISTER_31:
7431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7432 register_name = "DESAVE";
7440 CP0_CHECK(ctx->kscrexist & (1 << sel));
7441 tcg_gen_ld_tl(arg, cpu_env,
7442 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7443 tcg_gen_ext32s_tl(arg, arg);
7444 register_name = "KScratch";
7447 goto cp0_unimplemented;
7451 goto cp0_unimplemented;
7453 trace_mips_translate_c0("mfc0", register_name, reg, sel);
7457 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7458 register_name, reg, sel);
7459 gen_mfc0_unimplemented(ctx, arg);
7462 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7464 const char *register_name = "invalid";
7467 check_insn(ctx, ISA_MIPS32);
7469 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7474 case CP0_REGISTER_00:
7477 gen_helper_mtc0_index(cpu_env, arg);
7478 register_name = "Index";
7481 CP0_CHECK(ctx->insn_flags & ASE_MT);
7482 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7483 register_name = "MVPControl";
7486 CP0_CHECK(ctx->insn_flags & ASE_MT);
7488 register_name = "MVPConf0";
7491 CP0_CHECK(ctx->insn_flags & ASE_MT);
7493 register_name = "MVPConf1";
7498 register_name = "VPControl";
7501 goto cp0_unimplemented;
7504 case CP0_REGISTER_01:
7508 register_name = "Random";
7511 CP0_CHECK(ctx->insn_flags & ASE_MT);
7512 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7513 register_name = "VPEControl";
7516 CP0_CHECK(ctx->insn_flags & ASE_MT);
7517 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7518 register_name = "VPEConf0";
7521 CP0_CHECK(ctx->insn_flags & ASE_MT);
7522 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7523 register_name = "VPEConf1";
7526 CP0_CHECK(ctx->insn_flags & ASE_MT);
7527 gen_helper_mtc0_yqmask(cpu_env, arg);
7528 register_name = "YQMask";
7531 CP0_CHECK(ctx->insn_flags & ASE_MT);
7532 tcg_gen_st_tl(arg, cpu_env,
7533 offsetof(CPUMIPSState, CP0_VPESchedule));
7534 register_name = "VPESchedule";
7537 CP0_CHECK(ctx->insn_flags & ASE_MT);
7538 tcg_gen_st_tl(arg, cpu_env,
7539 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7540 register_name = "VPEScheFBack";
7543 CP0_CHECK(ctx->insn_flags & ASE_MT);
7544 gen_helper_mtc0_vpeopt(cpu_env, arg);
7545 register_name = "VPEOpt";
7548 goto cp0_unimplemented;
7551 case CP0_REGISTER_02:
7554 gen_helper_mtc0_entrylo0(cpu_env, arg);
7555 register_name = "EntryLo0";
7558 CP0_CHECK(ctx->insn_flags & ASE_MT);
7559 gen_helper_mtc0_tcstatus(cpu_env, arg);
7560 register_name = "TCStatus";
7563 CP0_CHECK(ctx->insn_flags & ASE_MT);
7564 gen_helper_mtc0_tcbind(cpu_env, arg);
7565 register_name = "TCBind";
7568 CP0_CHECK(ctx->insn_flags & ASE_MT);
7569 gen_helper_mtc0_tcrestart(cpu_env, arg);
7570 register_name = "TCRestart";
7573 CP0_CHECK(ctx->insn_flags & ASE_MT);
7574 gen_helper_mtc0_tchalt(cpu_env, arg);
7575 register_name = "TCHalt";
7578 CP0_CHECK(ctx->insn_flags & ASE_MT);
7579 gen_helper_mtc0_tccontext(cpu_env, arg);
7580 register_name = "TCContext";
7583 CP0_CHECK(ctx->insn_flags & ASE_MT);
7584 gen_helper_mtc0_tcschedule(cpu_env, arg);
7585 register_name = "TCSchedule";
7588 CP0_CHECK(ctx->insn_flags & ASE_MT);
7589 gen_helper_mtc0_tcschefback(cpu_env, arg);
7590 register_name = "TCScheFBack";
7593 goto cp0_unimplemented;
7596 case CP0_REGISTER_03:
7599 gen_helper_mtc0_entrylo1(cpu_env, arg);
7600 register_name = "EntryLo1";
7605 register_name = "GlobalNumber";
7608 goto cp0_unimplemented;
7611 case CP0_REGISTER_04:
7614 gen_helper_mtc0_context(cpu_env, arg);
7615 register_name = "Context";
7618 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7619 register_name = "ContextConfig";
7620 goto cp0_unimplemented;
7622 CP0_CHECK(ctx->ulri);
7623 tcg_gen_st_tl(arg, cpu_env,
7624 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7625 register_name = "UserLocal";
7628 goto cp0_unimplemented;
7631 case CP0_REGISTER_05:
7634 gen_helper_mtc0_pagemask(cpu_env, arg);
7635 register_name = "PageMask";
7638 check_insn(ctx, ISA_MIPS32R2);
7639 gen_helper_mtc0_pagegrain(cpu_env, arg);
7640 register_name = "PageGrain";
7641 ctx->base.is_jmp = DISAS_STOP;
7645 gen_helper_mtc0_segctl0(cpu_env, arg);
7646 register_name = "SegCtl0";
7650 gen_helper_mtc0_segctl1(cpu_env, arg);
7651 register_name = "SegCtl1";
7655 gen_helper_mtc0_segctl2(cpu_env, arg);
7656 register_name = "SegCtl2";
7660 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7661 register_name = "PWBase";
7665 gen_helper_mtc0_pwfield(cpu_env, arg);
7666 register_name = "PWField";
7670 gen_helper_mtc0_pwsize(cpu_env, arg);
7671 register_name = "PWSize";
7674 goto cp0_unimplemented;
7677 case CP0_REGISTER_06:
7680 gen_helper_mtc0_wired(cpu_env, arg);
7681 register_name = "Wired";
7684 check_insn(ctx, ISA_MIPS32R2);
7685 gen_helper_mtc0_srsconf0(cpu_env, arg);
7686 register_name = "SRSConf0";
7689 check_insn(ctx, ISA_MIPS32R2);
7690 gen_helper_mtc0_srsconf1(cpu_env, arg);
7691 register_name = "SRSConf1";
7694 check_insn(ctx, ISA_MIPS32R2);
7695 gen_helper_mtc0_srsconf2(cpu_env, arg);
7696 register_name = "SRSConf2";
7699 check_insn(ctx, ISA_MIPS32R2);
7700 gen_helper_mtc0_srsconf3(cpu_env, arg);
7701 register_name = "SRSConf3";
7704 check_insn(ctx, ISA_MIPS32R2);
7705 gen_helper_mtc0_srsconf4(cpu_env, arg);
7706 register_name = "SRSConf4";
7710 gen_helper_mtc0_pwctl(cpu_env, arg);
7711 register_name = "PWCtl";
7714 goto cp0_unimplemented;
7717 case CP0_REGISTER_07:
7720 check_insn(ctx, ISA_MIPS32R2);
7721 gen_helper_mtc0_hwrena(cpu_env, arg);
7722 ctx->base.is_jmp = DISAS_STOP;
7723 register_name = "HWREna";
7726 goto cp0_unimplemented;
7729 case CP0_REGISTER_08:
7733 register_name = "BadVAddr";
7737 register_name = "BadInstr";
7741 register_name = "BadInstrP";
7745 register_name = "BadInstrX";
7748 goto cp0_unimplemented;
7751 case CP0_REGISTER_09:
7754 gen_helper_mtc0_count(cpu_env, arg);
7755 register_name = "Count";
7758 CP0_CHECK(ctx->saar);
7759 gen_helper_mtc0_saari(cpu_env, arg);
7760 register_name = "SAARI";
7763 CP0_CHECK(ctx->saar);
7764 gen_helper_mtc0_saar(cpu_env, arg);
7765 register_name = "SAAR";
7768 goto cp0_unimplemented;
7771 case CP0_REGISTER_10:
7774 gen_helper_mtc0_entryhi(cpu_env, arg);
7775 register_name = "EntryHi";
7778 goto cp0_unimplemented;
7781 case CP0_REGISTER_11:
7784 gen_helper_mtc0_compare(cpu_env, arg);
7785 register_name = "Compare";
7787 /* 6,7 are implementation dependent */
7789 goto cp0_unimplemented;
7792 case CP0_REGISTER_12:
7795 save_cpu_state(ctx, 1);
7796 gen_helper_mtc0_status(cpu_env, arg);
7797 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7798 gen_save_pc(ctx->base.pc_next + 4);
7799 ctx->base.is_jmp = DISAS_EXIT;
7800 register_name = "Status";
7803 check_insn(ctx, ISA_MIPS32R2);
7804 gen_helper_mtc0_intctl(cpu_env, arg);
7805 /* Stop translation as we may have switched the execution mode */
7806 ctx->base.is_jmp = DISAS_STOP;
7807 register_name = "IntCtl";
7810 check_insn(ctx, ISA_MIPS32R2);
7811 gen_helper_mtc0_srsctl(cpu_env, arg);
7812 /* Stop translation as we may have switched the execution mode */
7813 ctx->base.is_jmp = DISAS_STOP;
7814 register_name = "SRSCtl";
7817 check_insn(ctx, ISA_MIPS32R2);
7818 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7819 /* Stop translation as we may have switched the execution mode */
7820 ctx->base.is_jmp = DISAS_STOP;
7821 register_name = "SRSMap";
7824 goto cp0_unimplemented;
7827 case CP0_REGISTER_13:
7830 save_cpu_state(ctx, 1);
7831 gen_helper_mtc0_cause(cpu_env, arg);
7832 /* Stop translation as we may have triggered an interrupt.
7833 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7834 * translated code to check for pending interrupts. */
7835 gen_save_pc(ctx->base.pc_next + 4);
7836 ctx->base.is_jmp = DISAS_EXIT;
7837 register_name = "Cause";
7840 goto cp0_unimplemented;
7843 case CP0_REGISTER_14:
7846 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7847 register_name = "EPC";
7850 goto cp0_unimplemented;
7853 case CP0_REGISTER_15:
7857 register_name = "PRid";
7860 check_insn(ctx, ISA_MIPS32R2);
7861 gen_helper_mtc0_ebase(cpu_env, arg);
7862 register_name = "EBase";
7865 goto cp0_unimplemented;
7868 case CP0_REGISTER_16:
7871 gen_helper_mtc0_config0(cpu_env, arg);
7872 register_name = "Config";
7873 /* Stop translation as we may have switched the execution mode */
7874 ctx->base.is_jmp = DISAS_STOP;
7877 /* ignored, read only */
7878 register_name = "Config1";
7881 gen_helper_mtc0_config2(cpu_env, arg);
7882 register_name = "Config2";
7883 /* Stop translation as we may have switched the execution mode */
7884 ctx->base.is_jmp = DISAS_STOP;
7887 gen_helper_mtc0_config3(cpu_env, arg);
7888 register_name = "Config3";
7889 /* Stop translation as we may have switched the execution mode */
7890 ctx->base.is_jmp = DISAS_STOP;
7893 gen_helper_mtc0_config4(cpu_env, arg);
7894 register_name = "Config4";
7895 ctx->base.is_jmp = DISAS_STOP;
7898 gen_helper_mtc0_config5(cpu_env, arg);
7899 register_name = "Config5";
7900 /* Stop translation as we may have switched the execution mode */
7901 ctx->base.is_jmp = DISAS_STOP;
7903 /* 6,7 are implementation dependent */
7906 register_name = "Config6";
7910 register_name = "Config7";
7913 register_name = "Invalid config selector";
7914 goto cp0_unimplemented;
7917 case CP0_REGISTER_17:
7920 gen_helper_mtc0_lladdr(cpu_env, arg);
7921 register_name = "LLAddr";
7924 CP0_CHECK(ctx->mrp);
7925 gen_helper_mtc0_maar(cpu_env, arg);
7926 register_name = "MAAR";
7929 CP0_CHECK(ctx->mrp);
7930 gen_helper_mtc0_maari(cpu_env, arg);
7931 register_name = "MAARI";
7934 goto cp0_unimplemented;
7937 case CP0_REGISTER_18:
7947 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7948 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7949 register_name = "WatchLo";
7952 goto cp0_unimplemented;
7955 case CP0_REGISTER_19:
7965 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7966 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7967 register_name = "WatchHi";
7970 goto cp0_unimplemented;
7973 case CP0_REGISTER_20:
7976 #if defined(TARGET_MIPS64)
7977 check_insn(ctx, ISA_MIPS3);
7978 gen_helper_mtc0_xcontext(cpu_env, arg);
7979 register_name = "XContext";
7983 goto cp0_unimplemented;
7986 case CP0_REGISTER_21:
7987 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7988 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7991 gen_helper_mtc0_framemask(cpu_env, arg);
7992 register_name = "Framemask";
7995 goto cp0_unimplemented;
7998 case CP0_REGISTER_22:
8000 register_name = "Diagnostic"; /* implementation dependent */
8002 case CP0_REGISTER_23:
8005 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8006 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8007 gen_save_pc(ctx->base.pc_next + 4);
8008 ctx->base.is_jmp = DISAS_EXIT;
8009 register_name = "Debug";
8012 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8013 register_name = "TraceControl";
8014 /* Stop translation as we may have switched the execution mode */
8015 ctx->base.is_jmp = DISAS_STOP;
8016 goto cp0_unimplemented;
8018 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8019 register_name = "TraceControl2";
8020 /* Stop translation as we may have switched the execution mode */
8021 ctx->base.is_jmp = DISAS_STOP;
8022 goto cp0_unimplemented;
8024 /* Stop translation as we may have switched the execution mode */
8025 ctx->base.is_jmp = DISAS_STOP;
8026 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8027 register_name = "UserTraceData";
8028 /* Stop translation as we may have switched the execution mode */
8029 ctx->base.is_jmp = DISAS_STOP;
8030 goto cp0_unimplemented;
8032 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8033 /* Stop translation as we may have switched the execution mode */
8034 ctx->base.is_jmp = DISAS_STOP;
8035 register_name = "TraceBPC";
8036 goto cp0_unimplemented;
8038 goto cp0_unimplemented;
8041 case CP0_REGISTER_24:
8045 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8046 register_name = "DEPC";
8049 goto cp0_unimplemented;
8052 case CP0_REGISTER_25:
8055 gen_helper_mtc0_performance0(cpu_env, arg);
8056 register_name = "Performance0";
8059 // gen_helper_mtc0_performance1(arg);
8060 register_name = "Performance1";
8061 goto cp0_unimplemented;
8063 // gen_helper_mtc0_performance2(arg);
8064 register_name = "Performance2";
8065 goto cp0_unimplemented;
8067 // gen_helper_mtc0_performance3(arg);
8068 register_name = "Performance3";
8069 goto cp0_unimplemented;
8071 // gen_helper_mtc0_performance4(arg);
8072 register_name = "Performance4";
8073 goto cp0_unimplemented;
8075 // gen_helper_mtc0_performance5(arg);
8076 register_name = "Performance5";
8077 goto cp0_unimplemented;
8079 // gen_helper_mtc0_performance6(arg);
8080 register_name = "Performance6";
8081 goto cp0_unimplemented;
8083 // gen_helper_mtc0_performance7(arg);
8084 register_name = "Performance7";
8085 goto cp0_unimplemented;
8087 goto cp0_unimplemented;
8090 case CP0_REGISTER_26:
8093 gen_helper_mtc0_errctl(cpu_env, arg);
8094 ctx->base.is_jmp = DISAS_STOP;
8095 register_name = "ErrCtl";
8098 goto cp0_unimplemented;
8101 case CP0_REGISTER_27:
8108 register_name = "CacheErr";
8111 goto cp0_unimplemented;
8114 case CP0_REGISTER_28:
8120 gen_helper_mtc0_taglo(cpu_env, arg);
8121 register_name = "TagLo";
8127 gen_helper_mtc0_datalo(cpu_env, arg);
8128 register_name = "DataLo";
8131 goto cp0_unimplemented;
8134 case CP0_REGISTER_29:
8140 gen_helper_mtc0_taghi(cpu_env, arg);
8141 register_name = "TagHi";
8147 gen_helper_mtc0_datahi(cpu_env, arg);
8148 register_name = "DataHi";
8151 register_name = "invalid sel";
8152 goto cp0_unimplemented;
8155 case CP0_REGISTER_30:
8158 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8159 register_name = "ErrorEPC";
8162 goto cp0_unimplemented;
8165 case CP0_REGISTER_31:
8169 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8170 register_name = "DESAVE";
8178 CP0_CHECK(ctx->kscrexist & (1 << sel));
8179 tcg_gen_st_tl(arg, cpu_env,
8180 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8181 register_name = "KScratch";
8184 goto cp0_unimplemented;
8188 goto cp0_unimplemented;
8190 trace_mips_translate_c0("mtc0", register_name, reg, sel);
8192 /* For simplicity assume that all writes can cause interrupts. */
8193 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8195 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8196 * translated code to check for pending interrupts. */
8197 gen_save_pc(ctx->base.pc_next + 4);
8198 ctx->base.is_jmp = DISAS_EXIT;
8203 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8204 register_name, reg, sel);
8207 #if defined(TARGET_MIPS64)
8208 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8210 const char *register_name = "invalid";
8213 check_insn(ctx, ISA_MIPS64);
8216 case CP0_REGISTER_00:
8219 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8220 register_name = "Index";
8223 CP0_CHECK(ctx->insn_flags & ASE_MT);
8224 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8225 register_name = "MVPControl";
8228 CP0_CHECK(ctx->insn_flags & ASE_MT);
8229 gen_helper_mfc0_mvpconf0(arg, cpu_env);
8230 register_name = "MVPConf0";
8233 CP0_CHECK(ctx->insn_flags & ASE_MT);
8234 gen_helper_mfc0_mvpconf1(arg, cpu_env);
8235 register_name = "MVPConf1";
8239 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8240 register_name = "VPControl";
8243 goto cp0_unimplemented;
8246 case CP0_REGISTER_01:
8249 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8250 gen_helper_mfc0_random(arg, cpu_env);
8251 register_name = "Random";
8254 CP0_CHECK(ctx->insn_flags & ASE_MT);
8255 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8256 register_name = "VPEControl";
8259 CP0_CHECK(ctx->insn_flags & ASE_MT);
8260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8261 register_name = "VPEConf0";
8264 CP0_CHECK(ctx->insn_flags & ASE_MT);
8265 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8266 register_name = "VPEConf1";
8269 CP0_CHECK(ctx->insn_flags & ASE_MT);
8270 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8271 register_name = "YQMask";
8274 CP0_CHECK(ctx->insn_flags & ASE_MT);
8275 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8276 register_name = "VPESchedule";
8279 CP0_CHECK(ctx->insn_flags & ASE_MT);
8280 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8281 register_name = "VPEScheFBack";
8284 CP0_CHECK(ctx->insn_flags & ASE_MT);
8285 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8286 register_name = "VPEOpt";
8289 goto cp0_unimplemented;
8292 case CP0_REGISTER_02:
8295 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8296 register_name = "EntryLo0";
8299 CP0_CHECK(ctx->insn_flags & ASE_MT);
8300 gen_helper_mfc0_tcstatus(arg, cpu_env);
8301 register_name = "TCStatus";
8304 CP0_CHECK(ctx->insn_flags & ASE_MT);
8305 gen_helper_mfc0_tcbind(arg, cpu_env);
8306 register_name = "TCBind";
8309 CP0_CHECK(ctx->insn_flags & ASE_MT);
8310 gen_helper_dmfc0_tcrestart(arg, cpu_env);
8311 register_name = "TCRestart";
8314 CP0_CHECK(ctx->insn_flags & ASE_MT);
8315 gen_helper_dmfc0_tchalt(arg, cpu_env);
8316 register_name = "TCHalt";
8319 CP0_CHECK(ctx->insn_flags & ASE_MT);
8320 gen_helper_dmfc0_tccontext(arg, cpu_env);
8321 register_name = "TCContext";
8324 CP0_CHECK(ctx->insn_flags & ASE_MT);
8325 gen_helper_dmfc0_tcschedule(arg, cpu_env);
8326 register_name = "TCSchedule";
8329 CP0_CHECK(ctx->insn_flags & ASE_MT);
8330 gen_helper_dmfc0_tcschefback(arg, cpu_env);
8331 register_name = "TCScheFBack";
8334 goto cp0_unimplemented;
8337 case CP0_REGISTER_03:
8340 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8341 register_name = "EntryLo1";
8345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8346 register_name = "GlobalNumber";
8349 goto cp0_unimplemented;
8352 case CP0_REGISTER_04:
8355 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8356 register_name = "Context";
8359 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8360 register_name = "ContextConfig";
8361 goto cp0_unimplemented;
8363 CP0_CHECK(ctx->ulri);
8364 tcg_gen_ld_tl(arg, cpu_env,
8365 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8366 register_name = "UserLocal";
8369 goto cp0_unimplemented;
8372 case CP0_REGISTER_05:
8375 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8376 register_name = "PageMask";
8379 check_insn(ctx, ISA_MIPS32R2);
8380 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8381 register_name = "PageGrain";
8385 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8386 register_name = "SegCtl0";
8390 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8391 register_name = "SegCtl1";
8395 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8396 register_name = "SegCtl2";
8400 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8401 register_name = "PWBase";
8405 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8406 register_name = "PWField";
8410 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8411 register_name = "PWSize";
8414 goto cp0_unimplemented;
8417 case CP0_REGISTER_06:
8420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8421 register_name = "Wired";
8424 check_insn(ctx, ISA_MIPS32R2);
8425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8426 register_name = "SRSConf0";
8429 check_insn(ctx, ISA_MIPS32R2);
8430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8431 register_name = "SRSConf1";
8434 check_insn(ctx, ISA_MIPS32R2);
8435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8436 register_name = "SRSConf2";
8439 check_insn(ctx, ISA_MIPS32R2);
8440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8441 register_name = "SRSConf3";
8444 check_insn(ctx, ISA_MIPS32R2);
8445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8446 register_name = "SRSConf4";
8450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8451 register_name = "PWCtl";
8454 goto cp0_unimplemented;
8457 case CP0_REGISTER_07:
8460 check_insn(ctx, ISA_MIPS32R2);
8461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8462 register_name = "HWREna";
8465 goto cp0_unimplemented;
8468 case CP0_REGISTER_08:
8471 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8472 register_name = "BadVAddr";
8476 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8477 register_name = "BadInstr";
8481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8482 register_name = "BadInstrP";
8486 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8487 tcg_gen_andi_tl(arg, arg, ~0xffff);
8488 register_name = "BadInstrX";
8491 goto cp0_unimplemented;
8494 case CP0_REGISTER_09:
8497 /* Mark as an IO operation because we read the time. */
8498 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8501 gen_helper_mfc0_count(arg, cpu_env);
8502 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8505 /* Break the TB to be able to take timer interrupts immediately
8506 after reading count. DISAS_STOP isn't sufficient, we need to
8507 ensure we break completely out of translated code. */
8508 gen_save_pc(ctx->base.pc_next + 4);
8509 ctx->base.is_jmp = DISAS_EXIT;
8510 register_name = "Count";
8513 CP0_CHECK(ctx->saar);
8514 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8515 register_name = "SAARI";
8518 CP0_CHECK(ctx->saar);
8519 gen_helper_dmfc0_saar(arg, cpu_env);
8520 register_name = "SAAR";
8523 goto cp0_unimplemented;
8526 case CP0_REGISTER_10:
8529 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8530 register_name = "EntryHi";
8533 goto cp0_unimplemented;
8536 case CP0_REGISTER_11:
8539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8540 register_name = "Compare";
8542 /* 6,7 are implementation dependent */
8544 goto cp0_unimplemented;
8547 case CP0_REGISTER_12:
8550 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8551 register_name = "Status";
8554 check_insn(ctx, ISA_MIPS32R2);
8555 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8556 register_name = "IntCtl";
8559 check_insn(ctx, ISA_MIPS32R2);
8560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8561 register_name = "SRSCtl";
8564 check_insn(ctx, ISA_MIPS32R2);
8565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8566 register_name = "SRSMap";
8569 goto cp0_unimplemented;
8572 case CP0_REGISTER_13:
8575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8576 register_name = "Cause";
8579 goto cp0_unimplemented;
8582 case CP0_REGISTER_14:
8585 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8586 register_name = "EPC";
8589 goto cp0_unimplemented;
8592 case CP0_REGISTER_15:
8595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8596 register_name = "PRid";
8599 check_insn(ctx, ISA_MIPS32R2);
8600 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8601 register_name = "EBase";
8604 check_insn(ctx, ISA_MIPS32R2);
8605 CP0_CHECK(ctx->cmgcr);
8606 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8607 register_name = "CMGCRBase";
8610 goto cp0_unimplemented;
8613 case CP0_REGISTER_16:
8616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8617 register_name = "Config";
8620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8621 register_name = "Config1";
8624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8625 register_name = "Config2";
8628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8629 register_name = "Config3";
8632 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8633 register_name = "Config4";
8636 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8637 register_name = "Config5";
8639 /* 6,7 are implementation dependent */
8641 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8642 register_name = "Config6";
8645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8646 register_name = "Config7";
8649 goto cp0_unimplemented;
8652 case CP0_REGISTER_17:
8655 gen_helper_dmfc0_lladdr(arg, cpu_env);
8656 register_name = "LLAddr";
8659 CP0_CHECK(ctx->mrp);
8660 gen_helper_dmfc0_maar(arg, cpu_env);
8661 register_name = "MAAR";
8664 CP0_CHECK(ctx->mrp);
8665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8666 register_name = "MAARI";
8669 goto cp0_unimplemented;
8672 case CP0_REGISTER_18:
8682 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8683 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8684 register_name = "WatchLo";
8687 goto cp0_unimplemented;
8690 case CP0_REGISTER_19:
8700 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8701 gen_helper_1e0i(mfc0_watchhi, arg, sel);
8702 register_name = "WatchHi";
8705 goto cp0_unimplemented;
8708 case CP0_REGISTER_20:
8711 check_insn(ctx, ISA_MIPS3);
8712 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8713 register_name = "XContext";
8716 goto cp0_unimplemented;
8719 case CP0_REGISTER_21:
8720 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8721 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8724 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8725 register_name = "Framemask";
8728 goto cp0_unimplemented;
8731 case CP0_REGISTER_22:
8732 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8733 register_name = "'Diagnostic"; /* implementation dependent */
8735 case CP0_REGISTER_23:
8738 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8739 register_name = "Debug";
8742 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8743 register_name = "TraceControl";
8744 goto cp0_unimplemented;
8746 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8747 register_name = "TraceControl2";
8748 goto cp0_unimplemented;
8750 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8751 register_name = "UserTraceData";
8752 goto cp0_unimplemented;
8754 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8755 register_name = "TraceBPC";
8756 goto cp0_unimplemented;
8758 goto cp0_unimplemented;
8761 case CP0_REGISTER_24:
8765 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8766 register_name = "DEPC";
8769 goto cp0_unimplemented;
8772 case CP0_REGISTER_25:
8775 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8776 register_name = "Performance0";
8779 // gen_helper_dmfc0_performance1(arg);
8780 register_name = "Performance1";
8781 goto cp0_unimplemented;
8783 // gen_helper_dmfc0_performance2(arg);
8784 register_name = "Performance2";
8785 goto cp0_unimplemented;
8787 // gen_helper_dmfc0_performance3(arg);
8788 register_name = "Performance3";
8789 goto cp0_unimplemented;
8791 // gen_helper_dmfc0_performance4(arg);
8792 register_name = "Performance4";
8793 goto cp0_unimplemented;
8795 // gen_helper_dmfc0_performance5(arg);
8796 register_name = "Performance5";
8797 goto cp0_unimplemented;
8799 // gen_helper_dmfc0_performance6(arg);
8800 register_name = "Performance6";
8801 goto cp0_unimplemented;
8803 // gen_helper_dmfc0_performance7(arg);
8804 register_name = "Performance7";
8805 goto cp0_unimplemented;
8807 goto cp0_unimplemented;
8810 case CP0_REGISTER_26:
8813 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8814 register_name = "ErrCtl";
8817 goto cp0_unimplemented;
8820 case CP0_REGISTER_27:
8827 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8828 register_name = "CacheErr";
8831 goto cp0_unimplemented;
8834 case CP0_REGISTER_28:
8840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8841 register_name = "TagLo";
8847 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8848 register_name = "DataLo";
8851 goto cp0_unimplemented;
8854 case CP0_REGISTER_29:
8860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8861 register_name = "TagHi";
8867 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8868 register_name = "DataHi";
8871 goto cp0_unimplemented;
8874 case CP0_REGISTER_30:
8877 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8878 register_name = "ErrorEPC";
8881 goto cp0_unimplemented;
8884 case CP0_REGISTER_31:
8888 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8889 register_name = "DESAVE";
8897 CP0_CHECK(ctx->kscrexist & (1 << sel));
8898 tcg_gen_ld_tl(arg, cpu_env,
8899 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8900 register_name = "KScratch";
8903 goto cp0_unimplemented;
8907 goto cp0_unimplemented;
8909 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
8913 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
8914 register_name, reg, sel);
8915 gen_mfc0_unimplemented(ctx, arg);
8918 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8920 const char *register_name = "invalid";
8923 check_insn(ctx, ISA_MIPS64);
8925 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8930 case CP0_REGISTER_00:
8933 gen_helper_mtc0_index(cpu_env, arg);
8934 register_name = "Index";
8937 CP0_CHECK(ctx->insn_flags & ASE_MT);
8938 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8939 register_name = "MVPControl";
8942 CP0_CHECK(ctx->insn_flags & ASE_MT);
8944 register_name = "MVPConf0";
8947 CP0_CHECK(ctx->insn_flags & ASE_MT);
8949 register_name = "MVPConf1";
8954 register_name = "VPControl";
8957 goto cp0_unimplemented;
8960 case CP0_REGISTER_01:
8964 register_name = "Random";
8967 CP0_CHECK(ctx->insn_flags & ASE_MT);
8968 gen_helper_mtc0_vpecontrol(cpu_env, arg);
8969 register_name = "VPEControl";
8972 CP0_CHECK(ctx->insn_flags & ASE_MT);
8973 gen_helper_mtc0_vpeconf0(cpu_env, arg);
8974 register_name = "VPEConf0";
8977 CP0_CHECK(ctx->insn_flags & ASE_MT);
8978 gen_helper_mtc0_vpeconf1(cpu_env, arg);
8979 register_name = "VPEConf1";
8982 CP0_CHECK(ctx->insn_flags & ASE_MT);
8983 gen_helper_mtc0_yqmask(cpu_env, arg);
8984 register_name = "YQMask";
8987 CP0_CHECK(ctx->insn_flags & ASE_MT);
8988 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8989 register_name = "VPESchedule";
8992 CP0_CHECK(ctx->insn_flags & ASE_MT);
8993 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8994 register_name = "VPEScheFBack";
8997 CP0_CHECK(ctx->insn_flags & ASE_MT);
8998 gen_helper_mtc0_vpeopt(cpu_env, arg);
8999 register_name = "VPEOpt";
9002 goto cp0_unimplemented;
9005 case CP0_REGISTER_02:
9008 gen_helper_dmtc0_entrylo0(cpu_env, arg);
9009 register_name = "EntryLo0";
9012 CP0_CHECK(ctx->insn_flags & ASE_MT);
9013 gen_helper_mtc0_tcstatus(cpu_env, arg);
9014 register_name = "TCStatus";
9017 CP0_CHECK(ctx->insn_flags & ASE_MT);
9018 gen_helper_mtc0_tcbind(cpu_env, arg);
9019 register_name = "TCBind";
9022 CP0_CHECK(ctx->insn_flags & ASE_MT);
9023 gen_helper_mtc0_tcrestart(cpu_env, arg);
9024 register_name = "TCRestart";
9027 CP0_CHECK(ctx->insn_flags & ASE_MT);
9028 gen_helper_mtc0_tchalt(cpu_env, arg);
9029 register_name = "TCHalt";
9032 CP0_CHECK(ctx->insn_flags & ASE_MT);
9033 gen_helper_mtc0_tccontext(cpu_env, arg);
9034 register_name = "TCContext";
9037 CP0_CHECK(ctx->insn_flags & ASE_MT);
9038 gen_helper_mtc0_tcschedule(cpu_env, arg);
9039 register_name = "TCSchedule";
9042 CP0_CHECK(ctx->insn_flags & ASE_MT);
9043 gen_helper_mtc0_tcschefback(cpu_env, arg);
9044 register_name = "TCScheFBack";
9047 goto cp0_unimplemented;
9050 case CP0_REGISTER_03:
9053 gen_helper_dmtc0_entrylo1(cpu_env, arg);
9054 register_name = "EntryLo1";
9059 register_name = "GlobalNumber";
9062 goto cp0_unimplemented;
9065 case CP0_REGISTER_04:
9068 gen_helper_mtc0_context(cpu_env, arg);
9069 register_name = "Context";
9072 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
9073 register_name = "ContextConfig";
9074 goto cp0_unimplemented;
9076 CP0_CHECK(ctx->ulri);
9077 tcg_gen_st_tl(arg, cpu_env,
9078 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9079 register_name = "UserLocal";
9082 goto cp0_unimplemented;
9085 case CP0_REGISTER_05:
9088 gen_helper_mtc0_pagemask(cpu_env, arg);
9089 register_name = "PageMask";
9092 check_insn(ctx, ISA_MIPS32R2);
9093 gen_helper_mtc0_pagegrain(cpu_env, arg);
9094 register_name = "PageGrain";
9098 gen_helper_mtc0_segctl0(cpu_env, arg);
9099 register_name = "SegCtl0";
9103 gen_helper_mtc0_segctl1(cpu_env, arg);
9104 register_name = "SegCtl1";
9108 gen_helper_mtc0_segctl2(cpu_env, arg);
9109 register_name = "SegCtl2";
9113 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9114 register_name = "PWBase";
9118 gen_helper_mtc0_pwfield(cpu_env, arg);
9119 register_name = "PWField";
9123 gen_helper_mtc0_pwsize(cpu_env, arg);
9124 register_name = "PWSize";
9127 goto cp0_unimplemented;
9130 case CP0_REGISTER_06:
9133 gen_helper_mtc0_wired(cpu_env, arg);
9134 register_name = "Wired";
9137 check_insn(ctx, ISA_MIPS32R2);
9138 gen_helper_mtc0_srsconf0(cpu_env, arg);
9139 register_name = "SRSConf0";
9142 check_insn(ctx, ISA_MIPS32R2);
9143 gen_helper_mtc0_srsconf1(cpu_env, arg);
9144 register_name = "SRSConf1";
9147 check_insn(ctx, ISA_MIPS32R2);
9148 gen_helper_mtc0_srsconf2(cpu_env, arg);
9149 register_name = "SRSConf2";
9152 check_insn(ctx, ISA_MIPS32R2);
9153 gen_helper_mtc0_srsconf3(cpu_env, arg);
9154 register_name = "SRSConf3";
9157 check_insn(ctx, ISA_MIPS32R2);
9158 gen_helper_mtc0_srsconf4(cpu_env, arg);
9159 register_name = "SRSConf4";
9163 gen_helper_mtc0_pwctl(cpu_env, arg);
9164 register_name = "PWCtl";
9167 goto cp0_unimplemented;
9170 case CP0_REGISTER_07:
9173 check_insn(ctx, ISA_MIPS32R2);
9174 gen_helper_mtc0_hwrena(cpu_env, arg);
9175 ctx->base.is_jmp = DISAS_STOP;
9176 register_name = "HWREna";
9179 goto cp0_unimplemented;
9182 case CP0_REGISTER_08:
9186 register_name = "BadVAddr";
9190 register_name = "BadInstr";
9194 register_name = "BadInstrP";
9198 register_name = "BadInstrX";
9201 goto cp0_unimplemented;
9204 case CP0_REGISTER_09:
9207 gen_helper_mtc0_count(cpu_env, arg);
9208 register_name = "Count";
9211 CP0_CHECK(ctx->saar);
9212 gen_helper_mtc0_saari(cpu_env, arg);
9213 register_name = "SAARI";
9216 CP0_CHECK(ctx->saar);
9217 gen_helper_mtc0_saar(cpu_env, arg);
9218 register_name = "SAAR";
9221 goto cp0_unimplemented;
9223 /* Stop translation as we may have switched the execution mode */
9224 ctx->base.is_jmp = DISAS_STOP;
9226 case CP0_REGISTER_10:
9229 gen_helper_mtc0_entryhi(cpu_env, arg);
9230 register_name = "EntryHi";
9233 goto cp0_unimplemented;
9236 case CP0_REGISTER_11:
9239 gen_helper_mtc0_compare(cpu_env, arg);
9240 register_name = "Compare";
9242 /* 6,7 are implementation dependent */
9244 goto cp0_unimplemented;
9246 /* Stop translation as we may have switched the execution mode */
9247 ctx->base.is_jmp = DISAS_STOP;
9249 case CP0_REGISTER_12:
9252 save_cpu_state(ctx, 1);
9253 gen_helper_mtc0_status(cpu_env, arg);
9254 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9255 gen_save_pc(ctx->base.pc_next + 4);
9256 ctx->base.is_jmp = DISAS_EXIT;
9257 register_name = "Status";
9260 check_insn(ctx, ISA_MIPS32R2);
9261 gen_helper_mtc0_intctl(cpu_env, arg);
9262 /* Stop translation as we may have switched the execution mode */
9263 ctx->base.is_jmp = DISAS_STOP;
9264 register_name = "IntCtl";
9267 check_insn(ctx, ISA_MIPS32R2);
9268 gen_helper_mtc0_srsctl(cpu_env, arg);
9269 /* Stop translation as we may have switched the execution mode */
9270 ctx->base.is_jmp = DISAS_STOP;
9271 register_name = "SRSCtl";
9274 check_insn(ctx, ISA_MIPS32R2);
9275 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9276 /* Stop translation as we may have switched the execution mode */
9277 ctx->base.is_jmp = DISAS_STOP;
9278 register_name = "SRSMap";
9281 goto cp0_unimplemented;
9284 case CP0_REGISTER_13:
9287 save_cpu_state(ctx, 1);
9288 gen_helper_mtc0_cause(cpu_env, arg);
9289 /* Stop translation as we may have triggered an interrupt.
9290 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9291 * translated code to check for pending interrupts. */
9292 gen_save_pc(ctx->base.pc_next + 4);
9293 ctx->base.is_jmp = DISAS_EXIT;
9294 register_name = "Cause";
9297 goto cp0_unimplemented;
9300 case CP0_REGISTER_14:
9303 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9304 register_name = "EPC";
9307 goto cp0_unimplemented;
9310 case CP0_REGISTER_15:
9314 register_name = "PRid";
9317 check_insn(ctx, ISA_MIPS32R2);
9318 gen_helper_mtc0_ebase(cpu_env, arg);
9319 register_name = "EBase";
9322 goto cp0_unimplemented;
9325 case CP0_REGISTER_16:
9328 gen_helper_mtc0_config0(cpu_env, arg);
9329 register_name = "Config";
9330 /* Stop translation as we may have switched the execution mode */
9331 ctx->base.is_jmp = DISAS_STOP;
9334 /* ignored, read only */
9335 register_name = "Config1";
9338 gen_helper_mtc0_config2(cpu_env, arg);
9339 register_name = "Config2";
9340 /* Stop translation as we may have switched the execution mode */
9341 ctx->base.is_jmp = DISAS_STOP;
9344 gen_helper_mtc0_config3(cpu_env, arg);
9345 register_name = "Config3";
9346 /* Stop translation as we may have switched the execution mode */
9347 ctx->base.is_jmp = DISAS_STOP;
9350 /* currently ignored */
9351 register_name = "Config4";
9354 gen_helper_mtc0_config5(cpu_env, arg);
9355 register_name = "Config5";
9356 /* Stop translation as we may have switched the execution mode */
9357 ctx->base.is_jmp = DISAS_STOP;
9359 /* 6,7 are implementation dependent */
9361 register_name = "Invalid config selector";
9362 goto cp0_unimplemented;
9365 case CP0_REGISTER_17:
9368 gen_helper_mtc0_lladdr(cpu_env, arg);
9369 register_name = "LLAddr";
9372 CP0_CHECK(ctx->mrp);
9373 gen_helper_mtc0_maar(cpu_env, arg);
9374 register_name = "MAAR";
9377 CP0_CHECK(ctx->mrp);
9378 gen_helper_mtc0_maari(cpu_env, arg);
9379 register_name = "MAARI";
9382 goto cp0_unimplemented;
9385 case CP0_REGISTER_18:
9395 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9396 gen_helper_0e1i(mtc0_watchlo, arg, sel);
9397 register_name = "WatchLo";
9400 goto cp0_unimplemented;
9403 case CP0_REGISTER_19:
9413 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9414 gen_helper_0e1i(mtc0_watchhi, arg, sel);
9415 register_name = "WatchHi";
9418 goto cp0_unimplemented;
9421 case CP0_REGISTER_20:
9424 check_insn(ctx, ISA_MIPS3);
9425 gen_helper_mtc0_xcontext(cpu_env, arg);
9426 register_name = "XContext";
9429 goto cp0_unimplemented;
9432 case CP0_REGISTER_21:
9433 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9434 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9437 gen_helper_mtc0_framemask(cpu_env, arg);
9438 register_name = "Framemask";
9441 goto cp0_unimplemented;
9444 case CP0_REGISTER_22:
9446 register_name = "Diagnostic"; /* implementation dependent */
9448 case CP0_REGISTER_23:
9451 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9452 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9453 gen_save_pc(ctx->base.pc_next + 4);
9454 ctx->base.is_jmp = DISAS_EXIT;
9455 register_name = "Debug";
9458 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9459 /* Stop translation as we may have switched the execution mode */
9460 ctx->base.is_jmp = DISAS_STOP;
9461 register_name = "TraceControl";
9462 goto cp0_unimplemented;
9464 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9465 /* Stop translation as we may have switched the execution mode */
9466 ctx->base.is_jmp = DISAS_STOP;
9467 register_name = "TraceControl2";
9468 goto cp0_unimplemented;
9470 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9471 /* Stop translation as we may have switched the execution mode */
9472 ctx->base.is_jmp = DISAS_STOP;
9473 register_name = "UserTraceData";
9474 goto cp0_unimplemented;
9476 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9477 /* Stop translation as we may have switched the execution mode */
9478 ctx->base.is_jmp = DISAS_STOP;
9479 register_name = "TraceBPC";
9480 goto cp0_unimplemented;
9482 goto cp0_unimplemented;
9485 case CP0_REGISTER_24:
9489 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9490 register_name = "DEPC";
9493 goto cp0_unimplemented;
9496 case CP0_REGISTER_25:
9499 gen_helper_mtc0_performance0(cpu_env, arg);
9500 register_name = "Performance0";
9503 // gen_helper_mtc0_performance1(cpu_env, arg);
9504 register_name = "Performance1";
9505 goto cp0_unimplemented;
9507 // gen_helper_mtc0_performance2(cpu_env, arg);
9508 register_name = "Performance2";
9509 goto cp0_unimplemented;
9511 // gen_helper_mtc0_performance3(cpu_env, arg);
9512 register_name = "Performance3";
9513 goto cp0_unimplemented;
9515 // gen_helper_mtc0_performance4(cpu_env, arg);
9516 register_name = "Performance4";
9517 goto cp0_unimplemented;
9519 // gen_helper_mtc0_performance5(cpu_env, arg);
9520 register_name = "Performance5";
9521 goto cp0_unimplemented;
9523 // gen_helper_mtc0_performance6(cpu_env, arg);
9524 register_name = "Performance6";
9525 goto cp0_unimplemented;
9527 // gen_helper_mtc0_performance7(cpu_env, arg);
9528 register_name = "Performance7";
9529 goto cp0_unimplemented;
9531 goto cp0_unimplemented;
9534 case CP0_REGISTER_26:
9537 gen_helper_mtc0_errctl(cpu_env, arg);
9538 ctx->base.is_jmp = DISAS_STOP;
9539 register_name = "ErrCtl";
9542 goto cp0_unimplemented;
9545 case CP0_REGISTER_27:
9552 register_name = "CacheErr";
9555 goto cp0_unimplemented;
9558 case CP0_REGISTER_28:
9564 gen_helper_mtc0_taglo(cpu_env, arg);
9565 register_name = "TagLo";
9571 gen_helper_mtc0_datalo(cpu_env, arg);
9572 register_name = "DataLo";
9575 goto cp0_unimplemented;
9578 case CP0_REGISTER_29:
9584 gen_helper_mtc0_taghi(cpu_env, arg);
9585 register_name = "TagHi";
9591 gen_helper_mtc0_datahi(cpu_env, arg);
9592 register_name = "DataHi";
9595 register_name = "invalid sel";
9596 goto cp0_unimplemented;
9599 case CP0_REGISTER_30:
9602 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9603 register_name = "ErrorEPC";
9606 goto cp0_unimplemented;
9609 case CP0_REGISTER_31:
9613 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9614 register_name = "DESAVE";
9622 CP0_CHECK(ctx->kscrexist & (1 << sel));
9623 tcg_gen_st_tl(arg, cpu_env,
9624 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9625 register_name = "KScratch";
9628 goto cp0_unimplemented;
9632 goto cp0_unimplemented;
9634 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9636 /* For simplicity assume that all writes can cause interrupts. */
9637 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9639 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9640 * translated code to check for pending interrupts. */
9641 gen_save_pc(ctx->base.pc_next + 4);
9642 ctx->base.is_jmp = DISAS_EXIT;
9647 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9648 register_name, reg, sel);
9650 #endif /* TARGET_MIPS64 */
9652 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9653 int u, int sel, int h)
9655 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9656 TCGv t0 = tcg_temp_local_new();
9658 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9659 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9660 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9661 tcg_gen_movi_tl(t0, -1);
9662 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9663 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9664 tcg_gen_movi_tl(t0, -1);
9670 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9673 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9683 gen_helper_mftc0_tcstatus(t0, cpu_env);
9686 gen_helper_mftc0_tcbind(t0, cpu_env);
9689 gen_helper_mftc0_tcrestart(t0, cpu_env);
9692 gen_helper_mftc0_tchalt(t0, cpu_env);
9695 gen_helper_mftc0_tccontext(t0, cpu_env);
9698 gen_helper_mftc0_tcschedule(t0, cpu_env);
9701 gen_helper_mftc0_tcschefback(t0, cpu_env);
9704 gen_mfc0(ctx, t0, rt, sel);
9711 gen_helper_mftc0_entryhi(t0, cpu_env);
9714 gen_mfc0(ctx, t0, rt, sel);
9720 gen_helper_mftc0_status(t0, cpu_env);
9723 gen_mfc0(ctx, t0, rt, sel);
9729 gen_helper_mftc0_cause(t0, cpu_env);
9739 gen_helper_mftc0_epc(t0, cpu_env);
9749 gen_helper_mftc0_ebase(t0, cpu_env);
9766 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9776 gen_helper_mftc0_debug(t0, cpu_env);
9779 gen_mfc0(ctx, t0, rt, sel);
9784 gen_mfc0(ctx, t0, rt, sel);
9786 } else switch (sel) {
9787 /* GPR registers. */
9789 gen_helper_1e0i(mftgpr, t0, rt);
9791 /* Auxiliary CPU registers */
9795 gen_helper_1e0i(mftlo, t0, 0);
9798 gen_helper_1e0i(mfthi, t0, 0);
9801 gen_helper_1e0i(mftacx, t0, 0);
9804 gen_helper_1e0i(mftlo, t0, 1);
9807 gen_helper_1e0i(mfthi, t0, 1);
9810 gen_helper_1e0i(mftacx, t0, 1);
9813 gen_helper_1e0i(mftlo, t0, 2);
9816 gen_helper_1e0i(mfthi, t0, 2);
9819 gen_helper_1e0i(mftacx, t0, 2);
9822 gen_helper_1e0i(mftlo, t0, 3);
9825 gen_helper_1e0i(mfthi, t0, 3);
9828 gen_helper_1e0i(mftacx, t0, 3);
9831 gen_helper_mftdsp(t0, cpu_env);
9837 /* Floating point (COP1). */
9839 /* XXX: For now we support only a single FPU context. */
9841 TCGv_i32 fp0 = tcg_temp_new_i32();
9843 gen_load_fpr32(ctx, fp0, rt);
9844 tcg_gen_ext_i32_tl(t0, fp0);
9845 tcg_temp_free_i32(fp0);
9847 TCGv_i32 fp0 = tcg_temp_new_i32();
9849 gen_load_fpr32h(ctx, fp0, rt);
9850 tcg_gen_ext_i32_tl(t0, fp0);
9851 tcg_temp_free_i32(fp0);
9855 /* XXX: For now we support only a single FPU context. */
9856 gen_helper_1e0i(cfc1, t0, rt);
9858 /* COP2: Not implemented. */
9865 trace_mips_translate_tr("mftr", rt, u, sel, h);
9866 gen_store_gpr(t0, rd);
9872 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9873 generate_exception_end(ctx, EXCP_RI);
9876 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9877 int u, int sel, int h)
9879 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9880 TCGv t0 = tcg_temp_local_new();
9882 gen_load_gpr(t0, rt);
9883 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9884 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9885 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9887 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9888 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9895 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9898 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9908 gen_helper_mttc0_tcstatus(cpu_env, t0);
9911 gen_helper_mttc0_tcbind(cpu_env, t0);
9914 gen_helper_mttc0_tcrestart(cpu_env, t0);
9917 gen_helper_mttc0_tchalt(cpu_env, t0);
9920 gen_helper_mttc0_tccontext(cpu_env, t0);
9923 gen_helper_mttc0_tcschedule(cpu_env, t0);
9926 gen_helper_mttc0_tcschefback(cpu_env, t0);
9929 gen_mtc0(ctx, t0, rd, sel);
9936 gen_helper_mttc0_entryhi(cpu_env, t0);
9939 gen_mtc0(ctx, t0, rd, sel);
9945 gen_helper_mttc0_status(cpu_env, t0);
9948 gen_mtc0(ctx, t0, rd, sel);
9954 gen_helper_mttc0_cause(cpu_env, t0);
9964 gen_helper_mttc0_ebase(cpu_env, t0);
9974 gen_helper_mttc0_debug(cpu_env, t0);
9977 gen_mtc0(ctx, t0, rd, sel);
9982 gen_mtc0(ctx, t0, rd, sel);
9984 } else switch (sel) {
9985 /* GPR registers. */
9987 gen_helper_0e1i(mttgpr, t0, rd);
9989 /* Auxiliary CPU registers */
9993 gen_helper_0e1i(mttlo, t0, 0);
9996 gen_helper_0e1i(mtthi, t0, 0);
9999 gen_helper_0e1i(mttacx, t0, 0);
10002 gen_helper_0e1i(mttlo, t0, 1);
10005 gen_helper_0e1i(mtthi, t0, 1);
10008 gen_helper_0e1i(mttacx, t0, 1);
10011 gen_helper_0e1i(mttlo, t0, 2);
10014 gen_helper_0e1i(mtthi, t0, 2);
10017 gen_helper_0e1i(mttacx, t0, 2);
10020 gen_helper_0e1i(mttlo, t0, 3);
10023 gen_helper_0e1i(mtthi, t0, 3);
10026 gen_helper_0e1i(mttacx, t0, 3);
10029 gen_helper_mttdsp(cpu_env, t0);
10035 /* Floating point (COP1). */
10037 /* XXX: For now we support only a single FPU context. */
10039 TCGv_i32 fp0 = tcg_temp_new_i32();
10041 tcg_gen_trunc_tl_i32(fp0, t0);
10042 gen_store_fpr32(ctx, fp0, rd);
10043 tcg_temp_free_i32(fp0);
10045 TCGv_i32 fp0 = tcg_temp_new_i32();
10047 tcg_gen_trunc_tl_i32(fp0, t0);
10048 gen_store_fpr32h(ctx, fp0, rd);
10049 tcg_temp_free_i32(fp0);
10053 /* XXX: For now we support only a single FPU context. */
10055 TCGv_i32 fs_tmp = tcg_const_i32(rd);
10057 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10058 tcg_temp_free_i32(fs_tmp);
10060 /* Stop translation as we may have changed hflags */
10061 ctx->base.is_jmp = DISAS_STOP;
10063 /* COP2: Not implemented. */
10070 trace_mips_translate_tr("mttr", rd, u, sel, h);
10076 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10077 generate_exception_end(ctx, EXCP_RI);
10080 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
10082 const char *opn = "ldst";
10084 check_cp0_enabled(ctx);
10088 /* Treat as NOP. */
10091 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10096 TCGv t0 = tcg_temp_new();
10098 gen_load_gpr(t0, rt);
10099 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10104 #if defined(TARGET_MIPS64)
10106 check_insn(ctx, ISA_MIPS3);
10108 /* Treat as NOP. */
10111 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10115 check_insn(ctx, ISA_MIPS3);
10117 TCGv t0 = tcg_temp_new();
10119 gen_load_gpr(t0, rt);
10120 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10129 /* Treat as NOP. */
10132 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10138 TCGv t0 = tcg_temp_new();
10139 gen_load_gpr(t0, rt);
10140 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10146 check_cp0_enabled(ctx);
10148 /* Treat as NOP. */
10151 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10152 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10156 check_cp0_enabled(ctx);
10157 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10158 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10163 if (!env->tlb->helper_tlbwi)
10165 gen_helper_tlbwi(cpu_env);
10169 if (ctx->ie >= 2) {
10170 if (!env->tlb->helper_tlbinv) {
10173 gen_helper_tlbinv(cpu_env);
10174 } /* treat as nop if TLBINV not supported */
10178 if (ctx->ie >= 2) {
10179 if (!env->tlb->helper_tlbinvf) {
10182 gen_helper_tlbinvf(cpu_env);
10183 } /* treat as nop if TLBINV not supported */
10187 if (!env->tlb->helper_tlbwr)
10189 gen_helper_tlbwr(cpu_env);
10193 if (!env->tlb->helper_tlbp)
10195 gen_helper_tlbp(cpu_env);
10199 if (!env->tlb->helper_tlbr)
10201 gen_helper_tlbr(cpu_env);
10203 case OPC_ERET: /* OPC_ERETNC */
10204 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10205 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10208 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10209 if (ctx->opcode & (1 << bit_shift)) {
10212 check_insn(ctx, ISA_MIPS32R5);
10213 gen_helper_eretnc(cpu_env);
10217 check_insn(ctx, ISA_MIPS2);
10218 gen_helper_eret(cpu_env);
10220 ctx->base.is_jmp = DISAS_EXIT;
10225 check_insn(ctx, ISA_MIPS32);
10226 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10227 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10230 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10232 generate_exception_end(ctx, EXCP_RI);
10234 gen_helper_deret(cpu_env);
10235 ctx->base.is_jmp = DISAS_EXIT;
10240 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10241 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10242 (ctx->hflags & MIPS_HFLAG_BMASK)) {
10245 /* If we get an exception, we want to restart at next instruction */
10246 ctx->base.pc_next += 4;
10247 save_cpu_state(ctx, 1);
10248 ctx->base.pc_next -= 4;
10249 gen_helper_wait(cpu_env);
10250 ctx->base.is_jmp = DISAS_NORETURN;
10255 generate_exception_end(ctx, EXCP_RI);
10258 (void)opn; /* avoid a compiler warning */
10260 #endif /* !CONFIG_USER_ONLY */
10262 /* CP1 Branches (before delay slot) */
10263 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10264 int32_t cc, int32_t offset)
10266 target_ulong btarget;
10267 TCGv_i32 t0 = tcg_temp_new_i32();
10269 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10270 generate_exception_end(ctx, EXCP_RI);
10275 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10277 btarget = ctx->base.pc_next + 4 + offset;
10281 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10282 tcg_gen_not_i32(t0, t0);
10283 tcg_gen_andi_i32(t0, t0, 1);
10284 tcg_gen_extu_i32_tl(bcond, t0);
10287 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10288 tcg_gen_not_i32(t0, t0);
10289 tcg_gen_andi_i32(t0, t0, 1);
10290 tcg_gen_extu_i32_tl(bcond, t0);
10293 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10294 tcg_gen_andi_i32(t0, t0, 1);
10295 tcg_gen_extu_i32_tl(bcond, t0);
10298 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10299 tcg_gen_andi_i32(t0, t0, 1);
10300 tcg_gen_extu_i32_tl(bcond, t0);
10302 ctx->hflags |= MIPS_HFLAG_BL;
10306 TCGv_i32 t1 = tcg_temp_new_i32();
10307 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10308 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10309 tcg_gen_nand_i32(t0, t0, t1);
10310 tcg_temp_free_i32(t1);
10311 tcg_gen_andi_i32(t0, t0, 1);
10312 tcg_gen_extu_i32_tl(bcond, t0);
10317 TCGv_i32 t1 = tcg_temp_new_i32();
10318 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10319 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10320 tcg_gen_or_i32(t0, t0, t1);
10321 tcg_temp_free_i32(t1);
10322 tcg_gen_andi_i32(t0, t0, 1);
10323 tcg_gen_extu_i32_tl(bcond, t0);
10328 TCGv_i32 t1 = tcg_temp_new_i32();
10329 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10330 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10331 tcg_gen_and_i32(t0, t0, t1);
10332 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10333 tcg_gen_and_i32(t0, t0, t1);
10334 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10335 tcg_gen_nand_i32(t0, t0, t1);
10336 tcg_temp_free_i32(t1);
10337 tcg_gen_andi_i32(t0, t0, 1);
10338 tcg_gen_extu_i32_tl(bcond, t0);
10343 TCGv_i32 t1 = tcg_temp_new_i32();
10344 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10345 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10346 tcg_gen_or_i32(t0, t0, t1);
10347 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10348 tcg_gen_or_i32(t0, t0, t1);
10349 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10350 tcg_gen_or_i32(t0, t0, t1);
10351 tcg_temp_free_i32(t1);
10352 tcg_gen_andi_i32(t0, t0, 1);
10353 tcg_gen_extu_i32_tl(bcond, t0);
10356 ctx->hflags |= MIPS_HFLAG_BC;
10359 MIPS_INVAL("cp1 cond branch");
10360 generate_exception_end(ctx, EXCP_RI);
10363 ctx->btarget = btarget;
10364 ctx->hflags |= MIPS_HFLAG_BDS32;
10366 tcg_temp_free_i32(t0);
10369 /* R6 CP1 Branches */
10370 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10371 int32_t ft, int32_t offset,
10372 int delayslot_size)
10374 target_ulong btarget;
10375 TCGv_i64 t0 = tcg_temp_new_i64();
10377 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10378 #ifdef MIPS_DEBUG_DISAS
10379 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10380 "\n", ctx->base.pc_next);
10382 generate_exception_end(ctx, EXCP_RI);
10386 gen_load_fpr64(ctx, t0, ft);
10387 tcg_gen_andi_i64(t0, t0, 1);
10389 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10393 tcg_gen_xori_i64(t0, t0, 1);
10394 ctx->hflags |= MIPS_HFLAG_BC;
10397 /* t0 already set */
10398 ctx->hflags |= MIPS_HFLAG_BC;
10401 MIPS_INVAL("cp1 cond branch");
10402 generate_exception_end(ctx, EXCP_RI);
10406 tcg_gen_trunc_i64_tl(bcond, t0);
10408 ctx->btarget = btarget;
10410 switch (delayslot_size) {
10412 ctx->hflags |= MIPS_HFLAG_BDS16;
10415 ctx->hflags |= MIPS_HFLAG_BDS32;
10420 tcg_temp_free_i64(t0);
10423 /* Coprocessor 1 (FPU) */
10425 #define FOP(func, fmt) (((fmt) << 21) | (func))
10428 OPC_ADD_S = FOP(0, FMT_S),
10429 OPC_SUB_S = FOP(1, FMT_S),
10430 OPC_MUL_S = FOP(2, FMT_S),
10431 OPC_DIV_S = FOP(3, FMT_S),
10432 OPC_SQRT_S = FOP(4, FMT_S),
10433 OPC_ABS_S = FOP(5, FMT_S),
10434 OPC_MOV_S = FOP(6, FMT_S),
10435 OPC_NEG_S = FOP(7, FMT_S),
10436 OPC_ROUND_L_S = FOP(8, FMT_S),
10437 OPC_TRUNC_L_S = FOP(9, FMT_S),
10438 OPC_CEIL_L_S = FOP(10, FMT_S),
10439 OPC_FLOOR_L_S = FOP(11, FMT_S),
10440 OPC_ROUND_W_S = FOP(12, FMT_S),
10441 OPC_TRUNC_W_S = FOP(13, FMT_S),
10442 OPC_CEIL_W_S = FOP(14, FMT_S),
10443 OPC_FLOOR_W_S = FOP(15, FMT_S),
10444 OPC_SEL_S = FOP(16, FMT_S),
10445 OPC_MOVCF_S = FOP(17, FMT_S),
10446 OPC_MOVZ_S = FOP(18, FMT_S),
10447 OPC_MOVN_S = FOP(19, FMT_S),
10448 OPC_SELEQZ_S = FOP(20, FMT_S),
10449 OPC_RECIP_S = FOP(21, FMT_S),
10450 OPC_RSQRT_S = FOP(22, FMT_S),
10451 OPC_SELNEZ_S = FOP(23, FMT_S),
10452 OPC_MADDF_S = FOP(24, FMT_S),
10453 OPC_MSUBF_S = FOP(25, FMT_S),
10454 OPC_RINT_S = FOP(26, FMT_S),
10455 OPC_CLASS_S = FOP(27, FMT_S),
10456 OPC_MIN_S = FOP(28, FMT_S),
10457 OPC_RECIP2_S = FOP(28, FMT_S),
10458 OPC_MINA_S = FOP(29, FMT_S),
10459 OPC_RECIP1_S = FOP(29, FMT_S),
10460 OPC_MAX_S = FOP(30, FMT_S),
10461 OPC_RSQRT1_S = FOP(30, FMT_S),
10462 OPC_MAXA_S = FOP(31, FMT_S),
10463 OPC_RSQRT2_S = FOP(31, FMT_S),
10464 OPC_CVT_D_S = FOP(33, FMT_S),
10465 OPC_CVT_W_S = FOP(36, FMT_S),
10466 OPC_CVT_L_S = FOP(37, FMT_S),
10467 OPC_CVT_PS_S = FOP(38, FMT_S),
10468 OPC_CMP_F_S = FOP (48, FMT_S),
10469 OPC_CMP_UN_S = FOP (49, FMT_S),
10470 OPC_CMP_EQ_S = FOP (50, FMT_S),
10471 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10472 OPC_CMP_OLT_S = FOP (52, FMT_S),
10473 OPC_CMP_ULT_S = FOP (53, FMT_S),
10474 OPC_CMP_OLE_S = FOP (54, FMT_S),
10475 OPC_CMP_ULE_S = FOP (55, FMT_S),
10476 OPC_CMP_SF_S = FOP (56, FMT_S),
10477 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10478 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10479 OPC_CMP_NGL_S = FOP (59, FMT_S),
10480 OPC_CMP_LT_S = FOP (60, FMT_S),
10481 OPC_CMP_NGE_S = FOP (61, FMT_S),
10482 OPC_CMP_LE_S = FOP (62, FMT_S),
10483 OPC_CMP_NGT_S = FOP (63, FMT_S),
10485 OPC_ADD_D = FOP(0, FMT_D),
10486 OPC_SUB_D = FOP(1, FMT_D),
10487 OPC_MUL_D = FOP(2, FMT_D),
10488 OPC_DIV_D = FOP(3, FMT_D),
10489 OPC_SQRT_D = FOP(4, FMT_D),
10490 OPC_ABS_D = FOP(5, FMT_D),
10491 OPC_MOV_D = FOP(6, FMT_D),
10492 OPC_NEG_D = FOP(7, FMT_D),
10493 OPC_ROUND_L_D = FOP(8, FMT_D),
10494 OPC_TRUNC_L_D = FOP(9, FMT_D),
10495 OPC_CEIL_L_D = FOP(10, FMT_D),
10496 OPC_FLOOR_L_D = FOP(11, FMT_D),
10497 OPC_ROUND_W_D = FOP(12, FMT_D),
10498 OPC_TRUNC_W_D = FOP(13, FMT_D),
10499 OPC_CEIL_W_D = FOP(14, FMT_D),
10500 OPC_FLOOR_W_D = FOP(15, FMT_D),
10501 OPC_SEL_D = FOP(16, FMT_D),
10502 OPC_MOVCF_D = FOP(17, FMT_D),
10503 OPC_MOVZ_D = FOP(18, FMT_D),
10504 OPC_MOVN_D = FOP(19, FMT_D),
10505 OPC_SELEQZ_D = FOP(20, FMT_D),
10506 OPC_RECIP_D = FOP(21, FMT_D),
10507 OPC_RSQRT_D = FOP(22, FMT_D),
10508 OPC_SELNEZ_D = FOP(23, FMT_D),
10509 OPC_MADDF_D = FOP(24, FMT_D),
10510 OPC_MSUBF_D = FOP(25, FMT_D),
10511 OPC_RINT_D = FOP(26, FMT_D),
10512 OPC_CLASS_D = FOP(27, FMT_D),
10513 OPC_MIN_D = FOP(28, FMT_D),
10514 OPC_RECIP2_D = FOP(28, FMT_D),
10515 OPC_MINA_D = FOP(29, FMT_D),
10516 OPC_RECIP1_D = FOP(29, FMT_D),
10517 OPC_MAX_D = FOP(30, FMT_D),
10518 OPC_RSQRT1_D = FOP(30, FMT_D),
10519 OPC_MAXA_D = FOP(31, FMT_D),
10520 OPC_RSQRT2_D = FOP(31, FMT_D),
10521 OPC_CVT_S_D = FOP(32, FMT_D),
10522 OPC_CVT_W_D = FOP(36, FMT_D),
10523 OPC_CVT_L_D = FOP(37, FMT_D),
10524 OPC_CMP_F_D = FOP (48, FMT_D),
10525 OPC_CMP_UN_D = FOP (49, FMT_D),
10526 OPC_CMP_EQ_D = FOP (50, FMT_D),
10527 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10528 OPC_CMP_OLT_D = FOP (52, FMT_D),
10529 OPC_CMP_ULT_D = FOP (53, FMT_D),
10530 OPC_CMP_OLE_D = FOP (54, FMT_D),
10531 OPC_CMP_ULE_D = FOP (55, FMT_D),
10532 OPC_CMP_SF_D = FOP (56, FMT_D),
10533 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10534 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10535 OPC_CMP_NGL_D = FOP (59, FMT_D),
10536 OPC_CMP_LT_D = FOP (60, FMT_D),
10537 OPC_CMP_NGE_D = FOP (61, FMT_D),
10538 OPC_CMP_LE_D = FOP (62, FMT_D),
10539 OPC_CMP_NGT_D = FOP (63, FMT_D),
10541 OPC_CVT_S_W = FOP(32, FMT_W),
10542 OPC_CVT_D_W = FOP(33, FMT_W),
10543 OPC_CVT_S_L = FOP(32, FMT_L),
10544 OPC_CVT_D_L = FOP(33, FMT_L),
10545 OPC_CVT_PS_PW = FOP(38, FMT_W),
10547 OPC_ADD_PS = FOP(0, FMT_PS),
10548 OPC_SUB_PS = FOP(1, FMT_PS),
10549 OPC_MUL_PS = FOP(2, FMT_PS),
10550 OPC_DIV_PS = FOP(3, FMT_PS),
10551 OPC_ABS_PS = FOP(5, FMT_PS),
10552 OPC_MOV_PS = FOP(6, FMT_PS),
10553 OPC_NEG_PS = FOP(7, FMT_PS),
10554 OPC_MOVCF_PS = FOP(17, FMT_PS),
10555 OPC_MOVZ_PS = FOP(18, FMT_PS),
10556 OPC_MOVN_PS = FOP(19, FMT_PS),
10557 OPC_ADDR_PS = FOP(24, FMT_PS),
10558 OPC_MULR_PS = FOP(26, FMT_PS),
10559 OPC_RECIP2_PS = FOP(28, FMT_PS),
10560 OPC_RECIP1_PS = FOP(29, FMT_PS),
10561 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10562 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10564 OPC_CVT_S_PU = FOP(32, FMT_PS),
10565 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10566 OPC_CVT_S_PL = FOP(40, FMT_PS),
10567 OPC_PLL_PS = FOP(44, FMT_PS),
10568 OPC_PLU_PS = FOP(45, FMT_PS),
10569 OPC_PUL_PS = FOP(46, FMT_PS),
10570 OPC_PUU_PS = FOP(47, FMT_PS),
10571 OPC_CMP_F_PS = FOP (48, FMT_PS),
10572 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10573 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10574 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10575 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10576 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10577 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10578 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10579 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10580 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10581 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10582 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10583 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10584 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10585 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10586 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10590 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10591 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10592 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10593 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10594 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10595 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10596 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10597 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10598 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10599 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10600 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10601 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10602 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10603 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10604 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10605 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10606 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10607 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10608 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10609 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10610 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10611 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10613 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10614 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10615 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10616 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10617 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10618 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10619 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10620 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10621 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10622 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10623 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10624 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10625 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10626 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10627 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10628 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10629 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10630 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10631 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10632 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10633 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10634 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10636 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10638 TCGv t0 = tcg_temp_new();
10643 TCGv_i32 fp0 = tcg_temp_new_i32();
10645 gen_load_fpr32(ctx, fp0, fs);
10646 tcg_gen_ext_i32_tl(t0, fp0);
10647 tcg_temp_free_i32(fp0);
10649 gen_store_gpr(t0, rt);
10652 gen_load_gpr(t0, rt);
10654 TCGv_i32 fp0 = tcg_temp_new_i32();
10656 tcg_gen_trunc_tl_i32(fp0, t0);
10657 gen_store_fpr32(ctx, fp0, fs);
10658 tcg_temp_free_i32(fp0);
10662 gen_helper_1e0i(cfc1, t0, fs);
10663 gen_store_gpr(t0, rt);
10666 gen_load_gpr(t0, rt);
10667 save_cpu_state(ctx, 0);
10669 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10671 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10672 tcg_temp_free_i32(fs_tmp);
10674 /* Stop translation as we may have changed hflags */
10675 ctx->base.is_jmp = DISAS_STOP;
10677 #if defined(TARGET_MIPS64)
10679 gen_load_fpr64(ctx, t0, fs);
10680 gen_store_gpr(t0, rt);
10683 gen_load_gpr(t0, rt);
10684 gen_store_fpr64(ctx, t0, fs);
10689 TCGv_i32 fp0 = tcg_temp_new_i32();
10691 gen_load_fpr32h(ctx, fp0, fs);
10692 tcg_gen_ext_i32_tl(t0, fp0);
10693 tcg_temp_free_i32(fp0);
10695 gen_store_gpr(t0, rt);
10698 gen_load_gpr(t0, rt);
10700 TCGv_i32 fp0 = tcg_temp_new_i32();
10702 tcg_gen_trunc_tl_i32(fp0, t0);
10703 gen_store_fpr32h(ctx, fp0, fs);
10704 tcg_temp_free_i32(fp0);
10708 MIPS_INVAL("cp1 move");
10709 generate_exception_end(ctx, EXCP_RI);
10717 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10724 /* Treat as NOP. */
10729 cond = TCG_COND_EQ;
10731 cond = TCG_COND_NE;
10733 l1 = gen_new_label();
10734 t0 = tcg_temp_new_i32();
10735 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10736 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10737 tcg_temp_free_i32(t0);
10739 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10741 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10746 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10750 TCGv_i32 t0 = tcg_temp_new_i32();
10751 TCGLabel *l1 = gen_new_label();
10754 cond = TCG_COND_EQ;
10756 cond = TCG_COND_NE;
10758 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10759 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10760 gen_load_fpr32(ctx, t0, fs);
10761 gen_store_fpr32(ctx, t0, fd);
10763 tcg_temp_free_i32(t0);
10766 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10769 TCGv_i32 t0 = tcg_temp_new_i32();
10771 TCGLabel *l1 = gen_new_label();
10774 cond = TCG_COND_EQ;
10776 cond = TCG_COND_NE;
10778 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10779 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10780 tcg_temp_free_i32(t0);
10781 fp0 = tcg_temp_new_i64();
10782 gen_load_fpr64(ctx, fp0, fs);
10783 gen_store_fpr64(ctx, fp0, fd);
10784 tcg_temp_free_i64(fp0);
10788 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10792 TCGv_i32 t0 = tcg_temp_new_i32();
10793 TCGLabel *l1 = gen_new_label();
10794 TCGLabel *l2 = gen_new_label();
10797 cond = TCG_COND_EQ;
10799 cond = TCG_COND_NE;
10801 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10802 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10803 gen_load_fpr32(ctx, t0, fs);
10804 gen_store_fpr32(ctx, t0, fd);
10807 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10808 tcg_gen_brcondi_i32(cond, t0, 0, l2);
10809 gen_load_fpr32h(ctx, t0, fs);
10810 gen_store_fpr32h(ctx, t0, fd);
10811 tcg_temp_free_i32(t0);
10815 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10818 TCGv_i32 t1 = tcg_const_i32(0);
10819 TCGv_i32 fp0 = tcg_temp_new_i32();
10820 TCGv_i32 fp1 = tcg_temp_new_i32();
10821 TCGv_i32 fp2 = tcg_temp_new_i32();
10822 gen_load_fpr32(ctx, fp0, fd);
10823 gen_load_fpr32(ctx, fp1, ft);
10824 gen_load_fpr32(ctx, fp2, fs);
10828 tcg_gen_andi_i32(fp0, fp0, 1);
10829 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10832 tcg_gen_andi_i32(fp1, fp1, 1);
10833 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10836 tcg_gen_andi_i32(fp1, fp1, 1);
10837 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10840 MIPS_INVAL("gen_sel_s");
10841 generate_exception_end(ctx, EXCP_RI);
10845 gen_store_fpr32(ctx, fp0, fd);
10846 tcg_temp_free_i32(fp2);
10847 tcg_temp_free_i32(fp1);
10848 tcg_temp_free_i32(fp0);
10849 tcg_temp_free_i32(t1);
10852 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10855 TCGv_i64 t1 = tcg_const_i64(0);
10856 TCGv_i64 fp0 = tcg_temp_new_i64();
10857 TCGv_i64 fp1 = tcg_temp_new_i64();
10858 TCGv_i64 fp2 = tcg_temp_new_i64();
10859 gen_load_fpr64(ctx, fp0, fd);
10860 gen_load_fpr64(ctx, fp1, ft);
10861 gen_load_fpr64(ctx, fp2, fs);
10865 tcg_gen_andi_i64(fp0, fp0, 1);
10866 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10869 tcg_gen_andi_i64(fp1, fp1, 1);
10870 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10873 tcg_gen_andi_i64(fp1, fp1, 1);
10874 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10877 MIPS_INVAL("gen_sel_d");
10878 generate_exception_end(ctx, EXCP_RI);
10882 gen_store_fpr64(ctx, fp0, fd);
10883 tcg_temp_free_i64(fp2);
10884 tcg_temp_free_i64(fp1);
10885 tcg_temp_free_i64(fp0);
10886 tcg_temp_free_i64(t1);
10889 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10890 int ft, int fs, int fd, int cc)
10892 uint32_t func = ctx->opcode & 0x3f;
10896 TCGv_i32 fp0 = tcg_temp_new_i32();
10897 TCGv_i32 fp1 = tcg_temp_new_i32();
10899 gen_load_fpr32(ctx, fp0, fs);
10900 gen_load_fpr32(ctx, fp1, ft);
10901 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10902 tcg_temp_free_i32(fp1);
10903 gen_store_fpr32(ctx, fp0, fd);
10904 tcg_temp_free_i32(fp0);
10909 TCGv_i32 fp0 = tcg_temp_new_i32();
10910 TCGv_i32 fp1 = tcg_temp_new_i32();
10912 gen_load_fpr32(ctx, fp0, fs);
10913 gen_load_fpr32(ctx, fp1, ft);
10914 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10915 tcg_temp_free_i32(fp1);
10916 gen_store_fpr32(ctx, fp0, fd);
10917 tcg_temp_free_i32(fp0);
10922 TCGv_i32 fp0 = tcg_temp_new_i32();
10923 TCGv_i32 fp1 = tcg_temp_new_i32();
10925 gen_load_fpr32(ctx, fp0, fs);
10926 gen_load_fpr32(ctx, fp1, ft);
10927 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10928 tcg_temp_free_i32(fp1);
10929 gen_store_fpr32(ctx, fp0, fd);
10930 tcg_temp_free_i32(fp0);
10935 TCGv_i32 fp0 = tcg_temp_new_i32();
10936 TCGv_i32 fp1 = tcg_temp_new_i32();
10938 gen_load_fpr32(ctx, fp0, fs);
10939 gen_load_fpr32(ctx, fp1, ft);
10940 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10941 tcg_temp_free_i32(fp1);
10942 gen_store_fpr32(ctx, fp0, fd);
10943 tcg_temp_free_i32(fp0);
10948 TCGv_i32 fp0 = tcg_temp_new_i32();
10950 gen_load_fpr32(ctx, fp0, fs);
10951 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10952 gen_store_fpr32(ctx, fp0, fd);
10953 tcg_temp_free_i32(fp0);
10958 TCGv_i32 fp0 = tcg_temp_new_i32();
10960 gen_load_fpr32(ctx, fp0, fs);
10961 if (ctx->abs2008) {
10962 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10964 gen_helper_float_abs_s(fp0, fp0);
10966 gen_store_fpr32(ctx, fp0, fd);
10967 tcg_temp_free_i32(fp0);
10972 TCGv_i32 fp0 = tcg_temp_new_i32();
10974 gen_load_fpr32(ctx, fp0, fs);
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 if (ctx->abs2008) {
10985 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10987 gen_helper_float_chs_s(fp0, fp0);
10989 gen_store_fpr32(ctx, fp0, fd);
10990 tcg_temp_free_i32(fp0);
10993 case OPC_ROUND_L_S:
10994 check_cp1_64bitmode(ctx);
10996 TCGv_i32 fp32 = tcg_temp_new_i32();
10997 TCGv_i64 fp64 = tcg_temp_new_i64();
10999 gen_load_fpr32(ctx, fp32, fs);
11000 if (ctx->nan2008) {
11001 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11003 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11005 tcg_temp_free_i32(fp32);
11006 gen_store_fpr64(ctx, fp64, fd);
11007 tcg_temp_free_i64(fp64);
11010 case OPC_TRUNC_L_S:
11011 check_cp1_64bitmode(ctx);
11013 TCGv_i32 fp32 = tcg_temp_new_i32();
11014 TCGv_i64 fp64 = tcg_temp_new_i64();
11016 gen_load_fpr32(ctx, fp32, fs);
11017 if (ctx->nan2008) {
11018 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11020 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11022 tcg_temp_free_i32(fp32);
11023 gen_store_fpr64(ctx, fp64, fd);
11024 tcg_temp_free_i64(fp64);
11028 check_cp1_64bitmode(ctx);
11030 TCGv_i32 fp32 = tcg_temp_new_i32();
11031 TCGv_i64 fp64 = tcg_temp_new_i64();
11033 gen_load_fpr32(ctx, fp32, fs);
11034 if (ctx->nan2008) {
11035 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11037 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11039 tcg_temp_free_i32(fp32);
11040 gen_store_fpr64(ctx, fp64, fd);
11041 tcg_temp_free_i64(fp64);
11044 case OPC_FLOOR_L_S:
11045 check_cp1_64bitmode(ctx);
11047 TCGv_i32 fp32 = tcg_temp_new_i32();
11048 TCGv_i64 fp64 = tcg_temp_new_i64();
11050 gen_load_fpr32(ctx, fp32, fs);
11051 if (ctx->nan2008) {
11052 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11054 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11056 tcg_temp_free_i32(fp32);
11057 gen_store_fpr64(ctx, fp64, fd);
11058 tcg_temp_free_i64(fp64);
11061 case OPC_ROUND_W_S:
11063 TCGv_i32 fp0 = tcg_temp_new_i32();
11065 gen_load_fpr32(ctx, fp0, fs);
11066 if (ctx->nan2008) {
11067 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11069 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11071 gen_store_fpr32(ctx, fp0, fd);
11072 tcg_temp_free_i32(fp0);
11075 case OPC_TRUNC_W_S:
11077 TCGv_i32 fp0 = tcg_temp_new_i32();
11079 gen_load_fpr32(ctx, fp0, fs);
11080 if (ctx->nan2008) {
11081 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11083 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11085 gen_store_fpr32(ctx, fp0, fd);
11086 tcg_temp_free_i32(fp0);
11091 TCGv_i32 fp0 = tcg_temp_new_i32();
11093 gen_load_fpr32(ctx, fp0, fs);
11094 if (ctx->nan2008) {
11095 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11097 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11099 gen_store_fpr32(ctx, fp0, fd);
11100 tcg_temp_free_i32(fp0);
11103 case OPC_FLOOR_W_S:
11105 TCGv_i32 fp0 = tcg_temp_new_i32();
11107 gen_load_fpr32(ctx, fp0, fs);
11108 if (ctx->nan2008) {
11109 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11111 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11113 gen_store_fpr32(ctx, fp0, fd);
11114 tcg_temp_free_i32(fp0);
11118 check_insn(ctx, ISA_MIPS32R6);
11119 gen_sel_s(ctx, op1, fd, ft, fs);
11122 check_insn(ctx, ISA_MIPS32R6);
11123 gen_sel_s(ctx, op1, fd, ft, fs);
11126 check_insn(ctx, ISA_MIPS32R6);
11127 gen_sel_s(ctx, op1, fd, ft, fs);
11130 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11131 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11134 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11136 TCGLabel *l1 = gen_new_label();
11140 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11142 fp0 = tcg_temp_new_i32();
11143 gen_load_fpr32(ctx, fp0, fs);
11144 gen_store_fpr32(ctx, fp0, fd);
11145 tcg_temp_free_i32(fp0);
11150 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11152 TCGLabel *l1 = gen_new_label();
11156 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11157 fp0 = tcg_temp_new_i32();
11158 gen_load_fpr32(ctx, fp0, fs);
11159 gen_store_fpr32(ctx, fp0, fd);
11160 tcg_temp_free_i32(fp0);
11167 TCGv_i32 fp0 = tcg_temp_new_i32();
11169 gen_load_fpr32(ctx, fp0, fs);
11170 gen_helper_float_recip_s(fp0, cpu_env, fp0);
11171 gen_store_fpr32(ctx, fp0, fd);
11172 tcg_temp_free_i32(fp0);
11177 TCGv_i32 fp0 = tcg_temp_new_i32();
11179 gen_load_fpr32(ctx, fp0, fs);
11180 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11181 gen_store_fpr32(ctx, fp0, fd);
11182 tcg_temp_free_i32(fp0);
11186 check_insn(ctx, ISA_MIPS32R6);
11188 TCGv_i32 fp0 = tcg_temp_new_i32();
11189 TCGv_i32 fp1 = tcg_temp_new_i32();
11190 TCGv_i32 fp2 = tcg_temp_new_i32();
11191 gen_load_fpr32(ctx, fp0, fs);
11192 gen_load_fpr32(ctx, fp1, ft);
11193 gen_load_fpr32(ctx, fp2, fd);
11194 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11195 gen_store_fpr32(ctx, fp2, fd);
11196 tcg_temp_free_i32(fp2);
11197 tcg_temp_free_i32(fp1);
11198 tcg_temp_free_i32(fp0);
11202 check_insn(ctx, ISA_MIPS32R6);
11204 TCGv_i32 fp0 = tcg_temp_new_i32();
11205 TCGv_i32 fp1 = tcg_temp_new_i32();
11206 TCGv_i32 fp2 = tcg_temp_new_i32();
11207 gen_load_fpr32(ctx, fp0, fs);
11208 gen_load_fpr32(ctx, fp1, ft);
11209 gen_load_fpr32(ctx, fp2, fd);
11210 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11211 gen_store_fpr32(ctx, fp2, fd);
11212 tcg_temp_free_i32(fp2);
11213 tcg_temp_free_i32(fp1);
11214 tcg_temp_free_i32(fp0);
11218 check_insn(ctx, ISA_MIPS32R6);
11220 TCGv_i32 fp0 = tcg_temp_new_i32();
11221 gen_load_fpr32(ctx, fp0, fs);
11222 gen_helper_float_rint_s(fp0, cpu_env, fp0);
11223 gen_store_fpr32(ctx, fp0, fd);
11224 tcg_temp_free_i32(fp0);
11228 check_insn(ctx, ISA_MIPS32R6);
11230 TCGv_i32 fp0 = tcg_temp_new_i32();
11231 gen_load_fpr32(ctx, fp0, fs);
11232 gen_helper_float_class_s(fp0, cpu_env, fp0);
11233 gen_store_fpr32(ctx, fp0, fd);
11234 tcg_temp_free_i32(fp0);
11237 case OPC_MIN_S: /* OPC_RECIP2_S */
11238 if (ctx->insn_flags & ISA_MIPS32R6) {
11240 TCGv_i32 fp0 = tcg_temp_new_i32();
11241 TCGv_i32 fp1 = tcg_temp_new_i32();
11242 TCGv_i32 fp2 = tcg_temp_new_i32();
11243 gen_load_fpr32(ctx, fp0, fs);
11244 gen_load_fpr32(ctx, fp1, ft);
11245 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11246 gen_store_fpr32(ctx, fp2, fd);
11247 tcg_temp_free_i32(fp2);
11248 tcg_temp_free_i32(fp1);
11249 tcg_temp_free_i32(fp0);
11252 check_cp1_64bitmode(ctx);
11254 TCGv_i32 fp0 = tcg_temp_new_i32();
11255 TCGv_i32 fp1 = tcg_temp_new_i32();
11257 gen_load_fpr32(ctx, fp0, fs);
11258 gen_load_fpr32(ctx, fp1, ft);
11259 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11260 tcg_temp_free_i32(fp1);
11261 gen_store_fpr32(ctx, fp0, fd);
11262 tcg_temp_free_i32(fp0);
11266 case OPC_MINA_S: /* OPC_RECIP1_S */
11267 if (ctx->insn_flags & ISA_MIPS32R6) {
11269 TCGv_i32 fp0 = tcg_temp_new_i32();
11270 TCGv_i32 fp1 = tcg_temp_new_i32();
11271 TCGv_i32 fp2 = tcg_temp_new_i32();
11272 gen_load_fpr32(ctx, fp0, fs);
11273 gen_load_fpr32(ctx, fp1, ft);
11274 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11275 gen_store_fpr32(ctx, fp2, fd);
11276 tcg_temp_free_i32(fp2);
11277 tcg_temp_free_i32(fp1);
11278 tcg_temp_free_i32(fp0);
11281 check_cp1_64bitmode(ctx);
11283 TCGv_i32 fp0 = tcg_temp_new_i32();
11285 gen_load_fpr32(ctx, fp0, fs);
11286 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11287 gen_store_fpr32(ctx, fp0, fd);
11288 tcg_temp_free_i32(fp0);
11292 case OPC_MAX_S: /* OPC_RSQRT1_S */
11293 if (ctx->insn_flags & ISA_MIPS32R6) {
11295 TCGv_i32 fp0 = tcg_temp_new_i32();
11296 TCGv_i32 fp1 = tcg_temp_new_i32();
11297 gen_load_fpr32(ctx, fp0, fs);
11298 gen_load_fpr32(ctx, fp1, ft);
11299 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11300 gen_store_fpr32(ctx, fp1, fd);
11301 tcg_temp_free_i32(fp1);
11302 tcg_temp_free_i32(fp0);
11305 check_cp1_64bitmode(ctx);
11307 TCGv_i32 fp0 = tcg_temp_new_i32();
11309 gen_load_fpr32(ctx, fp0, fs);
11310 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11311 gen_store_fpr32(ctx, fp0, fd);
11312 tcg_temp_free_i32(fp0);
11316 case OPC_MAXA_S: /* OPC_RSQRT2_S */
11317 if (ctx->insn_flags & ISA_MIPS32R6) {
11319 TCGv_i32 fp0 = tcg_temp_new_i32();
11320 TCGv_i32 fp1 = tcg_temp_new_i32();
11321 gen_load_fpr32(ctx, fp0, fs);
11322 gen_load_fpr32(ctx, fp1, ft);
11323 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11324 gen_store_fpr32(ctx, fp1, fd);
11325 tcg_temp_free_i32(fp1);
11326 tcg_temp_free_i32(fp0);
11329 check_cp1_64bitmode(ctx);
11331 TCGv_i32 fp0 = tcg_temp_new_i32();
11332 TCGv_i32 fp1 = tcg_temp_new_i32();
11334 gen_load_fpr32(ctx, fp0, fs);
11335 gen_load_fpr32(ctx, fp1, ft);
11336 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11337 tcg_temp_free_i32(fp1);
11338 gen_store_fpr32(ctx, fp0, fd);
11339 tcg_temp_free_i32(fp0);
11344 check_cp1_registers(ctx, fd);
11346 TCGv_i32 fp32 = tcg_temp_new_i32();
11347 TCGv_i64 fp64 = tcg_temp_new_i64();
11349 gen_load_fpr32(ctx, fp32, fs);
11350 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11351 tcg_temp_free_i32(fp32);
11352 gen_store_fpr64(ctx, fp64, fd);
11353 tcg_temp_free_i64(fp64);
11358 TCGv_i32 fp0 = tcg_temp_new_i32();
11360 gen_load_fpr32(ctx, fp0, fs);
11361 if (ctx->nan2008) {
11362 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11364 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11366 gen_store_fpr32(ctx, fp0, fd);
11367 tcg_temp_free_i32(fp0);
11371 check_cp1_64bitmode(ctx);
11373 TCGv_i32 fp32 = tcg_temp_new_i32();
11374 TCGv_i64 fp64 = tcg_temp_new_i64();
11376 gen_load_fpr32(ctx, fp32, fs);
11377 if (ctx->nan2008) {
11378 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11380 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11382 tcg_temp_free_i32(fp32);
11383 gen_store_fpr64(ctx, fp64, fd);
11384 tcg_temp_free_i64(fp64);
11390 TCGv_i64 fp64 = tcg_temp_new_i64();
11391 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11392 TCGv_i32 fp32_1 = tcg_temp_new_i32();
11394 gen_load_fpr32(ctx, fp32_0, fs);
11395 gen_load_fpr32(ctx, fp32_1, ft);
11396 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11397 tcg_temp_free_i32(fp32_1);
11398 tcg_temp_free_i32(fp32_0);
11399 gen_store_fpr64(ctx, fp64, fd);
11400 tcg_temp_free_i64(fp64);
11406 case OPC_CMP_UEQ_S:
11407 case OPC_CMP_OLT_S:
11408 case OPC_CMP_ULT_S:
11409 case OPC_CMP_OLE_S:
11410 case OPC_CMP_ULE_S:
11412 case OPC_CMP_NGLE_S:
11413 case OPC_CMP_SEQ_S:
11414 case OPC_CMP_NGL_S:
11416 case OPC_CMP_NGE_S:
11418 case OPC_CMP_NGT_S:
11419 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11420 if (ctx->opcode & (1 << 6)) {
11421 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11423 gen_cmp_s(ctx, func-48, ft, fs, cc);
11427 check_cp1_registers(ctx, fs | ft | fd);
11429 TCGv_i64 fp0 = tcg_temp_new_i64();
11430 TCGv_i64 fp1 = tcg_temp_new_i64();
11432 gen_load_fpr64(ctx, fp0, fs);
11433 gen_load_fpr64(ctx, fp1, ft);
11434 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11435 tcg_temp_free_i64(fp1);
11436 gen_store_fpr64(ctx, fp0, fd);
11437 tcg_temp_free_i64(fp0);
11441 check_cp1_registers(ctx, fs | ft | fd);
11443 TCGv_i64 fp0 = tcg_temp_new_i64();
11444 TCGv_i64 fp1 = tcg_temp_new_i64();
11446 gen_load_fpr64(ctx, fp0, fs);
11447 gen_load_fpr64(ctx, fp1, ft);
11448 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11449 tcg_temp_free_i64(fp1);
11450 gen_store_fpr64(ctx, fp0, fd);
11451 tcg_temp_free_i64(fp0);
11455 check_cp1_registers(ctx, fs | ft | fd);
11457 TCGv_i64 fp0 = tcg_temp_new_i64();
11458 TCGv_i64 fp1 = tcg_temp_new_i64();
11460 gen_load_fpr64(ctx, fp0, fs);
11461 gen_load_fpr64(ctx, fp1, ft);
11462 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11463 tcg_temp_free_i64(fp1);
11464 gen_store_fpr64(ctx, fp0, fd);
11465 tcg_temp_free_i64(fp0);
11469 check_cp1_registers(ctx, fs | ft | fd);
11471 TCGv_i64 fp0 = tcg_temp_new_i64();
11472 TCGv_i64 fp1 = tcg_temp_new_i64();
11474 gen_load_fpr64(ctx, fp0, fs);
11475 gen_load_fpr64(ctx, fp1, ft);
11476 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11477 tcg_temp_free_i64(fp1);
11478 gen_store_fpr64(ctx, fp0, fd);
11479 tcg_temp_free_i64(fp0);
11483 check_cp1_registers(ctx, fs | fd);
11485 TCGv_i64 fp0 = tcg_temp_new_i64();
11487 gen_load_fpr64(ctx, fp0, fs);
11488 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11489 gen_store_fpr64(ctx, fp0, fd);
11490 tcg_temp_free_i64(fp0);
11494 check_cp1_registers(ctx, fs | fd);
11496 TCGv_i64 fp0 = tcg_temp_new_i64();
11498 gen_load_fpr64(ctx, fp0, fs);
11499 if (ctx->abs2008) {
11500 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11502 gen_helper_float_abs_d(fp0, fp0);
11504 gen_store_fpr64(ctx, fp0, fd);
11505 tcg_temp_free_i64(fp0);
11509 check_cp1_registers(ctx, fs | fd);
11511 TCGv_i64 fp0 = tcg_temp_new_i64();
11513 gen_load_fpr64(ctx, fp0, fs);
11514 gen_store_fpr64(ctx, fp0, fd);
11515 tcg_temp_free_i64(fp0);
11519 check_cp1_registers(ctx, fs | fd);
11521 TCGv_i64 fp0 = tcg_temp_new_i64();
11523 gen_load_fpr64(ctx, fp0, fs);
11524 if (ctx->abs2008) {
11525 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11527 gen_helper_float_chs_d(fp0, fp0);
11529 gen_store_fpr64(ctx, fp0, fd);
11530 tcg_temp_free_i64(fp0);
11533 case OPC_ROUND_L_D:
11534 check_cp1_64bitmode(ctx);
11536 TCGv_i64 fp0 = tcg_temp_new_i64();
11538 gen_load_fpr64(ctx, fp0, fs);
11539 if (ctx->nan2008) {
11540 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11542 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11544 gen_store_fpr64(ctx, fp0, fd);
11545 tcg_temp_free_i64(fp0);
11548 case OPC_TRUNC_L_D:
11549 check_cp1_64bitmode(ctx);
11551 TCGv_i64 fp0 = tcg_temp_new_i64();
11553 gen_load_fpr64(ctx, fp0, fs);
11554 if (ctx->nan2008) {
11555 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11557 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11559 gen_store_fpr64(ctx, fp0, fd);
11560 tcg_temp_free_i64(fp0);
11564 check_cp1_64bitmode(ctx);
11566 TCGv_i64 fp0 = tcg_temp_new_i64();
11568 gen_load_fpr64(ctx, fp0, fs);
11569 if (ctx->nan2008) {
11570 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11572 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11574 gen_store_fpr64(ctx, fp0, fd);
11575 tcg_temp_free_i64(fp0);
11578 case OPC_FLOOR_L_D:
11579 check_cp1_64bitmode(ctx);
11581 TCGv_i64 fp0 = tcg_temp_new_i64();
11583 gen_load_fpr64(ctx, fp0, fs);
11584 if (ctx->nan2008) {
11585 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11587 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11589 gen_store_fpr64(ctx, fp0, fd);
11590 tcg_temp_free_i64(fp0);
11593 case OPC_ROUND_W_D:
11594 check_cp1_registers(ctx, fs);
11596 TCGv_i32 fp32 = tcg_temp_new_i32();
11597 TCGv_i64 fp64 = tcg_temp_new_i64();
11599 gen_load_fpr64(ctx, fp64, fs);
11600 if (ctx->nan2008) {
11601 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11603 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11605 tcg_temp_free_i64(fp64);
11606 gen_store_fpr32(ctx, fp32, fd);
11607 tcg_temp_free_i32(fp32);
11610 case OPC_TRUNC_W_D:
11611 check_cp1_registers(ctx, fs);
11613 TCGv_i32 fp32 = tcg_temp_new_i32();
11614 TCGv_i64 fp64 = tcg_temp_new_i64();
11616 gen_load_fpr64(ctx, fp64, fs);
11617 if (ctx->nan2008) {
11618 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11620 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11622 tcg_temp_free_i64(fp64);
11623 gen_store_fpr32(ctx, fp32, fd);
11624 tcg_temp_free_i32(fp32);
11628 check_cp1_registers(ctx, fs);
11630 TCGv_i32 fp32 = tcg_temp_new_i32();
11631 TCGv_i64 fp64 = tcg_temp_new_i64();
11633 gen_load_fpr64(ctx, fp64, fs);
11634 if (ctx->nan2008) {
11635 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11637 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11639 tcg_temp_free_i64(fp64);
11640 gen_store_fpr32(ctx, fp32, fd);
11641 tcg_temp_free_i32(fp32);
11644 case OPC_FLOOR_W_D:
11645 check_cp1_registers(ctx, fs);
11647 TCGv_i32 fp32 = tcg_temp_new_i32();
11648 TCGv_i64 fp64 = tcg_temp_new_i64();
11650 gen_load_fpr64(ctx, fp64, fs);
11651 if (ctx->nan2008) {
11652 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11654 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11656 tcg_temp_free_i64(fp64);
11657 gen_store_fpr32(ctx, fp32, fd);
11658 tcg_temp_free_i32(fp32);
11662 check_insn(ctx, ISA_MIPS32R6);
11663 gen_sel_d(ctx, op1, fd, ft, fs);
11666 check_insn(ctx, ISA_MIPS32R6);
11667 gen_sel_d(ctx, op1, fd, ft, fs);
11670 check_insn(ctx, ISA_MIPS32R6);
11671 gen_sel_d(ctx, op1, fd, ft, fs);
11674 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11675 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11678 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11680 TCGLabel *l1 = gen_new_label();
11684 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11686 fp0 = tcg_temp_new_i64();
11687 gen_load_fpr64(ctx, fp0, fs);
11688 gen_store_fpr64(ctx, fp0, fd);
11689 tcg_temp_free_i64(fp0);
11694 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11696 TCGLabel *l1 = gen_new_label();
11700 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11701 fp0 = tcg_temp_new_i64();
11702 gen_load_fpr64(ctx, fp0, fs);
11703 gen_store_fpr64(ctx, fp0, fd);
11704 tcg_temp_free_i64(fp0);
11710 check_cp1_registers(ctx, fs | fd);
11712 TCGv_i64 fp0 = tcg_temp_new_i64();
11714 gen_load_fpr64(ctx, fp0, fs);
11715 gen_helper_float_recip_d(fp0, cpu_env, fp0);
11716 gen_store_fpr64(ctx, fp0, fd);
11717 tcg_temp_free_i64(fp0);
11721 check_cp1_registers(ctx, fs | fd);
11723 TCGv_i64 fp0 = tcg_temp_new_i64();
11725 gen_load_fpr64(ctx, fp0, fs);
11726 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11727 gen_store_fpr64(ctx, fp0, fd);
11728 tcg_temp_free_i64(fp0);
11732 check_insn(ctx, ISA_MIPS32R6);
11734 TCGv_i64 fp0 = tcg_temp_new_i64();
11735 TCGv_i64 fp1 = tcg_temp_new_i64();
11736 TCGv_i64 fp2 = tcg_temp_new_i64();
11737 gen_load_fpr64(ctx, fp0, fs);
11738 gen_load_fpr64(ctx, fp1, ft);
11739 gen_load_fpr64(ctx, fp2, fd);
11740 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11741 gen_store_fpr64(ctx, fp2, fd);
11742 tcg_temp_free_i64(fp2);
11743 tcg_temp_free_i64(fp1);
11744 tcg_temp_free_i64(fp0);
11748 check_insn(ctx, ISA_MIPS32R6);
11750 TCGv_i64 fp0 = tcg_temp_new_i64();
11751 TCGv_i64 fp1 = tcg_temp_new_i64();
11752 TCGv_i64 fp2 = tcg_temp_new_i64();
11753 gen_load_fpr64(ctx, fp0, fs);
11754 gen_load_fpr64(ctx, fp1, ft);
11755 gen_load_fpr64(ctx, fp2, fd);
11756 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11757 gen_store_fpr64(ctx, fp2, fd);
11758 tcg_temp_free_i64(fp2);
11759 tcg_temp_free_i64(fp1);
11760 tcg_temp_free_i64(fp0);
11764 check_insn(ctx, ISA_MIPS32R6);
11766 TCGv_i64 fp0 = tcg_temp_new_i64();
11767 gen_load_fpr64(ctx, fp0, fs);
11768 gen_helper_float_rint_d(fp0, cpu_env, fp0);
11769 gen_store_fpr64(ctx, fp0, fd);
11770 tcg_temp_free_i64(fp0);
11774 check_insn(ctx, ISA_MIPS32R6);
11776 TCGv_i64 fp0 = tcg_temp_new_i64();
11777 gen_load_fpr64(ctx, fp0, fs);
11778 gen_helper_float_class_d(fp0, cpu_env, fp0);
11779 gen_store_fpr64(ctx, fp0, fd);
11780 tcg_temp_free_i64(fp0);
11783 case OPC_MIN_D: /* OPC_RECIP2_D */
11784 if (ctx->insn_flags & ISA_MIPS32R6) {
11786 TCGv_i64 fp0 = tcg_temp_new_i64();
11787 TCGv_i64 fp1 = tcg_temp_new_i64();
11788 gen_load_fpr64(ctx, fp0, fs);
11789 gen_load_fpr64(ctx, fp1, ft);
11790 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11791 gen_store_fpr64(ctx, fp1, fd);
11792 tcg_temp_free_i64(fp1);
11793 tcg_temp_free_i64(fp0);
11796 check_cp1_64bitmode(ctx);
11798 TCGv_i64 fp0 = tcg_temp_new_i64();
11799 TCGv_i64 fp1 = tcg_temp_new_i64();
11801 gen_load_fpr64(ctx, fp0, fs);
11802 gen_load_fpr64(ctx, fp1, ft);
11803 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11804 tcg_temp_free_i64(fp1);
11805 gen_store_fpr64(ctx, fp0, fd);
11806 tcg_temp_free_i64(fp0);
11810 case OPC_MINA_D: /* OPC_RECIP1_D */
11811 if (ctx->insn_flags & ISA_MIPS32R6) {
11813 TCGv_i64 fp0 = tcg_temp_new_i64();
11814 TCGv_i64 fp1 = tcg_temp_new_i64();
11815 gen_load_fpr64(ctx, fp0, fs);
11816 gen_load_fpr64(ctx, fp1, ft);
11817 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11818 gen_store_fpr64(ctx, fp1, fd);
11819 tcg_temp_free_i64(fp1);
11820 tcg_temp_free_i64(fp0);
11823 check_cp1_64bitmode(ctx);
11825 TCGv_i64 fp0 = tcg_temp_new_i64();
11827 gen_load_fpr64(ctx, fp0, fs);
11828 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11829 gen_store_fpr64(ctx, fp0, fd);
11830 tcg_temp_free_i64(fp0);
11834 case OPC_MAX_D: /* OPC_RSQRT1_D */
11835 if (ctx->insn_flags & ISA_MIPS32R6) {
11837 TCGv_i64 fp0 = tcg_temp_new_i64();
11838 TCGv_i64 fp1 = tcg_temp_new_i64();
11839 gen_load_fpr64(ctx, fp0, fs);
11840 gen_load_fpr64(ctx, fp1, ft);
11841 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11842 gen_store_fpr64(ctx, fp1, fd);
11843 tcg_temp_free_i64(fp1);
11844 tcg_temp_free_i64(fp0);
11847 check_cp1_64bitmode(ctx);
11849 TCGv_i64 fp0 = tcg_temp_new_i64();
11851 gen_load_fpr64(ctx, fp0, fs);
11852 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11853 gen_store_fpr64(ctx, fp0, fd);
11854 tcg_temp_free_i64(fp0);
11858 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11859 if (ctx->insn_flags & ISA_MIPS32R6) {
11861 TCGv_i64 fp0 = tcg_temp_new_i64();
11862 TCGv_i64 fp1 = tcg_temp_new_i64();
11863 gen_load_fpr64(ctx, fp0, fs);
11864 gen_load_fpr64(ctx, fp1, ft);
11865 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11866 gen_store_fpr64(ctx, fp1, fd);
11867 tcg_temp_free_i64(fp1);
11868 tcg_temp_free_i64(fp0);
11871 check_cp1_64bitmode(ctx);
11873 TCGv_i64 fp0 = tcg_temp_new_i64();
11874 TCGv_i64 fp1 = tcg_temp_new_i64();
11876 gen_load_fpr64(ctx, fp0, fs);
11877 gen_load_fpr64(ctx, fp1, ft);
11878 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11879 tcg_temp_free_i64(fp1);
11880 gen_store_fpr64(ctx, fp0, fd);
11881 tcg_temp_free_i64(fp0);
11888 case OPC_CMP_UEQ_D:
11889 case OPC_CMP_OLT_D:
11890 case OPC_CMP_ULT_D:
11891 case OPC_CMP_OLE_D:
11892 case OPC_CMP_ULE_D:
11894 case OPC_CMP_NGLE_D:
11895 case OPC_CMP_SEQ_D:
11896 case OPC_CMP_NGL_D:
11898 case OPC_CMP_NGE_D:
11900 case OPC_CMP_NGT_D:
11901 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11902 if (ctx->opcode & (1 << 6)) {
11903 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11905 gen_cmp_d(ctx, func-48, ft, fs, cc);
11909 check_cp1_registers(ctx, fs);
11911 TCGv_i32 fp32 = tcg_temp_new_i32();
11912 TCGv_i64 fp64 = tcg_temp_new_i64();
11914 gen_load_fpr64(ctx, fp64, fs);
11915 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11916 tcg_temp_free_i64(fp64);
11917 gen_store_fpr32(ctx, fp32, fd);
11918 tcg_temp_free_i32(fp32);
11922 check_cp1_registers(ctx, fs);
11924 TCGv_i32 fp32 = tcg_temp_new_i32();
11925 TCGv_i64 fp64 = tcg_temp_new_i64();
11927 gen_load_fpr64(ctx, fp64, fs);
11928 if (ctx->nan2008) {
11929 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11931 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11933 tcg_temp_free_i64(fp64);
11934 gen_store_fpr32(ctx, fp32, fd);
11935 tcg_temp_free_i32(fp32);
11939 check_cp1_64bitmode(ctx);
11941 TCGv_i64 fp0 = tcg_temp_new_i64();
11943 gen_load_fpr64(ctx, fp0, fs);
11944 if (ctx->nan2008) {
11945 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11947 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11949 gen_store_fpr64(ctx, fp0, fd);
11950 tcg_temp_free_i64(fp0);
11955 TCGv_i32 fp0 = tcg_temp_new_i32();
11957 gen_load_fpr32(ctx, fp0, fs);
11958 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11959 gen_store_fpr32(ctx, fp0, fd);
11960 tcg_temp_free_i32(fp0);
11964 check_cp1_registers(ctx, fd);
11966 TCGv_i32 fp32 = tcg_temp_new_i32();
11967 TCGv_i64 fp64 = tcg_temp_new_i64();
11969 gen_load_fpr32(ctx, fp32, fs);
11970 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11971 tcg_temp_free_i32(fp32);
11972 gen_store_fpr64(ctx, fp64, fd);
11973 tcg_temp_free_i64(fp64);
11977 check_cp1_64bitmode(ctx);
11979 TCGv_i32 fp32 = tcg_temp_new_i32();
11980 TCGv_i64 fp64 = tcg_temp_new_i64();
11982 gen_load_fpr64(ctx, fp64, fs);
11983 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11984 tcg_temp_free_i64(fp64);
11985 gen_store_fpr32(ctx, fp32, fd);
11986 tcg_temp_free_i32(fp32);
11990 check_cp1_64bitmode(ctx);
11992 TCGv_i64 fp0 = tcg_temp_new_i64();
11994 gen_load_fpr64(ctx, fp0, fs);
11995 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11996 gen_store_fpr64(ctx, fp0, fd);
11997 tcg_temp_free_i64(fp0);
12000 case OPC_CVT_PS_PW:
12003 TCGv_i64 fp0 = tcg_temp_new_i64();
12005 gen_load_fpr64(ctx, fp0, fs);
12006 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12007 gen_store_fpr64(ctx, fp0, fd);
12008 tcg_temp_free_i64(fp0);
12014 TCGv_i64 fp0 = tcg_temp_new_i64();
12015 TCGv_i64 fp1 = tcg_temp_new_i64();
12017 gen_load_fpr64(ctx, fp0, fs);
12018 gen_load_fpr64(ctx, fp1, ft);
12019 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12020 tcg_temp_free_i64(fp1);
12021 gen_store_fpr64(ctx, fp0, fd);
12022 tcg_temp_free_i64(fp0);
12028 TCGv_i64 fp0 = tcg_temp_new_i64();
12029 TCGv_i64 fp1 = tcg_temp_new_i64();
12031 gen_load_fpr64(ctx, fp0, fs);
12032 gen_load_fpr64(ctx, fp1, ft);
12033 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12034 tcg_temp_free_i64(fp1);
12035 gen_store_fpr64(ctx, fp0, fd);
12036 tcg_temp_free_i64(fp0);
12042 TCGv_i64 fp0 = tcg_temp_new_i64();
12043 TCGv_i64 fp1 = tcg_temp_new_i64();
12045 gen_load_fpr64(ctx, fp0, fs);
12046 gen_load_fpr64(ctx, fp1, ft);
12047 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12048 tcg_temp_free_i64(fp1);
12049 gen_store_fpr64(ctx, fp0, fd);
12050 tcg_temp_free_i64(fp0);
12056 TCGv_i64 fp0 = tcg_temp_new_i64();
12058 gen_load_fpr64(ctx, fp0, fs);
12059 gen_helper_float_abs_ps(fp0, fp0);
12060 gen_store_fpr64(ctx, fp0, fd);
12061 tcg_temp_free_i64(fp0);
12067 TCGv_i64 fp0 = tcg_temp_new_i64();
12069 gen_load_fpr64(ctx, fp0, fs);
12070 gen_store_fpr64(ctx, fp0, fd);
12071 tcg_temp_free_i64(fp0);
12077 TCGv_i64 fp0 = tcg_temp_new_i64();
12079 gen_load_fpr64(ctx, fp0, fs);
12080 gen_helper_float_chs_ps(fp0, fp0);
12081 gen_store_fpr64(ctx, fp0, fd);
12082 tcg_temp_free_i64(fp0);
12087 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12092 TCGLabel *l1 = gen_new_label();
12096 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12097 fp0 = tcg_temp_new_i64();
12098 gen_load_fpr64(ctx, fp0, fs);
12099 gen_store_fpr64(ctx, fp0, fd);
12100 tcg_temp_free_i64(fp0);
12107 TCGLabel *l1 = gen_new_label();
12111 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12112 fp0 = tcg_temp_new_i64();
12113 gen_load_fpr64(ctx, fp0, fs);
12114 gen_store_fpr64(ctx, fp0, fd);
12115 tcg_temp_free_i64(fp0);
12123 TCGv_i64 fp0 = tcg_temp_new_i64();
12124 TCGv_i64 fp1 = tcg_temp_new_i64();
12126 gen_load_fpr64(ctx, fp0, ft);
12127 gen_load_fpr64(ctx, fp1, fs);
12128 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12129 tcg_temp_free_i64(fp1);
12130 gen_store_fpr64(ctx, fp0, fd);
12131 tcg_temp_free_i64(fp0);
12137 TCGv_i64 fp0 = tcg_temp_new_i64();
12138 TCGv_i64 fp1 = tcg_temp_new_i64();
12140 gen_load_fpr64(ctx, fp0, ft);
12141 gen_load_fpr64(ctx, fp1, fs);
12142 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12143 tcg_temp_free_i64(fp1);
12144 gen_store_fpr64(ctx, fp0, fd);
12145 tcg_temp_free_i64(fp0);
12148 case OPC_RECIP2_PS:
12151 TCGv_i64 fp0 = tcg_temp_new_i64();
12152 TCGv_i64 fp1 = tcg_temp_new_i64();
12154 gen_load_fpr64(ctx, fp0, fs);
12155 gen_load_fpr64(ctx, fp1, ft);
12156 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12157 tcg_temp_free_i64(fp1);
12158 gen_store_fpr64(ctx, fp0, fd);
12159 tcg_temp_free_i64(fp0);
12162 case OPC_RECIP1_PS:
12165 TCGv_i64 fp0 = tcg_temp_new_i64();
12167 gen_load_fpr64(ctx, fp0, fs);
12168 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12169 gen_store_fpr64(ctx, fp0, fd);
12170 tcg_temp_free_i64(fp0);
12173 case OPC_RSQRT1_PS:
12176 TCGv_i64 fp0 = tcg_temp_new_i64();
12178 gen_load_fpr64(ctx, fp0, fs);
12179 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12180 gen_store_fpr64(ctx, fp0, fd);
12181 tcg_temp_free_i64(fp0);
12184 case OPC_RSQRT2_PS:
12187 TCGv_i64 fp0 = tcg_temp_new_i64();
12188 TCGv_i64 fp1 = tcg_temp_new_i64();
12190 gen_load_fpr64(ctx, fp0, fs);
12191 gen_load_fpr64(ctx, fp1, ft);
12192 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12193 tcg_temp_free_i64(fp1);
12194 gen_store_fpr64(ctx, fp0, fd);
12195 tcg_temp_free_i64(fp0);
12199 check_cp1_64bitmode(ctx);
12201 TCGv_i32 fp0 = tcg_temp_new_i32();
12203 gen_load_fpr32h(ctx, fp0, fs);
12204 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12205 gen_store_fpr32(ctx, fp0, fd);
12206 tcg_temp_free_i32(fp0);
12209 case OPC_CVT_PW_PS:
12212 TCGv_i64 fp0 = tcg_temp_new_i64();
12214 gen_load_fpr64(ctx, fp0, fs);
12215 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12216 gen_store_fpr64(ctx, fp0, fd);
12217 tcg_temp_free_i64(fp0);
12221 check_cp1_64bitmode(ctx);
12223 TCGv_i32 fp0 = tcg_temp_new_i32();
12225 gen_load_fpr32(ctx, fp0, fs);
12226 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12227 gen_store_fpr32(ctx, fp0, fd);
12228 tcg_temp_free_i32(fp0);
12234 TCGv_i32 fp0 = tcg_temp_new_i32();
12235 TCGv_i32 fp1 = tcg_temp_new_i32();
12237 gen_load_fpr32(ctx, fp0, fs);
12238 gen_load_fpr32(ctx, fp1, ft);
12239 gen_store_fpr32h(ctx, fp0, fd);
12240 gen_store_fpr32(ctx, fp1, fd);
12241 tcg_temp_free_i32(fp0);
12242 tcg_temp_free_i32(fp1);
12248 TCGv_i32 fp0 = tcg_temp_new_i32();
12249 TCGv_i32 fp1 = tcg_temp_new_i32();
12251 gen_load_fpr32(ctx, fp0, fs);
12252 gen_load_fpr32h(ctx, fp1, ft);
12253 gen_store_fpr32(ctx, fp1, fd);
12254 gen_store_fpr32h(ctx, fp0, fd);
12255 tcg_temp_free_i32(fp0);
12256 tcg_temp_free_i32(fp1);
12262 TCGv_i32 fp0 = tcg_temp_new_i32();
12263 TCGv_i32 fp1 = tcg_temp_new_i32();
12265 gen_load_fpr32h(ctx, fp0, fs);
12266 gen_load_fpr32(ctx, fp1, ft);
12267 gen_store_fpr32(ctx, fp1, fd);
12268 gen_store_fpr32h(ctx, fp0, fd);
12269 tcg_temp_free_i32(fp0);
12270 tcg_temp_free_i32(fp1);
12276 TCGv_i32 fp0 = tcg_temp_new_i32();
12277 TCGv_i32 fp1 = tcg_temp_new_i32();
12279 gen_load_fpr32h(ctx, fp0, fs);
12280 gen_load_fpr32h(ctx, fp1, ft);
12281 gen_store_fpr32(ctx, fp1, fd);
12282 gen_store_fpr32h(ctx, fp0, fd);
12283 tcg_temp_free_i32(fp0);
12284 tcg_temp_free_i32(fp1);
12288 case OPC_CMP_UN_PS:
12289 case OPC_CMP_EQ_PS:
12290 case OPC_CMP_UEQ_PS:
12291 case OPC_CMP_OLT_PS:
12292 case OPC_CMP_ULT_PS:
12293 case OPC_CMP_OLE_PS:
12294 case OPC_CMP_ULE_PS:
12295 case OPC_CMP_SF_PS:
12296 case OPC_CMP_NGLE_PS:
12297 case OPC_CMP_SEQ_PS:
12298 case OPC_CMP_NGL_PS:
12299 case OPC_CMP_LT_PS:
12300 case OPC_CMP_NGE_PS:
12301 case OPC_CMP_LE_PS:
12302 case OPC_CMP_NGT_PS:
12303 if (ctx->opcode & (1 << 6)) {
12304 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12306 gen_cmp_ps(ctx, func-48, ft, fs, cc);
12310 MIPS_INVAL("farith");
12311 generate_exception_end(ctx, EXCP_RI);
12316 /* Coprocessor 3 (FPU) */
12317 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12318 int fd, int fs, int base, int index)
12320 TCGv t0 = tcg_temp_new();
12323 gen_load_gpr(t0, index);
12324 } else if (index == 0) {
12325 gen_load_gpr(t0, base);
12327 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12329 /* Don't do NOP if destination is zero: we must perform the actual
12335 TCGv_i32 fp0 = tcg_temp_new_i32();
12337 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12338 tcg_gen_trunc_tl_i32(fp0, t0);
12339 gen_store_fpr32(ctx, fp0, fd);
12340 tcg_temp_free_i32(fp0);
12345 check_cp1_registers(ctx, fd);
12347 TCGv_i64 fp0 = tcg_temp_new_i64();
12348 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12349 gen_store_fpr64(ctx, fp0, fd);
12350 tcg_temp_free_i64(fp0);
12354 check_cp1_64bitmode(ctx);
12355 tcg_gen_andi_tl(t0, t0, ~0x7);
12357 TCGv_i64 fp0 = tcg_temp_new_i64();
12359 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12360 gen_store_fpr64(ctx, fp0, fd);
12361 tcg_temp_free_i64(fp0);
12367 TCGv_i32 fp0 = tcg_temp_new_i32();
12368 gen_load_fpr32(ctx, fp0, fs);
12369 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12370 tcg_temp_free_i32(fp0);
12375 check_cp1_registers(ctx, fs);
12377 TCGv_i64 fp0 = tcg_temp_new_i64();
12378 gen_load_fpr64(ctx, fp0, fs);
12379 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12380 tcg_temp_free_i64(fp0);
12384 check_cp1_64bitmode(ctx);
12385 tcg_gen_andi_tl(t0, t0, ~0x7);
12387 TCGv_i64 fp0 = tcg_temp_new_i64();
12388 gen_load_fpr64(ctx, fp0, fs);
12389 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12390 tcg_temp_free_i64(fp0);
12397 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12398 int fd, int fr, int fs, int ft)
12404 TCGv t0 = tcg_temp_local_new();
12405 TCGv_i32 fp = tcg_temp_new_i32();
12406 TCGv_i32 fph = tcg_temp_new_i32();
12407 TCGLabel *l1 = gen_new_label();
12408 TCGLabel *l2 = gen_new_label();
12410 gen_load_gpr(t0, fr);
12411 tcg_gen_andi_tl(t0, t0, 0x7);
12413 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12414 gen_load_fpr32(ctx, fp, fs);
12415 gen_load_fpr32h(ctx, fph, fs);
12416 gen_store_fpr32(ctx, fp, fd);
12417 gen_store_fpr32h(ctx, fph, fd);
12420 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12422 #ifdef TARGET_WORDS_BIGENDIAN
12423 gen_load_fpr32(ctx, fp, fs);
12424 gen_load_fpr32h(ctx, fph, ft);
12425 gen_store_fpr32h(ctx, fp, fd);
12426 gen_store_fpr32(ctx, fph, fd);
12428 gen_load_fpr32h(ctx, fph, fs);
12429 gen_load_fpr32(ctx, fp, ft);
12430 gen_store_fpr32(ctx, fph, fd);
12431 gen_store_fpr32h(ctx, fp, fd);
12434 tcg_temp_free_i32(fp);
12435 tcg_temp_free_i32(fph);
12441 TCGv_i32 fp0 = tcg_temp_new_i32();
12442 TCGv_i32 fp1 = tcg_temp_new_i32();
12443 TCGv_i32 fp2 = tcg_temp_new_i32();
12445 gen_load_fpr32(ctx, fp0, fs);
12446 gen_load_fpr32(ctx, fp1, ft);
12447 gen_load_fpr32(ctx, fp2, fr);
12448 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12449 tcg_temp_free_i32(fp0);
12450 tcg_temp_free_i32(fp1);
12451 gen_store_fpr32(ctx, fp2, fd);
12452 tcg_temp_free_i32(fp2);
12457 check_cp1_registers(ctx, fd | fs | ft | fr);
12459 TCGv_i64 fp0 = tcg_temp_new_i64();
12460 TCGv_i64 fp1 = tcg_temp_new_i64();
12461 TCGv_i64 fp2 = tcg_temp_new_i64();
12463 gen_load_fpr64(ctx, fp0, fs);
12464 gen_load_fpr64(ctx, fp1, ft);
12465 gen_load_fpr64(ctx, fp2, fr);
12466 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12467 tcg_temp_free_i64(fp0);
12468 tcg_temp_free_i64(fp1);
12469 gen_store_fpr64(ctx, fp2, fd);
12470 tcg_temp_free_i64(fp2);
12476 TCGv_i64 fp0 = tcg_temp_new_i64();
12477 TCGv_i64 fp1 = tcg_temp_new_i64();
12478 TCGv_i64 fp2 = tcg_temp_new_i64();
12480 gen_load_fpr64(ctx, fp0, fs);
12481 gen_load_fpr64(ctx, fp1, ft);
12482 gen_load_fpr64(ctx, fp2, fr);
12483 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12484 tcg_temp_free_i64(fp0);
12485 tcg_temp_free_i64(fp1);
12486 gen_store_fpr64(ctx, fp2, fd);
12487 tcg_temp_free_i64(fp2);
12493 TCGv_i32 fp0 = tcg_temp_new_i32();
12494 TCGv_i32 fp1 = tcg_temp_new_i32();
12495 TCGv_i32 fp2 = tcg_temp_new_i32();
12497 gen_load_fpr32(ctx, fp0, fs);
12498 gen_load_fpr32(ctx, fp1, ft);
12499 gen_load_fpr32(ctx, fp2, fr);
12500 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12501 tcg_temp_free_i32(fp0);
12502 tcg_temp_free_i32(fp1);
12503 gen_store_fpr32(ctx, fp2, fd);
12504 tcg_temp_free_i32(fp2);
12509 check_cp1_registers(ctx, fd | fs | ft | fr);
12511 TCGv_i64 fp0 = tcg_temp_new_i64();
12512 TCGv_i64 fp1 = tcg_temp_new_i64();
12513 TCGv_i64 fp2 = tcg_temp_new_i64();
12515 gen_load_fpr64(ctx, fp0, fs);
12516 gen_load_fpr64(ctx, fp1, ft);
12517 gen_load_fpr64(ctx, fp2, fr);
12518 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12519 tcg_temp_free_i64(fp0);
12520 tcg_temp_free_i64(fp1);
12521 gen_store_fpr64(ctx, fp2, fd);
12522 tcg_temp_free_i64(fp2);
12528 TCGv_i64 fp0 = tcg_temp_new_i64();
12529 TCGv_i64 fp1 = tcg_temp_new_i64();
12530 TCGv_i64 fp2 = tcg_temp_new_i64();
12532 gen_load_fpr64(ctx, fp0, fs);
12533 gen_load_fpr64(ctx, fp1, ft);
12534 gen_load_fpr64(ctx, fp2, fr);
12535 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12536 tcg_temp_free_i64(fp0);
12537 tcg_temp_free_i64(fp1);
12538 gen_store_fpr64(ctx, fp2, fd);
12539 tcg_temp_free_i64(fp2);
12545 TCGv_i32 fp0 = tcg_temp_new_i32();
12546 TCGv_i32 fp1 = tcg_temp_new_i32();
12547 TCGv_i32 fp2 = tcg_temp_new_i32();
12549 gen_load_fpr32(ctx, fp0, fs);
12550 gen_load_fpr32(ctx, fp1, ft);
12551 gen_load_fpr32(ctx, fp2, fr);
12552 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12553 tcg_temp_free_i32(fp0);
12554 tcg_temp_free_i32(fp1);
12555 gen_store_fpr32(ctx, fp2, fd);
12556 tcg_temp_free_i32(fp2);
12561 check_cp1_registers(ctx, fd | fs | ft | fr);
12563 TCGv_i64 fp0 = tcg_temp_new_i64();
12564 TCGv_i64 fp1 = tcg_temp_new_i64();
12565 TCGv_i64 fp2 = tcg_temp_new_i64();
12567 gen_load_fpr64(ctx, fp0, fs);
12568 gen_load_fpr64(ctx, fp1, ft);
12569 gen_load_fpr64(ctx, fp2, fr);
12570 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12571 tcg_temp_free_i64(fp0);
12572 tcg_temp_free_i64(fp1);
12573 gen_store_fpr64(ctx, fp2, fd);
12574 tcg_temp_free_i64(fp2);
12580 TCGv_i64 fp0 = tcg_temp_new_i64();
12581 TCGv_i64 fp1 = tcg_temp_new_i64();
12582 TCGv_i64 fp2 = tcg_temp_new_i64();
12584 gen_load_fpr64(ctx, fp0, fs);
12585 gen_load_fpr64(ctx, fp1, ft);
12586 gen_load_fpr64(ctx, fp2, fr);
12587 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12588 tcg_temp_free_i64(fp0);
12589 tcg_temp_free_i64(fp1);
12590 gen_store_fpr64(ctx, fp2, fd);
12591 tcg_temp_free_i64(fp2);
12597 TCGv_i32 fp0 = tcg_temp_new_i32();
12598 TCGv_i32 fp1 = tcg_temp_new_i32();
12599 TCGv_i32 fp2 = tcg_temp_new_i32();
12601 gen_load_fpr32(ctx, fp0, fs);
12602 gen_load_fpr32(ctx, fp1, ft);
12603 gen_load_fpr32(ctx, fp2, fr);
12604 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12605 tcg_temp_free_i32(fp0);
12606 tcg_temp_free_i32(fp1);
12607 gen_store_fpr32(ctx, fp2, fd);
12608 tcg_temp_free_i32(fp2);
12613 check_cp1_registers(ctx, fd | fs | ft | fr);
12615 TCGv_i64 fp0 = tcg_temp_new_i64();
12616 TCGv_i64 fp1 = tcg_temp_new_i64();
12617 TCGv_i64 fp2 = tcg_temp_new_i64();
12619 gen_load_fpr64(ctx, fp0, fs);
12620 gen_load_fpr64(ctx, fp1, ft);
12621 gen_load_fpr64(ctx, fp2, fr);
12622 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12623 tcg_temp_free_i64(fp0);
12624 tcg_temp_free_i64(fp1);
12625 gen_store_fpr64(ctx, fp2, fd);
12626 tcg_temp_free_i64(fp2);
12632 TCGv_i64 fp0 = tcg_temp_new_i64();
12633 TCGv_i64 fp1 = tcg_temp_new_i64();
12634 TCGv_i64 fp2 = tcg_temp_new_i64();
12636 gen_load_fpr64(ctx, fp0, fs);
12637 gen_load_fpr64(ctx, fp1, ft);
12638 gen_load_fpr64(ctx, fp2, fr);
12639 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12640 tcg_temp_free_i64(fp0);
12641 tcg_temp_free_i64(fp1);
12642 gen_store_fpr64(ctx, fp2, fd);
12643 tcg_temp_free_i64(fp2);
12647 MIPS_INVAL("flt3_arith");
12648 generate_exception_end(ctx, EXCP_RI);
12653 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12657 #if !defined(CONFIG_USER_ONLY)
12658 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12659 Therefore only check the ISA in system mode. */
12660 check_insn(ctx, ISA_MIPS32R2);
12662 t0 = tcg_temp_new();
12666 gen_helper_rdhwr_cpunum(t0, cpu_env);
12667 gen_store_gpr(t0, rt);
12670 gen_helper_rdhwr_synci_step(t0, cpu_env);
12671 gen_store_gpr(t0, rt);
12674 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12677 gen_helper_rdhwr_cc(t0, cpu_env);
12678 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12681 gen_store_gpr(t0, rt);
12682 /* Break the TB to be able to take timer interrupts immediately
12683 after reading count. DISAS_STOP isn't sufficient, we need to ensure
12684 we break completely out of translated code. */
12685 gen_save_pc(ctx->base.pc_next + 4);
12686 ctx->base.is_jmp = DISAS_EXIT;
12689 gen_helper_rdhwr_ccres(t0, cpu_env);
12690 gen_store_gpr(t0, rt);
12693 check_insn(ctx, ISA_MIPS32R6);
12695 /* Performance counter registers are not implemented other than
12696 * control register 0.
12698 generate_exception(ctx, EXCP_RI);
12700 gen_helper_rdhwr_performance(t0, cpu_env);
12701 gen_store_gpr(t0, rt);
12704 check_insn(ctx, ISA_MIPS32R6);
12705 gen_helper_rdhwr_xnp(t0, cpu_env);
12706 gen_store_gpr(t0, rt);
12709 #if defined(CONFIG_USER_ONLY)
12710 tcg_gen_ld_tl(t0, cpu_env,
12711 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12712 gen_store_gpr(t0, rt);
12715 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12716 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12717 tcg_gen_ld_tl(t0, cpu_env,
12718 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12719 gen_store_gpr(t0, rt);
12721 generate_exception_end(ctx, EXCP_RI);
12725 default: /* Invalid */
12726 MIPS_INVAL("rdhwr");
12727 generate_exception_end(ctx, EXCP_RI);
12733 static inline void clear_branch_hflags(DisasContext *ctx)
12735 ctx->hflags &= ~MIPS_HFLAG_BMASK;
12736 if (ctx->base.is_jmp == DISAS_NEXT) {
12737 save_cpu_state(ctx, 0);
12739 /* it is not safe to save ctx->hflags as hflags may be changed
12740 in execution time by the instruction in delay / forbidden slot. */
12741 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12745 static void gen_branch(DisasContext *ctx, int insn_bytes)
12747 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12748 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12749 /* Branches completion */
12750 clear_branch_hflags(ctx);
12751 ctx->base.is_jmp = DISAS_NORETURN;
12752 /* FIXME: Need to clear can_do_io. */
12753 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12754 case MIPS_HFLAG_FBNSLOT:
12755 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12758 /* unconditional branch */
12759 if (proc_hflags & MIPS_HFLAG_BX) {
12760 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12762 gen_goto_tb(ctx, 0, ctx->btarget);
12764 case MIPS_HFLAG_BL:
12765 /* blikely taken case */
12766 gen_goto_tb(ctx, 0, ctx->btarget);
12768 case MIPS_HFLAG_BC:
12769 /* Conditional branch */
12771 TCGLabel *l1 = gen_new_label();
12773 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12774 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12776 gen_goto_tb(ctx, 0, ctx->btarget);
12779 case MIPS_HFLAG_BR:
12780 /* unconditional branch to register */
12781 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12782 TCGv t0 = tcg_temp_new();
12783 TCGv_i32 t1 = tcg_temp_new_i32();
12785 tcg_gen_andi_tl(t0, btarget, 0x1);
12786 tcg_gen_trunc_tl_i32(t1, t0);
12788 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12789 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12790 tcg_gen_or_i32(hflags, hflags, t1);
12791 tcg_temp_free_i32(t1);
12793 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12795 tcg_gen_mov_tl(cpu_PC, btarget);
12797 if (ctx->base.singlestep_enabled) {
12798 save_cpu_state(ctx, 0);
12799 gen_helper_raise_exception_debug(cpu_env);
12801 tcg_gen_lookup_and_goto_ptr();
12804 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12810 /* Compact Branches */
12811 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12812 int rs, int rt, int32_t offset)
12814 int bcond_compute = 0;
12815 TCGv t0 = tcg_temp_new();
12816 TCGv t1 = tcg_temp_new();
12817 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12819 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12820 #ifdef MIPS_DEBUG_DISAS
12821 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12822 "\n", ctx->base.pc_next);
12824 generate_exception_end(ctx, EXCP_RI);
12828 /* Load needed operands and calculate btarget */
12830 /* compact branch */
12831 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12832 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12833 gen_load_gpr(t0, rs);
12834 gen_load_gpr(t1, rt);
12836 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12837 if (rs <= rt && rs == 0) {
12838 /* OPC_BEQZALC, OPC_BNEZALC */
12839 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12842 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12843 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12844 gen_load_gpr(t0, rs);
12845 gen_load_gpr(t1, rt);
12847 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12849 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12850 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12851 if (rs == 0 || rs == rt) {
12852 /* OPC_BLEZALC, OPC_BGEZALC */
12853 /* OPC_BGTZALC, OPC_BLTZALC */
12854 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12856 gen_load_gpr(t0, rs);
12857 gen_load_gpr(t1, rt);
12859 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12863 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12868 /* OPC_BEQZC, OPC_BNEZC */
12869 gen_load_gpr(t0, rs);
12871 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12873 /* OPC_JIC, OPC_JIALC */
12874 TCGv tbase = tcg_temp_new();
12875 TCGv toffset = tcg_temp_new();
12877 gen_load_gpr(tbase, rt);
12878 tcg_gen_movi_tl(toffset, offset);
12879 gen_op_addr_add(ctx, btarget, tbase, toffset);
12880 tcg_temp_free(tbase);
12881 tcg_temp_free(toffset);
12885 MIPS_INVAL("Compact branch/jump");
12886 generate_exception_end(ctx, EXCP_RI);
12890 if (bcond_compute == 0) {
12891 /* Uncoditional compact branch */
12894 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12897 ctx->hflags |= MIPS_HFLAG_BR;
12900 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12903 ctx->hflags |= MIPS_HFLAG_B;
12906 MIPS_INVAL("Compact branch/jump");
12907 generate_exception_end(ctx, EXCP_RI);
12911 /* Generating branch here as compact branches don't have delay slot */
12912 gen_branch(ctx, 4);
12914 /* Conditional compact branch */
12915 TCGLabel *fs = gen_new_label();
12916 save_cpu_state(ctx, 0);
12919 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12920 if (rs == 0 && rt != 0) {
12922 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12923 } else if (rs != 0 && rt != 0 && rs == rt) {
12925 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12928 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12931 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12932 if (rs == 0 && rt != 0) {
12934 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12935 } else if (rs != 0 && rt != 0 && rs == rt) {
12937 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12940 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12943 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12944 if (rs == 0 && rt != 0) {
12946 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12947 } else if (rs != 0 && rt != 0 && rs == rt) {
12949 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12952 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12955 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12956 if (rs == 0 && rt != 0) {
12958 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12959 } else if (rs != 0 && rt != 0 && rs == rt) {
12961 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12964 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12967 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12968 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12970 /* OPC_BOVC, OPC_BNVC */
12971 TCGv t2 = tcg_temp_new();
12972 TCGv t3 = tcg_temp_new();
12973 TCGv t4 = tcg_temp_new();
12974 TCGv input_overflow = tcg_temp_new();
12976 gen_load_gpr(t0, rs);
12977 gen_load_gpr(t1, rt);
12978 tcg_gen_ext32s_tl(t2, t0);
12979 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12980 tcg_gen_ext32s_tl(t3, t1);
12981 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12982 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12984 tcg_gen_add_tl(t4, t2, t3);
12985 tcg_gen_ext32s_tl(t4, t4);
12986 tcg_gen_xor_tl(t2, t2, t3);
12987 tcg_gen_xor_tl(t3, t4, t3);
12988 tcg_gen_andc_tl(t2, t3, t2);
12989 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12990 tcg_gen_or_tl(t4, t4, input_overflow);
12991 if (opc == OPC_BOVC) {
12993 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12996 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12998 tcg_temp_free(input_overflow);
13002 } else if (rs < rt && rs == 0) {
13003 /* OPC_BEQZALC, OPC_BNEZALC */
13004 if (opc == OPC_BEQZALC) {
13006 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13009 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13012 /* OPC_BEQC, OPC_BNEC */
13013 if (opc == OPC_BEQC) {
13015 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13018 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13023 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13026 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13029 MIPS_INVAL("Compact conditional branch/jump");
13030 generate_exception_end(ctx, EXCP_RI);
13034 /* Generating branch here as compact branches don't have delay slot */
13035 gen_goto_tb(ctx, 1, ctx->btarget);
13038 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13046 /* ISA extensions (ASEs) */
13047 /* MIPS16 extension to MIPS32 */
13049 /* MIPS16 major opcodes */
13051 M16_OPC_ADDIUSP = 0x00,
13052 M16_OPC_ADDIUPC = 0x01,
13054 M16_OPC_JAL = 0x03,
13055 M16_OPC_BEQZ = 0x04,
13056 M16_OPC_BNEQZ = 0x05,
13057 M16_OPC_SHIFT = 0x06,
13059 M16_OPC_RRIA = 0x08,
13060 M16_OPC_ADDIU8 = 0x09,
13061 M16_OPC_SLTI = 0x0a,
13062 M16_OPC_SLTIU = 0x0b,
13065 M16_OPC_CMPI = 0x0e,
13069 M16_OPC_LWSP = 0x12,
13071 M16_OPC_LBU = 0x14,
13072 M16_OPC_LHU = 0x15,
13073 M16_OPC_LWPC = 0x16,
13074 M16_OPC_LWU = 0x17,
13077 M16_OPC_SWSP = 0x1a,
13079 M16_OPC_RRR = 0x1c,
13081 M16_OPC_EXTEND = 0x1e,
13085 /* I8 funct field */
13104 /* RR funct field */
13138 /* I64 funct field */
13146 I64_DADDIUPC = 0x6,
13150 /* RR ry field for CNVT */
13152 RR_RY_CNVT_ZEB = 0x0,
13153 RR_RY_CNVT_ZEH = 0x1,
13154 RR_RY_CNVT_ZEW = 0x2,
13155 RR_RY_CNVT_SEB = 0x4,
13156 RR_RY_CNVT_SEH = 0x5,
13157 RR_RY_CNVT_SEW = 0x6,
13160 static int xlat (int r)
13162 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13167 static void gen_mips16_save (DisasContext *ctx,
13168 int xsregs, int aregs,
13169 int do_ra, int do_s0, int do_s1,
13172 TCGv t0 = tcg_temp_new();
13173 TCGv t1 = tcg_temp_new();
13174 TCGv t2 = tcg_temp_new();
13204 generate_exception_end(ctx, EXCP_RI);
13210 gen_base_offset_addr(ctx, t0, 29, 12);
13211 gen_load_gpr(t1, 7);
13212 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13215 gen_base_offset_addr(ctx, t0, 29, 8);
13216 gen_load_gpr(t1, 6);
13217 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13220 gen_base_offset_addr(ctx, t0, 29, 4);
13221 gen_load_gpr(t1, 5);
13222 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13225 gen_base_offset_addr(ctx, t0, 29, 0);
13226 gen_load_gpr(t1, 4);
13227 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13230 gen_load_gpr(t0, 29);
13232 #define DECR_AND_STORE(reg) do { \
13233 tcg_gen_movi_tl(t2, -4); \
13234 gen_op_addr_add(ctx, t0, t0, t2); \
13235 gen_load_gpr(t1, reg); \
13236 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13240 DECR_AND_STORE(31);
13245 DECR_AND_STORE(30);
13248 DECR_AND_STORE(23);
13251 DECR_AND_STORE(22);
13254 DECR_AND_STORE(21);
13257 DECR_AND_STORE(20);
13260 DECR_AND_STORE(19);
13263 DECR_AND_STORE(18);
13267 DECR_AND_STORE(17);
13270 DECR_AND_STORE(16);
13300 generate_exception_end(ctx, EXCP_RI);
13316 #undef DECR_AND_STORE
13318 tcg_gen_movi_tl(t2, -framesize);
13319 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13325 static void gen_mips16_restore (DisasContext *ctx,
13326 int xsregs, int aregs,
13327 int do_ra, int do_s0, int do_s1,
13331 TCGv t0 = tcg_temp_new();
13332 TCGv t1 = tcg_temp_new();
13333 TCGv t2 = tcg_temp_new();
13335 tcg_gen_movi_tl(t2, framesize);
13336 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13338 #define DECR_AND_LOAD(reg) do { \
13339 tcg_gen_movi_tl(t2, -4); \
13340 gen_op_addr_add(ctx, t0, t0, t2); \
13341 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13342 gen_store_gpr(t1, reg); \
13406 generate_exception_end(ctx, EXCP_RI);
13422 #undef DECR_AND_LOAD
13424 tcg_gen_movi_tl(t2, framesize);
13425 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13431 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13432 int is_64_bit, int extended)
13436 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13437 generate_exception_end(ctx, EXCP_RI);
13441 t0 = tcg_temp_new();
13443 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13444 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13446 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13452 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13455 TCGv_i32 t0 = tcg_const_i32(op);
13456 TCGv t1 = tcg_temp_new();
13457 gen_base_offset_addr(ctx, t1, base, offset);
13458 gen_helper_cache(cpu_env, t1, t0);
13461 #if defined(TARGET_MIPS64)
13462 static void decode_i64_mips16 (DisasContext *ctx,
13463 int ry, int funct, int16_t offset,
13468 check_insn(ctx, ISA_MIPS3);
13469 check_mips_64(ctx);
13470 offset = extended ? offset : offset << 3;
13471 gen_ld(ctx, OPC_LD, ry, 29, offset);
13474 check_insn(ctx, ISA_MIPS3);
13475 check_mips_64(ctx);
13476 offset = extended ? offset : offset << 3;
13477 gen_st(ctx, OPC_SD, ry, 29, offset);
13480 check_insn(ctx, ISA_MIPS3);
13481 check_mips_64(ctx);
13482 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13483 gen_st(ctx, OPC_SD, 31, 29, offset);
13486 check_insn(ctx, ISA_MIPS3);
13487 check_mips_64(ctx);
13488 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13489 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13492 check_insn(ctx, ISA_MIPS3);
13493 check_mips_64(ctx);
13494 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13495 generate_exception_end(ctx, EXCP_RI);
13497 offset = extended ? offset : offset << 3;
13498 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13502 check_insn(ctx, ISA_MIPS3);
13503 check_mips_64(ctx);
13504 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13505 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13508 check_insn(ctx, ISA_MIPS3);
13509 check_mips_64(ctx);
13510 offset = extended ? offset : offset << 2;
13511 gen_addiupc(ctx, ry, offset, 1, extended);
13514 check_insn(ctx, ISA_MIPS3);
13515 check_mips_64(ctx);
13516 offset = extended ? offset : offset << 2;
13517 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13523 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13525 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13526 int op, rx, ry, funct, sa;
13527 int16_t imm, offset;
13529 ctx->opcode = (ctx->opcode << 16) | extend;
13530 op = (ctx->opcode >> 11) & 0x1f;
13531 sa = (ctx->opcode >> 22) & 0x1f;
13532 funct = (ctx->opcode >> 8) & 0x7;
13533 rx = xlat((ctx->opcode >> 8) & 0x7);
13534 ry = xlat((ctx->opcode >> 5) & 0x7);
13535 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13536 | ((ctx->opcode >> 21) & 0x3f) << 5
13537 | (ctx->opcode & 0x1f));
13539 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13542 case M16_OPC_ADDIUSP:
13543 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13545 case M16_OPC_ADDIUPC:
13546 gen_addiupc(ctx, rx, imm, 0, 1);
13549 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13550 /* No delay slot, so just process as a normal instruction */
13553 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13554 /* No delay slot, so just process as a normal instruction */
13556 case M16_OPC_BNEQZ:
13557 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13558 /* No delay slot, so just process as a normal instruction */
13560 case M16_OPC_SHIFT:
13561 switch (ctx->opcode & 0x3) {
13563 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13566 #if defined(TARGET_MIPS64)
13567 check_mips_64(ctx);
13568 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13570 generate_exception_end(ctx, EXCP_RI);
13574 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13577 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13581 #if defined(TARGET_MIPS64)
13583 check_insn(ctx, ISA_MIPS3);
13584 check_mips_64(ctx);
13585 gen_ld(ctx, OPC_LD, ry, rx, offset);
13589 imm = ctx->opcode & 0xf;
13590 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13591 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13592 imm = (int16_t) (imm << 1) >> 1;
13593 if ((ctx->opcode >> 4) & 0x1) {
13594 #if defined(TARGET_MIPS64)
13595 check_mips_64(ctx);
13596 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13598 generate_exception_end(ctx, EXCP_RI);
13601 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13604 case M16_OPC_ADDIU8:
13605 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13608 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13610 case M16_OPC_SLTIU:
13611 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13616 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13619 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13622 gen_st(ctx, OPC_SW, 31, 29, imm);
13625 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13628 check_insn(ctx, ISA_MIPS32);
13630 int xsregs = (ctx->opcode >> 24) & 0x7;
13631 int aregs = (ctx->opcode >> 16) & 0xf;
13632 int do_ra = (ctx->opcode >> 6) & 0x1;
13633 int do_s0 = (ctx->opcode >> 5) & 0x1;
13634 int do_s1 = (ctx->opcode >> 4) & 0x1;
13635 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13636 | (ctx->opcode & 0xf)) << 3;
13638 if (ctx->opcode & (1 << 7)) {
13639 gen_mips16_save(ctx, xsregs, aregs,
13640 do_ra, do_s0, do_s1,
13643 gen_mips16_restore(ctx, xsregs, aregs,
13644 do_ra, do_s0, do_s1,
13650 generate_exception_end(ctx, EXCP_RI);
13655 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13658 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13660 #if defined(TARGET_MIPS64)
13662 check_insn(ctx, ISA_MIPS3);
13663 check_mips_64(ctx);
13664 gen_st(ctx, OPC_SD, ry, rx, offset);
13668 gen_ld(ctx, OPC_LB, ry, rx, offset);
13671 gen_ld(ctx, OPC_LH, ry, rx, offset);
13674 gen_ld(ctx, OPC_LW, rx, 29, offset);
13677 gen_ld(ctx, OPC_LW, ry, rx, offset);
13680 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13683 gen_ld(ctx, OPC_LHU, ry, rx, offset);
13686 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13688 #if defined(TARGET_MIPS64)
13690 check_insn(ctx, ISA_MIPS3);
13691 check_mips_64(ctx);
13692 gen_ld(ctx, OPC_LWU, ry, rx, offset);
13696 gen_st(ctx, OPC_SB, ry, rx, offset);
13699 gen_st(ctx, OPC_SH, ry, rx, offset);
13702 gen_st(ctx, OPC_SW, rx, 29, offset);
13705 gen_st(ctx, OPC_SW, ry, rx, offset);
13707 #if defined(TARGET_MIPS64)
13709 decode_i64_mips16(ctx, ry, funct, offset, 1);
13713 generate_exception_end(ctx, EXCP_RI);
13720 static inline bool is_uhi(int sdbbp_code)
13722 #ifdef CONFIG_USER_ONLY
13725 return semihosting_enabled() && sdbbp_code == 1;
13729 #ifdef CONFIG_USER_ONLY
13730 /* The above should dead-code away any calls to this..*/
13731 static inline void gen_helper_do_semihosting(void *env)
13733 g_assert_not_reached();
13737 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13741 int op, cnvt_op, op1, offset;
13745 op = (ctx->opcode >> 11) & 0x1f;
13746 sa = (ctx->opcode >> 2) & 0x7;
13747 sa = sa == 0 ? 8 : sa;
13748 rx = xlat((ctx->opcode >> 8) & 0x7);
13749 cnvt_op = (ctx->opcode >> 5) & 0x7;
13750 ry = xlat((ctx->opcode >> 5) & 0x7);
13751 op1 = offset = ctx->opcode & 0x1f;
13756 case M16_OPC_ADDIUSP:
13758 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13760 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13763 case M16_OPC_ADDIUPC:
13764 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13767 offset = (ctx->opcode & 0x7ff) << 1;
13768 offset = (int16_t)(offset << 4) >> 4;
13769 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13770 /* No delay slot, so just process as a normal instruction */
13773 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13774 offset = (((ctx->opcode & 0x1f) << 21)
13775 | ((ctx->opcode >> 5) & 0x1f) << 16
13777 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13778 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13782 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13783 ((int8_t)ctx->opcode) << 1, 0);
13784 /* No delay slot, so just process as a normal instruction */
13786 case M16_OPC_BNEQZ:
13787 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13788 ((int8_t)ctx->opcode) << 1, 0);
13789 /* No delay slot, so just process as a normal instruction */
13791 case M16_OPC_SHIFT:
13792 switch (ctx->opcode & 0x3) {
13794 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13797 #if defined(TARGET_MIPS64)
13798 check_insn(ctx, ISA_MIPS3);
13799 check_mips_64(ctx);
13800 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13802 generate_exception_end(ctx, EXCP_RI);
13806 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13809 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13813 #if defined(TARGET_MIPS64)
13815 check_insn(ctx, ISA_MIPS3);
13816 check_mips_64(ctx);
13817 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13822 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13824 if ((ctx->opcode >> 4) & 1) {
13825 #if defined(TARGET_MIPS64)
13826 check_insn(ctx, ISA_MIPS3);
13827 check_mips_64(ctx);
13828 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13830 generate_exception_end(ctx, EXCP_RI);
13833 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13837 case M16_OPC_ADDIU8:
13839 int16_t imm = (int8_t) ctx->opcode;
13841 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13846 int16_t imm = (uint8_t) ctx->opcode;
13847 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13850 case M16_OPC_SLTIU:
13852 int16_t imm = (uint8_t) ctx->opcode;
13853 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13860 funct = (ctx->opcode >> 8) & 0x7;
13863 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13864 ((int8_t)ctx->opcode) << 1, 0);
13867 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13868 ((int8_t)ctx->opcode) << 1, 0);
13871 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13874 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13875 ((int8_t)ctx->opcode) << 3);
13878 check_insn(ctx, ISA_MIPS32);
13880 int do_ra = ctx->opcode & (1 << 6);
13881 int do_s0 = ctx->opcode & (1 << 5);
13882 int do_s1 = ctx->opcode & (1 << 4);
13883 int framesize = ctx->opcode & 0xf;
13885 if (framesize == 0) {
13888 framesize = framesize << 3;
13891 if (ctx->opcode & (1 << 7)) {
13892 gen_mips16_save(ctx, 0, 0,
13893 do_ra, do_s0, do_s1, framesize);
13895 gen_mips16_restore(ctx, 0, 0,
13896 do_ra, do_s0, do_s1, framesize);
13902 int rz = xlat(ctx->opcode & 0x7);
13904 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13905 ((ctx->opcode >> 5) & 0x7);
13906 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13910 reg32 = ctx->opcode & 0x1f;
13911 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13914 generate_exception_end(ctx, EXCP_RI);
13921 int16_t imm = (uint8_t) ctx->opcode;
13923 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13928 int16_t imm = (uint8_t) ctx->opcode;
13929 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13932 #if defined(TARGET_MIPS64)
13934 check_insn(ctx, ISA_MIPS3);
13935 check_mips_64(ctx);
13936 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13940 gen_ld(ctx, OPC_LB, ry, rx, offset);
13943 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13946 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13949 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13952 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13955 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13958 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13960 #if defined (TARGET_MIPS64)
13962 check_insn(ctx, ISA_MIPS3);
13963 check_mips_64(ctx);
13964 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13968 gen_st(ctx, OPC_SB, ry, rx, offset);
13971 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13974 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13977 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13981 int rz = xlat((ctx->opcode >> 2) & 0x7);
13984 switch (ctx->opcode & 0x3) {
13986 mips32_op = OPC_ADDU;
13989 mips32_op = OPC_SUBU;
13991 #if defined(TARGET_MIPS64)
13993 mips32_op = OPC_DADDU;
13994 check_insn(ctx, ISA_MIPS3);
13995 check_mips_64(ctx);
13998 mips32_op = OPC_DSUBU;
13999 check_insn(ctx, ISA_MIPS3);
14000 check_mips_64(ctx);
14004 generate_exception_end(ctx, EXCP_RI);
14008 gen_arith(ctx, mips32_op, rz, rx, ry);
14017 int nd = (ctx->opcode >> 7) & 0x1;
14018 int link = (ctx->opcode >> 6) & 0x1;
14019 int ra = (ctx->opcode >> 5) & 0x1;
14022 check_insn(ctx, ISA_MIPS32);
14031 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14036 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14037 gen_helper_do_semihosting(cpu_env);
14039 /* XXX: not clear which exception should be raised
14040 * when in debug mode...
14042 check_insn(ctx, ISA_MIPS32);
14043 generate_exception_end(ctx, EXCP_DBp);
14047 gen_slt(ctx, OPC_SLT, 24, rx, ry);
14050 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14053 generate_exception_end(ctx, EXCP_BREAK);
14056 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14059 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14062 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14064 #if defined (TARGET_MIPS64)
14066 check_insn(ctx, ISA_MIPS3);
14067 check_mips_64(ctx);
14068 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14072 gen_logic(ctx, OPC_XOR, 24, rx, ry);
14075 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14078 gen_logic(ctx, OPC_AND, rx, rx, ry);
14081 gen_logic(ctx, OPC_OR, rx, rx, ry);
14084 gen_logic(ctx, OPC_XOR, rx, rx, ry);
14087 gen_logic(ctx, OPC_NOR, rx, ry, 0);
14090 gen_HILO(ctx, OPC_MFHI, 0, rx);
14093 check_insn(ctx, ISA_MIPS32);
14095 case RR_RY_CNVT_ZEB:
14096 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14098 case RR_RY_CNVT_ZEH:
14099 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14101 case RR_RY_CNVT_SEB:
14102 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14104 case RR_RY_CNVT_SEH:
14105 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14107 #if defined (TARGET_MIPS64)
14108 case RR_RY_CNVT_ZEW:
14109 check_insn(ctx, ISA_MIPS64);
14110 check_mips_64(ctx);
14111 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14113 case RR_RY_CNVT_SEW:
14114 check_insn(ctx, ISA_MIPS64);
14115 check_mips_64(ctx);
14116 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14120 generate_exception_end(ctx, EXCP_RI);
14125 gen_HILO(ctx, OPC_MFLO, 0, rx);
14127 #if defined (TARGET_MIPS64)
14129 check_insn(ctx, ISA_MIPS3);
14130 check_mips_64(ctx);
14131 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14134 check_insn(ctx, ISA_MIPS3);
14135 check_mips_64(ctx);
14136 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14139 check_insn(ctx, ISA_MIPS3);
14140 check_mips_64(ctx);
14141 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14144 check_insn(ctx, ISA_MIPS3);
14145 check_mips_64(ctx);
14146 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14150 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14153 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14156 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14159 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14161 #if defined (TARGET_MIPS64)
14163 check_insn(ctx, ISA_MIPS3);
14164 check_mips_64(ctx);
14165 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14168 check_insn(ctx, ISA_MIPS3);
14169 check_mips_64(ctx);
14170 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14173 check_insn(ctx, ISA_MIPS3);
14174 check_mips_64(ctx);
14175 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14178 check_insn(ctx, ISA_MIPS3);
14179 check_mips_64(ctx);
14180 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14184 generate_exception_end(ctx, EXCP_RI);
14188 case M16_OPC_EXTEND:
14189 decode_extended_mips16_opc(env, ctx);
14192 #if defined(TARGET_MIPS64)
14194 funct = (ctx->opcode >> 8) & 0x7;
14195 decode_i64_mips16(ctx, ry, funct, offset, 0);
14199 generate_exception_end(ctx, EXCP_RI);
14206 /* microMIPS extension to MIPS32/MIPS64 */
14209 * microMIPS32/microMIPS64 major opcodes
14211 * 1. MIPS Architecture for Programmers Volume II-B:
14212 * The microMIPS32 Instruction Set (Revision 3.05)
14214 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14216 * 2. MIPS Architecture For Programmers Volume II-A:
14217 * The MIPS64 Instruction Set (Revision 3.51)
14247 POOL32S = 0x16, /* MIPS64 */
14248 DADDIU32 = 0x17, /* MIPS64 */
14277 /* 0x29 is reserved */
14290 /* 0x31 is reserved */
14303 SD32 = 0x36, /* MIPS64 */
14304 LD32 = 0x37, /* MIPS64 */
14306 /* 0x39 is reserved */
14322 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14344 /* POOL32A encoding of minor opcode field */
14347 /* These opcodes are distinguished only by bits 9..6; those bits are
14348 * what are recorded below. */
14385 /* The following can be distinguished by their lower 6 bits. */
14395 /* POOL32AXF encoding of minor opcode field extension */
14398 * 1. MIPS Architecture for Programmers Volume II-B:
14399 * The microMIPS32 Instruction Set (Revision 3.05)
14401 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14403 * 2. MIPS Architecture for Programmers VolumeIV-e:
14404 * The MIPS DSP Application-Specific Extension
14405 * to the microMIPS32 Architecture (Revision 2.34)
14407 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14422 /* begin of microMIPS32 DSP */
14424 /* bits 13..12 for 0x01 */
14430 /* bits 13..12 for 0x2a */
14436 /* bits 13..12 for 0x32 */
14440 /* end of microMIPS32 DSP */
14442 /* bits 15..12 for 0x2c */
14459 /* bits 15..12 for 0x34 */
14467 /* bits 15..12 for 0x3c */
14469 JR = 0x0, /* alias */
14477 /* bits 15..12 for 0x05 */
14481 /* bits 15..12 for 0x0d */
14493 /* bits 15..12 for 0x15 */
14499 /* bits 15..12 for 0x1d */
14503 /* bits 15..12 for 0x2d */
14508 /* bits 15..12 for 0x35 */
14515 /* POOL32B encoding of minor opcode field (bits 15..12) */
14531 /* POOL32C encoding of minor opcode field (bits 15..12) */
14552 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14565 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14578 /* POOL32F encoding of minor opcode field (bits 5..0) */
14581 /* These are the bit 7..6 values */
14590 /* These are the bit 8..6 values */
14615 MOVZ_FMT_05 = 0x05,
14649 CABS_COND_FMT = 0x1c, /* MIPS3D */
14656 /* POOL32Fxf encoding of minor opcode extension field */
14694 /* POOL32I encoding of minor opcode field (bits 25..21) */
14724 /* These overlap and are distinguished by bit16 of the instruction */
14733 /* POOL16A encoding of minor opcode field */
14740 /* POOL16B encoding of minor opcode field */
14747 /* POOL16C encoding of minor opcode field */
14767 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14791 /* POOL16D encoding of minor opcode field */
14798 /* POOL16E encoding of minor opcode field */
14805 static int mmreg (int r)
14807 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14812 /* Used for 16-bit store instructions. */
14813 static int mmreg2 (int r)
14815 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14820 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14821 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14822 #define uMIPS_RS2(op) uMIPS_RS(op)
14823 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14824 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14825 #define uMIPS_RS5(op) (op & 0x1f)
14827 /* Signed immediate */
14828 #define SIMM(op, start, width) \
14829 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14832 /* Zero-extended immediate */
14833 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14835 static void gen_addiur1sp(DisasContext *ctx)
14837 int rd = mmreg(uMIPS_RD(ctx->opcode));
14839 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14842 static void gen_addiur2(DisasContext *ctx)
14844 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14845 int rd = mmreg(uMIPS_RD(ctx->opcode));
14846 int rs = mmreg(uMIPS_RS(ctx->opcode));
14848 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14851 static void gen_addiusp(DisasContext *ctx)
14853 int encoded = ZIMM(ctx->opcode, 1, 9);
14856 if (encoded <= 1) {
14857 decoded = 256 + encoded;
14858 } else if (encoded <= 255) {
14860 } else if (encoded <= 509) {
14861 decoded = encoded - 512;
14863 decoded = encoded - 768;
14866 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14869 static void gen_addius5(DisasContext *ctx)
14871 int imm = SIMM(ctx->opcode, 1, 4);
14872 int rd = (ctx->opcode >> 5) & 0x1f;
14874 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14877 static void gen_andi16(DisasContext *ctx)
14879 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14880 31, 32, 63, 64, 255, 32768, 65535 };
14881 int rd = mmreg(uMIPS_RD(ctx->opcode));
14882 int rs = mmreg(uMIPS_RS(ctx->opcode));
14883 int encoded = ZIMM(ctx->opcode, 0, 4);
14885 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14888 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14889 int base, int16_t offset)
14894 if (ctx->hflags & MIPS_HFLAG_BMASK) {
14895 generate_exception_end(ctx, EXCP_RI);
14899 t0 = tcg_temp_new();
14901 gen_base_offset_addr(ctx, t0, base, offset);
14903 t1 = tcg_const_tl(reglist);
14904 t2 = tcg_const_i32(ctx->mem_idx);
14906 save_cpu_state(ctx, 1);
14909 gen_helper_lwm(cpu_env, t0, t1, t2);
14912 gen_helper_swm(cpu_env, t0, t1, t2);
14914 #ifdef TARGET_MIPS64
14916 gen_helper_ldm(cpu_env, t0, t1, t2);
14919 gen_helper_sdm(cpu_env, t0, t1, t2);
14925 tcg_temp_free_i32(t2);
14929 static void gen_pool16c_insn(DisasContext *ctx)
14931 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14932 int rs = mmreg(ctx->opcode & 0x7);
14934 switch (((ctx->opcode) >> 4) & 0x3f) {
14939 gen_logic(ctx, OPC_NOR, rd, rs, 0);
14945 gen_logic(ctx, OPC_XOR, rd, rd, rs);
14951 gen_logic(ctx, OPC_AND, rd, rd, rs);
14957 gen_logic(ctx, OPC_OR, rd, rd, rs);
14964 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14965 int offset = ZIMM(ctx->opcode, 0, 4);
14967 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14976 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14977 int offset = ZIMM(ctx->opcode, 0, 4);
14979 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14986 int reg = ctx->opcode & 0x1f;
14988 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14994 int reg = ctx->opcode & 0x1f;
14995 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14996 /* Let normal delay slot handling in our caller take us
14997 to the branch target. */
15002 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15003 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15007 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15008 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15012 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15016 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15019 generate_exception_end(ctx, EXCP_BREAK);
15022 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15023 gen_helper_do_semihosting(cpu_env);
15025 /* XXX: not clear which exception should be raised
15026 * when in debug mode...
15028 check_insn(ctx, ISA_MIPS32);
15029 generate_exception_end(ctx, EXCP_DBp);
15032 case JRADDIUSP + 0:
15033 case JRADDIUSP + 1:
15035 int imm = ZIMM(ctx->opcode, 0, 5);
15036 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15037 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15038 /* Let normal delay slot handling in our caller take us
15039 to the branch target. */
15043 generate_exception_end(ctx, EXCP_RI);
15048 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15051 int rd, rs, re, rt;
15052 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15053 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15054 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15055 rd = rd_enc[enc_dest];
15056 re = re_enc[enc_dest];
15057 rs = rs_rt_enc[enc_rs];
15058 rt = rs_rt_enc[enc_rt];
15060 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15062 tcg_gen_movi_tl(cpu_gpr[rd], 0);
15065 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15067 tcg_gen_movi_tl(cpu_gpr[re], 0);
15071 static void gen_pool16c_r6_insn(DisasContext *ctx)
15073 int rt = mmreg((ctx->opcode >> 7) & 0x7);
15074 int rs = mmreg((ctx->opcode >> 4) & 0x7);
15076 switch (ctx->opcode & 0xf) {
15078 gen_logic(ctx, OPC_NOR, rt, rs, 0);
15081 gen_logic(ctx, OPC_AND, rt, rt, rs);
15085 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15086 int offset = extract32(ctx->opcode, 4, 4);
15087 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15090 case R6_JRC16: /* JRCADDIUSP */
15091 if ((ctx->opcode >> 4) & 1) {
15093 int imm = extract32(ctx->opcode, 5, 5);
15094 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15095 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15098 rs = extract32(ctx->opcode, 5, 5);
15099 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15111 int enc_dest = uMIPS_RD(ctx->opcode);
15112 int enc_rt = uMIPS_RS2(ctx->opcode);
15113 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15114 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15118 gen_logic(ctx, OPC_XOR, rt, rt, rs);
15121 gen_logic(ctx, OPC_OR, rt, rt, rs);
15125 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15126 int offset = extract32(ctx->opcode, 4, 4);
15127 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15130 case JALRC16: /* BREAK16, SDBBP16 */
15131 switch (ctx->opcode & 0x3f) {
15133 case JALRC16 + 0x20:
15135 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15140 generate_exception(ctx, EXCP_BREAK);
15144 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15145 gen_helper_do_semihosting(cpu_env);
15147 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15148 generate_exception(ctx, EXCP_RI);
15150 generate_exception(ctx, EXCP_DBp);
15157 generate_exception(ctx, EXCP_RI);
15162 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15164 TCGv t0 = tcg_temp_new();
15165 TCGv t1 = tcg_temp_new();
15167 gen_load_gpr(t0, base);
15170 gen_load_gpr(t1, index);
15171 tcg_gen_shli_tl(t1, t1, 2);
15172 gen_op_addr_add(ctx, t0, t1, t0);
15175 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15176 gen_store_gpr(t1, rd);
15182 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15183 int base, int16_t offset)
15187 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15188 generate_exception_end(ctx, EXCP_RI);
15192 t0 = tcg_temp_new();
15193 t1 = tcg_temp_new();
15195 gen_base_offset_addr(ctx, t0, base, offset);
15200 generate_exception_end(ctx, EXCP_RI);
15203 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15204 gen_store_gpr(t1, rd);
15205 tcg_gen_movi_tl(t1, 4);
15206 gen_op_addr_add(ctx, t0, t0, t1);
15207 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15208 gen_store_gpr(t1, rd+1);
15211 gen_load_gpr(t1, rd);
15212 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15213 tcg_gen_movi_tl(t1, 4);
15214 gen_op_addr_add(ctx, t0, t0, t1);
15215 gen_load_gpr(t1, rd+1);
15216 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15218 #ifdef TARGET_MIPS64
15221 generate_exception_end(ctx, EXCP_RI);
15224 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15225 gen_store_gpr(t1, rd);
15226 tcg_gen_movi_tl(t1, 8);
15227 gen_op_addr_add(ctx, t0, t0, t1);
15228 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15229 gen_store_gpr(t1, rd+1);
15232 gen_load_gpr(t1, rd);
15233 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15234 tcg_gen_movi_tl(t1, 8);
15235 gen_op_addr_add(ctx, t0, t0, t1);
15236 gen_load_gpr(t1, rd+1);
15237 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15245 static void gen_sync(int stype)
15247 TCGBar tcg_mo = TCG_BAR_SC;
15250 case 0x4: /* SYNC_WMB */
15251 tcg_mo |= TCG_MO_ST_ST;
15253 case 0x10: /* SYNC_MB */
15254 tcg_mo |= TCG_MO_ALL;
15256 case 0x11: /* SYNC_ACQUIRE */
15257 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15259 case 0x12: /* SYNC_RELEASE */
15260 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15262 case 0x13: /* SYNC_RMB */
15263 tcg_mo |= TCG_MO_LD_LD;
15266 tcg_mo |= TCG_MO_ALL;
15270 tcg_gen_mb(tcg_mo);
15273 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15275 int extension = (ctx->opcode >> 6) & 0x3f;
15276 int minor = (ctx->opcode >> 12) & 0xf;
15277 uint32_t mips32_op;
15279 switch (extension) {
15281 mips32_op = OPC_TEQ;
15284 mips32_op = OPC_TGE;
15287 mips32_op = OPC_TGEU;
15290 mips32_op = OPC_TLT;
15293 mips32_op = OPC_TLTU;
15296 mips32_op = OPC_TNE;
15298 gen_trap(ctx, mips32_op, rs, rt, -1);
15300 #ifndef CONFIG_USER_ONLY
15303 check_cp0_enabled(ctx);
15305 /* Treat as NOP. */
15308 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15312 check_cp0_enabled(ctx);
15314 TCGv t0 = tcg_temp_new();
15316 gen_load_gpr(t0, rt);
15317 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15323 switch (minor & 3) {
15325 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15328 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15331 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15334 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15337 goto pool32axf_invalid;
15341 switch (minor & 3) {
15343 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15346 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15349 goto pool32axf_invalid;
15355 check_insn(ctx, ISA_MIPS32R6);
15356 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15359 gen_bshfl(ctx, OPC_SEB, rs, rt);
15362 gen_bshfl(ctx, OPC_SEH, rs, rt);
15365 mips32_op = OPC_CLO;
15368 mips32_op = OPC_CLZ;
15370 check_insn(ctx, ISA_MIPS32);
15371 gen_cl(ctx, mips32_op, rt, rs);
15374 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15375 gen_rdhwr(ctx, rt, rs, 0);
15378 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15381 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15382 mips32_op = OPC_MULT;
15385 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15386 mips32_op = OPC_MULTU;
15389 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15390 mips32_op = OPC_DIV;
15393 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15394 mips32_op = OPC_DIVU;
15397 check_insn(ctx, ISA_MIPS32);
15398 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15401 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15402 mips32_op = OPC_MADD;
15405 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15406 mips32_op = OPC_MADDU;
15409 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15410 mips32_op = OPC_MSUB;
15413 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15414 mips32_op = OPC_MSUBU;
15416 check_insn(ctx, ISA_MIPS32);
15417 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15420 goto pool32axf_invalid;
15431 generate_exception_err(ctx, EXCP_CpU, 2);
15434 goto pool32axf_invalid;
15439 case JALR: /* JALRC */
15440 case JALR_HB: /* JALRC_HB */
15441 if (ctx->insn_flags & ISA_MIPS32R6) {
15442 /* JALRC, JALRC_HB */
15443 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15445 /* JALR, JALR_HB */
15446 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15447 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15452 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15453 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15454 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15457 goto pool32axf_invalid;
15463 check_cp0_enabled(ctx);
15464 check_insn(ctx, ISA_MIPS32R2);
15465 gen_load_srsgpr(rs, rt);
15468 check_cp0_enabled(ctx);
15469 check_insn(ctx, ISA_MIPS32R2);
15470 gen_store_srsgpr(rs, rt);
15473 goto pool32axf_invalid;
15476 #ifndef CONFIG_USER_ONLY
15480 mips32_op = OPC_TLBP;
15483 mips32_op = OPC_TLBR;
15486 mips32_op = OPC_TLBWI;
15489 mips32_op = OPC_TLBWR;
15492 mips32_op = OPC_TLBINV;
15495 mips32_op = OPC_TLBINVF;
15498 mips32_op = OPC_WAIT;
15501 mips32_op = OPC_DERET;
15504 mips32_op = OPC_ERET;
15506 gen_cp0(env, ctx, mips32_op, rt, rs);
15509 goto pool32axf_invalid;
15515 check_cp0_enabled(ctx);
15517 TCGv t0 = tcg_temp_new();
15519 save_cpu_state(ctx, 1);
15520 gen_helper_di(t0, cpu_env);
15521 gen_store_gpr(t0, rs);
15522 /* Stop translation as we may have switched the execution mode */
15523 ctx->base.is_jmp = DISAS_STOP;
15528 check_cp0_enabled(ctx);
15530 TCGv t0 = tcg_temp_new();
15532 save_cpu_state(ctx, 1);
15533 gen_helper_ei(t0, cpu_env);
15534 gen_store_gpr(t0, rs);
15535 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15536 of translated code to check for pending interrupts. */
15537 gen_save_pc(ctx->base.pc_next + 4);
15538 ctx->base.is_jmp = DISAS_EXIT;
15543 goto pool32axf_invalid;
15550 gen_sync(extract32(ctx->opcode, 16, 5));
15553 generate_exception_end(ctx, EXCP_SYSCALL);
15556 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15557 gen_helper_do_semihosting(cpu_env);
15559 check_insn(ctx, ISA_MIPS32);
15560 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15561 generate_exception_end(ctx, EXCP_RI);
15563 generate_exception_end(ctx, EXCP_DBp);
15568 goto pool32axf_invalid;
15572 switch (minor & 3) {
15574 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15577 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15580 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15583 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15586 goto pool32axf_invalid;
15590 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15593 gen_HILO(ctx, OPC_MFHI, 0, rs);
15596 gen_HILO(ctx, OPC_MFLO, 0, rs);
15599 gen_HILO(ctx, OPC_MTHI, 0, rs);
15602 gen_HILO(ctx, OPC_MTLO, 0, rs);
15605 goto pool32axf_invalid;
15610 MIPS_INVAL("pool32axf");
15611 generate_exception_end(ctx, EXCP_RI);
15616 /* Values for microMIPS fmt field. Variable-width, depending on which
15617 formats the instruction supports. */
15636 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15638 int extension = (ctx->opcode >> 6) & 0x3ff;
15639 uint32_t mips32_op;
15641 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15642 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15643 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15645 switch (extension) {
15646 case FLOAT_1BIT_FMT(CFC1, 0):
15647 mips32_op = OPC_CFC1;
15649 case FLOAT_1BIT_FMT(CTC1, 0):
15650 mips32_op = OPC_CTC1;
15652 case FLOAT_1BIT_FMT(MFC1, 0):
15653 mips32_op = OPC_MFC1;
15655 case FLOAT_1BIT_FMT(MTC1, 0):
15656 mips32_op = OPC_MTC1;
15658 case FLOAT_1BIT_FMT(MFHC1, 0):
15659 mips32_op = OPC_MFHC1;
15661 case FLOAT_1BIT_FMT(MTHC1, 0):
15662 mips32_op = OPC_MTHC1;
15664 gen_cp1(ctx, mips32_op, rt, rs);
15667 /* Reciprocal square root */
15668 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15669 mips32_op = OPC_RSQRT_S;
15671 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15672 mips32_op = OPC_RSQRT_D;
15676 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15677 mips32_op = OPC_SQRT_S;
15679 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15680 mips32_op = OPC_SQRT_D;
15684 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15685 mips32_op = OPC_RECIP_S;
15687 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15688 mips32_op = OPC_RECIP_D;
15692 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15693 mips32_op = OPC_FLOOR_L_S;
15695 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15696 mips32_op = OPC_FLOOR_L_D;
15698 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15699 mips32_op = OPC_FLOOR_W_S;
15701 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15702 mips32_op = OPC_FLOOR_W_D;
15706 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15707 mips32_op = OPC_CEIL_L_S;
15709 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15710 mips32_op = OPC_CEIL_L_D;
15712 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15713 mips32_op = OPC_CEIL_W_S;
15715 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15716 mips32_op = OPC_CEIL_W_D;
15720 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15721 mips32_op = OPC_TRUNC_L_S;
15723 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15724 mips32_op = OPC_TRUNC_L_D;
15726 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15727 mips32_op = OPC_TRUNC_W_S;
15729 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15730 mips32_op = OPC_TRUNC_W_D;
15734 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15735 mips32_op = OPC_ROUND_L_S;
15737 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15738 mips32_op = OPC_ROUND_L_D;
15740 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15741 mips32_op = OPC_ROUND_W_S;
15743 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15744 mips32_op = OPC_ROUND_W_D;
15747 /* Integer to floating-point conversion */
15748 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15749 mips32_op = OPC_CVT_L_S;
15751 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15752 mips32_op = OPC_CVT_L_D;
15754 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15755 mips32_op = OPC_CVT_W_S;
15757 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15758 mips32_op = OPC_CVT_W_D;
15761 /* Paired-foo conversions */
15762 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15763 mips32_op = OPC_CVT_S_PL;
15765 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15766 mips32_op = OPC_CVT_S_PU;
15768 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15769 mips32_op = OPC_CVT_PW_PS;
15771 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15772 mips32_op = OPC_CVT_PS_PW;
15775 /* Floating-point moves */
15776 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15777 mips32_op = OPC_MOV_S;
15779 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15780 mips32_op = OPC_MOV_D;
15782 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15783 mips32_op = OPC_MOV_PS;
15786 /* Absolute value */
15787 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15788 mips32_op = OPC_ABS_S;
15790 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15791 mips32_op = OPC_ABS_D;
15793 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15794 mips32_op = OPC_ABS_PS;
15798 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15799 mips32_op = OPC_NEG_S;
15801 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15802 mips32_op = OPC_NEG_D;
15804 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15805 mips32_op = OPC_NEG_PS;
15808 /* Reciprocal square root step */
15809 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15810 mips32_op = OPC_RSQRT1_S;
15812 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15813 mips32_op = OPC_RSQRT1_D;
15815 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15816 mips32_op = OPC_RSQRT1_PS;
15819 /* Reciprocal step */
15820 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15821 mips32_op = OPC_RECIP1_S;
15823 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15824 mips32_op = OPC_RECIP1_S;
15826 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15827 mips32_op = OPC_RECIP1_PS;
15830 /* Conversions from double */
15831 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15832 mips32_op = OPC_CVT_D_S;
15834 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15835 mips32_op = OPC_CVT_D_W;
15837 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15838 mips32_op = OPC_CVT_D_L;
15841 /* Conversions from single */
15842 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15843 mips32_op = OPC_CVT_S_D;
15845 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15846 mips32_op = OPC_CVT_S_W;
15848 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15849 mips32_op = OPC_CVT_S_L;
15851 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15854 /* Conditional moves on floating-point codes */
15855 case COND_FLOAT_MOV(MOVT, 0):
15856 case COND_FLOAT_MOV(MOVT, 1):
15857 case COND_FLOAT_MOV(MOVT, 2):
15858 case COND_FLOAT_MOV(MOVT, 3):
15859 case COND_FLOAT_MOV(MOVT, 4):
15860 case COND_FLOAT_MOV(MOVT, 5):
15861 case COND_FLOAT_MOV(MOVT, 6):
15862 case COND_FLOAT_MOV(MOVT, 7):
15863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15864 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15866 case COND_FLOAT_MOV(MOVF, 0):
15867 case COND_FLOAT_MOV(MOVF, 1):
15868 case COND_FLOAT_MOV(MOVF, 2):
15869 case COND_FLOAT_MOV(MOVF, 3):
15870 case COND_FLOAT_MOV(MOVF, 4):
15871 case COND_FLOAT_MOV(MOVF, 5):
15872 case COND_FLOAT_MOV(MOVF, 6):
15873 case COND_FLOAT_MOV(MOVF, 7):
15874 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15875 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15878 MIPS_INVAL("pool32fxf");
15879 generate_exception_end(ctx, EXCP_RI);
15884 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15888 int rt, rs, rd, rr;
15890 uint32_t op, minor, minor2, mips32_op;
15891 uint32_t cond, fmt, cc;
15893 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15894 ctx->opcode = (ctx->opcode << 16) | insn;
15896 rt = (ctx->opcode >> 21) & 0x1f;
15897 rs = (ctx->opcode >> 16) & 0x1f;
15898 rd = (ctx->opcode >> 11) & 0x1f;
15899 rr = (ctx->opcode >> 6) & 0x1f;
15900 imm = (int16_t) ctx->opcode;
15902 op = (ctx->opcode >> 26) & 0x3f;
15905 minor = ctx->opcode & 0x3f;
15908 minor = (ctx->opcode >> 6) & 0xf;
15911 mips32_op = OPC_SLL;
15914 mips32_op = OPC_SRA;
15917 mips32_op = OPC_SRL;
15920 mips32_op = OPC_ROTR;
15922 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15925 check_insn(ctx, ISA_MIPS32R6);
15926 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15929 check_insn(ctx, ISA_MIPS32R6);
15930 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15933 check_insn(ctx, ISA_MIPS32R6);
15934 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15937 goto pool32a_invalid;
15941 minor = (ctx->opcode >> 6) & 0xf;
15945 mips32_op = OPC_ADD;
15948 mips32_op = OPC_ADDU;
15951 mips32_op = OPC_SUB;
15954 mips32_op = OPC_SUBU;
15957 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15958 mips32_op = OPC_MUL;
15960 gen_arith(ctx, mips32_op, rd, rs, rt);
15964 mips32_op = OPC_SLLV;
15967 mips32_op = OPC_SRLV;
15970 mips32_op = OPC_SRAV;
15973 mips32_op = OPC_ROTRV;
15975 gen_shift(ctx, mips32_op, rd, rs, rt);
15977 /* Logical operations */
15979 mips32_op = OPC_AND;
15982 mips32_op = OPC_OR;
15985 mips32_op = OPC_NOR;
15988 mips32_op = OPC_XOR;
15990 gen_logic(ctx, mips32_op, rd, rs, rt);
15992 /* Set less than */
15994 mips32_op = OPC_SLT;
15997 mips32_op = OPC_SLTU;
15999 gen_slt(ctx, mips32_op, rd, rs, rt);
16002 goto pool32a_invalid;
16006 minor = (ctx->opcode >> 6) & 0xf;
16008 /* Conditional moves */
16009 case MOVN: /* MUL */
16010 if (ctx->insn_flags & ISA_MIPS32R6) {
16012 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16015 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16018 case MOVZ: /* MUH */
16019 if (ctx->insn_flags & ISA_MIPS32R6) {
16021 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16024 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16028 check_insn(ctx, ISA_MIPS32R6);
16029 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16032 check_insn(ctx, ISA_MIPS32R6);
16033 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16035 case LWXS: /* DIV */
16036 if (ctx->insn_flags & ISA_MIPS32R6) {
16038 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16041 gen_ldxs(ctx, rs, rt, rd);
16045 check_insn(ctx, ISA_MIPS32R6);
16046 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16049 check_insn(ctx, ISA_MIPS32R6);
16050 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16053 check_insn(ctx, ISA_MIPS32R6);
16054 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16057 goto pool32a_invalid;
16061 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16064 check_insn(ctx, ISA_MIPS32R6);
16065 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16066 extract32(ctx->opcode, 9, 2));
16069 check_insn(ctx, ISA_MIPS32R6);
16070 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16073 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16076 gen_pool32axf(env, ctx, rt, rs);
16079 generate_exception_end(ctx, EXCP_BREAK);
16082 check_insn(ctx, ISA_MIPS32R6);
16083 generate_exception_end(ctx, EXCP_RI);
16087 MIPS_INVAL("pool32a");
16088 generate_exception_end(ctx, EXCP_RI);
16093 minor = (ctx->opcode >> 12) & 0xf;
16096 check_cp0_enabled(ctx);
16097 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16098 gen_cache_operation(ctx, rt, rs, imm);
16103 /* COP2: Not implemented. */
16104 generate_exception_err(ctx, EXCP_CpU, 2);
16106 #ifdef TARGET_MIPS64
16109 check_insn(ctx, ISA_MIPS3);
16110 check_mips_64(ctx);
16115 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16117 #ifdef TARGET_MIPS64
16120 check_insn(ctx, ISA_MIPS3);
16121 check_mips_64(ctx);
16126 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16129 MIPS_INVAL("pool32b");
16130 generate_exception_end(ctx, EXCP_RI);
16135 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16136 minor = ctx->opcode & 0x3f;
16137 check_cp1_enabled(ctx);
16140 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16141 mips32_op = OPC_ALNV_PS;
16144 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16145 mips32_op = OPC_MADD_S;
16148 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16149 mips32_op = OPC_MADD_D;
16152 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16153 mips32_op = OPC_MADD_PS;
16156 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16157 mips32_op = OPC_MSUB_S;
16160 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16161 mips32_op = OPC_MSUB_D;
16164 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16165 mips32_op = OPC_MSUB_PS;
16168 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16169 mips32_op = OPC_NMADD_S;
16172 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16173 mips32_op = OPC_NMADD_D;
16176 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16177 mips32_op = OPC_NMADD_PS;
16180 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16181 mips32_op = OPC_NMSUB_S;
16184 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16185 mips32_op = OPC_NMSUB_D;
16188 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16189 mips32_op = OPC_NMSUB_PS;
16191 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16193 case CABS_COND_FMT:
16194 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16195 cond = (ctx->opcode >> 6) & 0xf;
16196 cc = (ctx->opcode >> 13) & 0x7;
16197 fmt = (ctx->opcode >> 10) & 0x3;
16200 gen_cmpabs_s(ctx, cond, rt, rs, cc);
16203 gen_cmpabs_d(ctx, cond, rt, rs, cc);
16206 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16209 goto pool32f_invalid;
16213 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16214 cond = (ctx->opcode >> 6) & 0xf;
16215 cc = (ctx->opcode >> 13) & 0x7;
16216 fmt = (ctx->opcode >> 10) & 0x3;
16219 gen_cmp_s(ctx, cond, rt, rs, cc);
16222 gen_cmp_d(ctx, cond, rt, rs, cc);
16225 gen_cmp_ps(ctx, cond, rt, rs, cc);
16228 goto pool32f_invalid;
16232 check_insn(ctx, ISA_MIPS32R6);
16233 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16236 check_insn(ctx, ISA_MIPS32R6);
16237 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16240 gen_pool32fxf(ctx, rt, rs);
16244 switch ((ctx->opcode >> 6) & 0x7) {
16246 mips32_op = OPC_PLL_PS;
16249 mips32_op = OPC_PLU_PS;
16252 mips32_op = OPC_PUL_PS;
16255 mips32_op = OPC_PUU_PS;
16258 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16259 mips32_op = OPC_CVT_PS_S;
16261 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16264 goto pool32f_invalid;
16268 check_insn(ctx, ISA_MIPS32R6);
16269 switch ((ctx->opcode >> 9) & 0x3) {
16271 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16274 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16277 goto pool32f_invalid;
16282 switch ((ctx->opcode >> 6) & 0x7) {
16284 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16285 mips32_op = OPC_LWXC1;
16288 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16289 mips32_op = OPC_SWXC1;
16292 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16293 mips32_op = OPC_LDXC1;
16296 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16297 mips32_op = OPC_SDXC1;
16300 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16301 mips32_op = OPC_LUXC1;
16304 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16305 mips32_op = OPC_SUXC1;
16307 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16310 goto pool32f_invalid;
16314 check_insn(ctx, ISA_MIPS32R6);
16315 switch ((ctx->opcode >> 9) & 0x3) {
16317 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16320 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16323 goto pool32f_invalid;
16328 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16329 fmt = (ctx->opcode >> 9) & 0x3;
16330 switch ((ctx->opcode >> 6) & 0x7) {
16334 mips32_op = OPC_RSQRT2_S;
16337 mips32_op = OPC_RSQRT2_D;
16340 mips32_op = OPC_RSQRT2_PS;
16343 goto pool32f_invalid;
16349 mips32_op = OPC_RECIP2_S;
16352 mips32_op = OPC_RECIP2_D;
16355 mips32_op = OPC_RECIP2_PS;
16358 goto pool32f_invalid;
16362 mips32_op = OPC_ADDR_PS;
16365 mips32_op = OPC_MULR_PS;
16367 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16370 goto pool32f_invalid;
16374 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16375 cc = (ctx->opcode >> 13) & 0x7;
16376 fmt = (ctx->opcode >> 9) & 0x3;
16377 switch ((ctx->opcode >> 6) & 0x7) {
16378 case MOVF_FMT: /* RINT_FMT */
16379 if (ctx->insn_flags & ISA_MIPS32R6) {
16383 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16386 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16389 goto pool32f_invalid;
16395 gen_movcf_s(ctx, rs, rt, cc, 0);
16398 gen_movcf_d(ctx, rs, rt, cc, 0);
16402 gen_movcf_ps(ctx, rs, rt, cc, 0);
16405 goto pool32f_invalid;
16409 case MOVT_FMT: /* CLASS_FMT */
16410 if (ctx->insn_flags & ISA_MIPS32R6) {
16414 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16417 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16420 goto pool32f_invalid;
16426 gen_movcf_s(ctx, rs, rt, cc, 1);
16429 gen_movcf_d(ctx, rs, rt, cc, 1);
16433 gen_movcf_ps(ctx, rs, rt, cc, 1);
16436 goto pool32f_invalid;
16441 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16444 goto pool32f_invalid;
16447 #define FINSN_3ARG_SDPS(prfx) \
16448 switch ((ctx->opcode >> 8) & 0x3) { \
16450 mips32_op = OPC_##prfx##_S; \
16453 mips32_op = OPC_##prfx##_D; \
16455 case FMT_SDPS_PS: \
16457 mips32_op = OPC_##prfx##_PS; \
16460 goto pool32f_invalid; \
16463 check_insn(ctx, ISA_MIPS32R6);
16464 switch ((ctx->opcode >> 9) & 0x3) {
16466 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16469 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16472 goto pool32f_invalid;
16476 check_insn(ctx, ISA_MIPS32R6);
16477 switch ((ctx->opcode >> 9) & 0x3) {
16479 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16482 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16485 goto pool32f_invalid;
16489 /* regular FP ops */
16490 switch ((ctx->opcode >> 6) & 0x3) {
16492 FINSN_3ARG_SDPS(ADD);
16495 FINSN_3ARG_SDPS(SUB);
16498 FINSN_3ARG_SDPS(MUL);
16501 fmt = (ctx->opcode >> 8) & 0x3;
16503 mips32_op = OPC_DIV_D;
16504 } else if (fmt == 0) {
16505 mips32_op = OPC_DIV_S;
16507 goto pool32f_invalid;
16511 goto pool32f_invalid;
16516 switch ((ctx->opcode >> 6) & 0x7) {
16517 case MOVN_FMT: /* SELEQZ_FMT */
16518 if (ctx->insn_flags & ISA_MIPS32R6) {
16520 switch ((ctx->opcode >> 9) & 0x3) {
16522 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16525 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16528 goto pool32f_invalid;
16532 FINSN_3ARG_SDPS(MOVN);
16536 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16537 FINSN_3ARG_SDPS(MOVN);
16539 case MOVZ_FMT: /* SELNEZ_FMT */
16540 if (ctx->insn_flags & ISA_MIPS32R6) {
16542 switch ((ctx->opcode >> 9) & 0x3) {
16544 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16547 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16550 goto pool32f_invalid;
16554 FINSN_3ARG_SDPS(MOVZ);
16558 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16559 FINSN_3ARG_SDPS(MOVZ);
16562 check_insn(ctx, ISA_MIPS32R6);
16563 switch ((ctx->opcode >> 9) & 0x3) {
16565 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16568 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16571 goto pool32f_invalid;
16575 check_insn(ctx, ISA_MIPS32R6);
16576 switch ((ctx->opcode >> 9) & 0x3) {
16578 mips32_op = OPC_MADDF_S;
16581 mips32_op = OPC_MADDF_D;
16584 goto pool32f_invalid;
16588 check_insn(ctx, ISA_MIPS32R6);
16589 switch ((ctx->opcode >> 9) & 0x3) {
16591 mips32_op = OPC_MSUBF_S;
16594 mips32_op = OPC_MSUBF_D;
16597 goto pool32f_invalid;
16601 goto pool32f_invalid;
16605 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16609 MIPS_INVAL("pool32f");
16610 generate_exception_end(ctx, EXCP_RI);
16614 generate_exception_err(ctx, EXCP_CpU, 1);
16618 minor = (ctx->opcode >> 21) & 0x1f;
16621 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16622 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16625 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16626 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16627 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16630 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16631 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16632 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16635 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16636 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16639 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16640 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16641 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16644 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16645 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16646 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16649 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16650 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16653 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16654 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16658 case TLTI: /* BC1EQZC */
16659 if (ctx->insn_flags & ISA_MIPS32R6) {
16661 check_cp1_enabled(ctx);
16662 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16665 mips32_op = OPC_TLTI;
16669 case TGEI: /* BC1NEZC */
16670 if (ctx->insn_flags & ISA_MIPS32R6) {
16672 check_cp1_enabled(ctx);
16673 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16676 mips32_op = OPC_TGEI;
16681 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16682 mips32_op = OPC_TLTIU;
16685 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16686 mips32_op = OPC_TGEIU;
16688 case TNEI: /* SYNCI */
16689 if (ctx->insn_flags & ISA_MIPS32R6) {
16691 /* Break the TB to be able to sync copied instructions
16693 ctx->base.is_jmp = DISAS_STOP;
16696 mips32_op = OPC_TNEI;
16701 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16702 mips32_op = OPC_TEQI;
16704 gen_trap(ctx, mips32_op, rs, -1, imm);
16709 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16710 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16711 4, rs, 0, imm << 1, 0);
16712 /* Compact branches don't have a delay slot, so just let
16713 the normal delay slot handling take us to the branch
16717 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16718 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16721 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16722 /* Break the TB to be able to sync copied instructions
16724 ctx->base.is_jmp = DISAS_STOP;
16728 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16729 /* COP2: Not implemented. */
16730 generate_exception_err(ctx, EXCP_CpU, 2);
16733 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16734 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16737 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16738 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16741 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16742 mips32_op = OPC_BC1FANY4;
16745 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16746 mips32_op = OPC_BC1TANY4;
16749 check_insn(ctx, ASE_MIPS3D);
16752 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16753 check_cp1_enabled(ctx);
16754 gen_compute_branch1(ctx, mips32_op,
16755 (ctx->opcode >> 18) & 0x7, imm << 1);
16757 generate_exception_err(ctx, EXCP_CpU, 1);
16762 /* MIPS DSP: not implemented */
16765 MIPS_INVAL("pool32i");
16766 generate_exception_end(ctx, EXCP_RI);
16771 minor = (ctx->opcode >> 12) & 0xf;
16772 offset = sextract32(ctx->opcode, 0,
16773 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16776 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16777 mips32_op = OPC_LWL;
16780 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16781 mips32_op = OPC_SWL;
16784 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16785 mips32_op = OPC_LWR;
16788 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16789 mips32_op = OPC_SWR;
16791 #if defined(TARGET_MIPS64)
16793 check_insn(ctx, ISA_MIPS3);
16794 check_mips_64(ctx);
16795 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16796 mips32_op = OPC_LDL;
16799 check_insn(ctx, ISA_MIPS3);
16800 check_mips_64(ctx);
16801 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16802 mips32_op = OPC_SDL;
16805 check_insn(ctx, ISA_MIPS3);
16806 check_mips_64(ctx);
16807 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16808 mips32_op = OPC_LDR;
16811 check_insn(ctx, ISA_MIPS3);
16812 check_mips_64(ctx);
16813 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16814 mips32_op = OPC_SDR;
16817 check_insn(ctx, ISA_MIPS3);
16818 check_mips_64(ctx);
16819 mips32_op = OPC_LWU;
16822 check_insn(ctx, ISA_MIPS3);
16823 check_mips_64(ctx);
16824 mips32_op = OPC_LLD;
16828 mips32_op = OPC_LL;
16831 gen_ld(ctx, mips32_op, rt, rs, offset);
16834 gen_st(ctx, mips32_op, rt, rs, offset);
16837 gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
16839 #if defined(TARGET_MIPS64)
16841 check_insn(ctx, ISA_MIPS3);
16842 check_mips_64(ctx);
16843 gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
16848 MIPS_INVAL("pool32c ld-eva");
16849 generate_exception_end(ctx, EXCP_RI);
16852 check_cp0_enabled(ctx);
16854 minor2 = (ctx->opcode >> 9) & 0x7;
16855 offset = sextract32(ctx->opcode, 0, 9);
16858 mips32_op = OPC_LBUE;
16861 mips32_op = OPC_LHUE;
16864 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16865 mips32_op = OPC_LWLE;
16868 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16869 mips32_op = OPC_LWRE;
16872 mips32_op = OPC_LBE;
16875 mips32_op = OPC_LHE;
16878 mips32_op = OPC_LLE;
16881 mips32_op = OPC_LWE;
16887 MIPS_INVAL("pool32c st-eva");
16888 generate_exception_end(ctx, EXCP_RI);
16891 check_cp0_enabled(ctx);
16893 minor2 = (ctx->opcode >> 9) & 0x7;
16894 offset = sextract32(ctx->opcode, 0, 9);
16897 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16898 mips32_op = OPC_SWLE;
16901 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16902 mips32_op = OPC_SWRE;
16905 /* Treat as no-op */
16906 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16907 /* hint codes 24-31 are reserved and signal RI */
16908 generate_exception(ctx, EXCP_RI);
16912 /* Treat as no-op */
16913 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16914 gen_cache_operation(ctx, rt, rs, offset);
16918 mips32_op = OPC_SBE;
16921 mips32_op = OPC_SHE;
16924 gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
16927 mips32_op = OPC_SWE;
16932 /* Treat as no-op */
16933 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16934 /* hint codes 24-31 are reserved and signal RI */
16935 generate_exception(ctx, EXCP_RI);
16939 MIPS_INVAL("pool32c");
16940 generate_exception_end(ctx, EXCP_RI);
16944 case ADDI32: /* AUI, LUI */
16945 if (ctx->insn_flags & ISA_MIPS32R6) {
16947 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16950 mips32_op = OPC_ADDI;
16955 mips32_op = OPC_ADDIU;
16957 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16960 /* Logical operations */
16962 mips32_op = OPC_ORI;
16965 mips32_op = OPC_XORI;
16968 mips32_op = OPC_ANDI;
16970 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16973 /* Set less than immediate */
16975 mips32_op = OPC_SLTI;
16978 mips32_op = OPC_SLTIU;
16980 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16983 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16984 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16985 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16986 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16988 case JALS32: /* BOVC, BEQC, BEQZALC */
16989 if (ctx->insn_flags & ISA_MIPS32R6) {
16992 mips32_op = OPC_BOVC;
16993 } else if (rs < rt && rs == 0) {
16995 mips32_op = OPC_BEQZALC;
16998 mips32_op = OPC_BEQC;
17000 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17003 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17004 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17005 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17008 case BEQ32: /* BC */
17009 if (ctx->insn_flags & ISA_MIPS32R6) {
17011 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17012 sextract32(ctx->opcode << 1, 0, 27));
17015 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17018 case BNE32: /* BALC */
17019 if (ctx->insn_flags & ISA_MIPS32R6) {
17021 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17022 sextract32(ctx->opcode << 1, 0, 27));
17025 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17028 case J32: /* BGTZC, BLTZC, BLTC */
17029 if (ctx->insn_flags & ISA_MIPS32R6) {
17030 if (rs == 0 && rt != 0) {
17032 mips32_op = OPC_BGTZC;
17033 } else if (rs != 0 && rt != 0 && rs == rt) {
17035 mips32_op = OPC_BLTZC;
17038 mips32_op = OPC_BLTC;
17040 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17043 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17044 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17047 case JAL32: /* BLEZC, BGEZC, BGEC */
17048 if (ctx->insn_flags & ISA_MIPS32R6) {
17049 if (rs == 0 && rt != 0) {
17051 mips32_op = OPC_BLEZC;
17052 } else if (rs != 0 && rt != 0 && rs == rt) {
17054 mips32_op = OPC_BGEZC;
17057 mips32_op = OPC_BGEC;
17059 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17062 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17063 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17064 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17067 /* Floating point (COP1) */
17069 mips32_op = OPC_LWC1;
17072 mips32_op = OPC_LDC1;
17075 mips32_op = OPC_SWC1;
17078 mips32_op = OPC_SDC1;
17080 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17082 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17083 if (ctx->insn_flags & ISA_MIPS32R6) {
17084 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17085 switch ((ctx->opcode >> 16) & 0x1f) {
17094 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17097 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17100 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17110 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17113 generate_exception(ctx, EXCP_RI);
17118 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17119 offset = SIMM(ctx->opcode, 0, 23) << 2;
17121 gen_addiupc(ctx, reg, offset, 0, 0);
17124 case BNVC: /* BNEC, BNEZALC */
17125 check_insn(ctx, ISA_MIPS32R6);
17128 mips32_op = OPC_BNVC;
17129 } else if (rs < rt && rs == 0) {
17131 mips32_op = OPC_BNEZALC;
17134 mips32_op = OPC_BNEC;
17136 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17138 case R6_BNEZC: /* JIALC */
17139 check_insn(ctx, ISA_MIPS32R6);
17142 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17143 sextract32(ctx->opcode << 1, 0, 22));
17146 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17149 case R6_BEQZC: /* JIC */
17150 check_insn(ctx, ISA_MIPS32R6);
17153 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17154 sextract32(ctx->opcode << 1, 0, 22));
17157 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17160 case BLEZALC: /* BGEZALC, BGEUC */
17161 check_insn(ctx, ISA_MIPS32R6);
17162 if (rs == 0 && rt != 0) {
17164 mips32_op = OPC_BLEZALC;
17165 } else if (rs != 0 && rt != 0 && rs == rt) {
17167 mips32_op = OPC_BGEZALC;
17170 mips32_op = OPC_BGEUC;
17172 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17174 case BGTZALC: /* BLTZALC, BLTUC */
17175 check_insn(ctx, ISA_MIPS32R6);
17176 if (rs == 0 && rt != 0) {
17178 mips32_op = OPC_BGTZALC;
17179 } else if (rs != 0 && rt != 0 && rs == rt) {
17181 mips32_op = OPC_BLTZALC;
17184 mips32_op = OPC_BLTUC;
17186 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17188 /* Loads and stores */
17190 mips32_op = OPC_LB;
17193 mips32_op = OPC_LBU;
17196 mips32_op = OPC_LH;
17199 mips32_op = OPC_LHU;
17202 mips32_op = OPC_LW;
17204 #ifdef TARGET_MIPS64
17206 check_insn(ctx, ISA_MIPS3);
17207 check_mips_64(ctx);
17208 mips32_op = OPC_LD;
17211 check_insn(ctx, ISA_MIPS3);
17212 check_mips_64(ctx);
17213 mips32_op = OPC_SD;
17217 mips32_op = OPC_SB;
17220 mips32_op = OPC_SH;
17223 mips32_op = OPC_SW;
17226 gen_ld(ctx, mips32_op, rt, rs, imm);
17229 gen_st(ctx, mips32_op, rt, rs, imm);
17232 generate_exception_end(ctx, EXCP_RI);
17237 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
17241 /* make sure instructions are on a halfword boundary */
17242 if (ctx->base.pc_next & 0x1) {
17243 env->CP0_BadVAddr = ctx->base.pc_next;
17244 generate_exception_end(ctx, EXCP_AdEL);
17248 op = (ctx->opcode >> 10) & 0x3f;
17249 /* Enforce properly-sized instructions in a delay slot */
17250 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17251 switch (op & 0x7) { /* MSB-3..MSB-5 */
17253 /* POOL32A, POOL32B, POOL32I, POOL32C */
17255 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17257 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17259 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17261 /* LB32, LH32, LWC132, LDC132, LW32 */
17262 if (ctx->hflags & MIPS_HFLAG_BDS16) {
17263 generate_exception_end(ctx, EXCP_RI);
17268 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17270 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17272 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17273 if (ctx->hflags & MIPS_HFLAG_BDS32) {
17274 generate_exception_end(ctx, EXCP_RI);
17284 int rd = mmreg(uMIPS_RD(ctx->opcode));
17285 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17286 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17289 switch (ctx->opcode & 0x1) {
17297 if (ctx->insn_flags & ISA_MIPS32R6) {
17298 /* In the Release 6 the register number location in
17299 * the instruction encoding has changed.
17301 gen_arith(ctx, opc, rs1, rd, rs2);
17303 gen_arith(ctx, opc, rd, rs1, rs2);
17309 int rd = mmreg(uMIPS_RD(ctx->opcode));
17310 int rs = mmreg(uMIPS_RS(ctx->opcode));
17311 int amount = (ctx->opcode >> 1) & 0x7;
17313 amount = amount == 0 ? 8 : amount;
17315 switch (ctx->opcode & 0x1) {
17324 gen_shift_imm(ctx, opc, rd, rs, amount);
17328 if (ctx->insn_flags & ISA_MIPS32R6) {
17329 gen_pool16c_r6_insn(ctx);
17331 gen_pool16c_insn(ctx);
17336 int rd = mmreg(uMIPS_RD(ctx->opcode));
17337 int rb = 28; /* GP */
17338 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17340 gen_ld(ctx, OPC_LW, rd, rb, offset);
17344 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17345 if (ctx->opcode & 1) {
17346 generate_exception_end(ctx, EXCP_RI);
17349 int enc_dest = uMIPS_RD(ctx->opcode);
17350 int enc_rt = uMIPS_RS2(ctx->opcode);
17351 int enc_rs = uMIPS_RS1(ctx->opcode);
17352 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17357 int rd = mmreg(uMIPS_RD(ctx->opcode));
17358 int rb = mmreg(uMIPS_RS(ctx->opcode));
17359 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17360 offset = (offset == 0xf ? -1 : offset);
17362 gen_ld(ctx, OPC_LBU, rd, rb, offset);
17367 int rd = mmreg(uMIPS_RD(ctx->opcode));
17368 int rb = mmreg(uMIPS_RS(ctx->opcode));
17369 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17371 gen_ld(ctx, OPC_LHU, rd, rb, offset);
17376 int rd = (ctx->opcode >> 5) & 0x1f;
17377 int rb = 29; /* SP */
17378 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17380 gen_ld(ctx, OPC_LW, rd, rb, offset);
17385 int rd = mmreg(uMIPS_RD(ctx->opcode));
17386 int rb = mmreg(uMIPS_RS(ctx->opcode));
17387 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17389 gen_ld(ctx, OPC_LW, rd, rb, offset);
17394 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17395 int rb = mmreg(uMIPS_RS(ctx->opcode));
17396 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17398 gen_st(ctx, OPC_SB, rd, rb, offset);
17403 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17404 int rb = mmreg(uMIPS_RS(ctx->opcode));
17405 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17407 gen_st(ctx, OPC_SH, rd, rb, offset);
17412 int rd = (ctx->opcode >> 5) & 0x1f;
17413 int rb = 29; /* SP */
17414 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17416 gen_st(ctx, OPC_SW, rd, rb, offset);
17421 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17422 int rb = mmreg(uMIPS_RS(ctx->opcode));
17423 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17425 gen_st(ctx, OPC_SW, rd, rb, offset);
17430 int rd = uMIPS_RD5(ctx->opcode);
17431 int rs = uMIPS_RS5(ctx->opcode);
17433 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17440 switch (ctx->opcode & 0x1) {
17450 switch (ctx->opcode & 0x1) {
17455 gen_addiur1sp(ctx);
17459 case B16: /* BC16 */
17460 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17461 sextract32(ctx->opcode, 0, 10) << 1,
17462 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17464 case BNEZ16: /* BNEZC16 */
17465 case BEQZ16: /* BEQZC16 */
17466 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17467 mmreg(uMIPS_RD(ctx->opcode)),
17468 0, sextract32(ctx->opcode, 0, 7) << 1,
17469 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17474 int reg = mmreg(uMIPS_RD(ctx->opcode));
17475 int imm = ZIMM(ctx->opcode, 0, 7);
17477 imm = (imm == 0x7f ? -1 : imm);
17478 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17484 generate_exception_end(ctx, EXCP_RI);
17487 decode_micromips32_opc(env, ctx);
17500 /* MAJOR, P16, and P32 pools opcodes */
17504 NM_MOVE_BALC = 0x02,
17512 NM_P16_SHIFT = 0x0c,
17530 NM_P_LS_U12 = 0x21,
17540 NM_P16_ADDU = 0x2c,
17554 NM_MOVEPREV = 0x3f,
17557 /* POOL32A instruction pool */
17559 NM_POOL32A0 = 0x00,
17560 NM_SPECIAL2 = 0x01,
17563 NM_POOL32A5 = 0x05,
17564 NM_POOL32A7 = 0x07,
17567 /* P.GP.W instruction pool */
17569 NM_ADDIUGP_W = 0x00,
17574 /* P48I instruction pool */
17578 NM_ADDIUGP48 = 0x02,
17579 NM_ADDIUPC48 = 0x03,
17584 /* P.U12 instruction pool */
17593 NM_ADDIUNEG = 0x08,
17600 /* POOL32F instruction pool */
17602 NM_POOL32F_0 = 0x00,
17603 NM_POOL32F_3 = 0x03,
17604 NM_POOL32F_5 = 0x05,
17607 /* POOL32S instruction pool */
17609 NM_POOL32S_0 = 0x00,
17610 NM_POOL32S_4 = 0x04,
17613 /* P.LUI instruction pool */
17619 /* P.GP.BH instruction pool */
17624 NM_ADDIUGP_B = 0x03,
17627 NM_P_GP_CP1 = 0x06,
17630 /* P.LS.U12 instruction pool */
17635 NM_P_PREFU12 = 0x03,
17648 /* P.LS.S9 instruction pool */
17654 NM_P_LS_UAWM = 0x05,
17657 /* P.BAL instruction pool */
17663 /* P.J instruction pool */
17666 NM_JALRC_HB = 0x01,
17667 NM_P_BALRSC = 0x08,
17670 /* P.BR1 instruction pool */
17678 /* P.BR2 instruction pool */
17685 /* P.BRI instruction pool */
17697 /* P16.SHIFT instruction pool */
17703 /* POOL16C instruction pool */
17705 NM_POOL16C_0 = 0x00,
17709 /* P16.A1 instruction pool */
17711 NM_ADDIUR1SP = 0x01,
17714 /* P16.A2 instruction pool */
17717 NM_P_ADDIURS5 = 0x01,
17720 /* P16.ADDU instruction pool */
17726 /* P16.SR instruction pool */
17729 NM_RESTORE_JRC16 = 0x01,
17732 /* P16.4X4 instruction pool */
17738 /* P16.LB instruction pool */
17745 /* P16.LH instruction pool */
17752 /* P.RI instruction pool */
17755 NM_P_SYSCALL = 0x01,
17760 /* POOL32A0 instruction pool */
17795 NM_D_E_MT_VPE = 0x56,
17803 /* CRC32 instruction pool */
17813 /* POOL32A5 instruction pool */
17815 NM_CMP_EQ_PH = 0x00,
17816 NM_CMP_LT_PH = 0x08,
17817 NM_CMP_LE_PH = 0x10,
17818 NM_CMPGU_EQ_QB = 0x18,
17819 NM_CMPGU_LT_QB = 0x20,
17820 NM_CMPGU_LE_QB = 0x28,
17821 NM_CMPGDU_EQ_QB = 0x30,
17822 NM_CMPGDU_LT_QB = 0x38,
17823 NM_CMPGDU_LE_QB = 0x40,
17824 NM_CMPU_EQ_QB = 0x48,
17825 NM_CMPU_LT_QB = 0x50,
17826 NM_CMPU_LE_QB = 0x58,
17827 NM_ADDQ_S_W = 0x60,
17828 NM_SUBQ_S_W = 0x68,
17832 NM_ADDQ_S_PH = 0x01,
17833 NM_ADDQH_R_PH = 0x09,
17834 NM_ADDQH_R_W = 0x11,
17835 NM_ADDU_S_QB = 0x19,
17836 NM_ADDU_S_PH = 0x21,
17837 NM_ADDUH_R_QB = 0x29,
17838 NM_SHRAV_R_PH = 0x31,
17839 NM_SHRAV_R_QB = 0x39,
17840 NM_SUBQ_S_PH = 0x41,
17841 NM_SUBQH_R_PH = 0x49,
17842 NM_SUBQH_R_W = 0x51,
17843 NM_SUBU_S_QB = 0x59,
17844 NM_SUBU_S_PH = 0x61,
17845 NM_SUBUH_R_QB = 0x69,
17846 NM_SHLLV_S_PH = 0x71,
17847 NM_PRECR_SRA_R_PH_W = 0x79,
17849 NM_MULEU_S_PH_QBL = 0x12,
17850 NM_MULEU_S_PH_QBR = 0x1a,
17851 NM_MULQ_RS_PH = 0x22,
17852 NM_MULQ_S_PH = 0x2a,
17853 NM_MULQ_RS_W = 0x32,
17854 NM_MULQ_S_W = 0x3a,
17857 NM_SHRAV_R_W = 0x5a,
17858 NM_SHRLV_PH = 0x62,
17859 NM_SHRLV_QB = 0x6a,
17860 NM_SHLLV_QB = 0x72,
17861 NM_SHLLV_S_W = 0x7a,
17865 NM_MULEQ_S_W_PHL = 0x04,
17866 NM_MULEQ_S_W_PHR = 0x0c,
17868 NM_MUL_S_PH = 0x05,
17869 NM_PRECR_QB_PH = 0x0d,
17870 NM_PRECRQ_QB_PH = 0x15,
17871 NM_PRECRQ_PH_W = 0x1d,
17872 NM_PRECRQ_RS_PH_W = 0x25,
17873 NM_PRECRQU_S_QB_PH = 0x2d,
17874 NM_PACKRL_PH = 0x35,
17878 NM_SHRA_R_W = 0x5e,
17879 NM_SHRA_R_PH = 0x66,
17880 NM_SHLL_S_PH = 0x76,
17881 NM_SHLL_S_W = 0x7e,
17886 /* POOL32A7 instruction pool */
17891 NM_POOL32AXF = 0x07,
17894 /* P.SR instruction pool */
17900 /* P.SHIFT instruction pool */
17908 /* P.ROTX instruction pool */
17913 /* P.INS instruction pool */
17918 /* P.EXT instruction pool */
17923 /* POOL32F_0 (fmt) instruction pool */
17928 NM_SELEQZ_S = 0x07,
17929 NM_SELEQZ_D = 0x47,
17933 NM_SELNEZ_S = 0x0f,
17934 NM_SELNEZ_D = 0x4f,
17949 /* POOL32F_3 instruction pool */
17953 NM_MINA_FMT = 0x04,
17954 NM_MAXA_FMT = 0x05,
17955 NM_POOL32FXF = 0x07,
17958 /* POOL32F_5 instruction pool */
17960 NM_CMP_CONDN_S = 0x00,
17961 NM_CMP_CONDN_D = 0x02,
17964 /* P.GP.LH instruction pool */
17970 /* P.GP.SH instruction pool */
17975 /* P.GP.CP1 instruction pool */
17983 /* P.LS.S0 instruction pool */
18000 NM_P_PREFS9 = 0x03,
18006 /* P.LS.S1 instruction pool */
18008 NM_ASET_ACLR = 0x02,
18016 /* P.LS.E0 instruction pool */
18032 /* P.PREFE instruction pool */
18038 /* P.LLE instruction pool */
18044 /* P.SCE instruction pool */
18050 /* P.LS.WM instruction pool */
18056 /* P.LS.UAWM instruction pool */
18062 /* P.BR3A instruction pool */
18068 NM_BPOSGE32C = 0x04,
18071 /* P16.RI instruction pool */
18073 NM_P16_SYSCALL = 0x01,
18078 /* POOL16C_0 instruction pool */
18080 NM_POOL16C_00 = 0x00,
18083 /* P16.JRC instruction pool */
18089 /* P.SYSCALL instruction pool */
18095 /* P.TRAP instruction pool */
18101 /* P.CMOVE instruction pool */
18107 /* POOL32Axf instruction pool */
18109 NM_POOL32AXF_1 = 0x01,
18110 NM_POOL32AXF_2 = 0x02,
18111 NM_POOL32AXF_4 = 0x04,
18112 NM_POOL32AXF_5 = 0x05,
18113 NM_POOL32AXF_7 = 0x07,
18116 /* POOL32Axf_1 instruction pool */
18118 NM_POOL32AXF_1_0 = 0x00,
18119 NM_POOL32AXF_1_1 = 0x01,
18120 NM_POOL32AXF_1_3 = 0x03,
18121 NM_POOL32AXF_1_4 = 0x04,
18122 NM_POOL32AXF_1_5 = 0x05,
18123 NM_POOL32AXF_1_7 = 0x07,
18126 /* POOL32Axf_2 instruction pool */
18128 NM_POOL32AXF_2_0_7 = 0x00,
18129 NM_POOL32AXF_2_8_15 = 0x01,
18130 NM_POOL32AXF_2_16_23 = 0x02,
18131 NM_POOL32AXF_2_24_31 = 0x03,
18134 /* POOL32Axf_7 instruction pool */
18136 NM_SHRA_R_QB = 0x0,
18141 /* POOL32Axf_1_0 instruction pool */
18149 /* POOL32Axf_1_1 instruction pool */
18155 /* POOL32Axf_1_3 instruction pool */
18163 /* POOL32Axf_1_4 instruction pool */
18169 /* POOL32Axf_1_5 instruction pool */
18171 NM_MAQ_S_W_PHR = 0x0,
18172 NM_MAQ_S_W_PHL = 0x1,
18173 NM_MAQ_SA_W_PHR = 0x2,
18174 NM_MAQ_SA_W_PHL = 0x3,
18177 /* POOL32Axf_1_7 instruction pool */
18181 NM_EXTR_RS_W = 0x2,
18185 /* POOL32Axf_2_0_7 instruction pool */
18188 NM_DPAQ_S_W_PH = 0x1,
18190 NM_DPSQ_S_W_PH = 0x3,
18197 /* POOL32Axf_2_8_15 instruction pool */
18199 NM_DPAX_W_PH = 0x0,
18200 NM_DPAQ_SA_L_W = 0x1,
18201 NM_DPSX_W_PH = 0x2,
18202 NM_DPSQ_SA_L_W = 0x3,
18205 NM_EXTRV_R_W = 0x7,
18208 /* POOL32Axf_2_16_23 instruction pool */
18210 NM_DPAU_H_QBL = 0x0,
18211 NM_DPAQX_S_W_PH = 0x1,
18212 NM_DPSU_H_QBL = 0x2,
18213 NM_DPSQX_S_W_PH = 0x3,
18216 NM_MULSA_W_PH = 0x6,
18217 NM_EXTRV_RS_W = 0x7,
18220 /* POOL32Axf_2_24_31 instruction pool */
18222 NM_DPAU_H_QBR = 0x0,
18223 NM_DPAQX_SA_W_PH = 0x1,
18224 NM_DPSU_H_QBR = 0x2,
18225 NM_DPSQX_SA_W_PH = 0x3,
18228 NM_MULSAQ_S_W_PH = 0x6,
18229 NM_EXTRV_S_H = 0x7,
18232 /* POOL32Axf_{4, 5} instruction pool */
18251 /* nanoMIPS DSP instructions */
18252 NM_ABSQ_S_QB = 0x00,
18253 NM_ABSQ_S_PH = 0x08,
18254 NM_ABSQ_S_W = 0x10,
18255 NM_PRECEQ_W_PHL = 0x28,
18256 NM_PRECEQ_W_PHR = 0x30,
18257 NM_PRECEQU_PH_QBL = 0x38,
18258 NM_PRECEQU_PH_QBR = 0x48,
18259 NM_PRECEU_PH_QBL = 0x58,
18260 NM_PRECEU_PH_QBR = 0x68,
18261 NM_PRECEQU_PH_QBLA = 0x39,
18262 NM_PRECEQU_PH_QBRA = 0x49,
18263 NM_PRECEU_PH_QBLA = 0x59,
18264 NM_PRECEU_PH_QBRA = 0x69,
18265 NM_REPLV_PH = 0x01,
18266 NM_REPLV_QB = 0x09,
18269 NM_RADDU_W_QB = 0x78,
18275 /* PP.SR instruction pool */
18279 NM_RESTORE_JRC = 0x03,
18282 /* P.SR.F instruction pool */
18285 NM_RESTOREF = 0x01,
18288 /* P16.SYSCALL instruction pool */
18290 NM_SYSCALL16 = 0x00,
18291 NM_HYPCALL16 = 0x01,
18294 /* POOL16C_00 instruction pool */
18302 /* PP.LSX and PP.LSXS instruction pool */
18340 /* ERETx instruction pool */
18346 /* POOL32FxF_{0, 1} insturction pool */
18355 NM_CVT_S_PL = 0x84,
18356 NM_CVT_S_PU = 0xa4,
18358 NM_CVT_L_S = 0x004,
18359 NM_CVT_L_D = 0x104,
18360 NM_CVT_W_S = 0x024,
18361 NM_CVT_W_D = 0x124,
18363 NM_RSQRT_S = 0x008,
18364 NM_RSQRT_D = 0x108,
18369 NM_RECIP_S = 0x048,
18370 NM_RECIP_D = 0x148,
18372 NM_FLOOR_L_S = 0x00c,
18373 NM_FLOOR_L_D = 0x10c,
18375 NM_FLOOR_W_S = 0x02c,
18376 NM_FLOOR_W_D = 0x12c,
18378 NM_CEIL_L_S = 0x04c,
18379 NM_CEIL_L_D = 0x14c,
18380 NM_CEIL_W_S = 0x06c,
18381 NM_CEIL_W_D = 0x16c,
18382 NM_TRUNC_L_S = 0x08c,
18383 NM_TRUNC_L_D = 0x18c,
18384 NM_TRUNC_W_S = 0x0ac,
18385 NM_TRUNC_W_D = 0x1ac,
18386 NM_ROUND_L_S = 0x0cc,
18387 NM_ROUND_L_D = 0x1cc,
18388 NM_ROUND_W_S = 0x0ec,
18389 NM_ROUND_W_D = 0x1ec,
18397 NM_CVT_D_S = 0x04d,
18398 NM_CVT_D_W = 0x0cd,
18399 NM_CVT_D_L = 0x14d,
18400 NM_CVT_S_D = 0x06d,
18401 NM_CVT_S_W = 0x0ed,
18402 NM_CVT_S_L = 0x16d,
18405 /* P.LL instruction pool */
18411 /* P.SC instruction pool */
18417 /* P.DVP instruction pool */
18426 * nanoMIPS decoding engine
18431 /* extraction utilities */
18433 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18434 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18435 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18436 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18437 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18439 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18440 static inline int decode_gpr_gpr3(int r)
18442 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18444 return map[r & 0x7];
18447 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18448 static inline int decode_gpr_gpr3_src_store(int r)
18450 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18452 return map[r & 0x7];
18455 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18456 static inline int decode_gpr_gpr4(int r)
18458 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18459 16, 17, 18, 19, 20, 21, 22, 23 };
18461 return map[r & 0xf];
18464 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18465 static inline int decode_gpr_gpr4_zero(int r)
18467 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18468 16, 17, 18, 19, 20, 21, 22, 23 };
18470 return map[r & 0xf];
18474 static void gen_adjust_sp(DisasContext *ctx, int u)
18476 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18479 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18480 uint8_t gp, uint16_t u)
18483 TCGv va = tcg_temp_new();
18484 TCGv t0 = tcg_temp_new();
18486 while (counter != count) {
18487 bool use_gp = gp && (counter == count - 1);
18488 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18489 int this_offset = -((counter + 1) << 2);
18490 gen_base_offset_addr(ctx, va, 29, this_offset);
18491 gen_load_gpr(t0, this_rt);
18492 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18493 (MO_TEUL | ctx->default_tcg_memop_mask));
18497 /* adjust stack pointer */
18498 gen_adjust_sp(ctx, -u);
18504 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18505 uint8_t gp, uint16_t u)
18508 TCGv va = tcg_temp_new();
18509 TCGv t0 = tcg_temp_new();
18511 while (counter != count) {
18512 bool use_gp = gp && (counter == count - 1);
18513 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18514 int this_offset = u - ((counter + 1) << 2);
18515 gen_base_offset_addr(ctx, va, 29, this_offset);
18516 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18517 ctx->default_tcg_memop_mask);
18518 tcg_gen_ext32s_tl(t0, t0);
18519 gen_store_gpr(t0, this_rt);
18523 /* adjust stack pointer */
18524 gen_adjust_sp(ctx, u);
18530 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18532 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18533 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
18535 switch (extract32(ctx->opcode, 2, 2)) {
18537 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18540 gen_logic(ctx, OPC_AND, rt, rt, rs);
18543 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18546 gen_logic(ctx, OPC_OR, rt, rt, rs);
18551 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18553 int rt = extract32(ctx->opcode, 21, 5);
18554 int rs = extract32(ctx->opcode, 16, 5);
18555 int rd = extract32(ctx->opcode, 11, 5);
18557 switch (extract32(ctx->opcode, 3, 7)) {
18559 switch (extract32(ctx->opcode, 10, 1)) {
18562 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18566 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18572 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18576 gen_bshfl(ctx, OPC_SEB, rs, rt);
18579 gen_bshfl(ctx, OPC_SEH, rs, rt);
18582 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18585 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18588 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18591 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18594 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18597 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18601 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18604 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18607 switch (extract32(ctx->opcode, 10, 1)) {
18609 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18612 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18617 gen_logic(ctx, OPC_AND, rd, rs, rt);
18620 gen_logic(ctx, OPC_OR, rd, rs, rt);
18623 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18626 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18629 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18634 #ifndef CONFIG_USER_ONLY
18635 TCGv t0 = tcg_temp_new();
18636 switch (extract32(ctx->opcode, 10, 1)) {
18639 check_cp0_enabled(ctx);
18640 gen_helper_dvp(t0, cpu_env);
18641 gen_store_gpr(t0, rt);
18646 check_cp0_enabled(ctx);
18647 gen_helper_evp(t0, cpu_env);
18648 gen_store_gpr(t0, rt);
18655 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18660 TCGv t0 = tcg_temp_new();
18661 TCGv t1 = tcg_temp_new();
18662 TCGv t2 = tcg_temp_new();
18664 gen_load_gpr(t1, rs);
18665 gen_load_gpr(t2, rt);
18666 tcg_gen_add_tl(t0, t1, t2);
18667 tcg_gen_ext32s_tl(t0, t0);
18668 tcg_gen_xor_tl(t1, t1, t2);
18669 tcg_gen_xor_tl(t2, t0, t2);
18670 tcg_gen_andc_tl(t1, t2, t1);
18672 /* operands of same sign, result different sign */
18673 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18674 gen_store_gpr(t0, rd);
18682 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18685 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18688 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18691 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18694 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18697 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18700 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18703 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18705 #ifndef CONFIG_USER_ONLY
18707 check_cp0_enabled(ctx);
18709 /* Treat as NOP. */
18712 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18715 check_cp0_enabled(ctx);
18717 TCGv t0 = tcg_temp_new();
18719 gen_load_gpr(t0, rt);
18720 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18724 case NM_D_E_MT_VPE:
18726 uint8_t sc = extract32(ctx->opcode, 10, 1);
18727 TCGv t0 = tcg_temp_new();
18734 gen_helper_dmt(t0);
18735 gen_store_gpr(t0, rt);
18736 } else if (rs == 0) {
18739 gen_helper_dvpe(t0, cpu_env);
18740 gen_store_gpr(t0, rt);
18742 generate_exception_end(ctx, EXCP_RI);
18749 gen_helper_emt(t0);
18750 gen_store_gpr(t0, rt);
18751 } else if (rs == 0) {
18754 gen_helper_evpe(t0, cpu_env);
18755 gen_store_gpr(t0, rt);
18757 generate_exception_end(ctx, EXCP_RI);
18768 TCGv t0 = tcg_temp_new();
18769 TCGv t1 = tcg_temp_new();
18771 gen_load_gpr(t0, rt);
18772 gen_load_gpr(t1, rs);
18773 gen_helper_fork(t0, t1);
18780 check_cp0_enabled(ctx);
18782 /* Treat as NOP. */
18785 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18786 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18790 check_cp0_enabled(ctx);
18791 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18792 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18797 TCGv t0 = tcg_temp_new();
18799 gen_load_gpr(t0, rs);
18800 gen_helper_yield(t0, cpu_env, t0);
18801 gen_store_gpr(t0, rt);
18807 generate_exception_end(ctx, EXCP_RI);
18813 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18814 int ret, int v1, int v2)
18820 t0 = tcg_temp_new_i32();
18822 v0_t = tcg_temp_new();
18823 v1_t = tcg_temp_new();
18825 tcg_gen_movi_i32(t0, v2 >> 3);
18827 gen_load_gpr(v0_t, ret);
18828 gen_load_gpr(v1_t, v1);
18831 case NM_MAQ_S_W_PHR:
18833 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18835 case NM_MAQ_S_W_PHL:
18837 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18839 case NM_MAQ_SA_W_PHR:
18841 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18843 case NM_MAQ_SA_W_PHL:
18845 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18848 generate_exception_end(ctx, EXCP_RI);
18852 tcg_temp_free_i32(t0);
18854 tcg_temp_free(v0_t);
18855 tcg_temp_free(v1_t);
18859 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18860 int ret, int v1, int v2)
18863 TCGv t0 = tcg_temp_new();
18864 TCGv t1 = tcg_temp_new();
18865 TCGv v0_t = tcg_temp_new();
18867 gen_load_gpr(v0_t, v1);
18870 case NM_POOL32AXF_1_0:
18872 switch (extract32(ctx->opcode, 12, 2)) {
18874 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18877 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18880 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18883 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18887 case NM_POOL32AXF_1_1:
18889 switch (extract32(ctx->opcode, 12, 2)) {
18891 tcg_gen_movi_tl(t0, v2);
18892 gen_helper_mthlip(t0, v0_t, cpu_env);
18895 tcg_gen_movi_tl(t0, v2 >> 3);
18896 gen_helper_shilo(t0, v0_t, cpu_env);
18899 generate_exception_end(ctx, EXCP_RI);
18903 case NM_POOL32AXF_1_3:
18905 imm = extract32(ctx->opcode, 14, 7);
18906 switch (extract32(ctx->opcode, 12, 2)) {
18908 tcg_gen_movi_tl(t0, imm);
18909 gen_helper_rddsp(t0, t0, cpu_env);
18910 gen_store_gpr(t0, ret);
18913 gen_load_gpr(t0, ret);
18914 tcg_gen_movi_tl(t1, imm);
18915 gen_helper_wrdsp(t0, t1, cpu_env);
18918 tcg_gen_movi_tl(t0, v2 >> 3);
18919 tcg_gen_movi_tl(t1, v1);
18920 gen_helper_extp(t0, t0, t1, cpu_env);
18921 gen_store_gpr(t0, ret);
18924 tcg_gen_movi_tl(t0, v2 >> 3);
18925 tcg_gen_movi_tl(t1, v1);
18926 gen_helper_extpdp(t0, t0, t1, cpu_env);
18927 gen_store_gpr(t0, ret);
18931 case NM_POOL32AXF_1_4:
18933 tcg_gen_movi_tl(t0, v2 >> 2);
18934 switch (extract32(ctx->opcode, 12, 1)) {
18936 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18937 gen_store_gpr(t0, ret);
18940 gen_helper_shrl_qb(t0, t0, v0_t);
18941 gen_store_gpr(t0, ret);
18945 case NM_POOL32AXF_1_5:
18946 opc = extract32(ctx->opcode, 12, 2);
18947 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18949 case NM_POOL32AXF_1_7:
18951 tcg_gen_movi_tl(t0, v2 >> 3);
18952 tcg_gen_movi_tl(t1, v1);
18953 switch (extract32(ctx->opcode, 12, 2)) {
18955 gen_helper_extr_w(t0, t0, t1, cpu_env);
18956 gen_store_gpr(t0, ret);
18959 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18960 gen_store_gpr(t0, ret);
18963 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18964 gen_store_gpr(t0, ret);
18967 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18968 gen_store_gpr(t0, ret);
18973 generate_exception_end(ctx, EXCP_RI);
18979 tcg_temp_free(v0_t);
18982 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18983 TCGv v0, TCGv v1, int rd)
18987 t0 = tcg_temp_new_i32();
18989 tcg_gen_movi_i32(t0, rd >> 3);
18992 case NM_POOL32AXF_2_0_7:
18993 switch (extract32(ctx->opcode, 9, 3)) {
18996 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18998 case NM_DPAQ_S_W_PH:
19000 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19004 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19006 case NM_DPSQ_S_W_PH:
19008 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19011 generate_exception_end(ctx, EXCP_RI);
19015 case NM_POOL32AXF_2_8_15:
19016 switch (extract32(ctx->opcode, 9, 3)) {
19019 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19021 case NM_DPAQ_SA_L_W:
19023 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19027 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19029 case NM_DPSQ_SA_L_W:
19031 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19034 generate_exception_end(ctx, EXCP_RI);
19038 case NM_POOL32AXF_2_16_23:
19039 switch (extract32(ctx->opcode, 9, 3)) {
19040 case NM_DPAU_H_QBL:
19042 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19044 case NM_DPAQX_S_W_PH:
19046 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19048 case NM_DPSU_H_QBL:
19050 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19052 case NM_DPSQX_S_W_PH:
19054 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19056 case NM_MULSA_W_PH:
19058 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19061 generate_exception_end(ctx, EXCP_RI);
19065 case NM_POOL32AXF_2_24_31:
19066 switch (extract32(ctx->opcode, 9, 3)) {
19067 case NM_DPAU_H_QBR:
19069 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19071 case NM_DPAQX_SA_W_PH:
19073 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19075 case NM_DPSU_H_QBR:
19077 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19079 case NM_DPSQX_SA_W_PH:
19081 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19083 case NM_MULSAQ_S_W_PH:
19085 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19088 generate_exception_end(ctx, EXCP_RI);
19093 generate_exception_end(ctx, EXCP_RI);
19097 tcg_temp_free_i32(t0);
19100 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19101 int rt, int rs, int rd)
19104 TCGv t0 = tcg_temp_new();
19105 TCGv t1 = tcg_temp_new();
19106 TCGv v0_t = tcg_temp_new();
19107 TCGv v1_t = tcg_temp_new();
19109 gen_load_gpr(v0_t, rt);
19110 gen_load_gpr(v1_t, rs);
19113 case NM_POOL32AXF_2_0_7:
19114 switch (extract32(ctx->opcode, 9, 3)) {
19116 case NM_DPAQ_S_W_PH:
19118 case NM_DPSQ_S_W_PH:
19119 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19124 gen_load_gpr(t0, rs);
19126 if (rd != 0 && rd != 2) {
19127 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19128 tcg_gen_ext32u_tl(t0, t0);
19129 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19130 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19132 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19138 int acc = extract32(ctx->opcode, 14, 2);
19139 TCGv_i64 t2 = tcg_temp_new_i64();
19140 TCGv_i64 t3 = tcg_temp_new_i64();
19142 gen_load_gpr(t0, rt);
19143 gen_load_gpr(t1, rs);
19144 tcg_gen_ext_tl_i64(t2, t0);
19145 tcg_gen_ext_tl_i64(t3, t1);
19146 tcg_gen_mul_i64(t2, t2, t3);
19147 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19148 tcg_gen_add_i64(t2, t2, t3);
19149 tcg_temp_free_i64(t3);
19150 gen_move_low32(cpu_LO[acc], t2);
19151 gen_move_high32(cpu_HI[acc], t2);
19152 tcg_temp_free_i64(t2);
19158 int acc = extract32(ctx->opcode, 14, 2);
19159 TCGv_i32 t2 = tcg_temp_new_i32();
19160 TCGv_i32 t3 = tcg_temp_new_i32();
19162 gen_load_gpr(t0, rs);
19163 gen_load_gpr(t1, rt);
19164 tcg_gen_trunc_tl_i32(t2, t0);
19165 tcg_gen_trunc_tl_i32(t3, t1);
19166 tcg_gen_muls2_i32(t2, t3, t2, t3);
19167 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19168 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19169 tcg_temp_free_i32(t2);
19170 tcg_temp_free_i32(t3);
19175 gen_load_gpr(v1_t, rs);
19176 tcg_gen_movi_tl(t0, rd >> 3);
19177 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19178 gen_store_gpr(t0, ret);
19182 case NM_POOL32AXF_2_8_15:
19183 switch (extract32(ctx->opcode, 9, 3)) {
19185 case NM_DPAQ_SA_L_W:
19187 case NM_DPSQ_SA_L_W:
19188 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19193 int acc = extract32(ctx->opcode, 14, 2);
19194 TCGv_i64 t2 = tcg_temp_new_i64();
19195 TCGv_i64 t3 = tcg_temp_new_i64();
19197 gen_load_gpr(t0, rs);
19198 gen_load_gpr(t1, rt);
19199 tcg_gen_ext32u_tl(t0, t0);
19200 tcg_gen_ext32u_tl(t1, t1);
19201 tcg_gen_extu_tl_i64(t2, t0);
19202 tcg_gen_extu_tl_i64(t3, t1);
19203 tcg_gen_mul_i64(t2, t2, t3);
19204 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19205 tcg_gen_add_i64(t2, t2, t3);
19206 tcg_temp_free_i64(t3);
19207 gen_move_low32(cpu_LO[acc], t2);
19208 gen_move_high32(cpu_HI[acc], t2);
19209 tcg_temp_free_i64(t2);
19215 int acc = extract32(ctx->opcode, 14, 2);
19216 TCGv_i32 t2 = tcg_temp_new_i32();
19217 TCGv_i32 t3 = tcg_temp_new_i32();
19219 gen_load_gpr(t0, rs);
19220 gen_load_gpr(t1, rt);
19221 tcg_gen_trunc_tl_i32(t2, t0);
19222 tcg_gen_trunc_tl_i32(t3, t1);
19223 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19224 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19225 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19226 tcg_temp_free_i32(t2);
19227 tcg_temp_free_i32(t3);
19232 tcg_gen_movi_tl(t0, rd >> 3);
19233 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19234 gen_store_gpr(t0, ret);
19237 generate_exception_end(ctx, EXCP_RI);
19241 case NM_POOL32AXF_2_16_23:
19242 switch (extract32(ctx->opcode, 9, 3)) {
19243 case NM_DPAU_H_QBL:
19244 case NM_DPAQX_S_W_PH:
19245 case NM_DPSU_H_QBL:
19246 case NM_DPSQX_S_W_PH:
19247 case NM_MULSA_W_PH:
19248 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19252 tcg_gen_movi_tl(t0, rd >> 3);
19253 gen_helper_extp(t0, t0, v1_t, cpu_env);
19254 gen_store_gpr(t0, ret);
19259 int acc = extract32(ctx->opcode, 14, 2);
19260 TCGv_i64 t2 = tcg_temp_new_i64();
19261 TCGv_i64 t3 = tcg_temp_new_i64();
19263 gen_load_gpr(t0, rs);
19264 gen_load_gpr(t1, rt);
19265 tcg_gen_ext_tl_i64(t2, t0);
19266 tcg_gen_ext_tl_i64(t3, t1);
19267 tcg_gen_mul_i64(t2, t2, t3);
19268 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19269 tcg_gen_sub_i64(t2, t3, t2);
19270 tcg_temp_free_i64(t3);
19271 gen_move_low32(cpu_LO[acc], t2);
19272 gen_move_high32(cpu_HI[acc], t2);
19273 tcg_temp_free_i64(t2);
19276 case NM_EXTRV_RS_W:
19278 tcg_gen_movi_tl(t0, rd >> 3);
19279 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19280 gen_store_gpr(t0, ret);
19284 case NM_POOL32AXF_2_24_31:
19285 switch (extract32(ctx->opcode, 9, 3)) {
19286 case NM_DPAU_H_QBR:
19287 case NM_DPAQX_SA_W_PH:
19288 case NM_DPSU_H_QBR:
19289 case NM_DPSQX_SA_W_PH:
19290 case NM_MULSAQ_S_W_PH:
19291 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19295 tcg_gen_movi_tl(t0, rd >> 3);
19296 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19297 gen_store_gpr(t0, ret);
19302 int acc = extract32(ctx->opcode, 14, 2);
19303 TCGv_i64 t2 = tcg_temp_new_i64();
19304 TCGv_i64 t3 = tcg_temp_new_i64();
19306 gen_load_gpr(t0, rs);
19307 gen_load_gpr(t1, rt);
19308 tcg_gen_ext32u_tl(t0, t0);
19309 tcg_gen_ext32u_tl(t1, t1);
19310 tcg_gen_extu_tl_i64(t2, t0);
19311 tcg_gen_extu_tl_i64(t3, t1);
19312 tcg_gen_mul_i64(t2, t2, t3);
19313 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19314 tcg_gen_sub_i64(t2, t3, t2);
19315 tcg_temp_free_i64(t3);
19316 gen_move_low32(cpu_LO[acc], t2);
19317 gen_move_high32(cpu_HI[acc], t2);
19318 tcg_temp_free_i64(t2);
19323 tcg_gen_movi_tl(t0, rd >> 3);
19324 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19325 gen_store_gpr(t0, ret);
19330 generate_exception_end(ctx, EXCP_RI);
19337 tcg_temp_free(v0_t);
19338 tcg_temp_free(v1_t);
19341 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19345 TCGv t0 = tcg_temp_new();
19346 TCGv v0_t = tcg_temp_new();
19348 gen_load_gpr(v0_t, rs);
19353 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19354 gen_store_gpr(v0_t, ret);
19358 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19359 gen_store_gpr(v0_t, ret);
19363 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19364 gen_store_gpr(v0_t, ret);
19366 case NM_PRECEQ_W_PHL:
19368 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19369 tcg_gen_ext32s_tl(v0_t, v0_t);
19370 gen_store_gpr(v0_t, ret);
19372 case NM_PRECEQ_W_PHR:
19374 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19375 tcg_gen_shli_tl(v0_t, v0_t, 16);
19376 tcg_gen_ext32s_tl(v0_t, v0_t);
19377 gen_store_gpr(v0_t, ret);
19379 case NM_PRECEQU_PH_QBL:
19381 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19382 gen_store_gpr(v0_t, ret);
19384 case NM_PRECEQU_PH_QBR:
19386 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19387 gen_store_gpr(v0_t, ret);
19389 case NM_PRECEQU_PH_QBLA:
19391 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19392 gen_store_gpr(v0_t, ret);
19394 case NM_PRECEQU_PH_QBRA:
19396 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19397 gen_store_gpr(v0_t, ret);
19399 case NM_PRECEU_PH_QBL:
19401 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19402 gen_store_gpr(v0_t, ret);
19404 case NM_PRECEU_PH_QBR:
19406 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19407 gen_store_gpr(v0_t, ret);
19409 case NM_PRECEU_PH_QBLA:
19411 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19412 gen_store_gpr(v0_t, ret);
19414 case NM_PRECEU_PH_QBRA:
19416 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19417 gen_store_gpr(v0_t, ret);
19421 tcg_gen_ext16u_tl(v0_t, v0_t);
19422 tcg_gen_shli_tl(t0, v0_t, 16);
19423 tcg_gen_or_tl(v0_t, v0_t, t0);
19424 tcg_gen_ext32s_tl(v0_t, v0_t);
19425 gen_store_gpr(v0_t, ret);
19429 tcg_gen_ext8u_tl(v0_t, v0_t);
19430 tcg_gen_shli_tl(t0, v0_t, 8);
19431 tcg_gen_or_tl(v0_t, v0_t, t0);
19432 tcg_gen_shli_tl(t0, v0_t, 16);
19433 tcg_gen_or_tl(v0_t, v0_t, t0);
19434 tcg_gen_ext32s_tl(v0_t, v0_t);
19435 gen_store_gpr(v0_t, ret);
19439 gen_helper_bitrev(v0_t, v0_t);
19440 gen_store_gpr(v0_t, ret);
19445 TCGv tv0 = tcg_temp_new();
19447 gen_load_gpr(tv0, rt);
19448 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19449 gen_store_gpr(v0_t, ret);
19450 tcg_temp_free(tv0);
19453 case NM_RADDU_W_QB:
19455 gen_helper_raddu_w_qb(v0_t, v0_t);
19456 gen_store_gpr(v0_t, ret);
19459 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19463 gen_cl(ctx, OPC_CLO, ret, rs);
19467 gen_cl(ctx, OPC_CLZ, ret, rs);
19470 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19473 generate_exception_end(ctx, EXCP_RI);
19477 tcg_temp_free(v0_t);
19481 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19482 int rt, int rs, int rd)
19484 TCGv t0 = tcg_temp_new();
19485 TCGv rs_t = tcg_temp_new();
19487 gen_load_gpr(rs_t, rs);
19492 tcg_gen_movi_tl(t0, rd >> 2);
19493 switch (extract32(ctx->opcode, 12, 1)) {
19496 gen_helper_shra_qb(t0, t0, rs_t);
19497 gen_store_gpr(t0, rt);
19501 gen_helper_shra_r_qb(t0, t0, rs_t);
19502 gen_store_gpr(t0, rt);
19508 tcg_gen_movi_tl(t0, rd >> 1);
19509 gen_helper_shrl_ph(t0, t0, rs_t);
19510 gen_store_gpr(t0, rt);
19516 target_long result;
19517 imm = extract32(ctx->opcode, 13, 8);
19518 result = (uint32_t)imm << 24 |
19519 (uint32_t)imm << 16 |
19520 (uint32_t)imm << 8 |
19522 result = (int32_t)result;
19523 tcg_gen_movi_tl(t0, result);
19524 gen_store_gpr(t0, rt);
19528 generate_exception_end(ctx, EXCP_RI);
19532 tcg_temp_free(rs_t);
19536 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19538 int rt = extract32(ctx->opcode, 21, 5);
19539 int rs = extract32(ctx->opcode, 16, 5);
19540 int rd = extract32(ctx->opcode, 11, 5);
19542 switch (extract32(ctx->opcode, 6, 3)) {
19543 case NM_POOL32AXF_1:
19545 int32_t op1 = extract32(ctx->opcode, 9, 3);
19546 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19549 case NM_POOL32AXF_2:
19551 int32_t op1 = extract32(ctx->opcode, 12, 2);
19552 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19555 case NM_POOL32AXF_4:
19557 int32_t op1 = extract32(ctx->opcode, 9, 7);
19558 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19561 case NM_POOL32AXF_5:
19562 switch (extract32(ctx->opcode, 9, 7)) {
19563 #ifndef CONFIG_USER_ONLY
19565 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19568 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19571 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19574 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19577 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19580 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19583 check_cp0_enabled(ctx);
19585 TCGv t0 = tcg_temp_new();
19587 save_cpu_state(ctx, 1);
19588 gen_helper_di(t0, cpu_env);
19589 gen_store_gpr(t0, rt);
19590 /* Stop translation as we may have switched the execution mode */
19591 ctx->base.is_jmp = DISAS_STOP;
19596 check_cp0_enabled(ctx);
19598 TCGv t0 = tcg_temp_new();
19600 save_cpu_state(ctx, 1);
19601 gen_helper_ei(t0, cpu_env);
19602 gen_store_gpr(t0, rt);
19603 /* Stop translation as we may have switched the execution mode */
19604 ctx->base.is_jmp = DISAS_STOP;
19609 gen_load_srsgpr(rs, rt);
19612 gen_store_srsgpr(rs, rt);
19615 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19618 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19621 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19625 generate_exception_end(ctx, EXCP_RI);
19629 case NM_POOL32AXF_7:
19631 int32_t op1 = extract32(ctx->opcode, 9, 3);
19632 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19636 generate_exception_end(ctx, EXCP_RI);
19641 /* Immediate Value Compact Branches */
19642 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19643 int rt, int32_t imm, int32_t offset)
19646 int bcond_compute = 0;
19647 TCGv t0 = tcg_temp_new();
19648 TCGv t1 = tcg_temp_new();
19650 gen_load_gpr(t0, rt);
19651 tcg_gen_movi_tl(t1, imm);
19652 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19654 /* Load needed operands and calculate btarget */
19657 if (rt == 0 && imm == 0) {
19658 /* Unconditional branch */
19659 } else if (rt == 0 && imm != 0) {
19664 cond = TCG_COND_EQ;
19670 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19671 generate_exception_end(ctx, EXCP_RI);
19673 } else if (rt == 0 && opc == NM_BBEQZC) {
19674 /* Unconditional branch */
19675 } else if (rt == 0 && opc == NM_BBNEZC) {
19679 tcg_gen_shri_tl(t0, t0, imm);
19680 tcg_gen_andi_tl(t0, t0, 1);
19681 tcg_gen_movi_tl(t1, 0);
19683 if (opc == NM_BBEQZC) {
19684 cond = TCG_COND_EQ;
19686 cond = TCG_COND_NE;
19691 if (rt == 0 && imm == 0) {
19694 } else if (rt == 0 && imm != 0) {
19695 /* Unconditional branch */
19698 cond = TCG_COND_NE;
19702 if (rt == 0 && imm == 0) {
19703 /* Unconditional branch */
19706 cond = TCG_COND_GE;
19711 cond = TCG_COND_LT;
19714 if (rt == 0 && imm == 0) {
19715 /* Unconditional branch */
19718 cond = TCG_COND_GEU;
19723 cond = TCG_COND_LTU;
19726 MIPS_INVAL("Immediate Value Compact branch");
19727 generate_exception_end(ctx, EXCP_RI);
19731 /* branch completion */
19732 clear_branch_hflags(ctx);
19733 ctx->base.is_jmp = DISAS_NORETURN;
19735 if (bcond_compute == 0) {
19736 /* Uncoditional compact branch */
19737 gen_goto_tb(ctx, 0, ctx->btarget);
19739 /* Conditional compact branch */
19740 TCGLabel *fs = gen_new_label();
19742 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19744 gen_goto_tb(ctx, 1, ctx->btarget);
19747 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19755 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19756 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19759 TCGv t0 = tcg_temp_new();
19760 TCGv t1 = tcg_temp_new();
19763 gen_load_gpr(t0, rs);
19767 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19770 /* calculate btarget */
19771 tcg_gen_shli_tl(t0, t0, 1);
19772 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19773 gen_op_addr_add(ctx, btarget, t1, t0);
19775 /* branch completion */
19776 clear_branch_hflags(ctx);
19777 ctx->base.is_jmp = DISAS_NORETURN;
19779 /* unconditional branch to register */
19780 tcg_gen_mov_tl(cpu_PC, btarget);
19781 tcg_gen_lookup_and_goto_ptr();
19787 /* nanoMIPS Branches */
19788 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19789 int rs, int rt, int32_t offset)
19791 int bcond_compute = 0;
19792 TCGv t0 = tcg_temp_new();
19793 TCGv t1 = tcg_temp_new();
19795 /* Load needed operands and calculate btarget */
19797 /* compact branch */
19800 gen_load_gpr(t0, rs);
19801 gen_load_gpr(t1, rt);
19803 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19807 if (rs == 0 || rs == rt) {
19808 /* OPC_BLEZALC, OPC_BGEZALC */
19809 /* OPC_BGTZALC, OPC_BLTZALC */
19810 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19812 gen_load_gpr(t0, rs);
19813 gen_load_gpr(t1, rt);
19815 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19818 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19822 /* OPC_BEQZC, OPC_BNEZC */
19823 gen_load_gpr(t0, rs);
19825 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19827 /* OPC_JIC, OPC_JIALC */
19828 TCGv tbase = tcg_temp_new();
19829 TCGv toffset = tcg_temp_new();
19831 gen_load_gpr(tbase, rt);
19832 tcg_gen_movi_tl(toffset, offset);
19833 gen_op_addr_add(ctx, btarget, tbase, toffset);
19834 tcg_temp_free(tbase);
19835 tcg_temp_free(toffset);
19839 MIPS_INVAL("Compact branch/jump");
19840 generate_exception_end(ctx, EXCP_RI);
19844 if (bcond_compute == 0) {
19845 /* Uncoditional compact branch */
19848 gen_goto_tb(ctx, 0, ctx->btarget);
19851 MIPS_INVAL("Compact branch/jump");
19852 generate_exception_end(ctx, EXCP_RI);
19856 /* Conditional compact branch */
19857 TCGLabel *fs = gen_new_label();
19861 if (rs == 0 && rt != 0) {
19863 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19864 } else if (rs != 0 && rt != 0 && rs == rt) {
19866 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19869 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19873 if (rs == 0 && rt != 0) {
19875 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19876 } else if (rs != 0 && rt != 0 && rs == rt) {
19878 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19881 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19885 if (rs == 0 && rt != 0) {
19887 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19888 } else if (rs != 0 && rt != 0 && rs == rt) {
19890 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19893 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19897 if (rs == 0 && rt != 0) {
19899 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19900 } else if (rs != 0 && rt != 0 && rs == rt) {
19902 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19905 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19909 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19912 MIPS_INVAL("Compact conditional branch/jump");
19913 generate_exception_end(ctx, EXCP_RI);
19917 /* branch completion */
19918 clear_branch_hflags(ctx);
19919 ctx->base.is_jmp = DISAS_NORETURN;
19921 /* Generating branch here as compact branches don't have delay slot */
19922 gen_goto_tb(ctx, 1, ctx->btarget);
19925 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19934 /* nanoMIPS CP1 Branches */
19935 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19936 int32_t ft, int32_t offset)
19938 target_ulong btarget;
19939 TCGv_i64 t0 = tcg_temp_new_i64();
19941 gen_load_fpr64(ctx, t0, ft);
19942 tcg_gen_andi_i64(t0, t0, 1);
19944 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19948 tcg_gen_xori_i64(t0, t0, 1);
19949 ctx->hflags |= MIPS_HFLAG_BC;
19952 /* t0 already set */
19953 ctx->hflags |= MIPS_HFLAG_BC;
19956 MIPS_INVAL("cp1 cond branch");
19957 generate_exception_end(ctx, EXCP_RI);
19961 tcg_gen_trunc_i64_tl(bcond, t0);
19963 ctx->btarget = btarget;
19966 tcg_temp_free_i64(t0);
19970 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19973 t0 = tcg_temp_new();
19974 t1 = tcg_temp_new();
19976 gen_load_gpr(t0, rs);
19977 gen_load_gpr(t1, rt);
19979 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19980 /* PP.LSXS instructions require shifting */
19981 switch (extract32(ctx->opcode, 7, 4)) {
19986 tcg_gen_shli_tl(t0, t0, 1);
19993 tcg_gen_shli_tl(t0, t0, 2);
19997 tcg_gen_shli_tl(t0, t0, 3);
20001 gen_op_addr_add(ctx, t0, t0, t1);
20003 switch (extract32(ctx->opcode, 7, 4)) {
20005 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20007 gen_store_gpr(t0, rd);
20011 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20013 gen_store_gpr(t0, rd);
20017 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20019 gen_store_gpr(t0, rd);
20022 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20024 gen_store_gpr(t0, rd);
20028 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20030 gen_store_gpr(t0, rd);
20034 gen_load_gpr(t1, rd);
20035 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20041 gen_load_gpr(t1, rd);
20042 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20048 gen_load_gpr(t1, rd);
20049 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20053 /*case NM_LWC1XS:*/
20055 /*case NM_LDC1XS:*/
20057 /*case NM_SWC1XS:*/
20059 /*case NM_SDC1XS:*/
20060 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20061 check_cp1_enabled(ctx);
20062 switch (extract32(ctx->opcode, 7, 4)) {
20064 /*case NM_LWC1XS:*/
20065 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20068 /*case NM_LDC1XS:*/
20069 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20072 /*case NM_SWC1XS:*/
20073 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20076 /*case NM_SDC1XS:*/
20077 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20081 generate_exception_err(ctx, EXCP_CpU, 1);
20085 generate_exception_end(ctx, EXCP_RI);
20093 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20097 rt = extract32(ctx->opcode, 21, 5);
20098 rs = extract32(ctx->opcode, 16, 5);
20099 rd = extract32(ctx->opcode, 11, 5);
20101 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20102 generate_exception_end(ctx, EXCP_RI);
20105 check_cp1_enabled(ctx);
20106 switch (extract32(ctx->opcode, 0, 3)) {
20108 switch (extract32(ctx->opcode, 3, 7)) {
20110 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20113 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20116 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20119 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20122 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20125 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20128 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20131 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20134 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20137 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20140 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20143 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20146 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20149 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20152 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20155 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20158 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20161 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20164 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20167 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20170 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20173 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20176 generate_exception_end(ctx, EXCP_RI);
20181 switch (extract32(ctx->opcode, 3, 3)) {
20183 switch (extract32(ctx->opcode, 9, 1)) {
20185 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20188 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20193 switch (extract32(ctx->opcode, 9, 1)) {
20195 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20198 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20203 switch (extract32(ctx->opcode, 9, 1)) {
20205 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20208 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20213 switch (extract32(ctx->opcode, 9, 1)) {
20215 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20218 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20223 switch (extract32(ctx->opcode, 6, 8)) {
20225 gen_cp1(ctx, OPC_CFC1, rt, rs);
20228 gen_cp1(ctx, OPC_CTC1, rt, rs);
20231 gen_cp1(ctx, OPC_MFC1, rt, rs);
20234 gen_cp1(ctx, OPC_MTC1, rt, rs);
20237 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20240 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20243 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20246 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20249 switch (extract32(ctx->opcode, 6, 9)) {
20251 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20254 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20257 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20260 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20263 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20266 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20269 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20272 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20275 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20278 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20281 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20284 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20287 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20290 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20293 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20296 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20299 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20302 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20305 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20308 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20311 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20314 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20317 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20320 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20323 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20326 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20329 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20332 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20335 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20338 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20341 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20344 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20347 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20350 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20353 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20356 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20359 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20362 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20365 generate_exception_end(ctx, EXCP_RI);
20374 switch (extract32(ctx->opcode, 3, 3)) {
20375 case NM_CMP_CONDN_S:
20376 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20378 case NM_CMP_CONDN_D:
20379 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20382 generate_exception_end(ctx, EXCP_RI);
20387 generate_exception_end(ctx, EXCP_RI);
20392 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20393 int rd, int rs, int rt)
20396 TCGv t0 = tcg_temp_new();
20397 TCGv v1_t = tcg_temp_new();
20398 TCGv v2_t = tcg_temp_new();
20400 gen_load_gpr(v1_t, rs);
20401 gen_load_gpr(v2_t, rt);
20406 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20410 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20414 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20416 case NM_CMPU_EQ_QB:
20418 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20420 case NM_CMPU_LT_QB:
20422 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20424 case NM_CMPU_LE_QB:
20426 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20428 case NM_CMPGU_EQ_QB:
20430 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20431 gen_store_gpr(v1_t, ret);
20433 case NM_CMPGU_LT_QB:
20435 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20436 gen_store_gpr(v1_t, ret);
20438 case NM_CMPGU_LE_QB:
20440 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20441 gen_store_gpr(v1_t, ret);
20443 case NM_CMPGDU_EQ_QB:
20445 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20446 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20447 gen_store_gpr(v1_t, ret);
20449 case NM_CMPGDU_LT_QB:
20451 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20452 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20453 gen_store_gpr(v1_t, ret);
20455 case NM_CMPGDU_LE_QB:
20457 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20458 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20459 gen_store_gpr(v1_t, ret);
20463 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20464 gen_store_gpr(v1_t, ret);
20468 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20469 gen_store_gpr(v1_t, ret);
20473 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20474 gen_store_gpr(v1_t, ret);
20478 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20479 gen_store_gpr(v1_t, ret);
20483 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20484 gen_store_gpr(v1_t, ret);
20488 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20489 gen_store_gpr(v1_t, ret);
20493 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20494 gen_store_gpr(v1_t, ret);
20498 switch (extract32(ctx->opcode, 10, 1)) {
20501 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20502 gen_store_gpr(v1_t, ret);
20506 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20507 gen_store_gpr(v1_t, ret);
20511 case NM_ADDQH_R_PH:
20513 switch (extract32(ctx->opcode, 10, 1)) {
20516 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20517 gen_store_gpr(v1_t, ret);
20521 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20522 gen_store_gpr(v1_t, ret);
20528 switch (extract32(ctx->opcode, 10, 1)) {
20531 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20532 gen_store_gpr(v1_t, ret);
20536 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20537 gen_store_gpr(v1_t, ret);
20543 switch (extract32(ctx->opcode, 10, 1)) {
20546 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20547 gen_store_gpr(v1_t, ret);
20551 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20552 gen_store_gpr(v1_t, ret);
20558 switch (extract32(ctx->opcode, 10, 1)) {
20561 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20562 gen_store_gpr(v1_t, ret);
20566 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20567 gen_store_gpr(v1_t, ret);
20571 case NM_ADDUH_R_QB:
20573 switch (extract32(ctx->opcode, 10, 1)) {
20576 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20577 gen_store_gpr(v1_t, ret);
20581 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20582 gen_store_gpr(v1_t, ret);
20586 case NM_SHRAV_R_PH:
20588 switch (extract32(ctx->opcode, 10, 1)) {
20591 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20592 gen_store_gpr(v1_t, ret);
20596 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20597 gen_store_gpr(v1_t, ret);
20601 case NM_SHRAV_R_QB:
20603 switch (extract32(ctx->opcode, 10, 1)) {
20606 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20607 gen_store_gpr(v1_t, ret);
20611 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20612 gen_store_gpr(v1_t, ret);
20618 switch (extract32(ctx->opcode, 10, 1)) {
20621 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20622 gen_store_gpr(v1_t, ret);
20626 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20627 gen_store_gpr(v1_t, ret);
20631 case NM_SUBQH_R_PH:
20633 switch (extract32(ctx->opcode, 10, 1)) {
20636 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20637 gen_store_gpr(v1_t, ret);
20641 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20642 gen_store_gpr(v1_t, ret);
20648 switch (extract32(ctx->opcode, 10, 1)) {
20651 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20652 gen_store_gpr(v1_t, ret);
20656 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20657 gen_store_gpr(v1_t, ret);
20663 switch (extract32(ctx->opcode, 10, 1)) {
20666 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20667 gen_store_gpr(v1_t, ret);
20671 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20672 gen_store_gpr(v1_t, ret);
20678 switch (extract32(ctx->opcode, 10, 1)) {
20681 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20682 gen_store_gpr(v1_t, ret);
20686 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20687 gen_store_gpr(v1_t, ret);
20691 case NM_SUBUH_R_QB:
20693 switch (extract32(ctx->opcode, 10, 1)) {
20696 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20697 gen_store_gpr(v1_t, ret);
20701 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20702 gen_store_gpr(v1_t, ret);
20706 case NM_SHLLV_S_PH:
20708 switch (extract32(ctx->opcode, 10, 1)) {
20711 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20712 gen_store_gpr(v1_t, ret);
20716 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20717 gen_store_gpr(v1_t, ret);
20721 case NM_PRECR_SRA_R_PH_W:
20723 switch (extract32(ctx->opcode, 10, 1)) {
20725 /* PRECR_SRA_PH_W */
20727 TCGv_i32 sa_t = tcg_const_i32(rd);
20728 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20730 gen_store_gpr(v1_t, rt);
20731 tcg_temp_free_i32(sa_t);
20735 /* PRECR_SRA_R_PH_W */
20737 TCGv_i32 sa_t = tcg_const_i32(rd);
20738 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20740 gen_store_gpr(v1_t, rt);
20741 tcg_temp_free_i32(sa_t);
20746 case NM_MULEU_S_PH_QBL:
20748 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20749 gen_store_gpr(v1_t, ret);
20751 case NM_MULEU_S_PH_QBR:
20753 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20754 gen_store_gpr(v1_t, ret);
20756 case NM_MULQ_RS_PH:
20758 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20759 gen_store_gpr(v1_t, ret);
20763 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20764 gen_store_gpr(v1_t, ret);
20768 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20769 gen_store_gpr(v1_t, ret);
20773 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20774 gen_store_gpr(v1_t, ret);
20778 gen_load_gpr(t0, rs);
20780 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20782 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20786 gen_helper_modsub(v1_t, v1_t, v2_t);
20787 gen_store_gpr(v1_t, ret);
20791 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20792 gen_store_gpr(v1_t, ret);
20796 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20797 gen_store_gpr(v1_t, ret);
20801 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20802 gen_store_gpr(v1_t, ret);
20806 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20807 gen_store_gpr(v1_t, ret);
20811 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20812 gen_store_gpr(v1_t, ret);
20817 TCGv tv0 = tcg_temp_new();
20818 TCGv tv1 = tcg_temp_new();
20819 int16_t imm = extract32(ctx->opcode, 16, 7);
20821 tcg_gen_movi_tl(tv0, rd >> 3);
20822 tcg_gen_movi_tl(tv1, imm);
20823 gen_helper_shilo(tv0, tv1, cpu_env);
20826 case NM_MULEQ_S_W_PHL:
20828 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20829 gen_store_gpr(v1_t, ret);
20831 case NM_MULEQ_S_W_PHR:
20833 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20834 gen_store_gpr(v1_t, ret);
20838 switch (extract32(ctx->opcode, 10, 1)) {
20841 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20842 gen_store_gpr(v1_t, ret);
20846 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20847 gen_store_gpr(v1_t, ret);
20851 case NM_PRECR_QB_PH:
20853 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20854 gen_store_gpr(v1_t, ret);
20856 case NM_PRECRQ_QB_PH:
20858 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20859 gen_store_gpr(v1_t, ret);
20861 case NM_PRECRQ_PH_W:
20863 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20864 gen_store_gpr(v1_t, ret);
20866 case NM_PRECRQ_RS_PH_W:
20868 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20869 gen_store_gpr(v1_t, ret);
20871 case NM_PRECRQU_S_QB_PH:
20873 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20874 gen_store_gpr(v1_t, ret);
20878 tcg_gen_movi_tl(t0, rd);
20879 gen_helper_shra_r_w(v1_t, t0, v1_t);
20880 gen_store_gpr(v1_t, rt);
20884 tcg_gen_movi_tl(t0, rd >> 1);
20885 switch (extract32(ctx->opcode, 10, 1)) {
20888 gen_helper_shra_ph(v1_t, t0, v1_t);
20889 gen_store_gpr(v1_t, rt);
20893 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20894 gen_store_gpr(v1_t, rt);
20900 tcg_gen_movi_tl(t0, rd >> 1);
20901 switch (extract32(ctx->opcode, 10, 2)) {
20904 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20905 gen_store_gpr(v1_t, rt);
20909 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20910 gen_store_gpr(v1_t, rt);
20913 generate_exception_end(ctx, EXCP_RI);
20919 tcg_gen_movi_tl(t0, rd);
20920 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20921 gen_store_gpr(v1_t, rt);
20927 imm = sextract32(ctx->opcode, 11, 11);
20928 imm = (int16_t)(imm << 6) >> 6;
20930 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20935 generate_exception_end(ctx, EXCP_RI);
20940 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20948 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20949 ctx->opcode = (ctx->opcode << 16) | insn;
20951 rt = extract32(ctx->opcode, 21, 5);
20952 rs = extract32(ctx->opcode, 16, 5);
20953 rd = extract32(ctx->opcode, 11, 5);
20955 op = extract32(ctx->opcode, 26, 6);
20960 switch (extract32(ctx->opcode, 19, 2)) {
20963 generate_exception_end(ctx, EXCP_RI);
20966 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20967 generate_exception_end(ctx, EXCP_SYSCALL);
20969 generate_exception_end(ctx, EXCP_RI);
20973 generate_exception_end(ctx, EXCP_BREAK);
20976 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20977 gen_helper_do_semihosting(cpu_env);
20979 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20980 generate_exception_end(ctx, EXCP_RI);
20982 generate_exception_end(ctx, EXCP_DBp);
20989 imm = extract32(ctx->opcode, 0, 16);
20991 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20993 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20995 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21000 offset = sextract32(ctx->opcode, 0, 1) << 21 |
21001 extract32(ctx->opcode, 1, 20) << 1;
21002 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21003 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21007 switch (ctx->opcode & 0x07) {
21009 gen_pool32a0_nanomips_insn(env, ctx);
21013 int32_t op1 = extract32(ctx->opcode, 3, 7);
21014 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21018 switch (extract32(ctx->opcode, 3, 3)) {
21020 gen_p_lsx(ctx, rd, rs, rt);
21023 /* In nanoMIPS, the shift field directly encodes the shift
21024 * amount, meaning that the supported shift values are in
21025 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
21026 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21027 extract32(ctx->opcode, 9, 2) - 1);
21030 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21033 gen_pool32axf_nanomips_insn(env, ctx);
21036 generate_exception_end(ctx, EXCP_RI);
21041 generate_exception_end(ctx, EXCP_RI);
21046 switch (ctx->opcode & 0x03) {
21049 offset = extract32(ctx->opcode, 0, 21);
21050 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21054 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21057 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21060 generate_exception_end(ctx, EXCP_RI);
21066 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21067 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21068 switch (extract32(ctx->opcode, 16, 5)) {
21072 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21078 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21079 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21085 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21091 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21094 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21101 t0 = tcg_temp_new();
21103 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21106 tcg_gen_movi_tl(t0, addr);
21107 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21115 t0 = tcg_temp_new();
21116 t1 = tcg_temp_new();
21118 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21121 tcg_gen_movi_tl(t0, addr);
21122 gen_load_gpr(t1, rt);
21124 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21131 generate_exception_end(ctx, EXCP_RI);
21137 switch (extract32(ctx->opcode, 12, 4)) {
21139 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21142 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21145 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21148 switch (extract32(ctx->opcode, 20, 1)) {
21150 switch (ctx->opcode & 3) {
21152 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21153 extract32(ctx->opcode, 2, 1),
21154 extract32(ctx->opcode, 3, 9) << 3);
21157 case NM_RESTORE_JRC:
21158 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21159 extract32(ctx->opcode, 2, 1),
21160 extract32(ctx->opcode, 3, 9) << 3);
21161 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21162 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21166 generate_exception_end(ctx, EXCP_RI);
21171 generate_exception_end(ctx, EXCP_RI);
21176 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21179 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21183 TCGv t0 = tcg_temp_new();
21185 imm = extract32(ctx->opcode, 0, 12);
21186 gen_load_gpr(t0, rs);
21187 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21188 gen_store_gpr(t0, rt);
21194 imm = (int16_t) extract32(ctx->opcode, 0, 12);
21195 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21199 int shift = extract32(ctx->opcode, 0, 5);
21200 switch (extract32(ctx->opcode, 5, 4)) {
21202 if (rt == 0 && shift == 0) {
21204 } else if (rt == 0 && shift == 3) {
21205 /* EHB - treat as NOP */
21206 } else if (rt == 0 && shift == 5) {
21207 /* PAUSE - treat as NOP */
21208 } else if (rt == 0 && shift == 6) {
21210 gen_sync(extract32(ctx->opcode, 16, 5));
21213 gen_shift_imm(ctx, OPC_SLL, rt, rs,
21214 extract32(ctx->opcode, 0, 5));
21218 gen_shift_imm(ctx, OPC_SRL, rt, rs,
21219 extract32(ctx->opcode, 0, 5));
21222 gen_shift_imm(ctx, OPC_SRA, rt, rs,
21223 extract32(ctx->opcode, 0, 5));
21226 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21227 extract32(ctx->opcode, 0, 5));
21235 TCGv t0 = tcg_temp_new();
21236 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21237 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21239 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21241 gen_load_gpr(t0, rs);
21242 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21245 tcg_temp_free_i32(shift);
21246 tcg_temp_free_i32(shiftx);
21247 tcg_temp_free_i32(stripe);
21251 switch (((ctx->opcode >> 10) & 2) |
21252 (extract32(ctx->opcode, 5, 1))) {
21255 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21256 extract32(ctx->opcode, 6, 5));
21259 generate_exception_end(ctx, EXCP_RI);
21264 switch (((ctx->opcode >> 10) & 2) |
21265 (extract32(ctx->opcode, 5, 1))) {
21268 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21269 extract32(ctx->opcode, 6, 5));
21272 generate_exception_end(ctx, EXCP_RI);
21277 generate_exception_end(ctx, EXCP_RI);
21282 gen_pool32f_nanomips_insn(ctx);
21287 switch (extract32(ctx->opcode, 1, 1)) {
21290 tcg_gen_movi_tl(cpu_gpr[rt],
21291 sextract32(ctx->opcode, 0, 1) << 31 |
21292 extract32(ctx->opcode, 2, 10) << 21 |
21293 extract32(ctx->opcode, 12, 9) << 12);
21298 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21299 extract32(ctx->opcode, 2, 10) << 21 |
21300 extract32(ctx->opcode, 12, 9) << 12;
21302 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21303 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21310 uint32_t u = extract32(ctx->opcode, 0, 18);
21312 switch (extract32(ctx->opcode, 18, 3)) {
21314 gen_ld(ctx, OPC_LB, rt, 28, u);
21317 gen_st(ctx, OPC_SB, rt, 28, u);
21320 gen_ld(ctx, OPC_LBU, rt, 28, u);
21324 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21329 switch (ctx->opcode & 1) {
21331 gen_ld(ctx, OPC_LH, rt, 28, u);
21334 gen_ld(ctx, OPC_LHU, rt, 28, u);
21340 switch (ctx->opcode & 1) {
21342 gen_st(ctx, OPC_SH, rt, 28, u);
21345 generate_exception_end(ctx, EXCP_RI);
21351 switch (ctx->opcode & 0x3) {
21353 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21356 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21359 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21362 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21367 generate_exception_end(ctx, EXCP_RI);
21374 uint32_t u = extract32(ctx->opcode, 0, 12);
21376 switch (extract32(ctx->opcode, 12, 4)) {
21380 /* Break the TB to be able to sync copied instructions
21382 ctx->base.is_jmp = DISAS_STOP;
21385 /* Treat as NOP. */
21389 gen_ld(ctx, OPC_LB, rt, rs, u);
21392 gen_ld(ctx, OPC_LH, rt, rs, u);
21395 gen_ld(ctx, OPC_LW, rt, rs, u);
21398 gen_ld(ctx, OPC_LBU, rt, rs, u);
21401 gen_ld(ctx, OPC_LHU, rt, rs, u);
21404 gen_st(ctx, OPC_SB, rt, rs, u);
21407 gen_st(ctx, OPC_SH, rt, rs, u);
21410 gen_st(ctx, OPC_SW, rt, rs, u);
21413 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21416 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21419 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21422 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21425 generate_exception_end(ctx, EXCP_RI);
21432 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21433 extract32(ctx->opcode, 0, 8);
21435 switch (extract32(ctx->opcode, 8, 3)) {
21437 switch (extract32(ctx->opcode, 11, 4)) {
21439 gen_ld(ctx, OPC_LB, rt, rs, s);
21442 gen_ld(ctx, OPC_LH, rt, rs, s);
21445 gen_ld(ctx, OPC_LW, rt, rs, s);
21448 gen_ld(ctx, OPC_LBU, rt, rs, s);
21451 gen_ld(ctx, OPC_LHU, rt, rs, s);
21454 gen_st(ctx, OPC_SB, rt, rs, s);
21457 gen_st(ctx, OPC_SH, rt, rs, s);
21460 gen_st(ctx, OPC_SW, rt, rs, s);
21463 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21466 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21469 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21472 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21477 /* Break the TB to be able to sync copied instructions
21479 ctx->base.is_jmp = DISAS_STOP;
21482 /* Treat as NOP. */
21486 generate_exception_end(ctx, EXCP_RI);
21491 switch (extract32(ctx->opcode, 11, 4)) {
21496 TCGv t0 = tcg_temp_new();
21497 TCGv t1 = tcg_temp_new();
21499 gen_base_offset_addr(ctx, t0, rs, s);
21501 switch (extract32(ctx->opcode, 11, 4)) {
21503 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21505 gen_store_gpr(t0, rt);
21508 gen_load_gpr(t1, rt);
21509 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21518 switch (ctx->opcode & 0x03) {
21520 gen_ld(ctx, OPC_LL, rt, rs, s);
21524 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21529 switch (ctx->opcode & 0x03) {
21531 gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
21535 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21541 check_cp0_enabled(ctx);
21542 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21543 gen_cache_operation(ctx, rt, rs, s);
21549 switch (extract32(ctx->opcode, 11, 4)) {
21552 check_cp0_enabled(ctx);
21553 gen_ld(ctx, OPC_LBE, rt, rs, s);
21557 check_cp0_enabled(ctx);
21558 gen_st(ctx, OPC_SBE, rt, rs, s);
21562 check_cp0_enabled(ctx);
21563 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21567 /* case NM_SYNCIE */
21569 check_cp0_enabled(ctx);
21570 /* Break the TB to be able to sync copied instructions
21572 ctx->base.is_jmp = DISAS_STOP;
21574 /* case NM_PREFE */
21576 check_cp0_enabled(ctx);
21577 /* Treat as NOP. */
21582 check_cp0_enabled(ctx);
21583 gen_ld(ctx, OPC_LHE, rt, rs, s);
21587 check_cp0_enabled(ctx);
21588 gen_st(ctx, OPC_SHE, rt, rs, s);
21592 check_cp0_enabled(ctx);
21593 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21596 check_nms_dl_il_sl_tl_l2c(ctx);
21597 gen_cache_operation(ctx, rt, rs, s);
21601 check_cp0_enabled(ctx);
21602 gen_ld(ctx, OPC_LWE, rt, rs, s);
21606 check_cp0_enabled(ctx);
21607 gen_st(ctx, OPC_SWE, rt, rs, s);
21610 switch (extract32(ctx->opcode, 2, 2)) {
21614 check_cp0_enabled(ctx);
21615 gen_ld(ctx, OPC_LLE, rt, rs, s);
21620 check_cp0_enabled(ctx);
21621 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21624 generate_exception_end(ctx, EXCP_RI);
21629 switch (extract32(ctx->opcode, 2, 2)) {
21633 check_cp0_enabled(ctx);
21634 gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
21639 check_cp0_enabled(ctx);
21640 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21644 generate_exception_end(ctx, EXCP_RI);
21654 int count = extract32(ctx->opcode, 12, 3);
21657 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21658 extract32(ctx->opcode, 0, 8);
21659 TCGv va = tcg_temp_new();
21660 TCGv t1 = tcg_temp_new();
21661 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21662 NM_P_LS_UAWM ? MO_UNALN : 0;
21664 count = (count == 0) ? 8 : count;
21665 while (counter != count) {
21666 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21667 int this_offset = offset + (counter << 2);
21669 gen_base_offset_addr(ctx, va, rs, this_offset);
21671 switch (extract32(ctx->opcode, 11, 1)) {
21673 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21675 gen_store_gpr(t1, this_rt);
21676 if ((this_rt == rs) &&
21677 (counter != (count - 1))) {
21678 /* UNPREDICTABLE */
21682 this_rt = (rt == 0) ? 0 : this_rt;
21683 gen_load_gpr(t1, this_rt);
21684 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21695 generate_exception_end(ctx, EXCP_RI);
21703 TCGv t0 = tcg_temp_new();
21704 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21705 extract32(ctx->opcode, 1, 20) << 1;
21706 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21707 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21708 extract32(ctx->opcode, 21, 3));
21709 gen_load_gpr(t0, rt);
21710 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21711 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21717 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21718 extract32(ctx->opcode, 1, 24) << 1;
21720 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21722 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21725 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21730 switch (extract32(ctx->opcode, 12, 4)) {
21733 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21736 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21739 generate_exception_end(ctx, EXCP_RI);
21745 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21746 extract32(ctx->opcode, 1, 13) << 1;
21747 switch (extract32(ctx->opcode, 14, 2)) {
21750 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21753 s = sextract32(ctx->opcode, 0, 1) << 14 |
21754 extract32(ctx->opcode, 1, 13) << 1;
21755 check_cp1_enabled(ctx);
21756 switch (extract32(ctx->opcode, 16, 5)) {
21758 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21761 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21766 int32_t imm = extract32(ctx->opcode, 1, 13) |
21767 extract32(ctx->opcode, 0, 1) << 13;
21769 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21774 generate_exception_end(ctx, EXCP_RI);
21780 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21782 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21786 if (rs == rt || rt == 0) {
21787 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21788 } else if (rs == 0) {
21789 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21791 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21799 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21800 extract32(ctx->opcode, 1, 13) << 1;
21801 switch (extract32(ctx->opcode, 14, 2)) {
21804 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21807 if (rs != 0 && rt != 0 && rs == rt) {
21809 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21811 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21815 if (rs == 0 || rs == rt) {
21817 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21819 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21823 generate_exception_end(ctx, EXCP_RI);
21830 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21831 extract32(ctx->opcode, 1, 10) << 1;
21832 uint32_t u = extract32(ctx->opcode, 11, 7);
21834 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21839 generate_exception_end(ctx, EXCP_RI);
21845 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21848 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
21849 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
21850 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
21854 /* make sure instructions are on a halfword boundary */
21855 if (ctx->base.pc_next & 0x1) {
21856 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21857 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21858 tcg_temp_free(tmp);
21859 generate_exception_end(ctx, EXCP_AdEL);
21863 op = extract32(ctx->opcode, 10, 6);
21866 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21869 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21870 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21873 switch (extract32(ctx->opcode, 3, 2)) {
21874 case NM_P16_SYSCALL:
21875 if (extract32(ctx->opcode, 2, 1) == 0) {
21876 generate_exception_end(ctx, EXCP_SYSCALL);
21878 generate_exception_end(ctx, EXCP_RI);
21882 generate_exception_end(ctx, EXCP_BREAK);
21885 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21886 gen_helper_do_semihosting(cpu_env);
21888 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21889 generate_exception_end(ctx, EXCP_RI);
21891 generate_exception_end(ctx, EXCP_DBp);
21896 generate_exception_end(ctx, EXCP_RI);
21903 int shift = extract32(ctx->opcode, 0, 3);
21905 shift = (shift == 0) ? 8 : shift;
21907 switch (extract32(ctx->opcode, 3, 1)) {
21915 gen_shift_imm(ctx, opc, rt, rs, shift);
21919 switch (ctx->opcode & 1) {
21921 gen_pool16c_nanomips_insn(ctx);
21924 gen_ldxs(ctx, rt, rs, rd);
21929 switch (extract32(ctx->opcode, 6, 1)) {
21931 imm = extract32(ctx->opcode, 0, 6) << 2;
21932 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21935 generate_exception_end(ctx, EXCP_RI);
21940 switch (extract32(ctx->opcode, 3, 1)) {
21942 imm = extract32(ctx->opcode, 0, 3) << 2;
21943 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21945 case NM_P_ADDIURS5:
21946 rt = extract32(ctx->opcode, 5, 5);
21948 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21949 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21950 (extract32(ctx->opcode, 0, 3));
21951 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21957 switch (ctx->opcode & 0x1) {
21959 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21962 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21967 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21968 extract32(ctx->opcode, 5, 3);
21969 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21970 extract32(ctx->opcode, 0, 3);
21971 rt = decode_gpr_gpr4(rt);
21972 rs = decode_gpr_gpr4(rs);
21973 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21974 (extract32(ctx->opcode, 3, 1))) {
21977 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21981 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21984 generate_exception_end(ctx, EXCP_RI);
21990 int imm = extract32(ctx->opcode, 0, 7);
21991 imm = (imm == 0x7f ? -1 : imm);
21993 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21999 uint32_t u = extract32(ctx->opcode, 0, 4);
22000 u = (u == 12) ? 0xff :
22001 (u == 13) ? 0xffff : u;
22002 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22006 offset = extract32(ctx->opcode, 0, 2);
22007 switch (extract32(ctx->opcode, 2, 2)) {
22009 gen_ld(ctx, OPC_LB, rt, rs, offset);
22012 rt = decode_gpr_gpr3_src_store(
22013 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22014 gen_st(ctx, OPC_SB, rt, rs, offset);
22017 gen_ld(ctx, OPC_LBU, rt, rs, offset);
22020 generate_exception_end(ctx, EXCP_RI);
22025 offset = extract32(ctx->opcode, 1, 2) << 1;
22026 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22028 gen_ld(ctx, OPC_LH, rt, rs, offset);
22031 rt = decode_gpr_gpr3_src_store(
22032 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22033 gen_st(ctx, OPC_SH, rt, rs, offset);
22036 gen_ld(ctx, OPC_LHU, rt, rs, offset);
22039 generate_exception_end(ctx, EXCP_RI);
22044 offset = extract32(ctx->opcode, 0, 4) << 2;
22045 gen_ld(ctx, OPC_LW, rt, rs, offset);
22048 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22049 offset = extract32(ctx->opcode, 0, 5) << 2;
22050 gen_ld(ctx, OPC_LW, rt, 29, offset);
22054 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22055 extract32(ctx->opcode, 5, 3);
22056 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22057 extract32(ctx->opcode, 0, 3);
22058 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22059 (extract32(ctx->opcode, 8, 1) << 2);
22060 rt = decode_gpr_gpr4(rt);
22061 rs = decode_gpr_gpr4(rs);
22062 gen_ld(ctx, OPC_LW, rt, rs, offset);
22066 rt = (extract32(ctx->opcode, 9, 1) << 3) |
22067 extract32(ctx->opcode, 5, 3);
22068 rs = (extract32(ctx->opcode, 4, 1) << 3) |
22069 extract32(ctx->opcode, 0, 3);
22070 offset = (extract32(ctx->opcode, 3, 1) << 3) |
22071 (extract32(ctx->opcode, 8, 1) << 2);
22072 rt = decode_gpr_gpr4_zero(rt);
22073 rs = decode_gpr_gpr4(rs);
22074 gen_st(ctx, OPC_SW, rt, rs, offset);
22077 offset = extract32(ctx->opcode, 0, 7) << 2;
22078 gen_ld(ctx, OPC_LW, rt, 28, offset);
22081 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22082 offset = extract32(ctx->opcode, 0, 5) << 2;
22083 gen_st(ctx, OPC_SW, rt, 29, offset);
22086 rt = decode_gpr_gpr3_src_store(
22087 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22088 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22089 offset = extract32(ctx->opcode, 0, 4) << 2;
22090 gen_st(ctx, OPC_SW, rt, rs, offset);
22093 rt = decode_gpr_gpr3_src_store(
22094 NANOMIPS_EXTRACT_RT3(ctx->opcode));
22095 offset = extract32(ctx->opcode, 0, 7) << 2;
22096 gen_st(ctx, OPC_SW, rt, 28, offset);
22099 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22100 (sextract32(ctx->opcode, 0, 1) << 10) |
22101 (extract32(ctx->opcode, 1, 9) << 1));
22104 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22105 (sextract32(ctx->opcode, 0, 1) << 10) |
22106 (extract32(ctx->opcode, 1, 9) << 1));
22109 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22110 (sextract32(ctx->opcode, 0, 1) << 7) |
22111 (extract32(ctx->opcode, 1, 6) << 1));
22114 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22115 (sextract32(ctx->opcode, 0, 1) << 7) |
22116 (extract32(ctx->opcode, 1, 6) << 1));
22119 switch (ctx->opcode & 0xf) {
22122 switch (extract32(ctx->opcode, 4, 1)) {
22124 gen_compute_branch_nm(ctx, OPC_JR, 2,
22125 extract32(ctx->opcode, 5, 5), 0, 0);
22128 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22129 extract32(ctx->opcode, 5, 5), 31, 0);
22136 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22137 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22138 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22139 extract32(ctx->opcode, 0, 4) << 1);
22146 int count = extract32(ctx->opcode, 0, 4);
22147 int u = extract32(ctx->opcode, 4, 4) << 4;
22149 rt = 30 + extract32(ctx->opcode, 9, 1);
22150 switch (extract32(ctx->opcode, 8, 1)) {
22152 gen_save(ctx, rt, count, 0, u);
22154 case NM_RESTORE_JRC16:
22155 gen_restore(ctx, rt, count, 0, u);
22156 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22165 static const int gpr2reg1[] = {4, 5, 6, 7};
22166 static const int gpr2reg2[] = {5, 6, 7, 8};
22168 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22169 extract32(ctx->opcode, 8, 1);
22170 int r1 = gpr2reg1[rd2];
22171 int r2 = gpr2reg2[rd2];
22172 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22173 extract32(ctx->opcode, 0, 3);
22174 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22175 extract32(ctx->opcode, 5, 3);
22176 TCGv t0 = tcg_temp_new();
22177 TCGv t1 = tcg_temp_new();
22178 if (op == NM_MOVEP) {
22181 rs = decode_gpr_gpr4_zero(r3);
22182 rt = decode_gpr_gpr4_zero(r4);
22184 rd = decode_gpr_gpr4(r3);
22185 re = decode_gpr_gpr4(r4);
22189 gen_load_gpr(t0, rs);
22190 gen_load_gpr(t1, rt);
22191 tcg_gen_mov_tl(cpu_gpr[rd], t0);
22192 tcg_gen_mov_tl(cpu_gpr[re], t1);
22198 return decode_nanomips_32_48_opc(env, ctx);
22205 /* SmartMIPS extension to MIPS32 */
22207 #if defined(TARGET_MIPS64)
22209 /* MDMX extension to MIPS64 */
22213 /* MIPSDSP functions. */
22214 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22215 int rd, int base, int offset)
22220 t0 = tcg_temp_new();
22223 gen_load_gpr(t0, offset);
22224 } else if (offset == 0) {
22225 gen_load_gpr(t0, base);
22227 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22232 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22233 gen_store_gpr(t0, rd);
22236 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22237 gen_store_gpr(t0, rd);
22240 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22241 gen_store_gpr(t0, rd);
22243 #if defined(TARGET_MIPS64)
22245 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22246 gen_store_gpr(t0, rd);
22253 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22254 int ret, int v1, int v2)
22260 /* Treat as NOP. */
22264 v1_t = tcg_temp_new();
22265 v2_t = tcg_temp_new();
22267 gen_load_gpr(v1_t, v1);
22268 gen_load_gpr(v2_t, v2);
22271 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22272 case OPC_MULT_G_2E:
22276 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22278 case OPC_ADDUH_R_QB:
22279 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22282 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22284 case OPC_ADDQH_R_PH:
22285 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22288 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22290 case OPC_ADDQH_R_W:
22291 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22294 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22296 case OPC_SUBUH_R_QB:
22297 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22300 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22302 case OPC_SUBQH_R_PH:
22303 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22306 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22308 case OPC_SUBQH_R_W:
22309 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22313 case OPC_ABSQ_S_PH_DSP:
22315 case OPC_ABSQ_S_QB:
22317 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22319 case OPC_ABSQ_S_PH:
22321 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22325 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22327 case OPC_PRECEQ_W_PHL:
22329 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22330 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22332 case OPC_PRECEQ_W_PHR:
22334 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22335 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22336 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22338 case OPC_PRECEQU_PH_QBL:
22340 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22342 case OPC_PRECEQU_PH_QBR:
22344 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22346 case OPC_PRECEQU_PH_QBLA:
22348 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22350 case OPC_PRECEQU_PH_QBRA:
22352 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22354 case OPC_PRECEU_PH_QBL:
22356 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22358 case OPC_PRECEU_PH_QBR:
22360 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22362 case OPC_PRECEU_PH_QBLA:
22364 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22366 case OPC_PRECEU_PH_QBRA:
22368 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22372 case OPC_ADDU_QB_DSP:
22376 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22378 case OPC_ADDQ_S_PH:
22380 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22384 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22388 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22390 case OPC_ADDU_S_QB:
22392 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22396 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22398 case OPC_ADDU_S_PH:
22400 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22404 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22406 case OPC_SUBQ_S_PH:
22408 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22412 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22416 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22418 case OPC_SUBU_S_QB:
22420 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22424 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22426 case OPC_SUBU_S_PH:
22428 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22432 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22436 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22440 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22442 case OPC_RADDU_W_QB:
22444 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22448 case OPC_CMPU_EQ_QB_DSP:
22450 case OPC_PRECR_QB_PH:
22452 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22454 case OPC_PRECRQ_QB_PH:
22456 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22458 case OPC_PRECR_SRA_PH_W:
22461 TCGv_i32 sa_t = tcg_const_i32(v2);
22462 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22464 tcg_temp_free_i32(sa_t);
22467 case OPC_PRECR_SRA_R_PH_W:
22470 TCGv_i32 sa_t = tcg_const_i32(v2);
22471 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22473 tcg_temp_free_i32(sa_t);
22476 case OPC_PRECRQ_PH_W:
22478 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22480 case OPC_PRECRQ_RS_PH_W:
22482 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22484 case OPC_PRECRQU_S_QB_PH:
22486 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22490 #ifdef TARGET_MIPS64
22491 case OPC_ABSQ_S_QH_DSP:
22493 case OPC_PRECEQ_L_PWL:
22495 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22497 case OPC_PRECEQ_L_PWR:
22499 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22501 case OPC_PRECEQ_PW_QHL:
22503 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22505 case OPC_PRECEQ_PW_QHR:
22507 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22509 case OPC_PRECEQ_PW_QHLA:
22511 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22513 case OPC_PRECEQ_PW_QHRA:
22515 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22517 case OPC_PRECEQU_QH_OBL:
22519 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22521 case OPC_PRECEQU_QH_OBR:
22523 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22525 case OPC_PRECEQU_QH_OBLA:
22527 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22529 case OPC_PRECEQU_QH_OBRA:
22531 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22533 case OPC_PRECEU_QH_OBL:
22535 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22537 case OPC_PRECEU_QH_OBR:
22539 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22541 case OPC_PRECEU_QH_OBLA:
22543 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22545 case OPC_PRECEU_QH_OBRA:
22547 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22549 case OPC_ABSQ_S_OB:
22551 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22553 case OPC_ABSQ_S_PW:
22555 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22557 case OPC_ABSQ_S_QH:
22559 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22563 case OPC_ADDU_OB_DSP:
22565 case OPC_RADDU_L_OB:
22567 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22571 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22573 case OPC_SUBQ_S_PW:
22575 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22579 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22581 case OPC_SUBQ_S_QH:
22583 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22587 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22589 case OPC_SUBU_S_OB:
22591 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22595 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22597 case OPC_SUBU_S_QH:
22599 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22603 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22605 case OPC_SUBUH_R_OB:
22607 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22611 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22613 case OPC_ADDQ_S_PW:
22615 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22619 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22621 case OPC_ADDQ_S_QH:
22623 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22627 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22629 case OPC_ADDU_S_OB:
22631 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22635 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22637 case OPC_ADDU_S_QH:
22639 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22643 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22645 case OPC_ADDUH_R_OB:
22647 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22651 case OPC_CMPU_EQ_OB_DSP:
22653 case OPC_PRECR_OB_QH:
22655 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22657 case OPC_PRECR_SRA_QH_PW:
22660 TCGv_i32 ret_t = tcg_const_i32(ret);
22661 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22662 tcg_temp_free_i32(ret_t);
22665 case OPC_PRECR_SRA_R_QH_PW:
22668 TCGv_i32 sa_v = tcg_const_i32(ret);
22669 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22670 tcg_temp_free_i32(sa_v);
22673 case OPC_PRECRQ_OB_QH:
22675 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22677 case OPC_PRECRQ_PW_L:
22679 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22681 case OPC_PRECRQ_QH_PW:
22683 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22685 case OPC_PRECRQ_RS_QH_PW:
22687 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22689 case OPC_PRECRQU_S_OB_QH:
22691 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22698 tcg_temp_free(v1_t);
22699 tcg_temp_free(v2_t);
22702 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22703 int ret, int v1, int v2)
22711 /* Treat as NOP. */
22715 t0 = tcg_temp_new();
22716 v1_t = tcg_temp_new();
22717 v2_t = tcg_temp_new();
22719 tcg_gen_movi_tl(t0, v1);
22720 gen_load_gpr(v1_t, v1);
22721 gen_load_gpr(v2_t, v2);
22724 case OPC_SHLL_QB_DSP:
22726 op2 = MASK_SHLL_QB(ctx->opcode);
22730 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22734 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22738 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22742 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22744 case OPC_SHLL_S_PH:
22746 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22748 case OPC_SHLLV_S_PH:
22750 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22754 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22756 case OPC_SHLLV_S_W:
22758 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22762 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22766 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22770 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22774 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22778 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22780 case OPC_SHRA_R_QB:
22782 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22786 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22788 case OPC_SHRAV_R_QB:
22790 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22794 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22796 case OPC_SHRA_R_PH:
22798 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22802 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22804 case OPC_SHRAV_R_PH:
22806 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22810 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22812 case OPC_SHRAV_R_W:
22814 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22816 default: /* Invalid */
22817 MIPS_INVAL("MASK SHLL.QB");
22818 generate_exception_end(ctx, EXCP_RI);
22823 #ifdef TARGET_MIPS64
22824 case OPC_SHLL_OB_DSP:
22825 op2 = MASK_SHLL_OB(ctx->opcode);
22829 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22833 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22835 case OPC_SHLL_S_PW:
22837 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22839 case OPC_SHLLV_S_PW:
22841 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22845 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22849 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22853 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22857 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22859 case OPC_SHLL_S_QH:
22861 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22863 case OPC_SHLLV_S_QH:
22865 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22869 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22873 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22875 case OPC_SHRA_R_OB:
22877 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22879 case OPC_SHRAV_R_OB:
22881 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22885 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22889 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22891 case OPC_SHRA_R_PW:
22893 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22895 case OPC_SHRAV_R_PW:
22897 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22901 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22905 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22907 case OPC_SHRA_R_QH:
22909 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22911 case OPC_SHRAV_R_QH:
22913 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22917 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22921 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22925 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22929 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22931 default: /* Invalid */
22932 MIPS_INVAL("MASK SHLL.OB");
22933 generate_exception_end(ctx, EXCP_RI);
22941 tcg_temp_free(v1_t);
22942 tcg_temp_free(v2_t);
22945 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22946 int ret, int v1, int v2, int check_ret)
22952 if ((ret == 0) && (check_ret == 1)) {
22953 /* Treat as NOP. */
22957 t0 = tcg_temp_new_i32();
22958 v1_t = tcg_temp_new();
22959 v2_t = tcg_temp_new();
22961 tcg_gen_movi_i32(t0, ret);
22962 gen_load_gpr(v1_t, v1);
22963 gen_load_gpr(v2_t, v2);
22966 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22967 * the same mask and op1. */
22968 case OPC_MULT_G_2E:
22972 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22975 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22978 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22980 case OPC_MULQ_RS_W:
22981 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22985 case OPC_DPA_W_PH_DSP:
22987 case OPC_DPAU_H_QBL:
22989 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22991 case OPC_DPAU_H_QBR:
22993 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22995 case OPC_DPSU_H_QBL:
22997 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22999 case OPC_DPSU_H_QBR:
23001 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23005 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23007 case OPC_DPAX_W_PH:
23009 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23011 case OPC_DPAQ_S_W_PH:
23013 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23015 case OPC_DPAQX_S_W_PH:
23017 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23019 case OPC_DPAQX_SA_W_PH:
23021 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23025 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23027 case OPC_DPSX_W_PH:
23029 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23031 case OPC_DPSQ_S_W_PH:
23033 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23035 case OPC_DPSQX_S_W_PH:
23037 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23039 case OPC_DPSQX_SA_W_PH:
23041 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23043 case OPC_MULSAQ_S_W_PH:
23045 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23047 case OPC_DPAQ_SA_L_W:
23049 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23051 case OPC_DPSQ_SA_L_W:
23053 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23055 case OPC_MAQ_S_W_PHL:
23057 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23059 case OPC_MAQ_S_W_PHR:
23061 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23063 case OPC_MAQ_SA_W_PHL:
23065 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23067 case OPC_MAQ_SA_W_PHR:
23069 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23071 case OPC_MULSA_W_PH:
23073 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23077 #ifdef TARGET_MIPS64
23078 case OPC_DPAQ_W_QH_DSP:
23080 int ac = ret & 0x03;
23081 tcg_gen_movi_i32(t0, ac);
23086 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23090 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23094 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23098 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23102 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23104 case OPC_DPAQ_S_W_QH:
23106 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23108 case OPC_DPAQ_SA_L_PW:
23110 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23112 case OPC_DPAU_H_OBL:
23114 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23116 case OPC_DPAU_H_OBR:
23118 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23122 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23124 case OPC_DPSQ_S_W_QH:
23126 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23128 case OPC_DPSQ_SA_L_PW:
23130 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23132 case OPC_DPSU_H_OBL:
23134 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23136 case OPC_DPSU_H_OBR:
23138 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23140 case OPC_MAQ_S_L_PWL:
23142 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23144 case OPC_MAQ_S_L_PWR:
23146 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23148 case OPC_MAQ_S_W_QHLL:
23150 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23152 case OPC_MAQ_SA_W_QHLL:
23154 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23156 case OPC_MAQ_S_W_QHLR:
23158 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23160 case OPC_MAQ_SA_W_QHLR:
23162 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23164 case OPC_MAQ_S_W_QHRL:
23166 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23168 case OPC_MAQ_SA_W_QHRL:
23170 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23172 case OPC_MAQ_S_W_QHRR:
23174 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23176 case OPC_MAQ_SA_W_QHRR:
23178 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23180 case OPC_MULSAQ_S_L_PW:
23182 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23184 case OPC_MULSAQ_S_W_QH:
23186 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23192 case OPC_ADDU_QB_DSP:
23194 case OPC_MULEU_S_PH_QBL:
23196 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23198 case OPC_MULEU_S_PH_QBR:
23200 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23202 case OPC_MULQ_RS_PH:
23204 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23206 case OPC_MULEQ_S_W_PHL:
23208 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23210 case OPC_MULEQ_S_W_PHR:
23212 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23214 case OPC_MULQ_S_PH:
23216 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23220 #ifdef TARGET_MIPS64
23221 case OPC_ADDU_OB_DSP:
23223 case OPC_MULEQ_S_PW_QHL:
23225 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23227 case OPC_MULEQ_S_PW_QHR:
23229 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23231 case OPC_MULEU_S_QH_OBL:
23233 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23235 case OPC_MULEU_S_QH_OBR:
23237 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23239 case OPC_MULQ_RS_QH:
23241 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23248 tcg_temp_free_i32(t0);
23249 tcg_temp_free(v1_t);
23250 tcg_temp_free(v2_t);
23253 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23261 /* Treat as NOP. */
23265 t0 = tcg_temp_new();
23266 val_t = tcg_temp_new();
23267 gen_load_gpr(val_t, val);
23270 case OPC_ABSQ_S_PH_DSP:
23274 gen_helper_bitrev(cpu_gpr[ret], val_t);
23279 target_long result;
23280 imm = (ctx->opcode >> 16) & 0xFF;
23281 result = (uint32_t)imm << 24 |
23282 (uint32_t)imm << 16 |
23283 (uint32_t)imm << 8 |
23285 result = (int32_t)result;
23286 tcg_gen_movi_tl(cpu_gpr[ret], result);
23291 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23292 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23293 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23294 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23295 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23296 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23301 imm = (ctx->opcode >> 16) & 0x03FF;
23302 imm = (int16_t)(imm << 6) >> 6;
23303 tcg_gen_movi_tl(cpu_gpr[ret], \
23304 (target_long)((int32_t)imm << 16 | \
23310 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23311 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23312 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23313 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23317 #ifdef TARGET_MIPS64
23318 case OPC_ABSQ_S_QH_DSP:
23325 imm = (ctx->opcode >> 16) & 0xFF;
23326 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23327 temp = (temp << 16) | temp;
23328 temp = (temp << 32) | temp;
23329 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23337 imm = (ctx->opcode >> 16) & 0x03FF;
23338 imm = (int16_t)(imm << 6) >> 6;
23339 temp = ((target_long)imm << 32) \
23340 | ((target_long)imm & 0xFFFFFFFF);
23341 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23349 imm = (ctx->opcode >> 16) & 0x03FF;
23350 imm = (int16_t)(imm << 6) >> 6;
23352 temp = ((uint64_t)(uint16_t)imm << 48) |
23353 ((uint64_t)(uint16_t)imm << 32) |
23354 ((uint64_t)(uint16_t)imm << 16) |
23355 (uint64_t)(uint16_t)imm;
23356 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23361 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23362 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23363 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23364 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23365 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23366 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23367 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23371 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23372 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23373 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23377 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23378 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23379 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23380 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23381 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23388 tcg_temp_free(val_t);
23391 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23392 uint32_t op1, uint32_t op2,
23393 int ret, int v1, int v2, int check_ret)
23399 if ((ret == 0) && (check_ret == 1)) {
23400 /* Treat as NOP. */
23404 t1 = tcg_temp_new();
23405 v1_t = tcg_temp_new();
23406 v2_t = tcg_temp_new();
23408 gen_load_gpr(v1_t, v1);
23409 gen_load_gpr(v2_t, v2);
23412 case OPC_CMPU_EQ_QB_DSP:
23414 case OPC_CMPU_EQ_QB:
23416 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23418 case OPC_CMPU_LT_QB:
23420 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23422 case OPC_CMPU_LE_QB:
23424 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23426 case OPC_CMPGU_EQ_QB:
23428 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23430 case OPC_CMPGU_LT_QB:
23432 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23434 case OPC_CMPGU_LE_QB:
23436 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23438 case OPC_CMPGDU_EQ_QB:
23440 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23441 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23442 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23443 tcg_gen_shli_tl(t1, t1, 24);
23444 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23446 case OPC_CMPGDU_LT_QB:
23448 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23449 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23450 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23451 tcg_gen_shli_tl(t1, t1, 24);
23452 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23454 case OPC_CMPGDU_LE_QB:
23456 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23457 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23458 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23459 tcg_gen_shli_tl(t1, t1, 24);
23460 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23462 case OPC_CMP_EQ_PH:
23464 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23466 case OPC_CMP_LT_PH:
23468 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23470 case OPC_CMP_LE_PH:
23472 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23476 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23480 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23482 case OPC_PACKRL_PH:
23484 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23488 #ifdef TARGET_MIPS64
23489 case OPC_CMPU_EQ_OB_DSP:
23491 case OPC_CMP_EQ_PW:
23493 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23495 case OPC_CMP_LT_PW:
23497 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23499 case OPC_CMP_LE_PW:
23501 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23503 case OPC_CMP_EQ_QH:
23505 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23507 case OPC_CMP_LT_QH:
23509 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23511 case OPC_CMP_LE_QH:
23513 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23515 case OPC_CMPGDU_EQ_OB:
23517 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23519 case OPC_CMPGDU_LT_OB:
23521 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23523 case OPC_CMPGDU_LE_OB:
23525 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23527 case OPC_CMPGU_EQ_OB:
23529 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23531 case OPC_CMPGU_LT_OB:
23533 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23535 case OPC_CMPGU_LE_OB:
23537 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23539 case OPC_CMPU_EQ_OB:
23541 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23543 case OPC_CMPU_LT_OB:
23545 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23547 case OPC_CMPU_LE_OB:
23549 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23551 case OPC_PACKRL_PW:
23553 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23557 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23561 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23565 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23573 tcg_temp_free(v1_t);
23574 tcg_temp_free(v2_t);
23577 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23578 uint32_t op1, int rt, int rs, int sa)
23585 /* Treat as NOP. */
23589 t0 = tcg_temp_new();
23590 gen_load_gpr(t0, rs);
23593 case OPC_APPEND_DSP:
23594 switch (MASK_APPEND(ctx->opcode)) {
23597 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23599 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23603 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23604 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23605 tcg_gen_shli_tl(t0, t0, 32 - sa);
23606 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23608 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23612 if (sa != 0 && sa != 2) {
23613 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23614 tcg_gen_ext32u_tl(t0, t0);
23615 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23616 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23618 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23620 default: /* Invalid */
23621 MIPS_INVAL("MASK APPEND");
23622 generate_exception_end(ctx, EXCP_RI);
23626 #ifdef TARGET_MIPS64
23627 case OPC_DAPPEND_DSP:
23628 switch (MASK_DAPPEND(ctx->opcode)) {
23631 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23635 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23636 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23637 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23641 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23642 tcg_gen_shli_tl(t0, t0, 64 - sa);
23643 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23648 if (sa != 0 && sa != 2 && sa != 4) {
23649 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23650 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23651 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23654 default: /* Invalid */
23655 MIPS_INVAL("MASK DAPPEND");
23656 generate_exception_end(ctx, EXCP_RI);
23665 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23666 int ret, int v1, int v2, int check_ret)
23675 if ((ret == 0) && (check_ret == 1)) {
23676 /* Treat as NOP. */
23680 t0 = tcg_temp_new();
23681 t1 = tcg_temp_new();
23682 v1_t = tcg_temp_new();
23683 v2_t = tcg_temp_new();
23685 gen_load_gpr(v1_t, v1);
23686 gen_load_gpr(v2_t, v2);
23689 case OPC_EXTR_W_DSP:
23693 tcg_gen_movi_tl(t0, v2);
23694 tcg_gen_movi_tl(t1, v1);
23695 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23698 tcg_gen_movi_tl(t0, v2);
23699 tcg_gen_movi_tl(t1, v1);
23700 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23702 case OPC_EXTR_RS_W:
23703 tcg_gen_movi_tl(t0, v2);
23704 tcg_gen_movi_tl(t1, v1);
23705 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23708 tcg_gen_movi_tl(t0, v2);
23709 tcg_gen_movi_tl(t1, v1);
23710 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23712 case OPC_EXTRV_S_H:
23713 tcg_gen_movi_tl(t0, v2);
23714 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23717 tcg_gen_movi_tl(t0, v2);
23718 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23720 case OPC_EXTRV_R_W:
23721 tcg_gen_movi_tl(t0, v2);
23722 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23724 case OPC_EXTRV_RS_W:
23725 tcg_gen_movi_tl(t0, v2);
23726 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23729 tcg_gen_movi_tl(t0, v2);
23730 tcg_gen_movi_tl(t1, v1);
23731 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23734 tcg_gen_movi_tl(t0, v2);
23735 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23738 tcg_gen_movi_tl(t0, v2);
23739 tcg_gen_movi_tl(t1, v1);
23740 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23743 tcg_gen_movi_tl(t0, v2);
23744 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23747 imm = (ctx->opcode >> 20) & 0x3F;
23748 tcg_gen_movi_tl(t0, ret);
23749 tcg_gen_movi_tl(t1, imm);
23750 gen_helper_shilo(t0, t1, cpu_env);
23753 tcg_gen_movi_tl(t0, ret);
23754 gen_helper_shilo(t0, v1_t, cpu_env);
23757 tcg_gen_movi_tl(t0, ret);
23758 gen_helper_mthlip(t0, v1_t, cpu_env);
23761 imm = (ctx->opcode >> 11) & 0x3FF;
23762 tcg_gen_movi_tl(t0, imm);
23763 gen_helper_wrdsp(v1_t, t0, cpu_env);
23766 imm = (ctx->opcode >> 16) & 0x03FF;
23767 tcg_gen_movi_tl(t0, imm);
23768 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23772 #ifdef TARGET_MIPS64
23773 case OPC_DEXTR_W_DSP:
23777 tcg_gen_movi_tl(t0, ret);
23778 gen_helper_dmthlip(v1_t, t0, cpu_env);
23782 int shift = (ctx->opcode >> 19) & 0x7F;
23783 int ac = (ctx->opcode >> 11) & 0x03;
23784 tcg_gen_movi_tl(t0, shift);
23785 tcg_gen_movi_tl(t1, ac);
23786 gen_helper_dshilo(t0, t1, cpu_env);
23791 int ac = (ctx->opcode >> 11) & 0x03;
23792 tcg_gen_movi_tl(t0, ac);
23793 gen_helper_dshilo(v1_t, t0, cpu_env);
23797 tcg_gen_movi_tl(t0, v2);
23798 tcg_gen_movi_tl(t1, v1);
23800 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23803 tcg_gen_movi_tl(t0, v2);
23804 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23807 tcg_gen_movi_tl(t0, v2);
23808 tcg_gen_movi_tl(t1, v1);
23809 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23812 tcg_gen_movi_tl(t0, v2);
23813 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23816 tcg_gen_movi_tl(t0, v2);
23817 tcg_gen_movi_tl(t1, v1);
23818 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23820 case OPC_DEXTR_R_L:
23821 tcg_gen_movi_tl(t0, v2);
23822 tcg_gen_movi_tl(t1, v1);
23823 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23825 case OPC_DEXTR_RS_L:
23826 tcg_gen_movi_tl(t0, v2);
23827 tcg_gen_movi_tl(t1, v1);
23828 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23831 tcg_gen_movi_tl(t0, v2);
23832 tcg_gen_movi_tl(t1, v1);
23833 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23835 case OPC_DEXTR_R_W:
23836 tcg_gen_movi_tl(t0, v2);
23837 tcg_gen_movi_tl(t1, v1);
23838 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23840 case OPC_DEXTR_RS_W:
23841 tcg_gen_movi_tl(t0, v2);
23842 tcg_gen_movi_tl(t1, v1);
23843 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23845 case OPC_DEXTR_S_H:
23846 tcg_gen_movi_tl(t0, v2);
23847 tcg_gen_movi_tl(t1, v1);
23848 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23850 case OPC_DEXTRV_S_H:
23851 tcg_gen_movi_tl(t0, v2);
23852 tcg_gen_movi_tl(t1, v1);
23853 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23856 tcg_gen_movi_tl(t0, v2);
23857 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23859 case OPC_DEXTRV_R_L:
23860 tcg_gen_movi_tl(t0, v2);
23861 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23863 case OPC_DEXTRV_RS_L:
23864 tcg_gen_movi_tl(t0, v2);
23865 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23868 tcg_gen_movi_tl(t0, v2);
23869 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23871 case OPC_DEXTRV_R_W:
23872 tcg_gen_movi_tl(t0, v2);
23873 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23875 case OPC_DEXTRV_RS_W:
23876 tcg_gen_movi_tl(t0, v2);
23877 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23886 tcg_temp_free(v1_t);
23887 tcg_temp_free(v2_t);
23890 /* End MIPSDSP functions. */
23892 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23894 int rs, rt, rd, sa;
23897 rs = (ctx->opcode >> 21) & 0x1f;
23898 rt = (ctx->opcode >> 16) & 0x1f;
23899 rd = (ctx->opcode >> 11) & 0x1f;
23900 sa = (ctx->opcode >> 6) & 0x1f;
23902 op1 = MASK_SPECIAL(ctx->opcode);
23905 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23911 op2 = MASK_R6_MULDIV(ctx->opcode);
23921 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23924 MIPS_INVAL("special_r6 muldiv");
23925 generate_exception_end(ctx, EXCP_RI);
23931 gen_cond_move(ctx, op1, rd, rs, rt);
23935 if (rt == 0 && sa == 1) {
23936 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23937 We need additionally to check other fields */
23938 gen_cl(ctx, op1, rd, rs);
23940 generate_exception_end(ctx, EXCP_RI);
23944 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23945 gen_helper_do_semihosting(cpu_env);
23947 if (ctx->hflags & MIPS_HFLAG_SBRI) {
23948 generate_exception_end(ctx, EXCP_RI);
23950 generate_exception_end(ctx, EXCP_DBp);
23954 #if defined(TARGET_MIPS64)
23956 check_mips_64(ctx);
23957 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23961 if (rt == 0 && sa == 1) {
23962 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23963 We need additionally to check other fields */
23964 check_mips_64(ctx);
23965 gen_cl(ctx, op1, rd, rs);
23967 generate_exception_end(ctx, EXCP_RI);
23975 op2 = MASK_R6_MULDIV(ctx->opcode);
23985 check_mips_64(ctx);
23986 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23989 MIPS_INVAL("special_r6 muldiv");
23990 generate_exception_end(ctx, EXCP_RI);
23995 default: /* Invalid */
23996 MIPS_INVAL("special_r6");
23997 generate_exception_end(ctx, EXCP_RI);
24002 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24004 int rs = extract32(ctx->opcode, 21, 5);
24005 int rt = extract32(ctx->opcode, 16, 5);
24006 int rd = extract32(ctx->opcode, 11, 5);
24007 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24010 case OPC_MOVN: /* Conditional move */
24012 gen_cond_move(ctx, op1, rd, rs, rt);
24014 case OPC_MFHI: /* Move from HI/LO */
24016 gen_HILO(ctx, op1, 0, rd);
24019 case OPC_MTLO: /* Move to HI/LO */
24020 gen_HILO(ctx, op1, 0, rs);
24024 gen_mul_txx9(ctx, op1, rd, rs, rt);
24028 gen_muldiv(ctx, op1, 0, rs, rt);
24030 #if defined(TARGET_MIPS64)
24035 check_insn_opc_user_only(ctx, INSN_R5900);
24036 gen_muldiv(ctx, op1, 0, rs, rt);
24040 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24042 default: /* Invalid */
24043 MIPS_INVAL("special_tx79");
24044 generate_exception_end(ctx, EXCP_RI);
24049 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24051 int rs, rt, rd, sa;
24054 rs = (ctx->opcode >> 21) & 0x1f;
24055 rt = (ctx->opcode >> 16) & 0x1f;
24056 rd = (ctx->opcode >> 11) & 0x1f;
24057 sa = (ctx->opcode >> 6) & 0x1f;
24059 op1 = MASK_SPECIAL(ctx->opcode);
24061 case OPC_MOVN: /* Conditional move */
24063 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24064 INSN_LOONGSON2E | INSN_LOONGSON2F);
24065 gen_cond_move(ctx, op1, rd, rs, rt);
24067 case OPC_MFHI: /* Move from HI/LO */
24069 gen_HILO(ctx, op1, rs & 3, rd);
24072 case OPC_MTLO: /* Move to HI/LO */
24073 gen_HILO(ctx, op1, rd & 3, rs);
24076 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24077 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24078 check_cp1_enabled(ctx);
24079 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24080 (ctx->opcode >> 16) & 1);
24082 generate_exception_err(ctx, EXCP_CpU, 1);
24088 check_insn(ctx, INSN_VR54XX);
24089 op1 = MASK_MUL_VR54XX(ctx->opcode);
24090 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24092 gen_muldiv(ctx, op1, rd & 3, rs, rt);
24097 gen_muldiv(ctx, op1, 0, rs, rt);
24099 #if defined(TARGET_MIPS64)
24104 check_insn(ctx, ISA_MIPS3);
24105 check_mips_64(ctx);
24106 gen_muldiv(ctx, op1, 0, rs, rt);
24110 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24113 #ifdef MIPS_STRICT_STANDARD
24114 MIPS_INVAL("SPIM");
24115 generate_exception_end(ctx, EXCP_RI);
24117 /* Implemented as RI exception for now. */
24118 MIPS_INVAL("spim (unofficial)");
24119 generate_exception_end(ctx, EXCP_RI);
24122 default: /* Invalid */
24123 MIPS_INVAL("special_legacy");
24124 generate_exception_end(ctx, EXCP_RI);
24129 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24131 int rs, rt, rd, sa;
24134 rs = (ctx->opcode >> 21) & 0x1f;
24135 rt = (ctx->opcode >> 16) & 0x1f;
24136 rd = (ctx->opcode >> 11) & 0x1f;
24137 sa = (ctx->opcode >> 6) & 0x1f;
24139 op1 = MASK_SPECIAL(ctx->opcode);
24141 case OPC_SLL: /* Shift with immediate */
24142 if (sa == 5 && rd == 0 &&
24143 rs == 0 && rt == 0) { /* PAUSE */
24144 if ((ctx->insn_flags & ISA_MIPS32R6) &&
24145 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24146 generate_exception_end(ctx, EXCP_RI);
24152 gen_shift_imm(ctx, op1, rd, rt, sa);
24155 switch ((ctx->opcode >> 21) & 0x1f) {
24157 /* rotr is decoded as srl on non-R2 CPUs */
24158 if (ctx->insn_flags & ISA_MIPS32R2) {
24163 gen_shift_imm(ctx, op1, rd, rt, sa);
24166 generate_exception_end(ctx, EXCP_RI);
24174 gen_arith(ctx, op1, rd, rs, rt);
24176 case OPC_SLLV: /* Shifts */
24178 gen_shift(ctx, op1, rd, rs, rt);
24181 switch ((ctx->opcode >> 6) & 0x1f) {
24183 /* rotrv is decoded as srlv on non-R2 CPUs */
24184 if (ctx->insn_flags & ISA_MIPS32R2) {
24189 gen_shift(ctx, op1, rd, rs, rt);
24192 generate_exception_end(ctx, EXCP_RI);
24196 case OPC_SLT: /* Set on less than */
24198 gen_slt(ctx, op1, rd, rs, rt);
24200 case OPC_AND: /* Logic*/
24204 gen_logic(ctx, op1, rd, rs, rt);
24207 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24209 case OPC_TGE: /* Traps */
24215 check_insn(ctx, ISA_MIPS2);
24216 gen_trap(ctx, op1, rs, rt, -1);
24218 case OPC_LSA: /* OPC_PMON */
24219 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24220 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24221 decode_opc_special_r6(env, ctx);
24223 /* Pmon entry point, also R4010 selsl */
24224 #ifdef MIPS_STRICT_STANDARD
24225 MIPS_INVAL("PMON / selsl");
24226 generate_exception_end(ctx, EXCP_RI);
24228 gen_helper_0e0i(pmon, sa);
24233 generate_exception_end(ctx, EXCP_SYSCALL);
24236 generate_exception_end(ctx, EXCP_BREAK);
24239 check_insn(ctx, ISA_MIPS2);
24240 gen_sync(extract32(ctx->opcode, 6, 5));
24243 #if defined(TARGET_MIPS64)
24244 /* MIPS64 specific opcodes */
24249 check_insn(ctx, ISA_MIPS3);
24250 check_mips_64(ctx);
24251 gen_shift_imm(ctx, op1, rd, rt, sa);
24254 switch ((ctx->opcode >> 21) & 0x1f) {
24256 /* drotr is decoded as dsrl on non-R2 CPUs */
24257 if (ctx->insn_flags & ISA_MIPS32R2) {
24262 check_insn(ctx, ISA_MIPS3);
24263 check_mips_64(ctx);
24264 gen_shift_imm(ctx, op1, rd, rt, sa);
24267 generate_exception_end(ctx, EXCP_RI);
24272 switch ((ctx->opcode >> 21) & 0x1f) {
24274 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24275 if (ctx->insn_flags & ISA_MIPS32R2) {
24280 check_insn(ctx, ISA_MIPS3);
24281 check_mips_64(ctx);
24282 gen_shift_imm(ctx, op1, rd, rt, sa);
24285 generate_exception_end(ctx, EXCP_RI);
24293 check_insn(ctx, ISA_MIPS3);
24294 check_mips_64(ctx);
24295 gen_arith(ctx, op1, rd, rs, rt);
24299 check_insn(ctx, ISA_MIPS3);
24300 check_mips_64(ctx);
24301 gen_shift(ctx, op1, rd, rs, rt);
24304 switch ((ctx->opcode >> 6) & 0x1f) {
24306 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24307 if (ctx->insn_flags & ISA_MIPS32R2) {
24312 check_insn(ctx, ISA_MIPS3);
24313 check_mips_64(ctx);
24314 gen_shift(ctx, op1, rd, rs, rt);
24317 generate_exception_end(ctx, EXCP_RI);
24322 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24323 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24324 decode_opc_special_r6(env, ctx);
24329 if (ctx->insn_flags & ISA_MIPS32R6) {
24330 decode_opc_special_r6(env, ctx);
24331 } else if (ctx->insn_flags & INSN_R5900) {
24332 decode_opc_special_tx79(env, ctx);
24334 decode_opc_special_legacy(env, ctx);
24340 #if defined(TARGET_MIPS64)
24344 * MMI (MultiMedia Interface) ASE instructions
24345 * ===========================================
24349 * MMI instructions category: data communication
24350 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24352 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24353 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24354 * PCPYUD PEXEH PEXTLW PPACW
24363 * Parallel Copy Halfword
24365 * 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
24366 * +-----------+---------+---------+---------+---------+-----------+
24367 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
24368 * +-----------+---------+---------+---------+---------+-----------+
24370 static void gen_mmi_pcpyh(DisasContext *ctx)
24372 uint32_t pd, rt, rd;
24375 opcode = ctx->opcode;
24377 pd = extract32(opcode, 21, 5);
24378 rt = extract32(opcode, 16, 5);
24379 rd = extract32(opcode, 11, 5);
24381 if (unlikely(pd != 0)) {
24382 generate_exception_end(ctx, EXCP_RI);
24383 } else if (rd == 0) {
24385 } else if (rt == 0) {
24386 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24387 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24389 TCGv_i64 t0 = tcg_temp_new();
24390 TCGv_i64 t1 = tcg_temp_new();
24391 uint64_t mask = (1ULL << 16) - 1;
24393 tcg_gen_andi_i64(t0, cpu_gpr[rt], mask);
24394 tcg_gen_movi_i64(t1, 0);
24395 tcg_gen_or_i64(t1, t0, t1);
24396 tcg_gen_shli_i64(t0, t0, 16);
24397 tcg_gen_or_i64(t1, t0, t1);
24398 tcg_gen_shli_i64(t0, t0, 16);
24399 tcg_gen_or_i64(t1, t0, t1);
24400 tcg_gen_shli_i64(t0, t0, 16);
24401 tcg_gen_or_i64(t1, t0, t1);
24403 tcg_gen_mov_i64(cpu_gpr[rd], t1);
24405 tcg_gen_andi_i64(t0, cpu_mmr[rt], mask);
24406 tcg_gen_movi_i64(t1, 0);
24407 tcg_gen_or_i64(t1, t0, t1);
24408 tcg_gen_shli_i64(t0, t0, 16);
24409 tcg_gen_or_i64(t1, t0, t1);
24410 tcg_gen_shli_i64(t0, t0, 16);
24411 tcg_gen_or_i64(t1, t0, t1);
24412 tcg_gen_shli_i64(t0, t0, 16);
24413 tcg_gen_or_i64(t1, t0, t1);
24415 tcg_gen_mov_i64(cpu_mmr[rd], t1);
24423 * PCPYLD rd, rs, rt
24425 * Parallel Copy Lower Doubleword
24427 * 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
24428 * +-----------+---------+---------+---------+---------+-----------+
24429 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
24430 * +-----------+---------+---------+---------+---------+-----------+
24432 static void gen_mmi_pcpyld(DisasContext *ctx)
24434 uint32_t rs, rt, rd;
24437 opcode = ctx->opcode;
24439 rs = extract32(opcode, 21, 5);
24440 rt = extract32(opcode, 16, 5);
24441 rd = extract32(opcode, 11, 5);
24447 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24449 tcg_gen_mov_i64(cpu_mmr[rd], cpu_gpr[rs]);
24452 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24455 tcg_gen_mov_i64(cpu_gpr[rd], cpu_gpr[rt]);
24462 * PCPYUD rd, rs, rt
24464 * Parallel Copy Upper Doubleword
24466 * 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
24467 * +-----------+---------+---------+---------+---------+-----------+
24468 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
24469 * +-----------+---------+---------+---------+---------+-----------+
24471 static void gen_mmi_pcpyud(DisasContext *ctx)
24473 uint32_t rs, rt, rd;
24476 opcode = ctx->opcode;
24478 rs = extract32(opcode, 21, 5);
24479 rt = extract32(opcode, 16, 5);
24480 rd = extract32(opcode, 11, 5);
24486 tcg_gen_movi_i64(cpu_gpr[rd], 0);
24488 tcg_gen_mov_i64(cpu_gpr[rd], cpu_mmr[rs]);
24491 tcg_gen_movi_i64(cpu_mmr[rd], 0);
24494 tcg_gen_mov_i64(cpu_mmr[rd], cpu_mmr[rt]);
24503 #if !defined(TARGET_MIPS64)
24505 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24506 #define MXU_APTN1_A 0
24507 #define MXU_APTN1_S 1
24509 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24510 #define MXU_APTN2_AA 0
24511 #define MXU_APTN2_AS 1
24512 #define MXU_APTN2_SA 2
24513 #define MXU_APTN2_SS 3
24515 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24516 #define MXU_EPTN2_AA 0
24517 #define MXU_EPTN2_AS 1
24518 #define MXU_EPTN2_SA 2
24519 #define MXU_EPTN2_SS 3
24521 /* MXU operand getting pattern 'optn2' */
24522 #define MXU_OPTN2_PTN0 0
24523 #define MXU_OPTN2_PTN1 1
24524 #define MXU_OPTN2_PTN2 2
24525 #define MXU_OPTN2_PTN3 3
24526 /* alternative naming scheme for 'optn2' */
24527 #define MXU_OPTN2_WW 0
24528 #define MXU_OPTN2_LW 1
24529 #define MXU_OPTN2_HW 2
24530 #define MXU_OPTN2_XW 3
24532 /* MXU operand getting pattern 'optn3' */
24533 #define MXU_OPTN3_PTN0 0
24534 #define MXU_OPTN3_PTN1 1
24535 #define MXU_OPTN3_PTN2 2
24536 #define MXU_OPTN3_PTN3 3
24537 #define MXU_OPTN3_PTN4 4
24538 #define MXU_OPTN3_PTN5 5
24539 #define MXU_OPTN3_PTN6 6
24540 #define MXU_OPTN3_PTN7 7
24544 * S32I2M XRa, rb - Register move from GRF to XRF
24546 static void gen_mxu_s32i2m(DisasContext *ctx)
24551 t0 = tcg_temp_new();
24553 XRa = extract32(ctx->opcode, 6, 5);
24554 Rb = extract32(ctx->opcode, 16, 5);
24556 gen_load_gpr(t0, Rb);
24558 gen_store_mxu_gpr(t0, XRa);
24559 } else if (XRa == 16) {
24560 gen_store_mxu_cr(t0);
24567 * S32M2I XRa, rb - Register move from XRF to GRF
24569 static void gen_mxu_s32m2i(DisasContext *ctx)
24574 t0 = tcg_temp_new();
24576 XRa = extract32(ctx->opcode, 6, 5);
24577 Rb = extract32(ctx->opcode, 16, 5);
24580 gen_load_mxu_gpr(t0, XRa);
24581 } else if (XRa == 16) {
24582 gen_load_mxu_cr(t0);
24585 gen_store_gpr(t0, Rb);
24591 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24593 static void gen_mxu_s8ldd(DisasContext *ctx)
24596 uint32_t XRa, Rb, s8, optn3;
24598 t0 = tcg_temp_new();
24599 t1 = tcg_temp_new();
24601 XRa = extract32(ctx->opcode, 6, 4);
24602 s8 = extract32(ctx->opcode, 10, 8);
24603 optn3 = extract32(ctx->opcode, 18, 3);
24604 Rb = extract32(ctx->opcode, 21, 5);
24606 gen_load_gpr(t0, Rb);
24607 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24610 /* XRa[7:0] = tmp8 */
24611 case MXU_OPTN3_PTN0:
24612 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24613 gen_load_mxu_gpr(t0, XRa);
24614 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24616 /* XRa[15:8] = tmp8 */
24617 case MXU_OPTN3_PTN1:
24618 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24619 gen_load_mxu_gpr(t0, XRa);
24620 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24622 /* XRa[23:16] = tmp8 */
24623 case MXU_OPTN3_PTN2:
24624 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24625 gen_load_mxu_gpr(t0, XRa);
24626 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24628 /* XRa[31:24] = tmp8 */
24629 case MXU_OPTN3_PTN3:
24630 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24631 gen_load_mxu_gpr(t0, XRa);
24632 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24634 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24635 case MXU_OPTN3_PTN4:
24636 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24637 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24639 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24640 case MXU_OPTN3_PTN5:
24641 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24642 tcg_gen_shli_tl(t1, t1, 8);
24643 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24645 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24646 case MXU_OPTN3_PTN6:
24647 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24648 tcg_gen_mov_tl(t0, t1);
24649 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24650 tcg_gen_shli_tl(t1, t1, 16);
24651 tcg_gen_or_tl(t0, t0, t1);
24653 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24654 case MXU_OPTN3_PTN7:
24655 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24656 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24657 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24661 gen_store_mxu_gpr(t0, XRa);
24668 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24670 static void gen_mxu_d16mul(DisasContext *ctx)
24672 TCGv t0, t1, t2, t3;
24673 uint32_t XRa, XRb, XRc, XRd, optn2;
24675 t0 = tcg_temp_new();
24676 t1 = tcg_temp_new();
24677 t2 = tcg_temp_new();
24678 t3 = tcg_temp_new();
24680 XRa = extract32(ctx->opcode, 6, 4);
24681 XRb = extract32(ctx->opcode, 10, 4);
24682 XRc = extract32(ctx->opcode, 14, 4);
24683 XRd = extract32(ctx->opcode, 18, 4);
24684 optn2 = extract32(ctx->opcode, 22, 2);
24686 gen_load_mxu_gpr(t1, XRb);
24687 tcg_gen_sextract_tl(t0, t1, 0, 16);
24688 tcg_gen_sextract_tl(t1, t1, 16, 16);
24689 gen_load_mxu_gpr(t3, XRc);
24690 tcg_gen_sextract_tl(t2, t3, 0, 16);
24691 tcg_gen_sextract_tl(t3, t3, 16, 16);
24694 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24695 tcg_gen_mul_tl(t3, t1, t3);
24696 tcg_gen_mul_tl(t2, t0, t2);
24698 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24699 tcg_gen_mul_tl(t3, t0, t3);
24700 tcg_gen_mul_tl(t2, t0, t2);
24702 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24703 tcg_gen_mul_tl(t3, t1, t3);
24704 tcg_gen_mul_tl(t2, t1, t2);
24706 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24707 tcg_gen_mul_tl(t3, t0, t3);
24708 tcg_gen_mul_tl(t2, t1, t2);
24711 gen_store_mxu_gpr(t3, XRa);
24712 gen_store_mxu_gpr(t2, XRd);
24721 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24724 static void gen_mxu_d16mac(DisasContext *ctx)
24726 TCGv t0, t1, t2, t3;
24727 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24729 t0 = tcg_temp_new();
24730 t1 = tcg_temp_new();
24731 t2 = tcg_temp_new();
24732 t3 = tcg_temp_new();
24734 XRa = extract32(ctx->opcode, 6, 4);
24735 XRb = extract32(ctx->opcode, 10, 4);
24736 XRc = extract32(ctx->opcode, 14, 4);
24737 XRd = extract32(ctx->opcode, 18, 4);
24738 optn2 = extract32(ctx->opcode, 22, 2);
24739 aptn2 = extract32(ctx->opcode, 24, 2);
24741 gen_load_mxu_gpr(t1, XRb);
24742 tcg_gen_sextract_tl(t0, t1, 0, 16);
24743 tcg_gen_sextract_tl(t1, t1, 16, 16);
24745 gen_load_mxu_gpr(t3, XRc);
24746 tcg_gen_sextract_tl(t2, t3, 0, 16);
24747 tcg_gen_sextract_tl(t3, t3, 16, 16);
24750 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24751 tcg_gen_mul_tl(t3, t1, t3);
24752 tcg_gen_mul_tl(t2, t0, t2);
24754 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24755 tcg_gen_mul_tl(t3, t0, t3);
24756 tcg_gen_mul_tl(t2, t0, t2);
24758 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24759 tcg_gen_mul_tl(t3, t1, t3);
24760 tcg_gen_mul_tl(t2, t1, t2);
24762 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24763 tcg_gen_mul_tl(t3, t0, t3);
24764 tcg_gen_mul_tl(t2, t1, t2);
24767 gen_load_mxu_gpr(t0, XRa);
24768 gen_load_mxu_gpr(t1, XRd);
24772 tcg_gen_add_tl(t3, t0, t3);
24773 tcg_gen_add_tl(t2, t1, t2);
24776 tcg_gen_add_tl(t3, t0, t3);
24777 tcg_gen_sub_tl(t2, t1, t2);
24780 tcg_gen_sub_tl(t3, t0, t3);
24781 tcg_gen_add_tl(t2, t1, t2);
24784 tcg_gen_sub_tl(t3, t0, t3);
24785 tcg_gen_sub_tl(t2, t1, t2);
24788 gen_store_mxu_gpr(t3, XRa);
24789 gen_store_mxu_gpr(t2, XRd);
24798 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24799 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24801 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24803 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24804 uint32_t XRa, XRb, XRc, XRd, sel;
24806 t0 = tcg_temp_new();
24807 t1 = tcg_temp_new();
24808 t2 = tcg_temp_new();
24809 t3 = tcg_temp_new();
24810 t4 = tcg_temp_new();
24811 t5 = tcg_temp_new();
24812 t6 = tcg_temp_new();
24813 t7 = tcg_temp_new();
24815 XRa = extract32(ctx->opcode, 6, 4);
24816 XRb = extract32(ctx->opcode, 10, 4);
24817 XRc = extract32(ctx->opcode, 14, 4);
24818 XRd = extract32(ctx->opcode, 18, 4);
24819 sel = extract32(ctx->opcode, 22, 2);
24821 gen_load_mxu_gpr(t3, XRb);
24822 gen_load_mxu_gpr(t7, XRc);
24826 tcg_gen_ext8s_tl(t0, t3);
24827 tcg_gen_shri_tl(t3, t3, 8);
24828 tcg_gen_ext8s_tl(t1, t3);
24829 tcg_gen_shri_tl(t3, t3, 8);
24830 tcg_gen_ext8s_tl(t2, t3);
24831 tcg_gen_shri_tl(t3, t3, 8);
24832 tcg_gen_ext8s_tl(t3, t3);
24835 tcg_gen_ext8u_tl(t0, t3);
24836 tcg_gen_shri_tl(t3, t3, 8);
24837 tcg_gen_ext8u_tl(t1, t3);
24838 tcg_gen_shri_tl(t3, t3, 8);
24839 tcg_gen_ext8u_tl(t2, t3);
24840 tcg_gen_shri_tl(t3, t3, 8);
24841 tcg_gen_ext8u_tl(t3, t3);
24844 tcg_gen_ext8u_tl(t4, t7);
24845 tcg_gen_shri_tl(t7, t7, 8);
24846 tcg_gen_ext8u_tl(t5, t7);
24847 tcg_gen_shri_tl(t7, t7, 8);
24848 tcg_gen_ext8u_tl(t6, t7);
24849 tcg_gen_shri_tl(t7, t7, 8);
24850 tcg_gen_ext8u_tl(t7, t7);
24852 tcg_gen_mul_tl(t0, t0, t4);
24853 tcg_gen_mul_tl(t1, t1, t5);
24854 tcg_gen_mul_tl(t2, t2, t6);
24855 tcg_gen_mul_tl(t3, t3, t7);
24857 tcg_gen_andi_tl(t0, t0, 0xFFFF);
24858 tcg_gen_andi_tl(t1, t1, 0xFFFF);
24859 tcg_gen_andi_tl(t2, t2, 0xFFFF);
24860 tcg_gen_andi_tl(t3, t3, 0xFFFF);
24862 tcg_gen_shli_tl(t1, t1, 16);
24863 tcg_gen_shli_tl(t3, t3, 16);
24865 tcg_gen_or_tl(t0, t0, t1);
24866 tcg_gen_or_tl(t1, t2, t3);
24868 gen_store_mxu_gpr(t0, XRd);
24869 gen_store_mxu_gpr(t1, XRa);
24882 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
24883 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24885 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24888 uint32_t XRa, Rb, s12, sel;
24890 t0 = tcg_temp_new();
24891 t1 = tcg_temp_new();
24893 XRa = extract32(ctx->opcode, 6, 4);
24894 s12 = extract32(ctx->opcode, 10, 10);
24895 sel = extract32(ctx->opcode, 20, 1);
24896 Rb = extract32(ctx->opcode, 21, 5);
24898 gen_load_gpr(t0, Rb);
24900 tcg_gen_movi_tl(t1, s12);
24901 tcg_gen_shli_tl(t1, t1, 2);
24903 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24905 tcg_gen_add_tl(t1, t0, t1);
24906 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24910 tcg_gen_bswap32_tl(t1, t1);
24912 gen_store_mxu_gpr(t1, XRa);
24920 * MXU instruction category: logic
24921 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24923 * S32NOR S32AND S32OR S32XOR
24927 * S32NOR XRa, XRb, XRc
24928 * Update XRa with the result of logical bitwise 'nor' operation
24929 * applied to the content of XRb and XRc.
24931 * 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
24932 * +-----------+---------+-----+-------+-------+-------+-----------+
24933 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24934 * +-----------+---------+-----+-------+-------+-------+-----------+
24936 static void gen_mxu_S32NOR(DisasContext *ctx)
24938 uint32_t pad, XRc, XRb, XRa;
24940 pad = extract32(ctx->opcode, 21, 5);
24941 XRc = extract32(ctx->opcode, 14, 4);
24942 XRb = extract32(ctx->opcode, 10, 4);
24943 XRa = extract32(ctx->opcode, 6, 4);
24945 if (unlikely(pad != 0)) {
24946 /* opcode padding incorrect -> do nothing */
24947 } else if (unlikely(XRa == 0)) {
24948 /* destination is zero register -> do nothing */
24949 } else if (unlikely((XRb == 0) && (XRc == 0))) {
24950 /* both operands zero registers -> just set destination to all 1s */
24951 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
24952 } else if (unlikely(XRb == 0)) {
24953 /* XRb zero register -> just set destination to the negation of XRc */
24954 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24955 } else if (unlikely(XRc == 0)) {
24956 /* XRa zero register -> just set destination to the negation of XRb */
24957 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24958 } else if (unlikely(XRb == XRc)) {
24959 /* both operands same -> just set destination to the negation of XRb */
24960 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24962 /* the most general case */
24963 tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24968 * S32AND XRa, XRb, XRc
24969 * Update XRa with the result of logical bitwise 'and' operation
24970 * applied to the content of XRb and XRc.
24972 * 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
24973 * +-----------+---------+-----+-------+-------+-------+-----------+
24974 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
24975 * +-----------+---------+-----+-------+-------+-------+-----------+
24977 static void gen_mxu_S32AND(DisasContext *ctx)
24979 uint32_t pad, XRc, XRb, XRa;
24981 pad = extract32(ctx->opcode, 21, 5);
24982 XRc = extract32(ctx->opcode, 14, 4);
24983 XRb = extract32(ctx->opcode, 10, 4);
24984 XRa = extract32(ctx->opcode, 6, 4);
24986 if (unlikely(pad != 0)) {
24987 /* opcode padding incorrect -> do nothing */
24988 } else if (unlikely(XRa == 0)) {
24989 /* destination is zero register -> do nothing */
24990 } else if (unlikely((XRb == 0) || (XRc == 0))) {
24991 /* one of operands zero register -> just set destination to all 0s */
24992 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24993 } else if (unlikely(XRb == XRc)) {
24994 /* both operands same -> just set destination to one of them */
24995 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24997 /* the most general case */
24998 tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25003 * S32OR XRa, XRb, XRc
25004 * Update XRa with the result of logical bitwise 'or' operation
25005 * applied to the content of XRb and XRc.
25007 * 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
25008 * +-----------+---------+-----+-------+-------+-------+-----------+
25009 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25010 * +-----------+---------+-----+-------+-------+-------+-----------+
25012 static void gen_mxu_S32OR(DisasContext *ctx)
25014 uint32_t pad, XRc, XRb, XRa;
25016 pad = extract32(ctx->opcode, 21, 5);
25017 XRc = extract32(ctx->opcode, 14, 4);
25018 XRb = extract32(ctx->opcode, 10, 4);
25019 XRa = extract32(ctx->opcode, 6, 4);
25021 if (unlikely(pad != 0)) {
25022 /* opcode padding incorrect -> do nothing */
25023 } else if (unlikely(XRa == 0)) {
25024 /* destination is zero register -> do nothing */
25025 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25026 /* both operands zero registers -> just set destination to all 0s */
25027 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25028 } else if (unlikely(XRb == 0)) {
25029 /* XRb zero register -> just set destination to the content of XRc */
25030 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25031 } else if (unlikely(XRc == 0)) {
25032 /* XRc zero register -> just set destination to the content of XRb */
25033 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25034 } else if (unlikely(XRb == XRc)) {
25035 /* both operands same -> just set destination to one of them */
25036 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25038 /* the most general case */
25039 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25044 * S32XOR XRa, XRb, XRc
25045 * Update XRa with the result of logical bitwise 'xor' operation
25046 * applied to the content of XRb and XRc.
25048 * 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
25049 * +-----------+---------+-----+-------+-------+-------+-----------+
25050 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25051 * +-----------+---------+-----+-------+-------+-------+-----------+
25053 static void gen_mxu_S32XOR(DisasContext *ctx)
25055 uint32_t pad, XRc, XRb, XRa;
25057 pad = extract32(ctx->opcode, 21, 5);
25058 XRc = extract32(ctx->opcode, 14, 4);
25059 XRb = extract32(ctx->opcode, 10, 4);
25060 XRa = extract32(ctx->opcode, 6, 4);
25062 if (unlikely(pad != 0)) {
25063 /* opcode padding incorrect -> do nothing */
25064 } else if (unlikely(XRa == 0)) {
25065 /* destination is zero register -> do nothing */
25066 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25067 /* both operands zero registers -> just set destination to all 0s */
25068 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25069 } else if (unlikely(XRb == 0)) {
25070 /* XRb zero register -> just set destination to the content of XRc */
25071 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25072 } else if (unlikely(XRc == 0)) {
25073 /* XRc zero register -> just set destination to the content of XRb */
25074 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25075 } else if (unlikely(XRb == XRc)) {
25076 /* both operands same -> just set destination to all 0s */
25077 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25079 /* the most general case */
25080 tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
25086 * MXU instruction category max/min
25087 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25089 * S32MAX D16MAX Q8MAX
25090 * S32MIN D16MIN Q8MIN
25094 * S32MAX XRa, XRb, XRc
25095 * Update XRa with the maximum of signed 32-bit integers contained
25098 * S32MIN XRa, XRb, XRc
25099 * Update XRa with the minimum of signed 32-bit integers contained
25102 * 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
25103 * +-----------+---------+-----+-------+-------+-------+-----------+
25104 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25105 * +-----------+---------+-----+-------+-------+-------+-----------+
25107 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
25109 uint32_t pad, opc, XRc, XRb, XRa;
25111 pad = extract32(ctx->opcode, 21, 5);
25112 opc = extract32(ctx->opcode, 18, 3);
25113 XRc = extract32(ctx->opcode, 14, 4);
25114 XRb = extract32(ctx->opcode, 10, 4);
25115 XRa = extract32(ctx->opcode, 6, 4);
25117 if (unlikely(pad != 0)) {
25118 /* opcode padding incorrect -> do nothing */
25119 } else if (unlikely(XRa == 0)) {
25120 /* destination is zero register -> do nothing */
25121 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25122 /* both operands zero registers -> just set destination to zero */
25123 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25124 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25125 /* exactly one operand is zero register - find which one is not...*/
25126 uint32_t XRx = XRb ? XRb : XRc;
25127 /* ...and do max/min operation with one operand 0 */
25128 if (opc == OPC_MXU_S32MAX) {
25129 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25131 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
25133 } else if (unlikely(XRb == XRc)) {
25134 /* both operands same -> just set destination to one of them */
25135 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25137 /* the most general case */
25138 if (opc == OPC_MXU_S32MAX) {
25139 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25142 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25150 * Update XRa with the 16-bit-wise maximums of signed integers
25151 * contained in XRb and XRc.
25154 * Update XRa with the 16-bit-wise minimums of signed integers
25155 * contained in XRb and XRc.
25157 * 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
25158 * +-----------+---------+-----+-------+-------+-------+-----------+
25159 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25160 * +-----------+---------+-----+-------+-------+-------+-----------+
25162 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25164 uint32_t pad, opc, XRc, XRb, XRa;
25166 pad = extract32(ctx->opcode, 21, 5);
25167 opc = extract32(ctx->opcode, 18, 3);
25168 XRc = extract32(ctx->opcode, 14, 4);
25169 XRb = extract32(ctx->opcode, 10, 4);
25170 XRa = extract32(ctx->opcode, 6, 4);
25172 if (unlikely(pad != 0)) {
25173 /* opcode padding incorrect -> do nothing */
25174 } else if (unlikely(XRc == 0)) {
25175 /* destination is zero register -> do nothing */
25176 } else if (unlikely((XRb == 0) && (XRa == 0))) {
25177 /* both operands zero registers -> just set destination to zero */
25178 tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25179 } else if (unlikely((XRb == 0) || (XRa == 0))) {
25180 /* exactly one operand is zero register - find which one is not...*/
25181 uint32_t XRx = XRb ? XRb : XRc;
25182 /* ...and do half-word-wise max/min with one operand 0 */
25183 TCGv_i32 t0 = tcg_temp_new();
25184 TCGv_i32 t1 = tcg_const_i32(0);
25186 /* the left half-word first */
25187 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25188 if (opc == OPC_MXU_D16MAX) {
25189 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25191 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25194 /* the right half-word */
25195 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25196 /* move half-words to the leftmost position */
25197 tcg_gen_shli_i32(t0, t0, 16);
25198 /* t0 will be max/min of t0 and t1 */
25199 if (opc == OPC_MXU_D16MAX) {
25200 tcg_gen_smax_i32(t0, t0, t1);
25202 tcg_gen_smin_i32(t0, t0, t1);
25204 /* return resulting half-words to its original position */
25205 tcg_gen_shri_i32(t0, t0, 16);
25206 /* finaly update the destination */
25207 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25211 } else if (unlikely(XRb == XRc)) {
25212 /* both operands same -> just set destination to one of them */
25213 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25215 /* the most general case */
25216 TCGv_i32 t0 = tcg_temp_new();
25217 TCGv_i32 t1 = tcg_temp_new();
25219 /* the left half-word first */
25220 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25221 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25222 if (opc == OPC_MXU_D16MAX) {
25223 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25225 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25228 /* the right half-word */
25229 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25230 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25231 /* move half-words to the leftmost position */
25232 tcg_gen_shli_i32(t0, t0, 16);
25233 tcg_gen_shli_i32(t1, t1, 16);
25234 /* t0 will be max/min of t0 and t1 */
25235 if (opc == OPC_MXU_D16MAX) {
25236 tcg_gen_smax_i32(t0, t0, t1);
25238 tcg_gen_smin_i32(t0, t0, t1);
25240 /* return resulting half-words to its original position */
25241 tcg_gen_shri_i32(t0, t0, 16);
25242 /* finaly update the destination */
25243 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25252 * Update XRa with the 8-bit-wise maximums of signed integers
25253 * contained in XRb and XRc.
25256 * Update XRa with the 8-bit-wise minimums of signed integers
25257 * contained in XRb and XRc.
25259 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25260 * +-----------+---------+-----+-------+-------+-------+-----------+
25261 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25262 * +-----------+---------+-----+-------+-------+-------+-----------+
25264 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25266 uint32_t pad, opc, XRc, XRb, XRa;
25268 pad = extract32(ctx->opcode, 21, 5);
25269 opc = extract32(ctx->opcode, 18, 3);
25270 XRc = extract32(ctx->opcode, 14, 4);
25271 XRb = extract32(ctx->opcode, 10, 4);
25272 XRa = extract32(ctx->opcode, 6, 4);
25274 if (unlikely(pad != 0)) {
25275 /* opcode padding incorrect -> do nothing */
25276 } else if (unlikely(XRa == 0)) {
25277 /* destination is zero register -> do nothing */
25278 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25279 /* both operands zero registers -> just set destination to zero */
25280 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25281 } else if (unlikely((XRb == 0) || (XRc == 0))) {
25282 /* exactly one operand is zero register - make it be the first...*/
25283 uint32_t XRx = XRb ? XRb : XRc;
25284 /* ...and do byte-wise max/min with one operand 0 */
25285 TCGv_i32 t0 = tcg_temp_new();
25286 TCGv_i32 t1 = tcg_const_i32(0);
25289 /* the leftmost byte (byte 3) first */
25290 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25291 if (opc == OPC_MXU_Q8MAX) {
25292 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25294 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25297 /* bytes 2, 1, 0 */
25298 for (i = 2; i >= 0; i--) {
25299 /* extract the byte */
25300 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25301 /* move the byte to the leftmost position */
25302 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25303 /* t0 will be max/min of t0 and t1 */
25304 if (opc == OPC_MXU_Q8MAX) {
25305 tcg_gen_smax_i32(t0, t0, t1);
25307 tcg_gen_smin_i32(t0, t0, t1);
25309 /* return resulting byte to its original position */
25310 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25311 /* finaly update the destination */
25312 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25317 } else if (unlikely(XRb == XRc)) {
25318 /* both operands same -> just set destination to one of them */
25319 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25321 /* the most general case */
25322 TCGv_i32 t0 = tcg_temp_new();
25323 TCGv_i32 t1 = tcg_temp_new();
25326 /* the leftmost bytes (bytes 3) first */
25327 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25328 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25329 if (opc == OPC_MXU_Q8MAX) {
25330 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25332 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25335 /* bytes 2, 1, 0 */
25336 for (i = 2; i >= 0; i--) {
25337 /* extract corresponding bytes */
25338 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25339 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25340 /* move the bytes to the leftmost position */
25341 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25342 tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25343 /* t0 will be max/min of t0 and t1 */
25344 if (opc == OPC_MXU_Q8MAX) {
25345 tcg_gen_smax_i32(t0, t0, t1);
25347 tcg_gen_smin_i32(t0, t0, t1);
25349 /* return resulting byte to its original position */
25350 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25351 /* finaly update the destination */
25352 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25362 * MXU instruction category: align
25363 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25369 * S32ALNI XRc, XRb, XRa, optn3
25370 * Arrange bytes from XRb and XRc according to one of five sets of
25371 * rules determined by optn3, and place the result in XRa.
25373 * 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
25374 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25375 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25376 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25379 static void gen_mxu_S32ALNI(DisasContext *ctx)
25381 uint32_t optn3, pad, XRc, XRb, XRa;
25383 optn3 = extract32(ctx->opcode, 23, 3);
25384 pad = extract32(ctx->opcode, 21, 2);
25385 XRc = extract32(ctx->opcode, 14, 4);
25386 XRb = extract32(ctx->opcode, 10, 4);
25387 XRa = extract32(ctx->opcode, 6, 4);
25389 if (unlikely(pad != 0)) {
25390 /* opcode padding incorrect -> do nothing */
25391 } else if (unlikely(XRa == 0)) {
25392 /* destination is zero register -> do nothing */
25393 } else if (unlikely((XRb == 0) && (XRc == 0))) {
25394 /* both operands zero registers -> just set destination to all 0s */
25395 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25396 } else if (unlikely(XRb == 0)) {
25397 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25399 case MXU_OPTN3_PTN0:
25400 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25402 case MXU_OPTN3_PTN1:
25403 case MXU_OPTN3_PTN2:
25404 case MXU_OPTN3_PTN3:
25405 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25408 case MXU_OPTN3_PTN4:
25409 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25412 } else if (unlikely(XRc == 0)) {
25413 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25415 case MXU_OPTN3_PTN0:
25416 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25418 case MXU_OPTN3_PTN1:
25419 case MXU_OPTN3_PTN2:
25420 case MXU_OPTN3_PTN3:
25421 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25423 case MXU_OPTN3_PTN4:
25424 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25427 } else if (unlikely(XRb == XRc)) {
25428 /* both operands same -> just rotation or moving from any of them */
25430 case MXU_OPTN3_PTN0:
25431 case MXU_OPTN3_PTN4:
25432 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25434 case MXU_OPTN3_PTN1:
25435 case MXU_OPTN3_PTN2:
25436 case MXU_OPTN3_PTN3:
25437 tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25441 /* the most general case */
25443 case MXU_OPTN3_PTN0:
25447 /* +---------------+ */
25448 /* | A B C D | E F G H */
25449 /* +-------+-------+ */
25454 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25457 case MXU_OPTN3_PTN1:
25461 /* +-------------------+ */
25462 /* A | B C D E | F G H */
25463 /* +---------+---------+ */
25468 TCGv_i32 t0 = tcg_temp_new();
25469 TCGv_i32 t1 = tcg_temp_new();
25471 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25472 tcg_gen_shli_i32(t0, t0, 8);
25474 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25475 tcg_gen_shri_i32(t1, t1, 24);
25477 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25483 case MXU_OPTN3_PTN2:
25487 /* +-------------------+ */
25488 /* A B | C D E F | G H */
25489 /* +---------+---------+ */
25494 TCGv_i32 t0 = tcg_temp_new();
25495 TCGv_i32 t1 = tcg_temp_new();
25497 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25498 tcg_gen_shli_i32(t0, t0, 16);
25500 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25501 tcg_gen_shri_i32(t1, t1, 16);
25503 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25509 case MXU_OPTN3_PTN3:
25513 /* +-------------------+ */
25514 /* A B C | D E F G | H */
25515 /* +---------+---------+ */
25520 TCGv_i32 t0 = tcg_temp_new();
25521 TCGv_i32 t1 = tcg_temp_new();
25523 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25524 tcg_gen_shli_i32(t0, t0, 24);
25526 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25527 tcg_gen_shri_i32(t1, t1, 8);
25529 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25535 case MXU_OPTN3_PTN4:
25539 /* +---------------+ */
25540 /* A B C D | E F G H | */
25541 /* +-------+-------+ */
25546 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25555 * Decoding engine for MXU
25556 * =======================
25561 * Decode MXU pool00
25563 * 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
25564 * +-----------+---------+-----+-------+-------+-------+-----------+
25565 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25566 * +-----------+---------+-----+-------+-------+-------+-----------+
25569 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25571 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25574 case OPC_MXU_S32MAX:
25575 case OPC_MXU_S32MIN:
25576 gen_mxu_S32MAX_S32MIN(ctx);
25578 case OPC_MXU_D16MAX:
25579 case OPC_MXU_D16MIN:
25580 gen_mxu_D16MAX_D16MIN(ctx);
25582 case OPC_MXU_Q8MAX:
25583 case OPC_MXU_Q8MIN:
25584 gen_mxu_Q8MAX_Q8MIN(ctx);
25586 case OPC_MXU_Q8SLT:
25587 /* TODO: Implement emulation of Q8SLT instruction. */
25588 MIPS_INVAL("OPC_MXU_Q8SLT");
25589 generate_exception_end(ctx, EXCP_RI);
25591 case OPC_MXU_Q8SLTU:
25592 /* TODO: Implement emulation of Q8SLTU instruction. */
25593 MIPS_INVAL("OPC_MXU_Q8SLTU");
25594 generate_exception_end(ctx, EXCP_RI);
25597 MIPS_INVAL("decode_opc_mxu");
25598 generate_exception_end(ctx, EXCP_RI);
25605 * Decode MXU pool01
25607 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25608 * 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
25609 * +-----------+---------+-----+-------+-------+-------+-----------+
25610 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25611 * +-----------+---------+-----+-------+-------+-------+-----------+
25614 * 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
25615 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25616 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25617 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25620 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25622 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25625 case OPC_MXU_S32SLT:
25626 /* TODO: Implement emulation of S32SLT instruction. */
25627 MIPS_INVAL("OPC_MXU_S32SLT");
25628 generate_exception_end(ctx, EXCP_RI);
25630 case OPC_MXU_D16SLT:
25631 /* TODO: Implement emulation of D16SLT instruction. */
25632 MIPS_INVAL("OPC_MXU_D16SLT");
25633 generate_exception_end(ctx, EXCP_RI);
25635 case OPC_MXU_D16AVG:
25636 /* TODO: Implement emulation of D16AVG instruction. */
25637 MIPS_INVAL("OPC_MXU_D16AVG");
25638 generate_exception_end(ctx, EXCP_RI);
25640 case OPC_MXU_D16AVGR:
25641 /* TODO: Implement emulation of D16AVGR instruction. */
25642 MIPS_INVAL("OPC_MXU_D16AVGR");
25643 generate_exception_end(ctx, EXCP_RI);
25645 case OPC_MXU_Q8AVG:
25646 /* TODO: Implement emulation of Q8AVG instruction. */
25647 MIPS_INVAL("OPC_MXU_Q8AVG");
25648 generate_exception_end(ctx, EXCP_RI);
25650 case OPC_MXU_Q8AVGR:
25651 /* TODO: Implement emulation of Q8AVGR instruction. */
25652 MIPS_INVAL("OPC_MXU_Q8AVGR");
25653 generate_exception_end(ctx, EXCP_RI);
25655 case OPC_MXU_Q8ADD:
25656 /* TODO: Implement emulation of Q8ADD instruction. */
25657 MIPS_INVAL("OPC_MXU_Q8ADD");
25658 generate_exception_end(ctx, EXCP_RI);
25661 MIPS_INVAL("decode_opc_mxu");
25662 generate_exception_end(ctx, EXCP_RI);
25669 * Decode MXU pool02
25671 * 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
25672 * +-----------+---------+-----+-------+-------+-------+-----------+
25673 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
25674 * +-----------+---------+-----+-------+-------+-------+-----------+
25677 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25679 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25682 case OPC_MXU_S32CPS:
25683 /* TODO: Implement emulation of S32CPS instruction. */
25684 MIPS_INVAL("OPC_MXU_S32CPS");
25685 generate_exception_end(ctx, EXCP_RI);
25687 case OPC_MXU_D16CPS:
25688 /* TODO: Implement emulation of D16CPS instruction. */
25689 MIPS_INVAL("OPC_MXU_D16CPS");
25690 generate_exception_end(ctx, EXCP_RI);
25692 case OPC_MXU_Q8ABD:
25693 /* TODO: Implement emulation of Q8ABD instruction. */
25694 MIPS_INVAL("OPC_MXU_Q8ABD");
25695 generate_exception_end(ctx, EXCP_RI);
25697 case OPC_MXU_Q16SAT:
25698 /* TODO: Implement emulation of Q16SAT instruction. */
25699 MIPS_INVAL("OPC_MXU_Q16SAT");
25700 generate_exception_end(ctx, EXCP_RI);
25703 MIPS_INVAL("decode_opc_mxu");
25704 generate_exception_end(ctx, EXCP_RI);
25711 * Decode MXU pool03
25714 * 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
25715 * +-----------+---+---+-------+-------+-------+-------+-----------+
25716 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
25717 * +-----------+---+---+-------+-------+-------+-------+-----------+
25720 * 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
25721 * +-----------+---+---+-------+-------+-------+-------+-----------+
25722 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
25723 * +-----------+---+---+-------+-------+-------+-------+-----------+
25726 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25728 uint32_t opcode = extract32(ctx->opcode, 24, 2);
25731 case OPC_MXU_D16MULF:
25732 /* TODO: Implement emulation of D16MULF instruction. */
25733 MIPS_INVAL("OPC_MXU_D16MULF");
25734 generate_exception_end(ctx, EXCP_RI);
25736 case OPC_MXU_D16MULE:
25737 /* TODO: Implement emulation of D16MULE instruction. */
25738 MIPS_INVAL("OPC_MXU_D16MULE");
25739 generate_exception_end(ctx, EXCP_RI);
25742 MIPS_INVAL("decode_opc_mxu");
25743 generate_exception_end(ctx, EXCP_RI);
25750 * Decode MXU pool04
25752 * 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
25753 * +-----------+---------+-+-------------------+-------+-----------+
25754 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
25755 * +-----------+---------+-+-------------------+-------+-----------+
25758 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25760 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25763 case OPC_MXU_S32LDD:
25764 case OPC_MXU_S32LDDR:
25765 gen_mxu_s32ldd_s32lddr(ctx);
25768 MIPS_INVAL("decode_opc_mxu");
25769 generate_exception_end(ctx, EXCP_RI);
25776 * Decode MXU pool05
25778 * 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
25779 * +-----------+---------+-+-------------------+-------+-----------+
25780 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
25781 * +-----------+---------+-+-------------------+-------+-----------+
25784 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25786 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25789 case OPC_MXU_S32STD:
25790 /* TODO: Implement emulation of S32STD instruction. */
25791 MIPS_INVAL("OPC_MXU_S32STD");
25792 generate_exception_end(ctx, EXCP_RI);
25794 case OPC_MXU_S32STDR:
25795 /* TODO: Implement emulation of S32STDR instruction. */
25796 MIPS_INVAL("OPC_MXU_S32STDR");
25797 generate_exception_end(ctx, EXCP_RI);
25800 MIPS_INVAL("decode_opc_mxu");
25801 generate_exception_end(ctx, EXCP_RI);
25808 * Decode MXU pool06
25810 * 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
25811 * +-----------+---------+---------+---+-------+-------+-----------+
25812 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
25813 * +-----------+---------+---------+---+-------+-------+-----------+
25816 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25818 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25821 case OPC_MXU_S32LDDV:
25822 /* TODO: Implement emulation of S32LDDV instruction. */
25823 MIPS_INVAL("OPC_MXU_S32LDDV");
25824 generate_exception_end(ctx, EXCP_RI);
25826 case OPC_MXU_S32LDDVR:
25827 /* TODO: Implement emulation of S32LDDVR instruction. */
25828 MIPS_INVAL("OPC_MXU_S32LDDVR");
25829 generate_exception_end(ctx, EXCP_RI);
25832 MIPS_INVAL("decode_opc_mxu");
25833 generate_exception_end(ctx, EXCP_RI);
25840 * Decode MXU pool07
25842 * 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
25843 * +-----------+---------+---------+---+-------+-------+-----------+
25844 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
25845 * +-----------+---------+---------+---+-------+-------+-----------+
25848 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
25850 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25853 case OPC_MXU_S32STDV:
25854 /* TODO: Implement emulation of S32TDV instruction. */
25855 MIPS_INVAL("OPC_MXU_S32TDV");
25856 generate_exception_end(ctx, EXCP_RI);
25858 case OPC_MXU_S32STDVR:
25859 /* TODO: Implement emulation of S32TDVR instruction. */
25860 MIPS_INVAL("OPC_MXU_S32TDVR");
25861 generate_exception_end(ctx, EXCP_RI);
25864 MIPS_INVAL("decode_opc_mxu");
25865 generate_exception_end(ctx, EXCP_RI);
25872 * Decode MXU pool08
25874 * 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
25875 * +-----------+---------+-+-------------------+-------+-----------+
25876 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
25877 * +-----------+---------+-+-------------------+-------+-----------+
25880 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
25882 uint32_t opcode = extract32(ctx->opcode, 20, 1);
25885 case OPC_MXU_S32LDI:
25886 /* TODO: Implement emulation of S32LDI instruction. */
25887 MIPS_INVAL("OPC_MXU_S32LDI");
25888 generate_exception_end(ctx, EXCP_RI);
25890 case OPC_MXU_S32LDIR:
25891 /* TODO: Implement emulation of S32LDIR instruction. */
25892 MIPS_INVAL("OPC_MXU_S32LDIR");
25893 generate_exception_end(ctx, EXCP_RI);
25896 MIPS_INVAL("decode_opc_mxu");
25897 generate_exception_end(ctx, EXCP_RI);
25904 * Decode MXU pool09
25906 * 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
25907 * +-----------+---------+-+-------------------+-------+-----------+
25908 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
25909 * +-----------+---------+-+-------------------+-------+-----------+
25912 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
25914 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25917 case OPC_MXU_S32SDI:
25918 /* TODO: Implement emulation of S32SDI instruction. */
25919 MIPS_INVAL("OPC_MXU_S32SDI");
25920 generate_exception_end(ctx, EXCP_RI);
25922 case OPC_MXU_S32SDIR:
25923 /* TODO: Implement emulation of S32SDIR instruction. */
25924 MIPS_INVAL("OPC_MXU_S32SDIR");
25925 generate_exception_end(ctx, EXCP_RI);
25928 MIPS_INVAL("decode_opc_mxu");
25929 generate_exception_end(ctx, EXCP_RI);
25936 * Decode MXU pool10
25938 * 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
25939 * +-----------+---------+---------+---+-------+-------+-----------+
25940 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
25941 * +-----------+---------+---------+---+-------+-------+-----------+
25944 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25946 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25949 case OPC_MXU_S32LDIV:
25950 /* TODO: Implement emulation of S32LDIV instruction. */
25951 MIPS_INVAL("OPC_MXU_S32LDIV");
25952 generate_exception_end(ctx, EXCP_RI);
25954 case OPC_MXU_S32LDIVR:
25955 /* TODO: Implement emulation of S32LDIVR instruction. */
25956 MIPS_INVAL("OPC_MXU_S32LDIVR");
25957 generate_exception_end(ctx, EXCP_RI);
25960 MIPS_INVAL("decode_opc_mxu");
25961 generate_exception_end(ctx, EXCP_RI);
25968 * Decode MXU pool11
25970 * 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
25971 * +-----------+---------+---------+---+-------+-------+-----------+
25972 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
25973 * +-----------+---------+---------+---+-------+-------+-----------+
25976 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25978 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25981 case OPC_MXU_S32SDIV:
25982 /* TODO: Implement emulation of S32SDIV instruction. */
25983 MIPS_INVAL("OPC_MXU_S32SDIV");
25984 generate_exception_end(ctx, EXCP_RI);
25986 case OPC_MXU_S32SDIVR:
25987 /* TODO: Implement emulation of S32SDIVR instruction. */
25988 MIPS_INVAL("OPC_MXU_S32SDIVR");
25989 generate_exception_end(ctx, EXCP_RI);
25992 MIPS_INVAL("decode_opc_mxu");
25993 generate_exception_end(ctx, EXCP_RI);
26000 * Decode MXU pool12
26002 * 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
26003 * +-----------+---+---+-------+-------+-------+-------+-----------+
26004 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26005 * +-----------+---+---+-------+-------+-------+-------+-----------+
26008 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
26010 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26013 case OPC_MXU_D32ACC:
26014 /* TODO: Implement emulation of D32ACC instruction. */
26015 MIPS_INVAL("OPC_MXU_D32ACC");
26016 generate_exception_end(ctx, EXCP_RI);
26018 case OPC_MXU_D32ACCM:
26019 /* TODO: Implement emulation of D32ACCM instruction. */
26020 MIPS_INVAL("OPC_MXU_D32ACCM");
26021 generate_exception_end(ctx, EXCP_RI);
26023 case OPC_MXU_D32ASUM:
26024 /* TODO: Implement emulation of D32ASUM instruction. */
26025 MIPS_INVAL("OPC_MXU_D32ASUM");
26026 generate_exception_end(ctx, EXCP_RI);
26029 MIPS_INVAL("decode_opc_mxu");
26030 generate_exception_end(ctx, EXCP_RI);
26037 * Decode MXU pool13
26039 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26040 * +-----------+---+---+-------+-------+-------+-------+-----------+
26041 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26042 * +-----------+---+---+-------+-------+-------+-------+-----------+
26045 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
26047 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26050 case OPC_MXU_Q16ACC:
26051 /* TODO: Implement emulation of Q16ACC instruction. */
26052 MIPS_INVAL("OPC_MXU_Q16ACC");
26053 generate_exception_end(ctx, EXCP_RI);
26055 case OPC_MXU_Q16ACCM:
26056 /* TODO: Implement emulation of Q16ACCM instruction. */
26057 MIPS_INVAL("OPC_MXU_Q16ACCM");
26058 generate_exception_end(ctx, EXCP_RI);
26060 case OPC_MXU_Q16ASUM:
26061 /* TODO: Implement emulation of Q16ASUM instruction. */
26062 MIPS_INVAL("OPC_MXU_Q16ASUM");
26063 generate_exception_end(ctx, EXCP_RI);
26066 MIPS_INVAL("decode_opc_mxu");
26067 generate_exception_end(ctx, EXCP_RI);
26074 * Decode MXU pool14
26077 * 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
26078 * +-----------+---+---+-------+-------+-------+-------+-----------+
26079 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26080 * +-----------+---+---+-------+-------+-------+-------+-----------+
26083 * 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
26084 * +-----------+---+---+-------+-------+-------+-------+-----------+
26085 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26086 * +-----------+---+---+-------+-------+-------+-------+-----------+
26089 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
26091 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26094 case OPC_MXU_Q8ADDE:
26095 /* TODO: Implement emulation of Q8ADDE instruction. */
26096 MIPS_INVAL("OPC_MXU_Q8ADDE");
26097 generate_exception_end(ctx, EXCP_RI);
26099 case OPC_MXU_D8SUM:
26100 /* TODO: Implement emulation of D8SUM instruction. */
26101 MIPS_INVAL("OPC_MXU_D8SUM");
26102 generate_exception_end(ctx, EXCP_RI);
26104 case OPC_MXU_D8SUMC:
26105 /* TODO: Implement emulation of D8SUMC instruction. */
26106 MIPS_INVAL("OPC_MXU_D8SUMC");
26107 generate_exception_end(ctx, EXCP_RI);
26110 MIPS_INVAL("decode_opc_mxu");
26111 generate_exception_end(ctx, EXCP_RI);
26118 * Decode MXU pool15
26120 * S32MUL, S32MULU, S32EXTRV:
26121 * 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
26122 * +-----------+---------+---------+---+-------+-------+-----------+
26123 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26124 * +-----------+---------+---------+---+-------+-------+-----------+
26127 * 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
26128 * +-----------+---------+---------+---+-------+-------+-----------+
26129 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26130 * +-----------+---------+---------+---+-------+-------+-----------+
26133 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
26135 uint32_t opcode = extract32(ctx->opcode, 14, 2);
26138 case OPC_MXU_S32MUL:
26139 /* TODO: Implement emulation of S32MUL instruction. */
26140 MIPS_INVAL("OPC_MXU_S32MUL");
26141 generate_exception_end(ctx, EXCP_RI);
26143 case OPC_MXU_S32MULU:
26144 /* TODO: Implement emulation of S32MULU instruction. */
26145 MIPS_INVAL("OPC_MXU_S32MULU");
26146 generate_exception_end(ctx, EXCP_RI);
26148 case OPC_MXU_S32EXTR:
26149 /* TODO: Implement emulation of S32EXTR instruction. */
26150 MIPS_INVAL("OPC_MXU_S32EXTR");
26151 generate_exception_end(ctx, EXCP_RI);
26153 case OPC_MXU_S32EXTRV:
26154 /* TODO: Implement emulation of S32EXTRV instruction. */
26155 MIPS_INVAL("OPC_MXU_S32EXTRV");
26156 generate_exception_end(ctx, EXCP_RI);
26159 MIPS_INVAL("decode_opc_mxu");
26160 generate_exception_end(ctx, EXCP_RI);
26167 * Decode MXU pool16
26170 * 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
26171 * +-----------+---------+-----+-------+-------+-------+-----------+
26172 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26173 * +-----------+---------+-----+-------+-------+-------+-----------+
26176 * 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
26177 * +-----------+---------+-----+-------+-------+-------+-----------+
26178 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26179 * +-----------+---------+-----+-------+-------+-------+-----------+
26182 * 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
26183 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26184 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26185 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26188 * 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
26189 * +-----------+-----+---+-----+-------+---------------+-----------+
26190 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26191 * +-----------+-----+---+-----+-------+---------------+-----------+
26193 * S32NOR, S32AND, S32OR, S32XOR:
26194 * 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
26195 * +-----------+---------+-----+-------+-------+-------+-----------+
26196 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26197 * +-----------+---------+-----+-------+-------+-------+-----------+
26200 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26202 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26205 case OPC_MXU_D32SARW:
26206 /* TODO: Implement emulation of D32SARW instruction. */
26207 MIPS_INVAL("OPC_MXU_D32SARW");
26208 generate_exception_end(ctx, EXCP_RI);
26210 case OPC_MXU_S32ALN:
26211 /* TODO: Implement emulation of S32ALN instruction. */
26212 MIPS_INVAL("OPC_MXU_S32ALN");
26213 generate_exception_end(ctx, EXCP_RI);
26215 case OPC_MXU_S32ALNI:
26216 gen_mxu_S32ALNI(ctx);
26218 case OPC_MXU_S32LUI:
26219 /* TODO: Implement emulation of S32LUI instruction. */
26220 MIPS_INVAL("OPC_MXU_S32LUI");
26221 generate_exception_end(ctx, EXCP_RI);
26223 case OPC_MXU_S32NOR:
26224 gen_mxu_S32NOR(ctx);
26226 case OPC_MXU_S32AND:
26227 gen_mxu_S32AND(ctx);
26229 case OPC_MXU_S32OR:
26230 gen_mxu_S32OR(ctx);
26232 case OPC_MXU_S32XOR:
26233 gen_mxu_S32XOR(ctx);
26236 MIPS_INVAL("decode_opc_mxu");
26237 generate_exception_end(ctx, EXCP_RI);
26244 * Decode MXU pool17
26246 * 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
26247 * +-----------+---------+---------+---+---------+-----+-----------+
26248 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26249 * +-----------+---------+---------+---+---------+-----+-----------+
26252 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26254 uint32_t opcode = extract32(ctx->opcode, 6, 2);
26258 /* TODO: Implement emulation of LXW instruction. */
26259 MIPS_INVAL("OPC_MXU_LXW");
26260 generate_exception_end(ctx, EXCP_RI);
26263 /* TODO: Implement emulation of LXH instruction. */
26264 MIPS_INVAL("OPC_MXU_LXH");
26265 generate_exception_end(ctx, EXCP_RI);
26268 /* TODO: Implement emulation of LXHU instruction. */
26269 MIPS_INVAL("OPC_MXU_LXHU");
26270 generate_exception_end(ctx, EXCP_RI);
26273 /* TODO: Implement emulation of LXB instruction. */
26274 MIPS_INVAL("OPC_MXU_LXB");
26275 generate_exception_end(ctx, EXCP_RI);
26278 /* TODO: Implement emulation of LXBU instruction. */
26279 MIPS_INVAL("OPC_MXU_LXBU");
26280 generate_exception_end(ctx, EXCP_RI);
26283 MIPS_INVAL("decode_opc_mxu");
26284 generate_exception_end(ctx, EXCP_RI);
26290 * Decode MXU pool18
26292 * 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
26293 * +-----------+---------+-----+-------+-------+-------+-----------+
26294 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26295 * +-----------+---------+-----+-------+-------+-------+-----------+
26298 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26300 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26303 case OPC_MXU_D32SLLV:
26304 /* TODO: Implement emulation of D32SLLV instruction. */
26305 MIPS_INVAL("OPC_MXU_D32SLLV");
26306 generate_exception_end(ctx, EXCP_RI);
26308 case OPC_MXU_D32SLRV:
26309 /* TODO: Implement emulation of D32SLRV instruction. */
26310 MIPS_INVAL("OPC_MXU_D32SLRV");
26311 generate_exception_end(ctx, EXCP_RI);
26313 case OPC_MXU_D32SARV:
26314 /* TODO: Implement emulation of D32SARV instruction. */
26315 MIPS_INVAL("OPC_MXU_D32SARV");
26316 generate_exception_end(ctx, EXCP_RI);
26318 case OPC_MXU_Q16SLLV:
26319 /* TODO: Implement emulation of Q16SLLV instruction. */
26320 MIPS_INVAL("OPC_MXU_Q16SLLV");
26321 generate_exception_end(ctx, EXCP_RI);
26323 case OPC_MXU_Q16SLRV:
26324 /* TODO: Implement emulation of Q16SLRV instruction. */
26325 MIPS_INVAL("OPC_MXU_Q16SLRV");
26326 generate_exception_end(ctx, EXCP_RI);
26328 case OPC_MXU_Q16SARV:
26329 /* TODO: Implement emulation of Q16SARV instruction. */
26330 MIPS_INVAL("OPC_MXU_Q16SARV");
26331 generate_exception_end(ctx, EXCP_RI);
26334 MIPS_INVAL("decode_opc_mxu");
26335 generate_exception_end(ctx, EXCP_RI);
26342 * Decode MXU pool19
26344 * 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
26345 * +-----------+---+---+-------+-------+-------+-------+-----------+
26346 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
26347 * +-----------+---+---+-------+-------+-------+-------+-----------+
26350 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26352 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26355 case OPC_MXU_Q8MUL:
26356 case OPC_MXU_Q8MULSU:
26357 gen_mxu_q8mul_q8mulsu(ctx);
26360 MIPS_INVAL("decode_opc_mxu");
26361 generate_exception_end(ctx, EXCP_RI);
26368 * Decode MXU pool20
26370 * 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
26371 * +-----------+---------+-----+-------+-------+-------+-----------+
26372 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
26373 * +-----------+---------+-----+-------+-------+-------+-----------+
26376 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26378 uint32_t opcode = extract32(ctx->opcode, 18, 3);
26381 case OPC_MXU_Q8MOVZ:
26382 /* TODO: Implement emulation of Q8MOVZ instruction. */
26383 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26384 generate_exception_end(ctx, EXCP_RI);
26386 case OPC_MXU_Q8MOVN:
26387 /* TODO: Implement emulation of Q8MOVN instruction. */
26388 MIPS_INVAL("OPC_MXU_Q8MOVN");
26389 generate_exception_end(ctx, EXCP_RI);
26391 case OPC_MXU_D16MOVZ:
26392 /* TODO: Implement emulation of D16MOVZ instruction. */
26393 MIPS_INVAL("OPC_MXU_D16MOVZ");
26394 generate_exception_end(ctx, EXCP_RI);
26396 case OPC_MXU_D16MOVN:
26397 /* TODO: Implement emulation of D16MOVN instruction. */
26398 MIPS_INVAL("OPC_MXU_D16MOVN");
26399 generate_exception_end(ctx, EXCP_RI);
26401 case OPC_MXU_S32MOVZ:
26402 /* TODO: Implement emulation of S32MOVZ instruction. */
26403 MIPS_INVAL("OPC_MXU_S32MOVZ");
26404 generate_exception_end(ctx, EXCP_RI);
26406 case OPC_MXU_S32MOVN:
26407 /* TODO: Implement emulation of S32MOVN instruction. */
26408 MIPS_INVAL("OPC_MXU_S32MOVN");
26409 generate_exception_end(ctx, EXCP_RI);
26412 MIPS_INVAL("decode_opc_mxu");
26413 generate_exception_end(ctx, EXCP_RI);
26420 * Decode MXU pool21
26422 * 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
26423 * +-----------+---+---+-------+-------+-------+-------+-----------+
26424 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
26425 * +-----------+---+---+-------+-------+-------+-------+-----------+
26428 static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26430 uint32_t opcode = extract32(ctx->opcode, 22, 2);
26433 case OPC_MXU_Q8MAC:
26434 /* TODO: Implement emulation of Q8MAC instruction. */
26435 MIPS_INVAL("OPC_MXU_Q8MAC");
26436 generate_exception_end(ctx, EXCP_RI);
26438 case OPC_MXU_Q8MACSU:
26439 /* TODO: Implement emulation of Q8MACSU instruction. */
26440 MIPS_INVAL("OPC_MXU_Q8MACSU");
26441 generate_exception_end(ctx, EXCP_RI);
26444 MIPS_INVAL("decode_opc_mxu");
26445 generate_exception_end(ctx, EXCP_RI);
26452 * Main MXU decoding function
26454 * 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
26455 * +-----------+---------------------------------------+-----------+
26456 * | SPECIAL2 | |x x x x x x|
26457 * +-----------+---------------------------------------+-----------+
26460 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26463 * TODO: Investigate necessity of including handling of
26464 * CLZ, CLO, SDBB in this function, as they belong to
26465 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26467 uint32_t opcode = extract32(ctx->opcode, 0, 6);
26469 if (opcode == OPC__MXU_MUL) {
26470 uint32_t rs, rt, rd, op1;
26472 rs = extract32(ctx->opcode, 21, 5);
26473 rt = extract32(ctx->opcode, 16, 5);
26474 rd = extract32(ctx->opcode, 11, 5);
26475 op1 = MASK_SPECIAL2(ctx->opcode);
26477 gen_arith(ctx, op1, rd, rs, rt);
26482 if (opcode == OPC_MXU_S32M2I) {
26483 gen_mxu_s32m2i(ctx);
26487 if (opcode == OPC_MXU_S32I2M) {
26488 gen_mxu_s32i2m(ctx);
26493 TCGv t_mxu_cr = tcg_temp_new();
26494 TCGLabel *l_exit = gen_new_label();
26496 gen_load_mxu_cr(t_mxu_cr);
26497 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26498 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26501 case OPC_MXU_S32MADD:
26502 /* TODO: Implement emulation of S32MADD instruction. */
26503 MIPS_INVAL("OPC_MXU_S32MADD");
26504 generate_exception_end(ctx, EXCP_RI);
26506 case OPC_MXU_S32MADDU:
26507 /* TODO: Implement emulation of S32MADDU instruction. */
26508 MIPS_INVAL("OPC_MXU_S32MADDU");
26509 generate_exception_end(ctx, EXCP_RI);
26511 case OPC_MXU__POOL00:
26512 decode_opc_mxu__pool00(env, ctx);
26514 case OPC_MXU_S32MSUB:
26515 /* TODO: Implement emulation of S32MSUB instruction. */
26516 MIPS_INVAL("OPC_MXU_S32MSUB");
26517 generate_exception_end(ctx, EXCP_RI);
26519 case OPC_MXU_S32MSUBU:
26520 /* TODO: Implement emulation of S32MSUBU instruction. */
26521 MIPS_INVAL("OPC_MXU_S32MSUBU");
26522 generate_exception_end(ctx, EXCP_RI);
26524 case OPC_MXU__POOL01:
26525 decode_opc_mxu__pool01(env, ctx);
26527 case OPC_MXU__POOL02:
26528 decode_opc_mxu__pool02(env, ctx);
26530 case OPC_MXU_D16MUL:
26531 gen_mxu_d16mul(ctx);
26533 case OPC_MXU__POOL03:
26534 decode_opc_mxu__pool03(env, ctx);
26536 case OPC_MXU_D16MAC:
26537 gen_mxu_d16mac(ctx);
26539 case OPC_MXU_D16MACF:
26540 /* TODO: Implement emulation of D16MACF instruction. */
26541 MIPS_INVAL("OPC_MXU_D16MACF");
26542 generate_exception_end(ctx, EXCP_RI);
26544 case OPC_MXU_D16MADL:
26545 /* TODO: Implement emulation of D16MADL instruction. */
26546 MIPS_INVAL("OPC_MXU_D16MADL");
26547 generate_exception_end(ctx, EXCP_RI);
26549 case OPC_MXU_S16MAD:
26550 /* TODO: Implement emulation of S16MAD instruction. */
26551 MIPS_INVAL("OPC_MXU_S16MAD");
26552 generate_exception_end(ctx, EXCP_RI);
26554 case OPC_MXU_Q16ADD:
26555 /* TODO: Implement emulation of Q16ADD instruction. */
26556 MIPS_INVAL("OPC_MXU_Q16ADD");
26557 generate_exception_end(ctx, EXCP_RI);
26559 case OPC_MXU_D16MACE:
26560 /* TODO: Implement emulation of D16MACE instruction. */
26561 MIPS_INVAL("OPC_MXU_D16MACE");
26562 generate_exception_end(ctx, EXCP_RI);
26564 case OPC_MXU__POOL04:
26565 decode_opc_mxu__pool04(env, ctx);
26567 case OPC_MXU__POOL05:
26568 decode_opc_mxu__pool05(env, ctx);
26570 case OPC_MXU__POOL06:
26571 decode_opc_mxu__pool06(env, ctx);
26573 case OPC_MXU__POOL07:
26574 decode_opc_mxu__pool07(env, ctx);
26576 case OPC_MXU__POOL08:
26577 decode_opc_mxu__pool08(env, ctx);
26579 case OPC_MXU__POOL09:
26580 decode_opc_mxu__pool09(env, ctx);
26582 case OPC_MXU__POOL10:
26583 decode_opc_mxu__pool10(env, ctx);
26585 case OPC_MXU__POOL11:
26586 decode_opc_mxu__pool11(env, ctx);
26588 case OPC_MXU_D32ADD:
26589 /* TODO: Implement emulation of D32ADD instruction. */
26590 MIPS_INVAL("OPC_MXU_D32ADD");
26591 generate_exception_end(ctx, EXCP_RI);
26593 case OPC_MXU__POOL12:
26594 decode_opc_mxu__pool12(env, ctx);
26596 case OPC_MXU__POOL13:
26597 decode_opc_mxu__pool13(env, ctx);
26599 case OPC_MXU__POOL14:
26600 decode_opc_mxu__pool14(env, ctx);
26602 case OPC_MXU_Q8ACCE:
26603 /* TODO: Implement emulation of Q8ACCE instruction. */
26604 MIPS_INVAL("OPC_MXU_Q8ACCE");
26605 generate_exception_end(ctx, EXCP_RI);
26607 case OPC_MXU_S8LDD:
26608 gen_mxu_s8ldd(ctx);
26610 case OPC_MXU_S8STD:
26611 /* TODO: Implement emulation of S8STD instruction. */
26612 MIPS_INVAL("OPC_MXU_S8STD");
26613 generate_exception_end(ctx, EXCP_RI);
26615 case OPC_MXU_S8LDI:
26616 /* TODO: Implement emulation of S8LDI instruction. */
26617 MIPS_INVAL("OPC_MXU_S8LDI");
26618 generate_exception_end(ctx, EXCP_RI);
26620 case OPC_MXU_S8SDI:
26621 /* TODO: Implement emulation of S8SDI instruction. */
26622 MIPS_INVAL("OPC_MXU_S8SDI");
26623 generate_exception_end(ctx, EXCP_RI);
26625 case OPC_MXU__POOL15:
26626 decode_opc_mxu__pool15(env, ctx);
26628 case OPC_MXU__POOL16:
26629 decode_opc_mxu__pool16(env, ctx);
26631 case OPC_MXU__POOL17:
26632 decode_opc_mxu__pool17(env, ctx);
26634 case OPC_MXU_S16LDD:
26635 /* TODO: Implement emulation of S16LDD instruction. */
26636 MIPS_INVAL("OPC_MXU_S16LDD");
26637 generate_exception_end(ctx, EXCP_RI);
26639 case OPC_MXU_S16STD:
26640 /* TODO: Implement emulation of S16STD instruction. */
26641 MIPS_INVAL("OPC_MXU_S16STD");
26642 generate_exception_end(ctx, EXCP_RI);
26644 case OPC_MXU_S16LDI:
26645 /* TODO: Implement emulation of S16LDI instruction. */
26646 MIPS_INVAL("OPC_MXU_S16LDI");
26647 generate_exception_end(ctx, EXCP_RI);
26649 case OPC_MXU_S16SDI:
26650 /* TODO: Implement emulation of S16SDI instruction. */
26651 MIPS_INVAL("OPC_MXU_S16SDI");
26652 generate_exception_end(ctx, EXCP_RI);
26654 case OPC_MXU_D32SLL:
26655 /* TODO: Implement emulation of D32SLL instruction. */
26656 MIPS_INVAL("OPC_MXU_D32SLL");
26657 generate_exception_end(ctx, EXCP_RI);
26659 case OPC_MXU_D32SLR:
26660 /* TODO: Implement emulation of D32SLR instruction. */
26661 MIPS_INVAL("OPC_MXU_D32SLR");
26662 generate_exception_end(ctx, EXCP_RI);
26664 case OPC_MXU_D32SARL:
26665 /* TODO: Implement emulation of D32SARL instruction. */
26666 MIPS_INVAL("OPC_MXU_D32SARL");
26667 generate_exception_end(ctx, EXCP_RI);
26669 case OPC_MXU_D32SAR:
26670 /* TODO: Implement emulation of D32SAR instruction. */
26671 MIPS_INVAL("OPC_MXU_D32SAR");
26672 generate_exception_end(ctx, EXCP_RI);
26674 case OPC_MXU_Q16SLL:
26675 /* TODO: Implement emulation of Q16SLL instruction. */
26676 MIPS_INVAL("OPC_MXU_Q16SLL");
26677 generate_exception_end(ctx, EXCP_RI);
26679 case OPC_MXU_Q16SLR:
26680 /* TODO: Implement emulation of Q16SLR instruction. */
26681 MIPS_INVAL("OPC_MXU_Q16SLR");
26682 generate_exception_end(ctx, EXCP_RI);
26684 case OPC_MXU__POOL18:
26685 decode_opc_mxu__pool18(env, ctx);
26687 case OPC_MXU_Q16SAR:
26688 /* TODO: Implement emulation of Q16SAR instruction. */
26689 MIPS_INVAL("OPC_MXU_Q16SAR");
26690 generate_exception_end(ctx, EXCP_RI);
26692 case OPC_MXU__POOL19:
26693 decode_opc_mxu__pool19(env, ctx);
26695 case OPC_MXU__POOL20:
26696 decode_opc_mxu__pool20(env, ctx);
26698 case OPC_MXU__POOL21:
26699 decode_opc_mxu__pool21(env, ctx);
26701 case OPC_MXU_Q16SCOP:
26702 /* TODO: Implement emulation of Q16SCOP instruction. */
26703 MIPS_INVAL("OPC_MXU_Q16SCOP");
26704 generate_exception_end(ctx, EXCP_RI);
26706 case OPC_MXU_Q8MADL:
26707 /* TODO: Implement emulation of Q8MADL instruction. */
26708 MIPS_INVAL("OPC_MXU_Q8MADL");
26709 generate_exception_end(ctx, EXCP_RI);
26711 case OPC_MXU_S32SFL:
26712 /* TODO: Implement emulation of S32SFL instruction. */
26713 MIPS_INVAL("OPC_MXU_S32SFL");
26714 generate_exception_end(ctx, EXCP_RI);
26716 case OPC_MXU_Q8SAD:
26717 /* TODO: Implement emulation of Q8SAD instruction. */
26718 MIPS_INVAL("OPC_MXU_Q8SAD");
26719 generate_exception_end(ctx, EXCP_RI);
26722 MIPS_INVAL("decode_opc_mxu");
26723 generate_exception_end(ctx, EXCP_RI);
26726 gen_set_label(l_exit);
26727 tcg_temp_free(t_mxu_cr);
26731 #endif /* !defined(TARGET_MIPS64) */
26734 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26739 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26741 rs = (ctx->opcode >> 21) & 0x1f;
26742 rt = (ctx->opcode >> 16) & 0x1f;
26743 rd = (ctx->opcode >> 11) & 0x1f;
26745 op1 = MASK_SPECIAL2(ctx->opcode);
26747 case OPC_MADD: /* Multiply and add/sub */
26751 check_insn(ctx, ISA_MIPS32);
26752 gen_muldiv(ctx, op1, rd & 3, rs, rt);
26755 gen_arith(ctx, op1, rd, rs, rt);
26758 case OPC_DIVU_G_2F:
26759 case OPC_MULT_G_2F:
26760 case OPC_MULTU_G_2F:
26762 case OPC_MODU_G_2F:
26763 check_insn(ctx, INSN_LOONGSON2F);
26764 gen_loongson_integer(ctx, op1, rd, rs, rt);
26768 check_insn(ctx, ISA_MIPS32);
26769 gen_cl(ctx, op1, rd, rs);
26772 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26773 gen_helper_do_semihosting(cpu_env);
26775 /* XXX: not clear which exception should be raised
26776 * when in debug mode...
26778 check_insn(ctx, ISA_MIPS32);
26779 generate_exception_end(ctx, EXCP_DBp);
26782 #if defined(TARGET_MIPS64)
26785 check_insn(ctx, ISA_MIPS64);
26786 check_mips_64(ctx);
26787 gen_cl(ctx, op1, rd, rs);
26789 case OPC_DMULT_G_2F:
26790 case OPC_DMULTU_G_2F:
26791 case OPC_DDIV_G_2F:
26792 case OPC_DDIVU_G_2F:
26793 case OPC_DMOD_G_2F:
26794 case OPC_DMODU_G_2F:
26795 check_insn(ctx, INSN_LOONGSON2F);
26796 gen_loongson_integer(ctx, op1, rd, rs, rt);
26799 default: /* Invalid */
26800 MIPS_INVAL("special2_legacy");
26801 generate_exception_end(ctx, EXCP_RI);
26806 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26808 int rs, rt, rd, sa;
26812 rs = (ctx->opcode >> 21) & 0x1f;
26813 rt = (ctx->opcode >> 16) & 0x1f;
26814 rd = (ctx->opcode >> 11) & 0x1f;
26815 sa = (ctx->opcode >> 6) & 0x1f;
26816 imm = (int16_t)ctx->opcode >> 7;
26818 op1 = MASK_SPECIAL3(ctx->opcode);
26822 /* hint codes 24-31 are reserved and signal RI */
26823 generate_exception_end(ctx, EXCP_RI);
26825 /* Treat as NOP. */
26828 check_cp0_enabled(ctx);
26829 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26830 gen_cache_operation(ctx, rt, rs, imm);
26834 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
26837 gen_ld(ctx, op1, rt, rs, imm);
26842 /* Treat as NOP. */
26845 op2 = MASK_BSHFL(ctx->opcode);
26851 gen_align(ctx, 32, rd, rs, rt, sa & 3);
26854 gen_bitswap(ctx, op2, rd, rt);
26859 #if defined(TARGET_MIPS64)
26861 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
26864 gen_ld(ctx, op1, rt, rs, imm);
26867 check_mips_64(ctx);
26870 /* Treat as NOP. */
26873 op2 = MASK_DBSHFL(ctx->opcode);
26883 gen_align(ctx, 64, rd, rs, rt, sa & 7);
26886 gen_bitswap(ctx, op2, rd, rt);
26893 default: /* Invalid */
26894 MIPS_INVAL("special3_r6");
26895 generate_exception_end(ctx, EXCP_RI);
26900 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
26905 rs = (ctx->opcode >> 21) & 0x1f;
26906 rt = (ctx->opcode >> 16) & 0x1f;
26907 rd = (ctx->opcode >> 11) & 0x1f;
26909 op1 = MASK_SPECIAL3(ctx->opcode);
26912 case OPC_DIVU_G_2E:
26914 case OPC_MODU_G_2E:
26915 case OPC_MULT_G_2E:
26916 case OPC_MULTU_G_2E:
26917 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26918 * the same mask and op1. */
26919 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
26920 op2 = MASK_ADDUH_QB(ctx->opcode);
26923 case OPC_ADDUH_R_QB:
26925 case OPC_ADDQH_R_PH:
26927 case OPC_ADDQH_R_W:
26929 case OPC_SUBUH_R_QB:
26931 case OPC_SUBQH_R_PH:
26933 case OPC_SUBQH_R_W:
26934 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26939 case OPC_MULQ_RS_W:
26940 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26943 MIPS_INVAL("MASK ADDUH.QB");
26944 generate_exception_end(ctx, EXCP_RI);
26947 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
26948 gen_loongson_integer(ctx, op1, rd, rs, rt);
26950 generate_exception_end(ctx, EXCP_RI);
26954 op2 = MASK_LX(ctx->opcode);
26956 #if defined(TARGET_MIPS64)
26962 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26964 default: /* Invalid */
26965 MIPS_INVAL("MASK LX");
26966 generate_exception_end(ctx, EXCP_RI);
26970 case OPC_ABSQ_S_PH_DSP:
26971 op2 = MASK_ABSQ_S_PH(ctx->opcode);
26973 case OPC_ABSQ_S_QB:
26974 case OPC_ABSQ_S_PH:
26976 case OPC_PRECEQ_W_PHL:
26977 case OPC_PRECEQ_W_PHR:
26978 case OPC_PRECEQU_PH_QBL:
26979 case OPC_PRECEQU_PH_QBR:
26980 case OPC_PRECEQU_PH_QBLA:
26981 case OPC_PRECEQU_PH_QBRA:
26982 case OPC_PRECEU_PH_QBL:
26983 case OPC_PRECEU_PH_QBR:
26984 case OPC_PRECEU_PH_QBLA:
26985 case OPC_PRECEU_PH_QBRA:
26986 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26993 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26996 MIPS_INVAL("MASK ABSQ_S.PH");
26997 generate_exception_end(ctx, EXCP_RI);
27001 case OPC_ADDU_QB_DSP:
27002 op2 = MASK_ADDU_QB(ctx->opcode);
27005 case OPC_ADDQ_S_PH:
27008 case OPC_ADDU_S_QB:
27010 case OPC_ADDU_S_PH:
27012 case OPC_SUBQ_S_PH:
27015 case OPC_SUBU_S_QB:
27017 case OPC_SUBU_S_PH:
27021 case OPC_RADDU_W_QB:
27022 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27024 case OPC_MULEU_S_PH_QBL:
27025 case OPC_MULEU_S_PH_QBR:
27026 case OPC_MULQ_RS_PH:
27027 case OPC_MULEQ_S_W_PHL:
27028 case OPC_MULEQ_S_W_PHR:
27029 case OPC_MULQ_S_PH:
27030 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27032 default: /* Invalid */
27033 MIPS_INVAL("MASK ADDU.QB");
27034 generate_exception_end(ctx, EXCP_RI);
27039 case OPC_CMPU_EQ_QB_DSP:
27040 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
27042 case OPC_PRECR_SRA_PH_W:
27043 case OPC_PRECR_SRA_R_PH_W:
27044 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27046 case OPC_PRECR_QB_PH:
27047 case OPC_PRECRQ_QB_PH:
27048 case OPC_PRECRQ_PH_W:
27049 case OPC_PRECRQ_RS_PH_W:
27050 case OPC_PRECRQU_S_QB_PH:
27051 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27053 case OPC_CMPU_EQ_QB:
27054 case OPC_CMPU_LT_QB:
27055 case OPC_CMPU_LE_QB:
27056 case OPC_CMP_EQ_PH:
27057 case OPC_CMP_LT_PH:
27058 case OPC_CMP_LE_PH:
27059 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27061 case OPC_CMPGU_EQ_QB:
27062 case OPC_CMPGU_LT_QB:
27063 case OPC_CMPGU_LE_QB:
27064 case OPC_CMPGDU_EQ_QB:
27065 case OPC_CMPGDU_LT_QB:
27066 case OPC_CMPGDU_LE_QB:
27069 case OPC_PACKRL_PH:
27070 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27072 default: /* Invalid */
27073 MIPS_INVAL("MASK CMPU.EQ.QB");
27074 generate_exception_end(ctx, EXCP_RI);
27078 case OPC_SHLL_QB_DSP:
27079 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27081 case OPC_DPA_W_PH_DSP:
27082 op2 = MASK_DPA_W_PH(ctx->opcode);
27084 case OPC_DPAU_H_QBL:
27085 case OPC_DPAU_H_QBR:
27086 case OPC_DPSU_H_QBL:
27087 case OPC_DPSU_H_QBR:
27089 case OPC_DPAX_W_PH:
27090 case OPC_DPAQ_S_W_PH:
27091 case OPC_DPAQX_S_W_PH:
27092 case OPC_DPAQX_SA_W_PH:
27094 case OPC_DPSX_W_PH:
27095 case OPC_DPSQ_S_W_PH:
27096 case OPC_DPSQX_S_W_PH:
27097 case OPC_DPSQX_SA_W_PH:
27098 case OPC_MULSAQ_S_W_PH:
27099 case OPC_DPAQ_SA_L_W:
27100 case OPC_DPSQ_SA_L_W:
27101 case OPC_MAQ_S_W_PHL:
27102 case OPC_MAQ_S_W_PHR:
27103 case OPC_MAQ_SA_W_PHL:
27104 case OPC_MAQ_SA_W_PHR:
27105 case OPC_MULSA_W_PH:
27106 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27108 default: /* Invalid */
27109 MIPS_INVAL("MASK DPAW.PH");
27110 generate_exception_end(ctx, EXCP_RI);
27115 op2 = MASK_INSV(ctx->opcode);
27126 t0 = tcg_temp_new();
27127 t1 = tcg_temp_new();
27129 gen_load_gpr(t0, rt);
27130 gen_load_gpr(t1, rs);
27132 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
27138 default: /* Invalid */
27139 MIPS_INVAL("MASK INSV");
27140 generate_exception_end(ctx, EXCP_RI);
27144 case OPC_APPEND_DSP:
27145 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27147 case OPC_EXTR_W_DSP:
27148 op2 = MASK_EXTR_W(ctx->opcode);
27152 case OPC_EXTR_RS_W:
27154 case OPC_EXTRV_S_H:
27156 case OPC_EXTRV_R_W:
27157 case OPC_EXTRV_RS_W:
27162 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27165 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27171 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27173 default: /* Invalid */
27174 MIPS_INVAL("MASK EXTR.W");
27175 generate_exception_end(ctx, EXCP_RI);
27179 #if defined(TARGET_MIPS64)
27180 case OPC_DDIV_G_2E:
27181 case OPC_DDIVU_G_2E:
27182 case OPC_DMULT_G_2E:
27183 case OPC_DMULTU_G_2E:
27184 case OPC_DMOD_G_2E:
27185 case OPC_DMODU_G_2E:
27186 check_insn(ctx, INSN_LOONGSON2E);
27187 gen_loongson_integer(ctx, op1, rd, rs, rt);
27189 case OPC_ABSQ_S_QH_DSP:
27190 op2 = MASK_ABSQ_S_QH(ctx->opcode);
27192 case OPC_PRECEQ_L_PWL:
27193 case OPC_PRECEQ_L_PWR:
27194 case OPC_PRECEQ_PW_QHL:
27195 case OPC_PRECEQ_PW_QHR:
27196 case OPC_PRECEQ_PW_QHLA:
27197 case OPC_PRECEQ_PW_QHRA:
27198 case OPC_PRECEQU_QH_OBL:
27199 case OPC_PRECEQU_QH_OBR:
27200 case OPC_PRECEQU_QH_OBLA:
27201 case OPC_PRECEQU_QH_OBRA:
27202 case OPC_PRECEU_QH_OBL:
27203 case OPC_PRECEU_QH_OBR:
27204 case OPC_PRECEU_QH_OBLA:
27205 case OPC_PRECEU_QH_OBRA:
27206 case OPC_ABSQ_S_OB:
27207 case OPC_ABSQ_S_PW:
27208 case OPC_ABSQ_S_QH:
27209 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27217 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27219 default: /* Invalid */
27220 MIPS_INVAL("MASK ABSQ_S.QH");
27221 generate_exception_end(ctx, EXCP_RI);
27225 case OPC_ADDU_OB_DSP:
27226 op2 = MASK_ADDU_OB(ctx->opcode);
27228 case OPC_RADDU_L_OB:
27230 case OPC_SUBQ_S_PW:
27232 case OPC_SUBQ_S_QH:
27234 case OPC_SUBU_S_OB:
27236 case OPC_SUBU_S_QH:
27238 case OPC_SUBUH_R_OB:
27240 case OPC_ADDQ_S_PW:
27242 case OPC_ADDQ_S_QH:
27244 case OPC_ADDU_S_OB:
27246 case OPC_ADDU_S_QH:
27248 case OPC_ADDUH_R_OB:
27249 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27251 case OPC_MULEQ_S_PW_QHL:
27252 case OPC_MULEQ_S_PW_QHR:
27253 case OPC_MULEU_S_QH_OBL:
27254 case OPC_MULEU_S_QH_OBR:
27255 case OPC_MULQ_RS_QH:
27256 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27258 default: /* Invalid */
27259 MIPS_INVAL("MASK ADDU.OB");
27260 generate_exception_end(ctx, EXCP_RI);
27264 case OPC_CMPU_EQ_OB_DSP:
27265 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27267 case OPC_PRECR_SRA_QH_PW:
27268 case OPC_PRECR_SRA_R_QH_PW:
27269 /* Return value is rt. */
27270 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27272 case OPC_PRECR_OB_QH:
27273 case OPC_PRECRQ_OB_QH:
27274 case OPC_PRECRQ_PW_L:
27275 case OPC_PRECRQ_QH_PW:
27276 case OPC_PRECRQ_RS_QH_PW:
27277 case OPC_PRECRQU_S_OB_QH:
27278 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27280 case OPC_CMPU_EQ_OB:
27281 case OPC_CMPU_LT_OB:
27282 case OPC_CMPU_LE_OB:
27283 case OPC_CMP_EQ_QH:
27284 case OPC_CMP_LT_QH:
27285 case OPC_CMP_LE_QH:
27286 case OPC_CMP_EQ_PW:
27287 case OPC_CMP_LT_PW:
27288 case OPC_CMP_LE_PW:
27289 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27291 case OPC_CMPGDU_EQ_OB:
27292 case OPC_CMPGDU_LT_OB:
27293 case OPC_CMPGDU_LE_OB:
27294 case OPC_CMPGU_EQ_OB:
27295 case OPC_CMPGU_LT_OB:
27296 case OPC_CMPGU_LE_OB:
27297 case OPC_PACKRL_PW:
27301 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27303 default: /* Invalid */
27304 MIPS_INVAL("MASK CMPU_EQ.OB");
27305 generate_exception_end(ctx, EXCP_RI);
27309 case OPC_DAPPEND_DSP:
27310 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27312 case OPC_DEXTR_W_DSP:
27313 op2 = MASK_DEXTR_W(ctx->opcode);
27320 case OPC_DEXTR_R_L:
27321 case OPC_DEXTR_RS_L:
27323 case OPC_DEXTR_R_W:
27324 case OPC_DEXTR_RS_W:
27325 case OPC_DEXTR_S_H:
27327 case OPC_DEXTRV_R_L:
27328 case OPC_DEXTRV_RS_L:
27329 case OPC_DEXTRV_S_H:
27331 case OPC_DEXTRV_R_W:
27332 case OPC_DEXTRV_RS_W:
27333 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27338 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27340 default: /* Invalid */
27341 MIPS_INVAL("MASK EXTR.W");
27342 generate_exception_end(ctx, EXCP_RI);
27346 case OPC_DPAQ_W_QH_DSP:
27347 op2 = MASK_DPAQ_W_QH(ctx->opcode);
27349 case OPC_DPAU_H_OBL:
27350 case OPC_DPAU_H_OBR:
27351 case OPC_DPSU_H_OBL:
27352 case OPC_DPSU_H_OBR:
27354 case OPC_DPAQ_S_W_QH:
27356 case OPC_DPSQ_S_W_QH:
27357 case OPC_MULSAQ_S_W_QH:
27358 case OPC_DPAQ_SA_L_PW:
27359 case OPC_DPSQ_SA_L_PW:
27360 case OPC_MULSAQ_S_L_PW:
27361 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27363 case OPC_MAQ_S_W_QHLL:
27364 case OPC_MAQ_S_W_QHLR:
27365 case OPC_MAQ_S_W_QHRL:
27366 case OPC_MAQ_S_W_QHRR:
27367 case OPC_MAQ_SA_W_QHLL:
27368 case OPC_MAQ_SA_W_QHLR:
27369 case OPC_MAQ_SA_W_QHRL:
27370 case OPC_MAQ_SA_W_QHRR:
27371 case OPC_MAQ_S_L_PWL:
27372 case OPC_MAQ_S_L_PWR:
27377 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27379 default: /* Invalid */
27380 MIPS_INVAL("MASK DPAQ.W.QH");
27381 generate_exception_end(ctx, EXCP_RI);
27385 case OPC_DINSV_DSP:
27386 op2 = MASK_INSV(ctx->opcode);
27397 t0 = tcg_temp_new();
27398 t1 = tcg_temp_new();
27400 gen_load_gpr(t0, rt);
27401 gen_load_gpr(t1, rs);
27403 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27409 default: /* Invalid */
27410 MIPS_INVAL("MASK DINSV");
27411 generate_exception_end(ctx, EXCP_RI);
27415 case OPC_SHLL_OB_DSP:
27416 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27419 default: /* Invalid */
27420 MIPS_INVAL("special3_legacy");
27421 generate_exception_end(ctx, EXCP_RI);
27427 #if defined(TARGET_MIPS64)
27429 static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27431 uint32_t opc = MASK_MMI0(ctx->opcode);
27434 case MMI_OPC_0_PADDW: /* TODO: MMI_OPC_0_PADDW */
27435 case MMI_OPC_0_PSUBW: /* TODO: MMI_OPC_0_PSUBW */
27436 case MMI_OPC_0_PCGTW: /* TODO: MMI_OPC_0_PCGTW */
27437 case MMI_OPC_0_PMAXW: /* TODO: MMI_OPC_0_PMAXW */
27438 case MMI_OPC_0_PADDH: /* TODO: MMI_OPC_0_PADDH */
27439 case MMI_OPC_0_PSUBH: /* TODO: MMI_OPC_0_PSUBH */
27440 case MMI_OPC_0_PCGTH: /* TODO: MMI_OPC_0_PCGTH */
27441 case MMI_OPC_0_PMAXH: /* TODO: MMI_OPC_0_PMAXH */
27442 case MMI_OPC_0_PADDB: /* TODO: MMI_OPC_0_PADDB */
27443 case MMI_OPC_0_PSUBB: /* TODO: MMI_OPC_0_PSUBB */
27444 case MMI_OPC_0_PCGTB: /* TODO: MMI_OPC_0_PCGTB */
27445 case MMI_OPC_0_PADDSW: /* TODO: MMI_OPC_0_PADDSW */
27446 case MMI_OPC_0_PSUBSW: /* TODO: MMI_OPC_0_PSUBSW */
27447 case MMI_OPC_0_PEXTLW: /* TODO: MMI_OPC_0_PEXTLW */
27448 case MMI_OPC_0_PPACW: /* TODO: MMI_OPC_0_PPACW */
27449 case MMI_OPC_0_PADDSH: /* TODO: MMI_OPC_0_PADDSH */
27450 case MMI_OPC_0_PSUBSH: /* TODO: MMI_OPC_0_PSUBSH */
27451 case MMI_OPC_0_PEXTLH: /* TODO: MMI_OPC_0_PEXTLH */
27452 case MMI_OPC_0_PPACH: /* TODO: MMI_OPC_0_PPACH */
27453 case MMI_OPC_0_PADDSB: /* TODO: MMI_OPC_0_PADDSB */
27454 case MMI_OPC_0_PSUBSB: /* TODO: MMI_OPC_0_PSUBSB */
27455 case MMI_OPC_0_PEXTLB: /* TODO: MMI_OPC_0_PEXTLB */
27456 case MMI_OPC_0_PPACB: /* TODO: MMI_OPC_0_PPACB */
27457 case MMI_OPC_0_PEXT5: /* TODO: MMI_OPC_0_PEXT5 */
27458 case MMI_OPC_0_PPAC5: /* TODO: MMI_OPC_0_PPAC5 */
27459 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27462 MIPS_INVAL("TX79 MMI class MMI0");
27463 generate_exception_end(ctx, EXCP_RI);
27468 static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27470 uint32_t opc = MASK_MMI1(ctx->opcode);
27473 case MMI_OPC_1_PABSW: /* TODO: MMI_OPC_1_PABSW */
27474 case MMI_OPC_1_PCEQW: /* TODO: MMI_OPC_1_PCEQW */
27475 case MMI_OPC_1_PMINW: /* TODO: MMI_OPC_1_PMINW */
27476 case MMI_OPC_1_PADSBH: /* TODO: MMI_OPC_1_PADSBH */
27477 case MMI_OPC_1_PABSH: /* TODO: MMI_OPC_1_PABSH */
27478 case MMI_OPC_1_PCEQH: /* TODO: MMI_OPC_1_PCEQH */
27479 case MMI_OPC_1_PMINH: /* TODO: MMI_OPC_1_PMINH */
27480 case MMI_OPC_1_PCEQB: /* TODO: MMI_OPC_1_PCEQB */
27481 case MMI_OPC_1_PADDUW: /* TODO: MMI_OPC_1_PADDUW */
27482 case MMI_OPC_1_PSUBUW: /* TODO: MMI_OPC_1_PSUBUW */
27483 case MMI_OPC_1_PEXTUW: /* TODO: MMI_OPC_1_PEXTUW */
27484 case MMI_OPC_1_PADDUH: /* TODO: MMI_OPC_1_PADDUH */
27485 case MMI_OPC_1_PSUBUH: /* TODO: MMI_OPC_1_PSUBUH */
27486 case MMI_OPC_1_PEXTUH: /* TODO: MMI_OPC_1_PEXTUH */
27487 case MMI_OPC_1_PADDUB: /* TODO: MMI_OPC_1_PADDUB */
27488 case MMI_OPC_1_PSUBUB: /* TODO: MMI_OPC_1_PSUBUB */
27489 case MMI_OPC_1_PEXTUB: /* TODO: MMI_OPC_1_PEXTUB */
27490 case MMI_OPC_1_QFSRV: /* TODO: MMI_OPC_1_QFSRV */
27491 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27494 MIPS_INVAL("TX79 MMI class MMI1");
27495 generate_exception_end(ctx, EXCP_RI);
27500 static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27502 uint32_t opc = MASK_MMI2(ctx->opcode);
27505 case MMI_OPC_2_PMADDW: /* TODO: MMI_OPC_2_PMADDW */
27506 case MMI_OPC_2_PSLLVW: /* TODO: MMI_OPC_2_PSLLVW */
27507 case MMI_OPC_2_PSRLVW: /* TODO: MMI_OPC_2_PSRLVW */
27508 case MMI_OPC_2_PMSUBW: /* TODO: MMI_OPC_2_PMSUBW */
27509 case MMI_OPC_2_PMFHI: /* TODO: MMI_OPC_2_PMFHI */
27510 case MMI_OPC_2_PMFLO: /* TODO: MMI_OPC_2_PMFLO */
27511 case MMI_OPC_2_PINTH: /* TODO: MMI_OPC_2_PINTH */
27512 case MMI_OPC_2_PMULTW: /* TODO: MMI_OPC_2_PMULTW */
27513 case MMI_OPC_2_PDIVW: /* TODO: MMI_OPC_2_PDIVW */
27514 case MMI_OPC_2_PMADDH: /* TODO: MMI_OPC_2_PMADDH */
27515 case MMI_OPC_2_PHMADH: /* TODO: MMI_OPC_2_PHMADH */
27516 case MMI_OPC_2_PAND: /* TODO: MMI_OPC_2_PAND */
27517 case MMI_OPC_2_PXOR: /* TODO: MMI_OPC_2_PXOR */
27518 case MMI_OPC_2_PMSUBH: /* TODO: MMI_OPC_2_PMSUBH */
27519 case MMI_OPC_2_PHMSBH: /* TODO: MMI_OPC_2_PHMSBH */
27520 case MMI_OPC_2_PEXEH: /* TODO: MMI_OPC_2_PEXEH */
27521 case MMI_OPC_2_PREVH: /* TODO: MMI_OPC_2_PREVH */
27522 case MMI_OPC_2_PMULTH: /* TODO: MMI_OPC_2_PMULTH */
27523 case MMI_OPC_2_PDIVBW: /* TODO: MMI_OPC_2_PDIVBW */
27524 case MMI_OPC_2_PEXEW: /* TODO: MMI_OPC_2_PEXEW */
27525 case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */
27526 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27528 case MMI_OPC_2_PCPYLD:
27529 gen_mmi_pcpyld(ctx);
27532 MIPS_INVAL("TX79 MMI class MMI2");
27533 generate_exception_end(ctx, EXCP_RI);
27538 static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27540 uint32_t opc = MASK_MMI3(ctx->opcode);
27543 case MMI_OPC_3_PMADDUW: /* TODO: MMI_OPC_3_PMADDUW */
27544 case MMI_OPC_3_PSRAVW: /* TODO: MMI_OPC_3_PSRAVW */
27545 case MMI_OPC_3_PMTHI: /* TODO: MMI_OPC_3_PMTHI */
27546 case MMI_OPC_3_PMTLO: /* TODO: MMI_OPC_3_PMTLO */
27547 case MMI_OPC_3_PINTEH: /* TODO: MMI_OPC_3_PINTEH */
27548 case MMI_OPC_3_PMULTUW: /* TODO: MMI_OPC_3_PMULTUW */
27549 case MMI_OPC_3_PDIVUW: /* TODO: MMI_OPC_3_PDIVUW */
27550 case MMI_OPC_3_POR: /* TODO: MMI_OPC_3_POR */
27551 case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */
27552 case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */
27553 case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */
27554 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27556 case MMI_OPC_3_PCPYH:
27557 gen_mmi_pcpyh(ctx);
27559 case MMI_OPC_3_PCPYUD:
27560 gen_mmi_pcpyud(ctx);
27563 MIPS_INVAL("TX79 MMI class MMI3");
27564 generate_exception_end(ctx, EXCP_RI);
27569 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27571 uint32_t opc = MASK_MMI(ctx->opcode);
27572 int rs = extract32(ctx->opcode, 21, 5);
27573 int rt = extract32(ctx->opcode, 16, 5);
27574 int rd = extract32(ctx->opcode, 11, 5);
27577 case MMI_OPC_CLASS_MMI0:
27578 decode_mmi0(env, ctx);
27580 case MMI_OPC_CLASS_MMI1:
27581 decode_mmi1(env, ctx);
27583 case MMI_OPC_CLASS_MMI2:
27584 decode_mmi2(env, ctx);
27586 case MMI_OPC_CLASS_MMI3:
27587 decode_mmi3(env, ctx);
27589 case MMI_OPC_MULT1:
27590 case MMI_OPC_MULTU1:
27592 case MMI_OPC_MADDU:
27593 case MMI_OPC_MADD1:
27594 case MMI_OPC_MADDU1:
27595 gen_mul_txx9(ctx, opc, rd, rs, rt);
27598 case MMI_OPC_DIVU1:
27599 gen_div1_tx79(ctx, opc, rs, rt);
27601 case MMI_OPC_MTLO1:
27602 case MMI_OPC_MTHI1:
27603 gen_HILO1_tx79(ctx, opc, rs);
27605 case MMI_OPC_MFLO1:
27606 case MMI_OPC_MFHI1:
27607 gen_HILO1_tx79(ctx, opc, rd);
27609 case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */
27610 case MMI_OPC_PMFHL: /* TODO: MMI_OPC_PMFHL */
27611 case MMI_OPC_PMTHL: /* TODO: MMI_OPC_PMTHL */
27612 case MMI_OPC_PSLLH: /* TODO: MMI_OPC_PSLLH */
27613 case MMI_OPC_PSRLH: /* TODO: MMI_OPC_PSRLH */
27614 case MMI_OPC_PSRAH: /* TODO: MMI_OPC_PSRAH */
27615 case MMI_OPC_PSLLW: /* TODO: MMI_OPC_PSLLW */
27616 case MMI_OPC_PSRLW: /* TODO: MMI_OPC_PSRLW */
27617 case MMI_OPC_PSRAW: /* TODO: MMI_OPC_PSRAW */
27618 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI */
27621 MIPS_INVAL("TX79 MMI class");
27622 generate_exception_end(ctx, EXCP_RI);
27627 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27629 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_LQ */
27632 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27634 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_SQ */
27638 * The TX79-specific instruction Store Quadword
27640 * +--------+-------+-------+------------------------+
27641 * | 011111 | base | rt | offset | SQ
27642 * +--------+-------+-------+------------------------+
27645 * has the same opcode as the Read Hardware Register instruction
27647 * +--------+-------+-------+-------+-------+--------+
27648 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
27649 * +--------+-------+-------+-------+-------+--------+
27652 * that is required, trapped and emulated by the Linux kernel. However, all
27653 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27654 * offset is odd. Therefore all valid SQ instructions can execute normally.
27655 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27656 * between SQ and RDHWR, as the Linux kernel does.
27658 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27660 int base = extract32(ctx->opcode, 21, 5);
27661 int rt = extract32(ctx->opcode, 16, 5);
27662 int offset = extract32(ctx->opcode, 0, 16);
27664 #ifdef CONFIG_USER_ONLY
27665 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27666 uint32_t op2 = extract32(ctx->opcode, 6, 5);
27668 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27669 int rd = extract32(ctx->opcode, 11, 5);
27671 gen_rdhwr(ctx, rt, rd, 0);
27676 gen_mmi_sq(ctx, base, rt, offset);
27681 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27683 int rs, rt, rd, sa;
27687 rs = (ctx->opcode >> 21) & 0x1f;
27688 rt = (ctx->opcode >> 16) & 0x1f;
27689 rd = (ctx->opcode >> 11) & 0x1f;
27690 sa = (ctx->opcode >> 6) & 0x1f;
27691 imm = sextract32(ctx->opcode, 7, 9);
27693 op1 = MASK_SPECIAL3(ctx->opcode);
27696 * EVA loads and stores overlap Loongson 2E instructions decoded by
27697 * decode_opc_special3_legacy(), so be careful to allow their decoding when
27704 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27712 check_cp0_enabled(ctx);
27713 gen_ld(ctx, op1, rt, rs, imm);
27717 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27722 check_cp0_enabled(ctx);
27723 gen_st(ctx, op1, rt, rs, imm);
27726 check_cp0_enabled(ctx);
27727 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
27730 check_cp0_enabled(ctx);
27731 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27732 gen_cache_operation(ctx, rt, rs, imm);
27734 /* Treat as NOP. */
27737 check_cp0_enabled(ctx);
27738 /* Treat as NOP. */
27746 check_insn(ctx, ISA_MIPS32R2);
27747 gen_bitops(ctx, op1, rt, rs, sa, rd);
27750 op2 = MASK_BSHFL(ctx->opcode);
27757 check_insn(ctx, ISA_MIPS32R6);
27758 decode_opc_special3_r6(env, ctx);
27761 check_insn(ctx, ISA_MIPS32R2);
27762 gen_bshfl(ctx, op2, rt, rd);
27766 #if defined(TARGET_MIPS64)
27773 check_insn(ctx, ISA_MIPS64R2);
27774 check_mips_64(ctx);
27775 gen_bitops(ctx, op1, rt, rs, sa, rd);
27778 op2 = MASK_DBSHFL(ctx->opcode);
27789 check_insn(ctx, ISA_MIPS32R6);
27790 decode_opc_special3_r6(env, ctx);
27793 check_insn(ctx, ISA_MIPS64R2);
27794 check_mips_64(ctx);
27795 op2 = MASK_DBSHFL(ctx->opcode);
27796 gen_bshfl(ctx, op2, rt, rd);
27802 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27807 TCGv t0 = tcg_temp_new();
27808 TCGv t1 = tcg_temp_new();
27810 gen_load_gpr(t0, rt);
27811 gen_load_gpr(t1, rs);
27812 gen_helper_fork(t0, t1);
27820 TCGv t0 = tcg_temp_new();
27822 gen_load_gpr(t0, rs);
27823 gen_helper_yield(t0, cpu_env, t0);
27824 gen_store_gpr(t0, rd);
27829 if (ctx->insn_flags & ISA_MIPS32R6) {
27830 decode_opc_special3_r6(env, ctx);
27832 decode_opc_special3_legacy(env, ctx);
27837 /* MIPS SIMD Architecture (MSA) */
27838 static inline int check_msa_access(DisasContext *ctx)
27840 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
27841 !(ctx->hflags & MIPS_HFLAG_F64))) {
27842 generate_exception_end(ctx, EXCP_RI);
27846 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
27847 if (ctx->insn_flags & ASE_MSA) {
27848 generate_exception_end(ctx, EXCP_MSADIS);
27851 generate_exception_end(ctx, EXCP_RI);
27858 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
27860 /* generates tcg ops to check if any element is 0 */
27861 /* Note this function only works with MSA_WRLEN = 128 */
27862 uint64_t eval_zero_or_big = 0;
27863 uint64_t eval_big = 0;
27864 TCGv_i64 t0 = tcg_temp_new_i64();
27865 TCGv_i64 t1 = tcg_temp_new_i64();
27868 eval_zero_or_big = 0x0101010101010101ULL;
27869 eval_big = 0x8080808080808080ULL;
27872 eval_zero_or_big = 0x0001000100010001ULL;
27873 eval_big = 0x8000800080008000ULL;
27876 eval_zero_or_big = 0x0000000100000001ULL;
27877 eval_big = 0x8000000080000000ULL;
27880 eval_zero_or_big = 0x0000000000000001ULL;
27881 eval_big = 0x8000000000000000ULL;
27884 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
27885 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
27886 tcg_gen_andi_i64(t0, t0, eval_big);
27887 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
27888 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
27889 tcg_gen_andi_i64(t1, t1, eval_big);
27890 tcg_gen_or_i64(t0, t0, t1);
27891 /* if all bits are zero then all elements are not zero */
27892 /* if some bit is non-zero then some element is zero */
27893 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
27894 tcg_gen_trunc_i64_tl(tresult, t0);
27895 tcg_temp_free_i64(t0);
27896 tcg_temp_free_i64(t1);
27899 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
27901 uint8_t df = (ctx->opcode >> 21) & 0x3;
27902 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27903 int64_t s16 = (int16_t)ctx->opcode;
27905 check_msa_access(ctx);
27907 if (ctx->hflags & MIPS_HFLAG_BMASK) {
27908 generate_exception_end(ctx, EXCP_RI);
27915 TCGv_i64 t0 = tcg_temp_new_i64();
27916 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
27917 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
27918 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
27919 tcg_gen_trunc_i64_tl(bcond, t0);
27920 tcg_temp_free_i64(t0);
27927 gen_check_zero_element(bcond, df, wt);
27933 gen_check_zero_element(bcond, df, wt);
27934 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
27938 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
27940 ctx->hflags |= MIPS_HFLAG_BC;
27941 ctx->hflags |= MIPS_HFLAG_BDS32;
27944 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
27946 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
27947 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
27948 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27949 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27951 TCGv_i32 twd = tcg_const_i32(wd);
27952 TCGv_i32 tws = tcg_const_i32(ws);
27953 TCGv_i32 ti8 = tcg_const_i32(i8);
27955 switch (MASK_MSA_I8(ctx->opcode)) {
27957 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
27960 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
27963 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
27966 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
27969 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27972 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27975 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27981 uint8_t df = (ctx->opcode >> 24) & 0x3;
27982 if (df == DF_DOUBLE) {
27983 generate_exception_end(ctx, EXCP_RI);
27985 TCGv_i32 tdf = tcg_const_i32(df);
27986 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27987 tcg_temp_free_i32(tdf);
27992 MIPS_INVAL("MSA instruction");
27993 generate_exception_end(ctx, EXCP_RI);
27997 tcg_temp_free_i32(twd);
27998 tcg_temp_free_i32(tws);
27999 tcg_temp_free_i32(ti8);
28002 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
28004 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28005 uint8_t df = (ctx->opcode >> 21) & 0x3;
28006 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
28007 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
28008 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28009 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28011 TCGv_i32 tdf = tcg_const_i32(df);
28012 TCGv_i32 twd = tcg_const_i32(wd);
28013 TCGv_i32 tws = tcg_const_i32(ws);
28014 TCGv_i32 timm = tcg_temp_new_i32();
28015 tcg_gen_movi_i32(timm, u5);
28017 switch (MASK_MSA_I5(ctx->opcode)) {
28019 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
28022 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
28024 case OPC_MAXI_S_df:
28025 tcg_gen_movi_i32(timm, s5);
28026 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
28028 case OPC_MAXI_U_df:
28029 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
28031 case OPC_MINI_S_df:
28032 tcg_gen_movi_i32(timm, s5);
28033 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
28035 case OPC_MINI_U_df:
28036 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
28039 tcg_gen_movi_i32(timm, s5);
28040 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
28042 case OPC_CLTI_S_df:
28043 tcg_gen_movi_i32(timm, s5);
28044 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
28046 case OPC_CLTI_U_df:
28047 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
28049 case OPC_CLEI_S_df:
28050 tcg_gen_movi_i32(timm, s5);
28051 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
28053 case OPC_CLEI_U_df:
28054 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
28058 int32_t s10 = sextract32(ctx->opcode, 11, 10);
28059 tcg_gen_movi_i32(timm, s10);
28060 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
28064 MIPS_INVAL("MSA instruction");
28065 generate_exception_end(ctx, EXCP_RI);
28069 tcg_temp_free_i32(tdf);
28070 tcg_temp_free_i32(twd);
28071 tcg_temp_free_i32(tws);
28072 tcg_temp_free_i32(timm);
28075 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
28077 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28078 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
28079 uint32_t df = 0, m = 0;
28080 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28081 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28088 if ((dfm & 0x40) == 0x00) {
28091 } else if ((dfm & 0x60) == 0x40) {
28094 } else if ((dfm & 0x70) == 0x60) {
28097 } else if ((dfm & 0x78) == 0x70) {
28101 generate_exception_end(ctx, EXCP_RI);
28105 tdf = tcg_const_i32(df);
28106 tm = tcg_const_i32(m);
28107 twd = tcg_const_i32(wd);
28108 tws = tcg_const_i32(ws);
28110 switch (MASK_MSA_BIT(ctx->opcode)) {
28112 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
28115 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
28118 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
28121 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
28124 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
28127 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
28129 case OPC_BINSLI_df:
28130 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
28132 case OPC_BINSRI_df:
28133 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
28136 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
28139 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
28142 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
28145 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
28148 MIPS_INVAL("MSA instruction");
28149 generate_exception_end(ctx, EXCP_RI);
28153 tcg_temp_free_i32(tdf);
28154 tcg_temp_free_i32(tm);
28155 tcg_temp_free_i32(twd);
28156 tcg_temp_free_i32(tws);
28159 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28161 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28162 uint8_t df = (ctx->opcode >> 21) & 0x3;
28163 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28164 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28165 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28167 TCGv_i32 tdf = tcg_const_i32(df);
28168 TCGv_i32 twd = tcg_const_i32(wd);
28169 TCGv_i32 tws = tcg_const_i32(ws);
28170 TCGv_i32 twt = tcg_const_i32(wt);
28172 switch (MASK_MSA_3R(ctx->opcode)) {
28174 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28177 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28180 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28183 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28185 case OPC_SUBS_S_df:
28186 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28189 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28192 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28195 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28198 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28201 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28203 case OPC_ADDS_A_df:
28204 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28206 case OPC_SUBS_U_df:
28207 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28210 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28213 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28216 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28219 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28222 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28225 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28227 case OPC_ADDS_S_df:
28228 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28230 case OPC_SUBSUS_U_df:
28231 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28234 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28237 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28240 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28243 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28246 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28249 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28251 case OPC_ADDS_U_df:
28252 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28254 case OPC_SUBSUU_S_df:
28255 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28258 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28261 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28264 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28267 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28270 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28272 case OPC_ASUB_S_df:
28273 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28276 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28279 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28282 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28285 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28288 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28291 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28293 case OPC_ASUB_U_df:
28294 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28297 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28300 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28303 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28306 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28308 case OPC_AVER_S_df:
28309 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28312 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28315 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28318 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28321 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28323 case OPC_AVER_U_df:
28324 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28327 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28330 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28333 case OPC_DOTP_S_df:
28334 case OPC_DOTP_U_df:
28335 case OPC_DPADD_S_df:
28336 case OPC_DPADD_U_df:
28337 case OPC_DPSUB_S_df:
28338 case OPC_HADD_S_df:
28339 case OPC_DPSUB_U_df:
28340 case OPC_HADD_U_df:
28341 case OPC_HSUB_S_df:
28342 case OPC_HSUB_U_df:
28343 if (df == DF_BYTE) {
28344 generate_exception_end(ctx, EXCP_RI);
28347 switch (MASK_MSA_3R(ctx->opcode)) {
28348 case OPC_DOTP_S_df:
28349 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28351 case OPC_DOTP_U_df:
28352 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28354 case OPC_DPADD_S_df:
28355 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28357 case OPC_DPADD_U_df:
28358 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28360 case OPC_DPSUB_S_df:
28361 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28363 case OPC_HADD_S_df:
28364 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28366 case OPC_DPSUB_U_df:
28367 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28369 case OPC_HADD_U_df:
28370 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28372 case OPC_HSUB_S_df:
28373 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28375 case OPC_HSUB_U_df:
28376 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28381 MIPS_INVAL("MSA instruction");
28382 generate_exception_end(ctx, EXCP_RI);
28385 tcg_temp_free_i32(twd);
28386 tcg_temp_free_i32(tws);
28387 tcg_temp_free_i32(twt);
28388 tcg_temp_free_i32(tdf);
28391 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28393 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28394 uint8_t source = (ctx->opcode >> 11) & 0x1f;
28395 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28396 TCGv telm = tcg_temp_new();
28397 TCGv_i32 tsr = tcg_const_i32(source);
28398 TCGv_i32 tdt = tcg_const_i32(dest);
28400 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28402 gen_load_gpr(telm, source);
28403 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28406 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28407 gen_store_gpr(telm, dest);
28410 gen_helper_msa_move_v(cpu_env, tdt, tsr);
28413 MIPS_INVAL("MSA instruction");
28414 generate_exception_end(ctx, EXCP_RI);
28418 tcg_temp_free(telm);
28419 tcg_temp_free_i32(tdt);
28420 tcg_temp_free_i32(tsr);
28423 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28426 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28427 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28428 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28430 TCGv_i32 tws = tcg_const_i32(ws);
28431 TCGv_i32 twd = tcg_const_i32(wd);
28432 TCGv_i32 tn = tcg_const_i32(n);
28433 TCGv_i32 tdf = tcg_const_i32(df);
28435 switch (MASK_MSA_ELM(ctx->opcode)) {
28437 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28439 case OPC_SPLATI_df:
28440 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28443 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28445 case OPC_COPY_S_df:
28446 case OPC_COPY_U_df:
28447 case OPC_INSERT_df:
28448 #if !defined(TARGET_MIPS64)
28449 /* Double format valid only for MIPS64 */
28450 if (df == DF_DOUBLE) {
28451 generate_exception_end(ctx, EXCP_RI);
28454 if ((MASK_MSA_ELM(ctx->opcode) == OPC_COPY_U_df) &&
28456 generate_exception_end(ctx, EXCP_RI);
28460 switch (MASK_MSA_ELM(ctx->opcode)) {
28461 case OPC_COPY_S_df:
28462 if (likely(wd != 0)) {
28465 gen_helper_msa_copy_s_b(cpu_env, twd, tws, tn);
28468 gen_helper_msa_copy_s_h(cpu_env, twd, tws, tn);
28471 gen_helper_msa_copy_s_w(cpu_env, twd, tws, tn);
28473 #if defined(TARGET_MIPS64)
28475 gen_helper_msa_copy_s_d(cpu_env, twd, tws, tn);
28483 case OPC_COPY_U_df:
28484 if (likely(wd != 0)) {
28487 gen_helper_msa_copy_u_b(cpu_env, twd, tws, tn);
28490 gen_helper_msa_copy_u_h(cpu_env, twd, tws, tn);
28492 #if defined(TARGET_MIPS64)
28494 gen_helper_msa_copy_u_w(cpu_env, twd, tws, tn);
28502 case OPC_INSERT_df:
28505 gen_helper_msa_insert_b(cpu_env, twd, tws, tn);
28508 gen_helper_msa_insert_h(cpu_env, twd, tws, tn);
28511 gen_helper_msa_insert_w(cpu_env, twd, tws, tn);
28513 #if defined(TARGET_MIPS64)
28515 gen_helper_msa_insert_d(cpu_env, twd, tws, tn);
28525 MIPS_INVAL("MSA instruction");
28526 generate_exception_end(ctx, EXCP_RI);
28528 tcg_temp_free_i32(twd);
28529 tcg_temp_free_i32(tws);
28530 tcg_temp_free_i32(tn);
28531 tcg_temp_free_i32(tdf);
28534 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28536 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28537 uint32_t df = 0, n = 0;
28539 if ((dfn & 0x30) == 0x00) {
28542 } else if ((dfn & 0x38) == 0x20) {
28545 } else if ((dfn & 0x3c) == 0x30) {
28548 } else if ((dfn & 0x3e) == 0x38) {
28551 } else if (dfn == 0x3E) {
28552 /* CTCMSA, CFCMSA, MOVE.V */
28553 gen_msa_elm_3e(env, ctx);
28556 generate_exception_end(ctx, EXCP_RI);
28560 gen_msa_elm_df(env, ctx, df, n);
28563 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28565 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28566 uint8_t df = (ctx->opcode >> 21) & 0x1;
28567 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28568 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28569 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28571 TCGv_i32 twd = tcg_const_i32(wd);
28572 TCGv_i32 tws = tcg_const_i32(ws);
28573 TCGv_i32 twt = tcg_const_i32(wt);
28574 TCGv_i32 tdf = tcg_temp_new_i32();
28576 /* adjust df value for floating-point instruction */
28577 tcg_gen_movi_i32(tdf, df + 2);
28579 switch (MASK_MSA_3RF(ctx->opcode)) {
28581 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28584 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28587 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28590 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28593 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28596 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28599 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28602 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28605 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28608 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28611 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28614 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28617 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28620 tcg_gen_movi_i32(tdf, df + 1);
28621 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28624 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28627 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28629 case OPC_MADD_Q_df:
28630 tcg_gen_movi_i32(tdf, df + 1);
28631 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28634 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28636 case OPC_MSUB_Q_df:
28637 tcg_gen_movi_i32(tdf, df + 1);
28638 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28641 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28644 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28647 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28650 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28653 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28656 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28659 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28662 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28665 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28668 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28671 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28674 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28677 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28679 case OPC_MULR_Q_df:
28680 tcg_gen_movi_i32(tdf, df + 1);
28681 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28684 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28686 case OPC_FMIN_A_df:
28687 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28689 case OPC_MADDR_Q_df:
28690 tcg_gen_movi_i32(tdf, df + 1);
28691 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28694 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28697 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28699 case OPC_MSUBR_Q_df:
28700 tcg_gen_movi_i32(tdf, df + 1);
28701 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28704 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28706 case OPC_FMAX_A_df:
28707 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28710 MIPS_INVAL("MSA instruction");
28711 generate_exception_end(ctx, EXCP_RI);
28715 tcg_temp_free_i32(twd);
28716 tcg_temp_free_i32(tws);
28717 tcg_temp_free_i32(twt);
28718 tcg_temp_free_i32(tdf);
28721 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28723 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28724 (op & (0x7 << 18)))
28725 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28726 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28727 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28728 uint8_t df = (ctx->opcode >> 16) & 0x3;
28729 TCGv_i32 twd = tcg_const_i32(wd);
28730 TCGv_i32 tws = tcg_const_i32(ws);
28731 TCGv_i32 twt = tcg_const_i32(wt);
28732 TCGv_i32 tdf = tcg_const_i32(df);
28734 switch (MASK_MSA_2R(ctx->opcode)) {
28736 #if !defined(TARGET_MIPS64)
28737 /* Double format valid only for MIPS64 */
28738 if (df == DF_DOUBLE) {
28739 generate_exception_end(ctx, EXCP_RI);
28743 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28746 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28749 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28752 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28755 MIPS_INVAL("MSA instruction");
28756 generate_exception_end(ctx, EXCP_RI);
28760 tcg_temp_free_i32(twd);
28761 tcg_temp_free_i32(tws);
28762 tcg_temp_free_i32(twt);
28763 tcg_temp_free_i32(tdf);
28766 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28768 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28769 (op & (0xf << 17)))
28770 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28771 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28772 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28773 uint8_t df = (ctx->opcode >> 16) & 0x1;
28774 TCGv_i32 twd = tcg_const_i32(wd);
28775 TCGv_i32 tws = tcg_const_i32(ws);
28776 TCGv_i32 twt = tcg_const_i32(wt);
28777 /* adjust df value for floating-point instruction */
28778 TCGv_i32 tdf = tcg_const_i32(df + 2);
28780 switch (MASK_MSA_2RF(ctx->opcode)) {
28781 case OPC_FCLASS_df:
28782 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28784 case OPC_FTRUNC_S_df:
28785 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28787 case OPC_FTRUNC_U_df:
28788 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28791 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28793 case OPC_FRSQRT_df:
28794 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28797 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28800 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28803 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28805 case OPC_FEXUPL_df:
28806 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28808 case OPC_FEXUPR_df:
28809 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28812 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28815 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28817 case OPC_FTINT_S_df:
28818 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28820 case OPC_FTINT_U_df:
28821 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
28823 case OPC_FFINT_S_df:
28824 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
28826 case OPC_FFINT_U_df:
28827 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
28831 tcg_temp_free_i32(twd);
28832 tcg_temp_free_i32(tws);
28833 tcg_temp_free_i32(twt);
28834 tcg_temp_free_i32(tdf);
28837 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
28839 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
28840 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28841 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28842 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28843 TCGv_i32 twd = tcg_const_i32(wd);
28844 TCGv_i32 tws = tcg_const_i32(ws);
28845 TCGv_i32 twt = tcg_const_i32(wt);
28847 switch (MASK_MSA_VEC(ctx->opcode)) {
28849 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
28852 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
28855 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
28858 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
28861 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
28864 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
28867 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
28870 MIPS_INVAL("MSA instruction");
28871 generate_exception_end(ctx, EXCP_RI);
28875 tcg_temp_free_i32(twd);
28876 tcg_temp_free_i32(tws);
28877 tcg_temp_free_i32(twt);
28880 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
28882 switch (MASK_MSA_VEC(ctx->opcode)) {
28890 gen_msa_vec_v(env, ctx);
28893 gen_msa_2r(env, ctx);
28896 gen_msa_2rf(env, ctx);
28899 MIPS_INVAL("MSA instruction");
28900 generate_exception_end(ctx, EXCP_RI);
28905 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
28907 uint32_t opcode = ctx->opcode;
28908 check_insn(ctx, ASE_MSA);
28909 check_msa_access(ctx);
28911 switch (MASK_MSA_MINOR(opcode)) {
28912 case OPC_MSA_I8_00:
28913 case OPC_MSA_I8_01:
28914 case OPC_MSA_I8_02:
28915 gen_msa_i8(env, ctx);
28917 case OPC_MSA_I5_06:
28918 case OPC_MSA_I5_07:
28919 gen_msa_i5(env, ctx);
28921 case OPC_MSA_BIT_09:
28922 case OPC_MSA_BIT_0A:
28923 gen_msa_bit(env, ctx);
28925 case OPC_MSA_3R_0D:
28926 case OPC_MSA_3R_0E:
28927 case OPC_MSA_3R_0F:
28928 case OPC_MSA_3R_10:
28929 case OPC_MSA_3R_11:
28930 case OPC_MSA_3R_12:
28931 case OPC_MSA_3R_13:
28932 case OPC_MSA_3R_14:
28933 case OPC_MSA_3R_15:
28934 gen_msa_3r(env, ctx);
28937 gen_msa_elm(env, ctx);
28939 case OPC_MSA_3RF_1A:
28940 case OPC_MSA_3RF_1B:
28941 case OPC_MSA_3RF_1C:
28942 gen_msa_3rf(env, ctx);
28945 gen_msa_vec(env, ctx);
28956 int32_t s10 = sextract32(ctx->opcode, 16, 10);
28957 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
28958 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28959 uint8_t df = (ctx->opcode >> 0) & 0x3;
28961 TCGv_i32 twd = tcg_const_i32(wd);
28962 TCGv taddr = tcg_temp_new();
28963 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
28965 switch (MASK_MSA_MINOR(opcode)) {
28967 gen_helper_msa_ld_b(cpu_env, twd, taddr);
28970 gen_helper_msa_ld_h(cpu_env, twd, taddr);
28973 gen_helper_msa_ld_w(cpu_env, twd, taddr);
28976 gen_helper_msa_ld_d(cpu_env, twd, taddr);
28979 gen_helper_msa_st_b(cpu_env, twd, taddr);
28982 gen_helper_msa_st_h(cpu_env, twd, taddr);
28985 gen_helper_msa_st_w(cpu_env, twd, taddr);
28988 gen_helper_msa_st_d(cpu_env, twd, taddr);
28992 tcg_temp_free_i32(twd);
28993 tcg_temp_free(taddr);
28997 MIPS_INVAL("MSA instruction");
28998 generate_exception_end(ctx, EXCP_RI);
29004 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
29007 int rs, rt, rd, sa;
29011 /* make sure instructions are on a word boundary */
29012 if (ctx->base.pc_next & 0x3) {
29013 env->CP0_BadVAddr = ctx->base.pc_next;
29014 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
29018 /* Handle blikely not taken case */
29019 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
29020 TCGLabel *l1 = gen_new_label();
29022 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
29023 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
29024 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
29028 op = MASK_OP_MAJOR(ctx->opcode);
29029 rs = (ctx->opcode >> 21) & 0x1f;
29030 rt = (ctx->opcode >> 16) & 0x1f;
29031 rd = (ctx->opcode >> 11) & 0x1f;
29032 sa = (ctx->opcode >> 6) & 0x1f;
29033 imm = (int16_t)ctx->opcode;
29036 decode_opc_special(env, ctx);
29039 #if defined(TARGET_MIPS64)
29040 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
29041 decode_mmi(env, ctx);
29043 if (ctx->insn_flags & ASE_MXU) {
29044 decode_opc_mxu(env, ctx);
29047 decode_opc_special2_legacy(env, ctx);
29051 #if defined(TARGET_MIPS64)
29052 if (ctx->insn_flags & INSN_R5900) {
29053 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
29055 decode_opc_special3(env, ctx);
29058 decode_opc_special3(env, ctx);
29062 op1 = MASK_REGIMM(ctx->opcode);
29064 case OPC_BLTZL: /* REGIMM branches */
29068 check_insn(ctx, ISA_MIPS2);
29069 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29073 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
29077 if (ctx->insn_flags & ISA_MIPS32R6) {
29079 /* OPC_NAL, OPC_BAL */
29080 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
29082 generate_exception_end(ctx, EXCP_RI);
29085 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
29088 case OPC_TGEI: /* REGIMM traps */
29095 check_insn(ctx, ISA_MIPS2);
29096 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29097 gen_trap(ctx, op1, rs, -1, imm);
29100 check_insn(ctx, ISA_MIPS32R6);
29101 generate_exception_end(ctx, EXCP_RI);
29104 check_insn(ctx, ISA_MIPS32R2);
29105 /* Break the TB to be able to sync copied instructions
29107 ctx->base.is_jmp = DISAS_STOP;
29109 case OPC_BPOSGE32: /* MIPS DSP branch */
29110 #if defined(TARGET_MIPS64)
29114 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
29116 #if defined(TARGET_MIPS64)
29118 check_insn(ctx, ISA_MIPS32R6);
29119 check_mips_64(ctx);
29121 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
29125 check_insn(ctx, ISA_MIPS32R6);
29126 check_mips_64(ctx);
29128 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
29132 default: /* Invalid */
29133 MIPS_INVAL("regimm");
29134 generate_exception_end(ctx, EXCP_RI);
29139 check_cp0_enabled(ctx);
29140 op1 = MASK_CP0(ctx->opcode);
29148 #if defined(TARGET_MIPS64)
29152 #ifndef CONFIG_USER_ONLY
29153 gen_cp0(env, ctx, op1, rt, rd);
29154 #endif /* !CONFIG_USER_ONLY */
29172 #ifndef CONFIG_USER_ONLY
29173 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
29174 #endif /* !CONFIG_USER_ONLY */
29177 #ifndef CONFIG_USER_ONLY
29180 TCGv t0 = tcg_temp_new();
29182 op2 = MASK_MFMC0(ctx->opcode);
29186 gen_helper_dmt(t0);
29187 gen_store_gpr(t0, rt);
29191 gen_helper_emt(t0);
29192 gen_store_gpr(t0, rt);
29196 gen_helper_dvpe(t0, cpu_env);
29197 gen_store_gpr(t0, rt);
29201 gen_helper_evpe(t0, cpu_env);
29202 gen_store_gpr(t0, rt);
29205 check_insn(ctx, ISA_MIPS32R6);
29207 gen_helper_dvp(t0, cpu_env);
29208 gen_store_gpr(t0, rt);
29212 check_insn(ctx, ISA_MIPS32R6);
29214 gen_helper_evp(t0, cpu_env);
29215 gen_store_gpr(t0, rt);
29219 check_insn(ctx, ISA_MIPS32R2);
29220 save_cpu_state(ctx, 1);
29221 gen_helper_di(t0, cpu_env);
29222 gen_store_gpr(t0, rt);
29223 /* Stop translation as we may have switched
29224 the execution mode. */
29225 ctx->base.is_jmp = DISAS_STOP;
29228 check_insn(ctx, ISA_MIPS32R2);
29229 save_cpu_state(ctx, 1);
29230 gen_helper_ei(t0, cpu_env);
29231 gen_store_gpr(t0, rt);
29232 /* DISAS_STOP isn't sufficient, we need to ensure we break
29233 out of translated code to check for pending interrupts */
29234 gen_save_pc(ctx->base.pc_next + 4);
29235 ctx->base.is_jmp = DISAS_EXIT;
29237 default: /* Invalid */
29238 MIPS_INVAL("mfmc0");
29239 generate_exception_end(ctx, EXCP_RI);
29244 #endif /* !CONFIG_USER_ONLY */
29247 check_insn(ctx, ISA_MIPS32R2);
29248 gen_load_srsgpr(rt, rd);
29251 check_insn(ctx, ISA_MIPS32R2);
29252 gen_store_srsgpr(rt, rd);
29256 generate_exception_end(ctx, EXCP_RI);
29260 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29261 if (ctx->insn_flags & ISA_MIPS32R6) {
29262 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29263 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29266 /* Arithmetic with immediate opcode */
29267 gen_arith_imm(ctx, op, rt, rs, imm);
29271 gen_arith_imm(ctx, op, rt, rs, imm);
29273 case OPC_SLTI: /* Set on less than with immediate opcode */
29275 gen_slt_imm(ctx, op, rt, rs, imm);
29277 case OPC_ANDI: /* Arithmetic with immediate opcode */
29278 case OPC_LUI: /* OPC_AUI */
29281 gen_logic_imm(ctx, op, rt, rs, imm);
29283 case OPC_J: /* Jump */
29285 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29286 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29289 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29290 if (ctx->insn_flags & ISA_MIPS32R6) {
29292 generate_exception_end(ctx, EXCP_RI);
29295 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29296 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29299 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29302 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29303 if (ctx->insn_flags & ISA_MIPS32R6) {
29305 generate_exception_end(ctx, EXCP_RI);
29308 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29309 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29312 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29315 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29318 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29320 check_insn(ctx, ISA_MIPS32R6);
29321 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29322 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29325 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29328 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29330 check_insn(ctx, ISA_MIPS32R6);
29331 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29332 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29337 check_insn(ctx, ISA_MIPS2);
29338 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29342 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29344 case OPC_LL: /* Load and stores */
29345 check_insn(ctx, ISA_MIPS2);
29346 if (ctx->insn_flags & INSN_R5900) {
29347 check_insn_opc_user_only(ctx, INSN_R5900);
29352 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29360 gen_ld(ctx, op, rt, rs, imm);
29364 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29369 gen_st(ctx, op, rt, rs, imm);
29372 check_insn(ctx, ISA_MIPS2);
29373 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29374 if (ctx->insn_flags & INSN_R5900) {
29375 check_insn_opc_user_only(ctx, INSN_R5900);
29377 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
29380 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29381 check_cp0_enabled(ctx);
29382 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29383 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29384 gen_cache_operation(ctx, rt, rs, imm);
29386 /* Treat as NOP. */
29389 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29390 if (ctx->insn_flags & INSN_R5900) {
29391 /* Treat as NOP. */
29393 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29394 /* Treat as NOP. */
29398 /* Floating point (COP1). */
29403 gen_cop1_ldst(ctx, op, rt, rs, imm);
29407 op1 = MASK_CP1(ctx->opcode);
29412 check_cp1_enabled(ctx);
29413 check_insn(ctx, ISA_MIPS32R2);
29419 check_cp1_enabled(ctx);
29420 gen_cp1(ctx, op1, rt, rd);
29422 #if defined(TARGET_MIPS64)
29425 check_cp1_enabled(ctx);
29426 check_insn(ctx, ISA_MIPS3);
29427 check_mips_64(ctx);
29428 gen_cp1(ctx, op1, rt, rd);
29431 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29432 check_cp1_enabled(ctx);
29433 if (ctx->insn_flags & ISA_MIPS32R6) {
29435 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29440 check_insn(ctx, ASE_MIPS3D);
29441 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29442 (rt >> 2) & 0x7, imm << 2);
29446 check_cp1_enabled(ctx);
29447 check_insn(ctx, ISA_MIPS32R6);
29448 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29452 check_cp1_enabled(ctx);
29453 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29455 check_insn(ctx, ASE_MIPS3D);
29458 check_cp1_enabled(ctx);
29459 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29460 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29461 (rt >> 2) & 0x7, imm << 2);
29468 check_cp1_enabled(ctx);
29469 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29475 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29476 check_cp1_enabled(ctx);
29477 if (ctx->insn_flags & ISA_MIPS32R6) {
29479 case R6_OPC_CMP_AF_S:
29480 case R6_OPC_CMP_UN_S:
29481 case R6_OPC_CMP_EQ_S:
29482 case R6_OPC_CMP_UEQ_S:
29483 case R6_OPC_CMP_LT_S:
29484 case R6_OPC_CMP_ULT_S:
29485 case R6_OPC_CMP_LE_S:
29486 case R6_OPC_CMP_ULE_S:
29487 case R6_OPC_CMP_SAF_S:
29488 case R6_OPC_CMP_SUN_S:
29489 case R6_OPC_CMP_SEQ_S:
29490 case R6_OPC_CMP_SEUQ_S:
29491 case R6_OPC_CMP_SLT_S:
29492 case R6_OPC_CMP_SULT_S:
29493 case R6_OPC_CMP_SLE_S:
29494 case R6_OPC_CMP_SULE_S:
29495 case R6_OPC_CMP_OR_S:
29496 case R6_OPC_CMP_UNE_S:
29497 case R6_OPC_CMP_NE_S:
29498 case R6_OPC_CMP_SOR_S:
29499 case R6_OPC_CMP_SUNE_S:
29500 case R6_OPC_CMP_SNE_S:
29501 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29503 case R6_OPC_CMP_AF_D:
29504 case R6_OPC_CMP_UN_D:
29505 case R6_OPC_CMP_EQ_D:
29506 case R6_OPC_CMP_UEQ_D:
29507 case R6_OPC_CMP_LT_D:
29508 case R6_OPC_CMP_ULT_D:
29509 case R6_OPC_CMP_LE_D:
29510 case R6_OPC_CMP_ULE_D:
29511 case R6_OPC_CMP_SAF_D:
29512 case R6_OPC_CMP_SUN_D:
29513 case R6_OPC_CMP_SEQ_D:
29514 case R6_OPC_CMP_SEUQ_D:
29515 case R6_OPC_CMP_SLT_D:
29516 case R6_OPC_CMP_SULT_D:
29517 case R6_OPC_CMP_SLE_D:
29518 case R6_OPC_CMP_SULE_D:
29519 case R6_OPC_CMP_OR_D:
29520 case R6_OPC_CMP_UNE_D:
29521 case R6_OPC_CMP_NE_D:
29522 case R6_OPC_CMP_SOR_D:
29523 case R6_OPC_CMP_SUNE_D:
29524 case R6_OPC_CMP_SNE_D:
29525 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29528 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29529 rt, rd, sa, (imm >> 8) & 0x7);
29534 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29549 check_insn(ctx, ASE_MSA);
29550 gen_msa_branch(env, ctx, op1);
29554 generate_exception_end(ctx, EXCP_RI);
29559 /* Compact branches [R6] and COP2 [non-R6] */
29560 case OPC_BC: /* OPC_LWC2 */
29561 case OPC_BALC: /* OPC_SWC2 */
29562 if (ctx->insn_flags & ISA_MIPS32R6) {
29563 /* OPC_BC, OPC_BALC */
29564 gen_compute_compact_branch(ctx, op, 0, 0,
29565 sextract32(ctx->opcode << 2, 0, 28));
29567 /* OPC_LWC2, OPC_SWC2 */
29568 /* COP2: Not implemented. */
29569 generate_exception_err(ctx, EXCP_CpU, 2);
29572 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29573 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29574 if (ctx->insn_flags & ISA_MIPS32R6) {
29576 /* OPC_BEQZC, OPC_BNEZC */
29577 gen_compute_compact_branch(ctx, op, rs, 0,
29578 sextract32(ctx->opcode << 2, 0, 23));
29580 /* OPC_JIC, OPC_JIALC */
29581 gen_compute_compact_branch(ctx, op, 0, rt, imm);
29584 /* OPC_LWC2, OPC_SWC2 */
29585 /* COP2: Not implemented. */
29586 generate_exception_err(ctx, EXCP_CpU, 2);
29590 check_insn(ctx, INSN_LOONGSON2F);
29591 /* Note that these instructions use different fields. */
29592 gen_loongson_multimedia(ctx, sa, rd, rt);
29596 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29597 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29598 check_cp1_enabled(ctx);
29599 op1 = MASK_CP3(ctx->opcode);
29603 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29609 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29610 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29613 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29614 /* Treat as NOP. */
29617 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29631 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29632 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29636 generate_exception_end(ctx, EXCP_RI);
29640 generate_exception_err(ctx, EXCP_CpU, 1);
29644 #if defined(TARGET_MIPS64)
29645 /* MIPS64 opcodes */
29647 if (ctx->insn_flags & INSN_R5900) {
29648 check_insn_opc_user_only(ctx, INSN_R5900);
29653 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29657 check_insn(ctx, ISA_MIPS3);
29658 check_mips_64(ctx);
29659 gen_ld(ctx, op, rt, rs, imm);
29663 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29666 check_insn(ctx, ISA_MIPS3);
29667 check_mips_64(ctx);
29668 gen_st(ctx, op, rt, rs, imm);
29671 check_insn_opc_removed(ctx, ISA_MIPS32R6);
29672 check_insn(ctx, ISA_MIPS3);
29673 if (ctx->insn_flags & INSN_R5900) {
29674 check_insn_opc_user_only(ctx, INSN_R5900);
29676 check_mips_64(ctx);
29677 gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
29679 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29680 if (ctx->insn_flags & ISA_MIPS32R6) {
29681 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29682 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29685 check_insn(ctx, ISA_MIPS3);
29686 check_mips_64(ctx);
29687 gen_arith_imm(ctx, op, rt, rs, imm);
29691 check_insn(ctx, ISA_MIPS3);
29692 check_mips_64(ctx);
29693 gen_arith_imm(ctx, op, rt, rs, imm);
29696 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29697 if (ctx->insn_flags & ISA_MIPS32R6) {
29698 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29700 MIPS_INVAL("major opcode");
29701 generate_exception_end(ctx, EXCP_RI);
29705 case OPC_DAUI: /* OPC_JALX */
29706 if (ctx->insn_flags & ISA_MIPS32R6) {
29707 #if defined(TARGET_MIPS64)
29709 check_mips_64(ctx);
29711 generate_exception(ctx, EXCP_RI);
29712 } else if (rt != 0) {
29713 TCGv t0 = tcg_temp_new();
29714 gen_load_gpr(t0, rs);
29715 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29719 generate_exception_end(ctx, EXCP_RI);
29720 MIPS_INVAL("major opcode");
29724 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29725 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29726 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29729 case OPC_MSA: /* OPC_MDMX */
29730 if (ctx->insn_flags & INSN_R5900) {
29731 #if defined(TARGET_MIPS64)
29732 gen_mmi_lq(env, ctx); /* MMI_OPC_LQ */
29735 /* MDMX: Not implemented. */
29740 check_insn(ctx, ISA_MIPS32R6);
29741 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29743 default: /* Invalid */
29744 MIPS_INVAL("major opcode");
29745 generate_exception_end(ctx, EXCP_RI);
29750 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29752 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29753 CPUMIPSState *env = cs->env_ptr;
29755 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29756 ctx->saved_pc = -1;
29757 ctx->insn_flags = env->insn_flags;
29758 ctx->CP0_Config1 = env->CP0_Config1;
29759 ctx->CP0_Config2 = env->CP0_Config2;
29760 ctx->CP0_Config3 = env->CP0_Config3;
29761 ctx->CP0_Config5 = env->CP0_Config5;
29763 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29764 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29765 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29766 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29767 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29768 ctx->PAMask = env->PAMask;
29769 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29770 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29771 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29772 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29773 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29774 /* Restore delay slot state from the tb context. */
29775 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29776 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29777 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29778 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29779 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29780 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29781 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29782 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29783 restore_cpu_state(env, ctx);
29784 #ifdef CONFIG_USER_ONLY
29785 ctx->mem_idx = MIPS_HFLAG_UM;
29787 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29789 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29790 MO_UNALN : MO_ALIGN;
29792 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29796 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29800 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29802 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29804 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29808 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29809 const CPUBreakpoint *bp)
29811 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29813 save_cpu_state(ctx, 1);
29814 ctx->base.is_jmp = DISAS_NORETURN;
29815 gen_helper_raise_exception_debug(cpu_env);
29816 /* The address covered by the breakpoint must be included in
29817 [tb->pc, tb->pc + tb->size) in order to for it to be
29818 properly cleared -- thus we increment the PC here so that
29819 the logic setting tb->size below does the right thing. */
29820 ctx->base.pc_next += 4;
29824 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
29826 CPUMIPSState *env = cs->env_ptr;
29827 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29831 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
29832 if (ctx->insn_flags & ISA_NANOMIPS32) {
29833 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29834 insn_bytes = decode_nanomips_opc(env, ctx);
29835 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
29836 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
29838 decode_opc(env, ctx);
29839 } else if (ctx->insn_flags & ASE_MICROMIPS) {
29840 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29841 insn_bytes = decode_micromips_opc(env, ctx);
29842 } else if (ctx->insn_flags & ASE_MIPS16) {
29843 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29844 insn_bytes = decode_mips16_opc(env, ctx);
29846 generate_exception_end(ctx, EXCP_RI);
29847 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
29851 if (ctx->hflags & MIPS_HFLAG_BMASK) {
29852 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
29853 MIPS_HFLAG_FBNSLOT))) {
29854 /* force to generate branch as there is neither delay nor
29858 if ((ctx->hflags & MIPS_HFLAG_M16) &&
29859 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
29860 /* Force to generate branch as microMIPS R6 doesn't restrict
29861 branches in the forbidden slot. */
29866 gen_branch(ctx, insn_bytes);
29868 ctx->base.pc_next += insn_bytes;
29870 if (ctx->base.is_jmp != DISAS_NEXT) {
29873 /* Execute a branch and its delay slot as a single instruction.
29874 This is what GDB expects and is consistent with what the
29875 hardware does (e.g. if a delay slot instruction faults, the
29876 reported PC is the PC of the branch). */
29877 if (ctx->base.singlestep_enabled &&
29878 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
29879 ctx->base.is_jmp = DISAS_TOO_MANY;
29881 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
29882 ctx->base.is_jmp = DISAS_TOO_MANY;
29886 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29888 DisasContext *ctx = container_of(dcbase, DisasContext, base);
29890 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
29891 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
29892 gen_helper_raise_exception_debug(cpu_env);
29894 switch (ctx->base.is_jmp) {
29896 gen_save_pc(ctx->base.pc_next);
29897 tcg_gen_lookup_and_goto_ptr();
29900 case DISAS_TOO_MANY:
29901 save_cpu_state(ctx, 0);
29902 gen_goto_tb(ctx, 0, ctx->base.pc_next);
29905 tcg_gen_exit_tb(NULL, 0);
29907 case DISAS_NORETURN:
29910 g_assert_not_reached();
29915 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
29917 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
29918 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
29921 static const TranslatorOps mips_tr_ops = {
29922 .init_disas_context = mips_tr_init_disas_context,
29923 .tb_start = mips_tr_tb_start,
29924 .insn_start = mips_tr_insn_start,
29925 .breakpoint_check = mips_tr_breakpoint_check,
29926 .translate_insn = mips_tr_translate_insn,
29927 .tb_stop = mips_tr_tb_stop,
29928 .disas_log = mips_tr_disas_log,
29931 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
29935 translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
29938 static void fpu_dump_state(CPUMIPSState *env, FILE *f, int flags)
29941 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
29943 #define printfpr(fp) \
29946 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
29947 " fd:%13g fs:%13g psu: %13g\n", \
29948 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
29949 (double)(fp)->fd, \
29950 (double)(fp)->fs[FP_ENDIAN_IDX], \
29951 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
29954 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
29955 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
29956 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
29957 " fd:%13g fs:%13g psu:%13g\n", \
29958 tmp.w[FP_ENDIAN_IDX], tmp.d, \
29960 (double)tmp.fs[FP_ENDIAN_IDX], \
29961 (double)tmp.fs[!FP_ENDIAN_IDX]); \
29967 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
29968 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
29969 get_float_exception_flags(&env->active_fpu.fp_status));
29970 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
29971 qemu_fprintf(f, "%3s: ", fregnames[i]);
29972 printfpr(&env->active_fpu.fpr[i]);
29978 void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
29980 MIPSCPU *cpu = MIPS_CPU(cs);
29981 CPUMIPSState *env = &cpu->env;
29984 qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29985 " LO=0x" TARGET_FMT_lx " ds %04x "
29986 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
29987 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29988 env->hflags, env->btarget, env->bcond);
29989 for (i = 0; i < 32; i++) {
29991 qemu_fprintf(f, "GPR%02d:", i);
29992 qemu_fprintf(f, " %s " TARGET_FMT_lx,
29993 regnames[i], env->active_tc.gpr[i]);
29995 qemu_fprintf(f, "\n");
29998 qemu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
29999 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
30000 qemu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
30002 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
30003 qemu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
30004 env->CP0_Config2, env->CP0_Config3);
30005 qemu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
30006 env->CP0_Config4, env->CP0_Config5);
30007 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
30008 fpu_dump_state(env, f, flags);
30012 void mips_tcg_init(void)
30017 for (i = 1; i < 32; i++)
30018 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
30019 offsetof(CPUMIPSState, active_tc.gpr[i]),
30022 for (i = 0; i < 32; i++) {
30023 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
30025 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
30026 /* The scalar floating-point unit (FPU) registers are mapped on
30027 * the MSA vector registers. */
30028 fpu_f64[i] = msa_wr_d[i * 2];
30029 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
30030 msa_wr_d[i * 2 + 1] =
30031 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
30034 cpu_PC = tcg_global_mem_new(cpu_env,
30035 offsetof(CPUMIPSState, active_tc.PC), "PC");
30036 for (i = 0; i < MIPS_DSP_ACC; i++) {
30037 cpu_HI[i] = tcg_global_mem_new(cpu_env,
30038 offsetof(CPUMIPSState, active_tc.HI[i]),
30040 cpu_LO[i] = tcg_global_mem_new(cpu_env,
30041 offsetof(CPUMIPSState, active_tc.LO[i]),
30044 cpu_dspctrl = tcg_global_mem_new(cpu_env,
30045 offsetof(CPUMIPSState, active_tc.DSPControl),
30047 bcond = tcg_global_mem_new(cpu_env,
30048 offsetof(CPUMIPSState, bcond), "bcond");
30049 btarget = tcg_global_mem_new(cpu_env,
30050 offsetof(CPUMIPSState, btarget), "btarget");
30051 hflags = tcg_global_mem_new_i32(cpu_env,
30052 offsetof(CPUMIPSState, hflags), "hflags");
30054 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
30055 offsetof(CPUMIPSState, active_fpu.fcr0),
30057 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
30058 offsetof(CPUMIPSState, active_fpu.fcr31),
30060 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
30062 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
30065 #if defined(TARGET_MIPS64)
30067 for (i = 1; i < 32; i++) {
30068 cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
30069 offsetof(CPUMIPSState,
30075 #if !defined(TARGET_MIPS64)
30076 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
30077 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
30078 offsetof(CPUMIPSState,
30079 active_tc.mxu_gpr[i]),
30083 mxu_CR = tcg_global_mem_new(cpu_env,
30084 offsetof(CPUMIPSState, active_tc.mxu_cr),
30085 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
30089 #include "translate_init.inc.c"
30091 void cpu_mips_realize_env(CPUMIPSState *env)
30093 env->exception_base = (int32_t)0xBFC00000;
30095 #ifndef CONFIG_USER_ONLY
30096 mmu_init(env, env->cpu_model);
30098 fpu_init(env, env->cpu_model);
30099 mvp_init(env, env->cpu_model);
30102 bool cpu_supports_cps_smp(const char *cpu_type)
30104 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
30105 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
30108 bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
30110 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
30111 return (mcc->cpu_def->insn_flags & isa) != 0;
30114 void cpu_set_exception_base(int vp_index, target_ulong address)
30116 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
30117 vp->env.exception_base = address;
30120 void cpu_state_reset(CPUMIPSState *env)
30122 CPUState *cs = env_cpu(env);
30124 /* Reset registers to their default values */
30125 env->CP0_PRid = env->cpu_model->CP0_PRid;
30126 env->CP0_Config0 = env->cpu_model->CP0_Config0;
30127 #ifdef TARGET_WORDS_BIGENDIAN
30128 env->CP0_Config0 |= (1 << CP0C0_BE);
30130 env->CP0_Config1 = env->cpu_model->CP0_Config1;
30131 env->CP0_Config2 = env->cpu_model->CP0_Config2;
30132 env->CP0_Config3 = env->cpu_model->CP0_Config3;
30133 env->CP0_Config4 = env->cpu_model->CP0_Config4;
30134 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
30135 env->CP0_Config5 = env->cpu_model->CP0_Config5;
30136 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
30137 env->CP0_Config6 = env->cpu_model->CP0_Config6;
30138 env->CP0_Config7 = env->cpu_model->CP0_Config7;
30139 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
30140 << env->cpu_model->CP0_LLAddr_shift;
30141 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
30142 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
30143 env->CCRes = env->cpu_model->CCRes;
30144 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
30145 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
30146 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
30147 env->current_tc = 0;
30148 env->SEGBITS = env->cpu_model->SEGBITS;
30149 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
30150 #if defined(TARGET_MIPS64)
30151 if (env->cpu_model->insn_flags & ISA_MIPS3) {
30152 env->SEGMask |= 3ULL << 62;
30155 env->PABITS = env->cpu_model->PABITS;
30156 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
30157 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
30158 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
30159 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
30160 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
30161 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
30162 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
30163 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
30164 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
30165 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
30166 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
30167 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
30168 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
30169 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
30170 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
30171 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
30172 env->msair = env->cpu_model->MSAIR;
30173 env->insn_flags = env->cpu_model->insn_flags;
30175 #if defined(CONFIG_USER_ONLY)
30176 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
30177 # ifdef TARGET_MIPS64
30178 /* Enable 64-bit register mode. */
30179 env->CP0_Status |= (1 << CP0St_PX);
30181 # ifdef TARGET_ABI_MIPSN64
30182 /* Enable 64-bit address mode. */
30183 env->CP0_Status |= (1 << CP0St_UX);
30185 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
30186 hardware registers. */
30187 env->CP0_HWREna |= 0x0000000F;
30188 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
30189 env->CP0_Status |= (1 << CP0St_CU1);
30191 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
30192 env->CP0_Status |= (1 << CP0St_MX);
30194 # if defined(TARGET_MIPS64)
30195 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
30196 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
30197 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
30198 env->CP0_Status |= (1 << CP0St_FR);
30202 if (env->hflags & MIPS_HFLAG_BMASK) {
30203 /* If the exception was raised from a delay slot,
30204 come back to the jump. */
30205 env->CP0_ErrorEPC = (env->active_tc.PC
30206 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
30208 env->CP0_ErrorEPC = env->active_tc.PC;
30210 env->active_tc.PC = env->exception_base;
30211 env->CP0_Random = env->tlb->nb_tlb - 1;
30212 env->tlb->tlb_in_use = env->tlb->nb_tlb;
30213 env->CP0_Wired = 0;
30214 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
30215 env->CP0_EBase = (cs->cpu_index & 0x3FF);
30216 if (mips_um_ksegs_enabled()) {
30217 env->CP0_EBase |= 0x40000000;
30219 env->CP0_EBase |= (int32_t)0x80000000;
30221 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
30222 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
30224 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
30226 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30227 /* vectored interrupts not implemented, timer on int 7,
30228 no performance counters. */
30229 env->CP0_IntCtl = 0xe0000000;
30233 for (i = 0; i < 7; i++) {
30234 env->CP0_WatchLo[i] = 0;
30235 env->CP0_WatchHi[i] = 0x80000000;
30237 env->CP0_WatchLo[7] = 0;
30238 env->CP0_WatchHi[7] = 0;
30240 /* Count register increments in debug mode, EJTAG version 1 */
30241 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30243 cpu_mips_store_count(env, 1);
30245 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30248 /* Only TC0 on VPE 0 starts as active. */
30249 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30250 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30251 env->tcs[i].CP0_TCHalt = 1;
30253 env->active_tc.CP0_TCHalt = 1;
30256 if (cs->cpu_index == 0) {
30257 /* VPE0 starts up enabled. */
30258 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30259 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30261 /* TC0 starts up unhalted. */
30263 env->active_tc.CP0_TCHalt = 0;
30264 env->tcs[0].CP0_TCHalt = 0;
30265 /* With thread 0 active. */
30266 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30267 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30272 * Configure default legacy segmentation control. We use this regardless of
30273 * whether segmentation control is presented to the guest.
30275 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30276 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
30277 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30278 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30279 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30280 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30282 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30283 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30284 (3 << CP0SC_C)) << 16;
30285 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30286 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30287 (1 << CP0SC_EU) | (2 << CP0SC_C);
30288 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30289 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30290 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30291 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30292 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30294 if ((env->insn_flags & ISA_MIPS32R6) &&
30295 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30296 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30297 env->CP0_Status |= (1 << CP0St_FR);
30300 if (env->insn_flags & ISA_MIPS32R6) {
30302 env->CP0_PWSize = 0x40;
30308 env->CP0_PWField = 0x0C30C302;
30315 env->CP0_PWField = 0x02;
30318 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30319 /* microMIPS on reset when Config3.ISA is 3 */
30320 env->hflags |= MIPS_HFLAG_M16;
30324 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30328 compute_hflags(env);
30329 restore_fp_status(env);
30330 restore_pamask(env);
30331 cs->exception_index = EXCP_NONE;
30333 if (semihosting_get_argc()) {
30334 /* UHI interface can be used to obtain argc and argv */
30335 env->active_tc.gpr[4] = -1;
30339 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30340 target_ulong *data)
30342 env->active_tc.PC = data[0];
30343 env->hflags &= ~MIPS_HFLAG_BMASK;
30344 env->hflags |= data[1];
30345 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30346 case MIPS_HFLAG_BR:
30348 case MIPS_HFLAG_BC:
30349 case MIPS_HFLAG_BL:
30351 env->btarget = data[2];