2 * MIPS emulation for QEMU - main translation routines
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 #include "qemu/osdep.h"
27 #include "disas/disas.h"
28 #include "exec/exec-all.h"
30 #include "exec/cpu_ldst.h"
31 #include "hw/mips/cpudevs.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
35 #include "exec/semihost.h"
37 #include "target/mips/trace.h"
38 #include "trace-tcg.h"
39 #include "exec/translator.h"
42 #define MIPS_DEBUG_DISAS 0
44 /* MIPS major opcodes */
45 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
48 /* indirect opcode tables */
49 OPC_SPECIAL = (0x00 << 26),
50 OPC_REGIMM = (0x01 << 26),
51 OPC_CP0 = (0x10 << 26),
52 OPC_CP1 = (0x11 << 26),
53 OPC_CP2 = (0x12 << 26),
54 OPC_CP3 = (0x13 << 26),
55 OPC_SPECIAL2 = (0x1C << 26),
56 OPC_SPECIAL3 = (0x1F << 26),
57 /* arithmetic with immediate */
58 OPC_ADDI = (0x08 << 26),
59 OPC_ADDIU = (0x09 << 26),
60 OPC_SLTI = (0x0A << 26),
61 OPC_SLTIU = (0x0B << 26),
62 /* logic with immediate */
63 OPC_ANDI = (0x0C << 26),
64 OPC_ORI = (0x0D << 26),
65 OPC_XORI = (0x0E << 26),
66 OPC_LUI = (0x0F << 26),
67 /* arithmetic with immediate */
68 OPC_DADDI = (0x18 << 26),
69 OPC_DADDIU = (0x19 << 26),
70 /* Jump and branches */
72 OPC_JAL = (0x03 << 26),
73 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
74 OPC_BEQL = (0x14 << 26),
75 OPC_BNE = (0x05 << 26),
76 OPC_BNEL = (0x15 << 26),
77 OPC_BLEZ = (0x06 << 26),
78 OPC_BLEZL = (0x16 << 26),
79 OPC_BGTZ = (0x07 << 26),
80 OPC_BGTZL = (0x17 << 26),
81 OPC_JALX = (0x1D << 26),
82 OPC_DAUI = (0x1D << 26),
84 OPC_LDL = (0x1A << 26),
85 OPC_LDR = (0x1B << 26),
86 OPC_LB = (0x20 << 26),
87 OPC_LH = (0x21 << 26),
88 OPC_LWL = (0x22 << 26),
89 OPC_LW = (0x23 << 26),
90 OPC_LWPC = OPC_LW | 0x5,
91 OPC_LBU = (0x24 << 26),
92 OPC_LHU = (0x25 << 26),
93 OPC_LWR = (0x26 << 26),
94 OPC_LWU = (0x27 << 26),
95 OPC_SB = (0x28 << 26),
96 OPC_SH = (0x29 << 26),
97 OPC_SWL = (0x2A << 26),
98 OPC_SW = (0x2B << 26),
99 OPC_SDL = (0x2C << 26),
100 OPC_SDR = (0x2D << 26),
101 OPC_SWR = (0x2E << 26),
102 OPC_LL = (0x30 << 26),
103 OPC_LLD = (0x34 << 26),
104 OPC_LD = (0x37 << 26),
105 OPC_LDPC = OPC_LD | 0x5,
106 OPC_SC = (0x38 << 26),
107 OPC_SCD = (0x3C << 26),
108 OPC_SD = (0x3F << 26),
109 /* Floating point load/store */
110 OPC_LWC1 = (0x31 << 26),
111 OPC_LWC2 = (0x32 << 26),
112 OPC_LDC1 = (0x35 << 26),
113 OPC_LDC2 = (0x36 << 26),
114 OPC_SWC1 = (0x39 << 26),
115 OPC_SWC2 = (0x3A << 26),
116 OPC_SDC1 = (0x3D << 26),
117 OPC_SDC2 = (0x3E << 26),
118 /* Compact Branches */
119 OPC_BLEZALC = (0x06 << 26),
120 OPC_BGEZALC = (0x06 << 26),
121 OPC_BGEUC = (0x06 << 26),
122 OPC_BGTZALC = (0x07 << 26),
123 OPC_BLTZALC = (0x07 << 26),
124 OPC_BLTUC = (0x07 << 26),
125 OPC_BOVC = (0x08 << 26),
126 OPC_BEQZALC = (0x08 << 26),
127 OPC_BEQC = (0x08 << 26),
128 OPC_BLEZC = (0x16 << 26),
129 OPC_BGEZC = (0x16 << 26),
130 OPC_BGEC = (0x16 << 26),
131 OPC_BGTZC = (0x17 << 26),
132 OPC_BLTZC = (0x17 << 26),
133 OPC_BLTC = (0x17 << 26),
134 OPC_BNVC = (0x18 << 26),
135 OPC_BNEZALC = (0x18 << 26),
136 OPC_BNEC = (0x18 << 26),
137 OPC_BC = (0x32 << 26),
138 OPC_BEQZC = (0x36 << 26),
139 OPC_JIC = (0x36 << 26),
140 OPC_BALC = (0x3A << 26),
141 OPC_BNEZC = (0x3E << 26),
142 OPC_JIALC = (0x3E << 26),
143 /* MDMX ASE specific */
144 OPC_MDMX = (0x1E << 26),
145 /* MSA ASE, same as MDMX */
147 /* Cache and prefetch */
148 OPC_CACHE = (0x2F << 26),
149 OPC_PREF = (0x33 << 26),
150 /* PC-relative address computation / loads */
151 OPC_PCREL = (0x3B << 26),
154 /* PC-relative address computation / loads */
155 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
156 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
158 /* Instructions determined by bits 19 and 20 */
159 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
160 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
161 OPC_LWUPC = OPC_PCREL | (2 << 19),
163 /* Instructions determined by bits 16 ... 20 */
164 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
165 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
168 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
171 /* MIPS special opcodes */
172 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
176 OPC_SLL = 0x00 | OPC_SPECIAL,
177 /* NOP is SLL r0, r0, 0 */
178 /* SSNOP is SLL r0, r0, 1 */
179 /* EHB is SLL r0, r0, 3 */
180 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
181 OPC_ROTR = OPC_SRL | (1 << 21),
182 OPC_SRA = 0x03 | OPC_SPECIAL,
183 OPC_SLLV = 0x04 | OPC_SPECIAL,
184 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
185 OPC_ROTRV = OPC_SRLV | (1 << 6),
186 OPC_SRAV = 0x07 | OPC_SPECIAL,
187 OPC_DSLLV = 0x14 | OPC_SPECIAL,
188 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
189 OPC_DROTRV = OPC_DSRLV | (1 << 6),
190 OPC_DSRAV = 0x17 | OPC_SPECIAL,
191 OPC_DSLL = 0x38 | OPC_SPECIAL,
192 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
193 OPC_DROTR = OPC_DSRL | (1 << 21),
194 OPC_DSRA = 0x3B | OPC_SPECIAL,
195 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
196 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
197 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
198 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
199 /* Multiplication / division */
200 OPC_MULT = 0x18 | OPC_SPECIAL,
201 OPC_MULTU = 0x19 | OPC_SPECIAL,
202 OPC_DIV = 0x1A | OPC_SPECIAL,
203 OPC_DIVU = 0x1B | OPC_SPECIAL,
204 OPC_DMULT = 0x1C | OPC_SPECIAL,
205 OPC_DMULTU = 0x1D | OPC_SPECIAL,
206 OPC_DDIV = 0x1E | OPC_SPECIAL,
207 OPC_DDIVU = 0x1F | OPC_SPECIAL,
209 /* 2 registers arithmetic / logic */
210 OPC_ADD = 0x20 | OPC_SPECIAL,
211 OPC_ADDU = 0x21 | OPC_SPECIAL,
212 OPC_SUB = 0x22 | OPC_SPECIAL,
213 OPC_SUBU = 0x23 | OPC_SPECIAL,
214 OPC_AND = 0x24 | OPC_SPECIAL,
215 OPC_OR = 0x25 | OPC_SPECIAL,
216 OPC_XOR = 0x26 | OPC_SPECIAL,
217 OPC_NOR = 0x27 | OPC_SPECIAL,
218 OPC_SLT = 0x2A | OPC_SPECIAL,
219 OPC_SLTU = 0x2B | OPC_SPECIAL,
220 OPC_DADD = 0x2C | OPC_SPECIAL,
221 OPC_DADDU = 0x2D | OPC_SPECIAL,
222 OPC_DSUB = 0x2E | OPC_SPECIAL,
223 OPC_DSUBU = 0x2F | OPC_SPECIAL,
225 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
226 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
228 OPC_TGE = 0x30 | OPC_SPECIAL,
229 OPC_TGEU = 0x31 | OPC_SPECIAL,
230 OPC_TLT = 0x32 | OPC_SPECIAL,
231 OPC_TLTU = 0x33 | OPC_SPECIAL,
232 OPC_TEQ = 0x34 | OPC_SPECIAL,
233 OPC_TNE = 0x36 | OPC_SPECIAL,
234 /* HI / LO registers load & stores */
235 OPC_MFHI = 0x10 | OPC_SPECIAL,
236 OPC_MTHI = 0x11 | OPC_SPECIAL,
237 OPC_MFLO = 0x12 | OPC_SPECIAL,
238 OPC_MTLO = 0x13 | OPC_SPECIAL,
239 /* Conditional moves */
240 OPC_MOVZ = 0x0A | OPC_SPECIAL,
241 OPC_MOVN = 0x0B | OPC_SPECIAL,
243 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
244 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
246 OPC_MOVCI = 0x01 | OPC_SPECIAL,
249 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
250 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
251 OPC_BREAK = 0x0D | OPC_SPECIAL,
252 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
253 OPC_SYNC = 0x0F | OPC_SPECIAL,
255 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
256 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
257 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
258 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
261 /* R6 Multiply and Divide instructions have the same Opcode
262 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
263 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
266 R6_OPC_MUL = OPC_MULT | (2 << 6),
267 R6_OPC_MUH = OPC_MULT | (3 << 6),
268 R6_OPC_MULU = OPC_MULTU | (2 << 6),
269 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
270 R6_OPC_DIV = OPC_DIV | (2 << 6),
271 R6_OPC_MOD = OPC_DIV | (3 << 6),
272 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
273 R6_OPC_MODU = OPC_DIVU | (3 << 6),
275 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
276 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
277 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
278 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
279 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
280 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
281 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
282 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
284 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
285 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
286 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
287 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
288 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
290 OPC_LSA = 0x05 | OPC_SPECIAL,
291 OPC_DLSA = 0x15 | OPC_SPECIAL,
294 /* Multiplication variants of the vr54xx. */
295 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
298 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
299 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
300 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
301 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
302 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
303 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
304 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
305 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
306 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
307 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
308 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
309 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
310 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
311 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
314 /* REGIMM (rt field) opcodes */
315 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
318 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
319 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
320 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
321 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
322 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
323 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
324 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
325 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
326 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
327 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
328 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
329 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
330 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
331 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
332 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
333 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
335 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
336 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
339 /* Special2 opcodes */
340 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
343 /* Multiply & xxx operations */
344 OPC_MADD = 0x00 | OPC_SPECIAL2,
345 OPC_MADDU = 0x01 | OPC_SPECIAL2,
346 OPC_MUL = 0x02 | OPC_SPECIAL2,
347 OPC_MSUB = 0x04 | OPC_SPECIAL2,
348 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
350 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
351 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
352 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
353 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
354 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
355 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
356 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
357 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
358 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
359 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
360 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
361 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
363 OPC_CLZ = 0x20 | OPC_SPECIAL2,
364 OPC_CLO = 0x21 | OPC_SPECIAL2,
365 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
366 OPC_DCLO = 0x25 | OPC_SPECIAL2,
368 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
371 /* Special3 opcodes */
372 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
375 OPC_EXT = 0x00 | OPC_SPECIAL3,
376 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
377 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
378 OPC_DEXT = 0x03 | OPC_SPECIAL3,
379 OPC_INS = 0x04 | OPC_SPECIAL3,
380 OPC_DINSM = 0x05 | OPC_SPECIAL3,
381 OPC_DINSU = 0x06 | OPC_SPECIAL3,
382 OPC_DINS = 0x07 | OPC_SPECIAL3,
383 OPC_FORK = 0x08 | OPC_SPECIAL3,
384 OPC_YIELD = 0x09 | OPC_SPECIAL3,
385 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
386 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
387 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
390 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
391 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
392 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
393 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
394 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
395 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
396 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
397 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
398 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
399 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
400 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
401 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
404 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
405 /* MIPS DSP Arithmetic */
406 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
407 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
408 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
409 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
410 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
411 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
413 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
414 /* MIPS DSP GPR-Based Shift Sub-class */
415 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
416 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
417 /* MIPS DSP Multiply Sub-class insns */
418 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
419 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
420 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
421 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
422 /* DSP Bit/Manipulation Sub-class */
423 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
424 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
425 /* MIPS DSP Append Sub-class */
426 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
427 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
428 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
429 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
430 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
433 OPC_LWLE = 0x19 | OPC_SPECIAL3,
434 OPC_LWRE = 0x1A | OPC_SPECIAL3,
435 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
436 OPC_SBE = 0x1C | OPC_SPECIAL3,
437 OPC_SHE = 0x1D | OPC_SPECIAL3,
438 OPC_SCE = 0x1E | OPC_SPECIAL3,
439 OPC_SWE = 0x1F | OPC_SPECIAL3,
440 OPC_SWLE = 0x21 | OPC_SPECIAL3,
441 OPC_SWRE = 0x22 | OPC_SPECIAL3,
442 OPC_PREFE = 0x23 | OPC_SPECIAL3,
443 OPC_LBUE = 0x28 | OPC_SPECIAL3,
444 OPC_LHUE = 0x29 | OPC_SPECIAL3,
445 OPC_LBE = 0x2C | OPC_SPECIAL3,
446 OPC_LHE = 0x2D | OPC_SPECIAL3,
447 OPC_LLE = 0x2E | OPC_SPECIAL3,
448 OPC_LWE = 0x2F | OPC_SPECIAL3,
451 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
452 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
453 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
454 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
455 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
456 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
460 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
463 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
464 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
465 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
466 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
467 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
468 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
469 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
470 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
474 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
477 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
478 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
479 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
480 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
481 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
482 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
483 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
484 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
485 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
486 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
487 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
490 /* MIPS DSP REGIMM opcodes */
492 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
493 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
496 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
499 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
500 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
501 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
502 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
505 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
507 /* MIPS DSP Arithmetic Sub-class */
508 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
509 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
510 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
511 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
512 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
513 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
515 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
516 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
517 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
518 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
519 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
520 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
521 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
522 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
523 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
524 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
525 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
526 /* MIPS DSP Multiply Sub-class insns */
527 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
528 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
529 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
530 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
531 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
532 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
535 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
536 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
538 /* MIPS DSP Arithmetic Sub-class */
539 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
541 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
542 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
543 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
544 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
545 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
546 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
548 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
549 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
550 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
551 /* MIPS DSP Multiply Sub-class insns */
552 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
553 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
554 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
555 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
558 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
560 /* MIPS DSP Arithmetic Sub-class */
561 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
564 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
566 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
567 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
572 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
573 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
574 /* DSP Bit/Manipulation Sub-class */
575 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
576 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
577 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
578 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
579 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
582 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
584 /* MIPS DSP Arithmetic Sub-class */
585 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
592 /* DSP Compare-Pick Sub-class */
593 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
600 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
601 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
602 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
603 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
604 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
605 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
606 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
607 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
610 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
612 /* MIPS DSP GPR-Based Shift Sub-class */
613 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
627 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
628 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
629 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
630 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
631 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
632 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
633 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
634 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
637 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
639 /* MIPS DSP Multiply Sub-class insns */
640 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
646 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
649 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
652 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
654 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
655 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
656 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
657 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
658 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
659 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
660 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
661 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
664 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
666 /* DSP Bit/Manipulation Sub-class */
667 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
670 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
672 /* MIPS DSP Append Sub-class */
673 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
674 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
675 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
678 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
680 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
681 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
683 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
684 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
685 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
686 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
687 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
688 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
689 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
690 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
691 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
692 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
693 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
694 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
695 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
696 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
697 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
700 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
702 /* MIPS DSP Arithmetic Sub-class */
703 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
712 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
713 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
719 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
720 /* DSP Bit/Manipulation Sub-class */
721 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
722 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
723 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
724 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
725 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
726 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
729 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
731 /* MIPS DSP Multiply Sub-class insns */
732 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
733 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
734 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
735 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
736 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
737 /* MIPS DSP Arithmetic Sub-class */
738 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
739 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
740 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
741 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
742 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
743 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
744 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
745 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
746 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
747 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
748 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
749 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
750 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
751 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
752 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
753 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
754 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
755 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
756 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
757 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
758 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
761 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
763 /* DSP Compare-Pick Sub-class */
764 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
775 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
776 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
783 /* MIPS DSP Arithmetic Sub-class */
784 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
785 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
786 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
787 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
788 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
789 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
790 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
794 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
796 /* DSP Append Sub-class */
797 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
798 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
799 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
800 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
803 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
805 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
806 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
807 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
819 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
820 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
821 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
822 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
823 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
824 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
825 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
826 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
829 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
831 /* DSP Bit/Manipulation Sub-class */
832 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
835 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
837 /* MIPS DSP Multiply Sub-class insns */
838 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
856 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
857 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
858 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
859 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
860 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
861 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
862 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
863 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
866 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
868 /* MIPS DSP GPR-Based Shift Sub-class */
869 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
887 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
888 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
889 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
890 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
891 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
892 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
893 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
894 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
897 /* Coprocessor 0 (rs field) */
898 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
901 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
902 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
903 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
904 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
905 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
906 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
907 OPC_MFTR = (0x08 << 21) | OPC_CP0,
908 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
909 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
910 OPC_MTTR = (0x0C << 21) | OPC_CP0,
911 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
912 OPC_C0 = (0x10 << 21) | OPC_CP0,
913 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
914 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
915 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
916 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
917 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
918 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
919 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
920 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
921 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
922 OPC_C0_A = (0x1A << 21) | OPC_CP0,
923 OPC_C0_B = (0x1B << 21) | OPC_CP0,
924 OPC_C0_C = (0x1C << 21) | OPC_CP0,
925 OPC_C0_D = (0x1D << 21) | OPC_CP0,
926 OPC_C0_E = (0x1E << 21) | OPC_CP0,
927 OPC_C0_F = (0x1F << 21) | OPC_CP0,
931 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
934 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
935 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
936 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
937 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
938 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
939 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
940 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
941 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
944 /* Coprocessor 0 (with rs == C0) */
945 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
948 OPC_TLBR = 0x01 | OPC_C0,
949 OPC_TLBWI = 0x02 | OPC_C0,
950 OPC_TLBINV = 0x03 | OPC_C0,
951 OPC_TLBINVF = 0x04 | OPC_C0,
952 OPC_TLBWR = 0x06 | OPC_C0,
953 OPC_TLBP = 0x08 | OPC_C0,
954 OPC_RFE = 0x10 | OPC_C0,
955 OPC_ERET = 0x18 | OPC_C0,
956 OPC_DERET = 0x1F | OPC_C0,
957 OPC_WAIT = 0x20 | OPC_C0,
960 /* Coprocessor 1 (rs field) */
961 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
963 /* Values for the fmt field in FP instructions */
965 /* 0 - 15 are reserved */
966 FMT_S = 16, /* single fp */
967 FMT_D = 17, /* double fp */
968 FMT_E = 18, /* extended fp */
969 FMT_Q = 19, /* quad fp */
970 FMT_W = 20, /* 32-bit fixed */
971 FMT_L = 21, /* 64-bit fixed */
972 FMT_PS = 22, /* paired single fp */
973 /* 23 - 31 are reserved */
977 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
978 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
979 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
980 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
981 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
982 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
983 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
984 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
985 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
986 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
987 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
988 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
989 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
990 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
991 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
992 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
993 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
994 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
995 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
996 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
997 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
998 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
999 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
1000 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
1001 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
1002 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
1003 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
1004 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
1005 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
1006 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
1009 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1010 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1013 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1014 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1015 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1016 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1020 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1021 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1025 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1026 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1029 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1032 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1033 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1034 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1035 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1036 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1037 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1038 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1039 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1040 OPC_BC2 = (0x08 << 21) | OPC_CP2,
1041 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1042 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1045 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1048 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1049 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1050 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1051 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1052 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1053 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1054 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1055 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1057 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1058 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1059 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1060 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1061 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1062 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1063 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1064 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1066 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1067 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1068 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1069 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1070 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1071 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1072 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1073 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1075 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1076 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1077 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1078 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1079 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1080 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1081 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1082 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1084 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1085 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1086 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1087 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1088 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1089 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1091 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1092 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1093 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1094 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1095 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1096 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1098 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1099 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1100 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1101 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1102 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1103 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1105 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1106 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1107 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1108 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1109 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1110 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1112 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1113 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1114 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1115 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1116 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1117 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1119 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1120 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1121 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1122 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1123 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1124 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1126 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1127 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1128 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1129 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1130 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1131 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1133 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1134 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1135 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1136 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1137 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1138 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1142 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1145 OPC_LWXC1 = 0x00 | OPC_CP3,
1146 OPC_LDXC1 = 0x01 | OPC_CP3,
1147 OPC_LUXC1 = 0x05 | OPC_CP3,
1148 OPC_SWXC1 = 0x08 | OPC_CP3,
1149 OPC_SDXC1 = 0x09 | OPC_CP3,
1150 OPC_SUXC1 = 0x0D | OPC_CP3,
1151 OPC_PREFX = 0x0F | OPC_CP3,
1152 OPC_ALNV_PS = 0x1E | OPC_CP3,
1153 OPC_MADD_S = 0x20 | OPC_CP3,
1154 OPC_MADD_D = 0x21 | OPC_CP3,
1155 OPC_MADD_PS = 0x26 | OPC_CP3,
1156 OPC_MSUB_S = 0x28 | OPC_CP3,
1157 OPC_MSUB_D = 0x29 | OPC_CP3,
1158 OPC_MSUB_PS = 0x2E | OPC_CP3,
1159 OPC_NMADD_S = 0x30 | OPC_CP3,
1160 OPC_NMADD_D = 0x31 | OPC_CP3,
1161 OPC_NMADD_PS= 0x36 | OPC_CP3,
1162 OPC_NMSUB_S = 0x38 | OPC_CP3,
1163 OPC_NMSUB_D = 0x39 | OPC_CP3,
1164 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1168 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1170 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1171 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1172 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1173 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1174 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1175 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1176 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1177 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1178 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1179 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1180 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1181 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1182 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1183 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1184 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1185 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1186 OPC_MSA_ELM = 0x19 | OPC_MSA,
1187 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1188 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1189 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1190 OPC_MSA_VEC = 0x1E | OPC_MSA,
1192 /* MI10 instruction */
1193 OPC_LD_B = (0x20) | OPC_MSA,
1194 OPC_LD_H = (0x21) | OPC_MSA,
1195 OPC_LD_W = (0x22) | OPC_MSA,
1196 OPC_LD_D = (0x23) | OPC_MSA,
1197 OPC_ST_B = (0x24) | OPC_MSA,
1198 OPC_ST_H = (0x25) | OPC_MSA,
1199 OPC_ST_W = (0x26) | OPC_MSA,
1200 OPC_ST_D = (0x27) | OPC_MSA,
1204 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1205 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1206 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1207 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1208 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1209 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1210 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1211 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1212 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1213 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1214 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1215 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1216 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1218 /* I8 instruction */
1219 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1220 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1221 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1222 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1223 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1224 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1225 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1226 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1227 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1228 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1230 /* VEC/2R/2RF instruction */
1231 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1232 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1233 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1234 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1235 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1236 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1237 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1239 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1240 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1242 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1243 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1244 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1245 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1246 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1248 /* 2RF instruction df(bit 16) = _w, _d */
1249 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1250 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1251 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1252 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1253 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1254 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1255 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1256 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1257 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1258 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1259 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1260 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1261 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1262 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1263 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1264 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1266 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1267 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1268 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1269 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1270 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1271 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1272 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1273 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1274 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1275 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1276 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1277 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1278 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1279 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1280 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1281 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1282 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1283 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1284 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1285 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1286 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1287 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1288 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1289 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1290 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1291 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1292 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1293 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1294 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1295 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1296 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1297 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1298 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1299 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1300 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1301 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1302 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1303 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1304 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1305 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1306 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1307 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1308 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1309 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1310 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1311 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1312 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1313 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1314 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1315 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1316 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1317 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1318 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1319 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1320 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1321 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1322 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1323 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1324 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1325 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1326 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1327 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1328 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1329 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1331 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1332 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1334 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1335 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1336 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1337 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1338 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1339 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1342 /* 3RF instruction _df(bit 21) = _w, _d */
1343 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1345 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1346 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1347 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1348 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1349 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1350 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1351 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1352 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1353 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1356 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1357 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1358 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1359 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1361 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1362 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1363 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1364 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1365 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1366 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1367 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1368 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1369 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1370 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1372 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1373 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1374 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1375 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1376 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1377 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1378 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1379 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1380 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1381 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1382 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1383 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1385 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1386 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1387 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1388 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1389 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1390 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1391 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1392 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1393 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1394 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1395 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1396 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1397 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1402 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1403 * ============================================
1405 * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
1406 * instructions set. It is designed to fit the needs of signal, graphical and
1407 * video processing applications. MXU instruction set is used in Xburst family
1408 * of microprocessors by Ingenic.
1410 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1411 * the control register.
1413 * The notation used in MXU assembler mnemonics:
1415 * XRa, XRb, XRc, XRd - MXU registers
1416 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1417 * s12 - a subfield of an instruction code
1418 * strd2 - a subfield of an instruction code
1419 * eptn2 - a subfield of an instruction code
1420 * eptn3 - a subfield of an instruction code
1421 * optn2 - a subfield of an instruction code
1422 * optn3 - a subfield of an instruction code
1423 * sft4 - a subfield of an instruction code
1425 * Load/Store instructions Multiplication instructions
1426 * ----------------------- ---------------------------
1428 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1429 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1430 * S32LDDV XRa, Rb, rc, strd2 S32SUB XRa, XRd, Rs, Rt
1431 * S32STDV XRa, Rb, rc, strd2 S32SUBU XRa, XRd, Rs, Rt
1432 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1433 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1434 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1435 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1436 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1437 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1438 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1439 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1440 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1441 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1442 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1443 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1444 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1445 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1446 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1447 * S16SDI XRa, Rb, s10, eptn2
1448 * S8LDD XRa, Rb, s8, eptn3
1449 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1450 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1451 * S8SDI XRa, Rb, s8, eptn3
1452 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1453 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1454 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1455 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1456 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1457 * S32CPS XRa, XRb, XRc
1458 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1459 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1460 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1461 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1462 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1463 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1464 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1465 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1466 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1467 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1468 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1469 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1470 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1471 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1472 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1473 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1474 * Q8SLT XRa, XRb, XRc
1475 * Q8SLTU XRa, XRb, XRc
1476 * Q8MOVZ XRa, XRb, XRc Shift instructions
1477 * Q8MOVN XRa, XRb, XRc ------------------
1479 * D32SLL XRa, XRb, XRc, XRd, sft4
1480 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1481 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1482 * D32SARL XRa, XRb, XRc, sft4
1483 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1484 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1485 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1486 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1487 * Q16SLL XRa, XRb, XRc, XRd, sft4
1488 * Q16SLR XRa, XRb, XRc, XRd, sft4
1489 * Miscelaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1490 * ------------------------- Q16SLLV XRa, XRb, Rb
1491 * Q16SLRV XRa, XRb, Rb
1492 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1493 * S32ALN XRa, XRb, XRc, Rb
1494 * S32ALNI XRa, XRb, XRc, s3
1495 * S32LUI XRa, s8, optn3 Move instructions
1496 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1497 * S32EXTRV XRa, XRb, Rs, Rt
1498 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1499 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1505 * ┌─ 000000 ─ OPC_MXU_S32MADD
1506 * ├─ 000001 ─ OPC_MXU_S32MADDU
1507 * ├─ 000010 ─ <not assigned>
1509 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1510 * │ ├─ 001 ─ OPC_MXU_S32MIN
1511 * │ ├─ 010 ─ OPC_MXU_D16MAX
1512 * │ ├─ 011 ─ OPC_MXU_D16MIN
1513 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1514 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1515 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1516 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1517 * ├─ 000100 ─ OPC_MXU_S32MSUB
1518 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1519 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1520 * │ ├─ 001 ─ OPC_MXU_D16SLT
1521 * │ ├─ 010 ─ OPC_MXU_D16AVG
1522 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1523 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1524 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1525 * │ └─ 111 ─ OPC_MXU_Q8ADD
1528 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1529 * │ ├─ 010 ─ OPC_MXU_D16CPS
1530 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1531 * │ └─ 110 ─ OPC_MXU_Q16SAT
1532 * ├─ 001000 ─ OPC_MXU_D16MUL
1534 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1535 * │ └─ 01 ─ OPC_MXU_D16MULE
1536 * ├─ 001010 ─ OPC_MXU_D16MAC
1537 * ├─ 001011 ─ OPC_MXU_D16MACF
1538 * ├─ 001100 ─ OPC_MXU_D16MADL
1540 * ├─ 001101 ─ OPC_MXU__POOL04 ─┬─ 00 ─ OPC_MXU_S16MAD
1541 * │ └─ 01 ─ OPC_MXU_S16MAD_1
1542 * ├─ 001110 ─ OPC_MXU_Q16ADD
1543 * ├─ 001111 ─ OPC_MXU_D16MACE
1545 * ├─ 010000 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32LDD
1546 * │ └─ 1 ─ OPC_MXU_S32LDDR
1549 * ├─ 010001 ─ OPC_MXU__POOL06 ─┬─ 0 ─ OPC_MXU_S32STD
1550 * │ └─ 1 ─ OPC_MXU_S32STDR
1553 * ├─ 010010 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1554 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1557 * ├─ 010011 ─ OPC_MXU__POOL08 ─┬─ 0000 ─ OPC_MXU_S32STDV
1558 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1561 * ├─ 010100 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32LDI
1562 * │ └─ 1 ─ OPC_MXU_S32LDIR
1565 * ├─ 010101 ─ OPC_MXU__POOL10 ─┬─ 0 ─ OPC_MXU_S32SDI
1566 * │ └─ 1 ─ OPC_MXU_S32SDIR
1569 * ├─ 010110 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1570 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1573 * ├─ 010111 ─ OPC_MXU__POOL12 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1574 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1575 * ├─ 011000 ─ OPC_MXU_D32ADD
1577 * MXU ├─ 011001 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_D32ACC
1578 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1579 * │ └─ 10 ─ OPC_MXU_D32ASUM
1580 * ├─ 011010 ─ <not assigned>
1582 * ├─ 011011 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q16ACC
1583 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1584 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1587 * ├─ 011100 ─ OPC_MXU__POOL15 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1588 * │ ├─ 01 ─ OPC_MXU_D8SUM
1589 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1590 * ├─ 011110 ─ <not assigned>
1591 * ├─ 011111 ─ <not assigned>
1592 * ├─ 100000 ─ <not assigned>
1593 * ├─ 100001 ─ <not assigned>
1594 * ├─ 100010 ─ OPC_MXU_S8LDD
1595 * ├─ 100011 ─ OPC_MXU_S8STD
1596 * ├─ 100100 ─ OPC_MXU_S8LDI
1597 * ├─ 100101 ─ OPC_MXU_S8SDI
1599 * ├─ 100110 ─ OPC_MXU__POOL16 ─┬─ 00 ─ OPC_MXU_S32MUL
1600 * │ ├─ 00 ─ OPC_MXU_S32MULU
1601 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1602 * │ └─ 00 ─ OPC_MXU_S32EXTRV
1605 * ├─ 100111 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_D32SARW
1606 * │ ├─ 001 ─ OPC_MXU_S32ALN
1607 * ├─ 101000 ─ OPC_MXU_LXB ├─ 010 ─ OPC_MXU_S32ALNI
1608 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_S32NOR
1609 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_S32AND
1610 * ├─ 101011 ─ OPC_MXU_S16STD ├─ 101 ─ OPC_MXU_S32OR
1611 * ├─ 101100 ─ OPC_MXU_S16LDI ├─ 110 ─ OPC_MXU_S32XOR
1612 * ├─ 101101 ─ OPC_MXU_S16SDI └─ 111 ─ OPC_MXU_S32LUI
1613 * ├─ 101000 ─ <not assigned>
1614 * ├─ 101001 ─ <not assigned>
1615 * ├─ 101010 ─ <not assigned>
1616 * ├─ 101011 ─ <not assigned>
1617 * ├─ 101100 ─ <not assigned>
1618 * ├─ 101101 ─ <not assigned>
1619 * ├─ 101110 ─ OPC_MXU_S32M2I
1620 * ├─ 101111 ─ OPC_MXU_S32I2M
1621 * ├─ 110000 ─ OPC_MXU_D32SLL
1622 * ├─ 110001 ─ OPC_MXU_D32SLR
1623 * ├─ 110010 ─ OPC_MXU_D32SARL
1624 * ├─ 110011 ─ OPC_MXU_D32SAR
1625 * ├─ 110100 ─ OPC_MXU_Q16SLL
1626 * ├─ 110101 ─ OPC_MXU_Q16SLR 20..18
1627 * ├─ 110110 ─ OPC_MXU__POOL18 ─┬─ 000 ─ OPC_MXU_D32SLLV
1628 * │ ├─ 001 ─ OPC_MXU_D32SLRV
1629 * │ ├─ 010 ─ OPC_MXU_D32SARV
1630 * │ ├─ 011 ─ OPC_MXU_Q16SLLV
1631 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1632 * │ └─ 101 ─ OPC_MXU_Q16SARV
1633 * ├─ 110111 ─ OPC_MXU_Q16SAR
1635 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1636 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1639 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1640 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1641 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1642 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1643 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1644 * │ └─ 101 ─ OPC_MXU_S32MOV
1647 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1648 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1649 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1650 * ├─ 111100 ─ OPC_MXU_Q8MADL
1651 * ├─ 111101 ─ OPC_MXU_S32SFL
1652 * ├─ 111110 ─ OPC_MXU_Q8SAD
1653 * └─ 111111 ─ <not assigned>
1658 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1659 * Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1663 OPC_MXU_S32MADD = 0x00,
1664 OPC_MXU_S32MADDU = 0x01,
1665 /* not assigned 0x02 */
1666 OPC_MXU__POOL00 = 0x03,
1667 OPC_MXU_S32MSUB = 0x04,
1668 OPC_MXU_S32MSUBU = 0x05,
1669 OPC_MXU__POOL01 = 0x06,
1670 OPC_MXU__POOL02 = 0x07,
1671 OPC_MXU_D16MUL = 0x08,
1672 OPC_MXU__POOL03 = 0x09,
1673 OPC_MXU_D16MAC = 0x0A,
1674 OPC_MXU_D16MACF = 0x0B,
1675 OPC_MXU_D16MADL = 0x0C,
1676 OPC_MXU__POOL04 = 0x0D,
1677 OPC_MXU_Q16ADD = 0x0E,
1678 OPC_MXU_D16MACE = 0x0F,
1679 OPC_MXU__POOL05 = 0x10,
1680 OPC_MXU__POOL06 = 0x11,
1681 OPC_MXU__POOL07 = 0x12,
1682 OPC_MXU__POOL08 = 0x13,
1683 OPC_MXU__POOL09 = 0x14,
1684 OPC_MXU__POOL10 = 0x15,
1685 OPC_MXU__POOL11 = 0x16,
1686 OPC_MXU__POOL12 = 0x17,
1687 OPC_MXU_D32ADD = 0x18,
1688 OPC_MXU__POOL13 = 0x19,
1689 /* not assigned 0x1A */
1690 OPC_MXU__POOL14 = 0x1B,
1691 OPC_MXU__POOL15 = 0x1C,
1692 OPC_MXU_Q8ACCE = 0x1D,
1693 /* not assigned 0x1E */
1694 /* not assigned 0x1F */
1695 /* not assigned 0x20 */
1696 /* not assigned 0x21 */
1697 OPC_MXU_S8LDD = 0x22,
1698 OPC_MXU_S8STD = 0x23,
1699 OPC_MXU_S8LDI = 0x24,
1700 OPC_MXU_S8SDI = 0x25,
1701 OPC_MXU__POOL16 = 0x26,
1702 OPC_MXU__POOL17 = 0x27,
1704 /* not assigned 0x29 */
1705 OPC_MXU_S16LDD = 0x2A,
1706 OPC_MXU_S16STD = 0x2B,
1707 OPC_MXU_S16LDI = 0x2C,
1708 OPC_MXU_S16SDI = 0x2D,
1709 OPC_MXU_S32M2I = 0x2E,
1710 OPC_MXU_S32I2M = 0x2F,
1711 OPC_MXU_D32SLL = 0x30,
1712 OPC_MXU_D32SLR = 0x31,
1713 OPC_MXU_D32SARL = 0x32,
1714 OPC_MXU_D32SAR = 0x33,
1715 OPC_MXU_Q16SLL = 0x34,
1716 OPC_MXU_Q16SLR = 0x35,
1717 OPC_MXU__POOL18 = 0x36,
1718 OPC_MXU_Q16SAR = 0x37,
1719 OPC_MXU__POOL19 = 0x38,
1720 OPC_MXU__POOL20 = 0x39,
1721 OPC_MXU__POOL21 = 0x3A,
1722 OPC_MXU_Q16SCOP = 0x3B,
1723 OPC_MXU_Q8MADL = 0x3C,
1724 OPC_MXU_S32SFL = 0x3D,
1725 OPC_MXU_Q8SAD = 0x3E,
1726 /* not assigned 0x3F */
1734 OPC_MXU_S32MAX = 0x00,
1735 OPC_MXU_S32MIN = 0x01,
1736 OPC_MXU_D16MAX = 0x02,
1737 OPC_MXU_D16MIN = 0x03,
1738 OPC_MXU_Q8MAX = 0x04,
1739 OPC_MXU_Q8MIN = 0x05,
1740 OPC_MXU_Q8SLT = 0x06,
1741 OPC_MXU_Q8SLTU = 0x07,
1748 OPC_MXU_S32SLT = 0x00,
1749 OPC_MXU_D16SLT = 0x01,
1750 OPC_MXU_D16AVG = 0x02,
1751 OPC_MXU_D16AVGR = 0x03,
1752 OPC_MXU_Q8AVG = 0x04,
1753 OPC_MXU_Q8AVGR = 0x05,
1754 OPC_MXU_Q8ADD = 0x07,
1761 OPC_MXU_S32CPS = 0x00,
1762 OPC_MXU_D16CPS = 0x02,
1763 OPC_MXU_Q8ABD = 0x04,
1764 OPC_MXU_Q16SAT = 0x06,
1771 OPC_MXU_D16MULF = 0x00,
1772 OPC_MXU_D16MULE = 0x01,
1779 OPC_MXU_S16MAD = 0x00,
1780 OPC_MXU_S16MAD_1 = 0x01,
1787 OPC_MXU_S32LDD = 0x00,
1788 OPC_MXU_S32LDDR = 0x01,
1795 OPC_MXU_S32STD = 0x00,
1796 OPC_MXU_S32STDR = 0x01,
1803 OPC_MXU_S32LDDV = 0x00,
1804 OPC_MXU_S32LDDVR = 0x01,
1811 OPC_MXU_S32STDV = 0x00,
1812 OPC_MXU_S32STDVR = 0x01,
1819 OPC_MXU_S32LDI = 0x00,
1820 OPC_MXU_S32LDIR = 0x01,
1827 OPC_MXU_S32SDI = 0x00,
1828 OPC_MXU_S32SDIR = 0x01,
1835 OPC_MXU_S32LDIV = 0x00,
1836 OPC_MXU_S32LDIVR = 0x01,
1843 OPC_MXU_S32SDIV = 0x00,
1844 OPC_MXU_S32SDIVR = 0x01,
1851 OPC_MXU_D32ACC = 0x00,
1852 OPC_MXU_D32ACCM = 0x01,
1853 OPC_MXU_D32ASUM = 0x02,
1860 OPC_MXU_Q16ACC = 0x00,
1861 OPC_MXU_Q16ACCM = 0x01,
1862 OPC_MXU_Q16ASUM = 0x02,
1869 OPC_MXU_Q8ADDE = 0x00,
1870 OPC_MXU_D8SUM = 0x01,
1871 OPC_MXU_D8SUMC = 0x02,
1878 OPC_MXU_S32MUL = 0x00,
1879 OPC_MXU_S32MULU = 0x01,
1880 OPC_MXU_S32EXTR = 0x02,
1881 OPC_MXU_S32EXTRV = 0x03,
1888 OPC_MXU_D32SARW = 0x00,
1889 OPC_MXU_S32ALN = 0x01,
1890 OPC_MXU_S32ALNI = 0x02,
1891 OPC_MXU_S32NOR = 0x03,
1892 OPC_MXU_S32AND = 0x04,
1893 OPC_MXU_S32OR = 0x05,
1894 OPC_MXU_S32XOR = 0x06,
1895 OPC_MXU_S32LUI = 0x07,
1902 OPC_MXU_D32SLLV = 0x00,
1903 OPC_MXU_D32SLRV = 0x01,
1904 OPC_MXU_D32SARV = 0x03,
1905 OPC_MXU_Q16SLLV = 0x04,
1906 OPC_MXU_Q16SLRV = 0x05,
1907 OPC_MXU_Q16SARV = 0x07,
1914 OPC_MXU_Q8MUL = 0x00,
1915 OPC_MXU_Q8MULSU = 0x01,
1922 OPC_MXU_Q8MOVZ = 0x00,
1923 OPC_MXU_Q8MOVN = 0x01,
1924 OPC_MXU_D16MOVZ = 0x02,
1925 OPC_MXU_D16MOVN = 0x03,
1926 OPC_MXU_S32MOVZ = 0x04,
1927 OPC_MXU_S32MOVN = 0x05,
1934 OPC_MXU_Q8MAC = 0x00,
1935 OPC_MXU_Q8MACSU = 0x01,
1939 * Overview of the TX79-specific instruction set
1940 * =============================================
1942 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1943 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1944 * instructions and certain multimedia instructions (MMIs). These MMIs
1945 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1946 * or sixteen 8-bit paths.
1950 * The Toshiba TX System RISC TX79 Core Architecture manual,
1951 * https://wiki.qemu.org/File:C790.pdf
1953 * Three-Operand Multiply and Multiply-Add (4 instructions)
1954 * --------------------------------------------------------
1955 * MADD [rd,] rs, rt Multiply/Add
1956 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1957 * MULT [rd,] rs, rt Multiply (3-operand)
1958 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1960 * Multiply Instructions for Pipeline 1 (10 instructions)
1961 * ------------------------------------------------------
1962 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1963 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1964 * DIV1 rs, rt Divide Pipeline 1
1965 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1966 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1967 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1968 * MFHI1 rd Move From HI1 Register
1969 * MFLO1 rd Move From LO1 Register
1970 * MTHI1 rs Move To HI1 Register
1971 * MTLO1 rs Move To LO1 Register
1973 * Arithmetic (19 instructions)
1974 * ----------------------------
1975 * PADDB rd, rs, rt Parallel Add Byte
1976 * PSUBB rd, rs, rt Parallel Subtract Byte
1977 * PADDH rd, rs, rt Parallel Add Halfword
1978 * PSUBH rd, rs, rt Parallel Subtract Halfword
1979 * PADDW rd, rs, rt Parallel Add Word
1980 * PSUBW rd, rs, rt Parallel Subtract Word
1981 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1982 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1983 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1984 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1985 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1986 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1987 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1988 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1989 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1990 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1991 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1992 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1993 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1995 * Min/Max (4 instructions)
1996 * ------------------------
1997 * PMAXH rd, rs, rt Parallel Maximum Halfword
1998 * PMINH rd, rs, rt Parallel Minimum Halfword
1999 * PMAXW rd, rs, rt Parallel Maximum Word
2000 * PMINW rd, rs, rt Parallel Minimum Word
2002 * Absolute (2 instructions)
2003 * -------------------------
2004 * PABSH rd, rt Parallel Absolute Halfword
2005 * PABSW rd, rt Parallel Absolute Word
2007 * Logical (4 instructions)
2008 * ------------------------
2009 * PAND rd, rs, rt Parallel AND
2010 * POR rd, rs, rt Parallel OR
2011 * PXOR rd, rs, rt Parallel XOR
2012 * PNOR rd, rs, rt Parallel NOR
2014 * Shift (9 instructions)
2015 * ----------------------
2016 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2017 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2018 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2019 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2020 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2021 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2022 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2023 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2024 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2026 * Compare (6 instructions)
2027 * ------------------------
2028 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2029 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2030 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2031 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2032 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2033 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2035 * LZC (1 instruction)
2036 * -------------------
2037 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2039 * Quadword Load and Store (2 instructions)
2040 * ----------------------------------------
2041 * LQ rt, offset(base) Load Quadword
2042 * SQ rt, offset(base) Store Quadword
2044 * Multiply and Divide (19 instructions)
2045 * -------------------------------------
2046 * PMULTW rd, rs, rt Parallel Multiply Word
2047 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2048 * PDIVW rs, rt Parallel Divide Word
2049 * PDIVUW rs, rt Parallel Divide Unsigned Word
2050 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2051 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2052 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2053 * PMULTH rd, rs, rt Parallel Multiply Halfword
2054 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2055 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2056 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2057 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2058 * PDIVBW rs, rt Parallel Divide Broadcast Word
2059 * PMFHI rd Parallel Move From HI Register
2060 * PMFLO rd Parallel Move From LO Register
2061 * PMTHI rs Parallel Move To HI Register
2062 * PMTLO rs Parallel Move To LO Register
2063 * PMFHL rd Parallel Move From HI/LO Register
2064 * PMTHL rs Parallel Move To HI/LO Register
2066 * Pack/Extend (11 instructions)
2067 * -----------------------------
2068 * PPAC5 rd, rt Parallel Pack to 5 bits
2069 * PPACB rd, rs, rt Parallel Pack to Byte
2070 * PPACH rd, rs, rt Parallel Pack to Halfword
2071 * PPACW rd, rs, rt Parallel Pack to Word
2072 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2073 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2074 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2075 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2076 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2077 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2078 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2080 * Others (16 instructions)
2081 * ------------------------
2082 * PCPYH rd, rt Parallel Copy Halfword
2083 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2084 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2085 * PREVH rd, rt Parallel Reverse Halfword
2086 * PINTH rd, rs, rt Parallel Interleave Halfword
2087 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2088 * PEXEH rd, rt Parallel Exchange Even Halfword
2089 * PEXCH rd, rt Parallel Exchange Center Halfword
2090 * PEXEW rd, rt Parallel Exchange Even Word
2091 * PEXCW rd, rt Parallel Exchange Center Word
2092 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2093 * MFSA rd Move from Shift Amount Register
2094 * MTSA rs Move to Shift Amount Register
2095 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2096 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2097 * PROT3W rd, rt Parallel Rotate 3 Words
2099 * The TX79-specific Multimedia Instruction encodings
2100 * ==================================================
2102 * TX79 Multimedia Instruction encoding table keys:
2104 * * This code is reserved for future use. An attempt to execute it
2105 * causes a Reserved Instruction exception.
2106 * % This code indicates an instruction class. The instruction word
2107 * must be further decoded by examining additional tables that show
2108 * the values for other instruction fields.
2109 * # This code is reserved for the unsupported instructions DMULT,
2110 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2111 * to execute it causes a Reserved Instruction exception.
2113 * TX79 Multimedia Instructions encoded by opcode field (MMI, LQ, SQ):
2116 * +--------+----------------------------------------+
2118 * +--------+----------------------------------------+
2120 * opcode bits 28..26
2121 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2122 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2123 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2124 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2125 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2126 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2127 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2128 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2129 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2130 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2131 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2135 TX79_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2136 TX79_LQ = 0x1E << 26, /* Same as OPC_MSA */
2137 TX79_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
2141 * TX79 Multimedia Instructions with opcode field = MMI:
2144 * +--------+-------------------------------+--------+
2145 * | MMI | |function|
2146 * +--------+-------------------------------+--------+
2148 * function bits 2..0
2149 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2150 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2151 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2152 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2153 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2154 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2155 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2156 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2157 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2158 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2159 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2162 #define MASK_TX79_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2164 TX79_MMI_MADD = 0x00 | TX79_CLASS_MMI, /* Same as OPC_MADD */
2165 TX79_MMI_MADDU = 0x01 | TX79_CLASS_MMI, /* Same as OPC_MADDU */
2166 TX79_MMI_PLZCW = 0x04 | TX79_CLASS_MMI,
2167 TX79_MMI_CLASS_MMI0 = 0x08 | TX79_CLASS_MMI,
2168 TX79_MMI_CLASS_MMI2 = 0x09 | TX79_CLASS_MMI,
2169 TX79_MMI_MFHI1 = 0x10 | TX79_CLASS_MMI, /* Same minor as OPC_MFHI */
2170 TX79_MMI_MTHI1 = 0x11 | TX79_CLASS_MMI, /* Same minor as OPC_MTHI */
2171 TX79_MMI_MFLO1 = 0x12 | TX79_CLASS_MMI, /* Same minor as OPC_MFLO */
2172 TX79_MMI_MTLO1 = 0x13 | TX79_CLASS_MMI, /* Same minor as OPC_MTLO */
2173 TX79_MMI_MULT1 = 0x18 | TX79_CLASS_MMI, /* Same minor as OPC_MULT */
2174 TX79_MMI_MULTU1 = 0x19 | TX79_CLASS_MMI, /* Same minor as OPC_MULTU */
2175 TX79_MMI_DIV1 = 0x1A | TX79_CLASS_MMI, /* Same minor as OPC_DIV */
2176 TX79_MMI_DIVU1 = 0x1B | TX79_CLASS_MMI, /* Same minor as OPC_DIVU */
2177 TX79_MMI_MADD1 = 0x20 | TX79_CLASS_MMI,
2178 TX79_MMI_MADDU1 = 0x21 | TX79_CLASS_MMI,
2179 TX79_MMI_CLASS_MMI1 = 0x28 | TX79_CLASS_MMI,
2180 TX79_MMI_CLASS_MMI3 = 0x29 | TX79_CLASS_MMI,
2181 TX79_MMI_PMFHL = 0x30 | TX79_CLASS_MMI,
2182 TX79_MMI_PMTHL = 0x31 | TX79_CLASS_MMI,
2183 TX79_MMI_PSLLH = 0x34 | TX79_CLASS_MMI,
2184 TX79_MMI_PSRLH = 0x36 | TX79_CLASS_MMI,
2185 TX79_MMI_PSRAH = 0x37 | TX79_CLASS_MMI,
2186 TX79_MMI_PSLLW = 0x3C | TX79_CLASS_MMI,
2187 TX79_MMI_PSRLW = 0x3E | TX79_CLASS_MMI,
2188 TX79_MMI_PSRAW = 0x3F | TX79_CLASS_MMI,
2192 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI0:
2195 * +--------+----------------------+--------+--------+
2196 * | MMI | |function| MMI0 |
2197 * +--------+----------------------+--------+--------+
2199 * function bits 7..6
2200 * bits | 0 | 1 | 2 | 3
2201 * 10..8 | 00 | 01 | 10 | 11
2202 * -------+-------+-------+-------+-------
2203 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2204 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2205 * 2 010 | PADDB | PSUBB | PCGTB | *
2206 * 3 011 | * | * | * | *
2207 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2208 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2209 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2210 * 7 111 | * | * | PEXT5 | PPAC5
2213 #define MASK_TX79_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2215 TX79_MMI0_PADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI0,
2216 TX79_MMI0_PSUBW = (0x01 << 6) | TX79_MMI_CLASS_MMI0,
2217 TX79_MMI0_PCGTW = (0x02 << 6) | TX79_MMI_CLASS_MMI0,
2218 TX79_MMI0_PMAXW = (0x03 << 6) | TX79_MMI_CLASS_MMI0,
2219 TX79_MMI0_PADDH = (0x04 << 6) | TX79_MMI_CLASS_MMI0,
2220 TX79_MMI0_PSUBH = (0x05 << 6) | TX79_MMI_CLASS_MMI0,
2221 TX79_MMI0_PCGTH = (0x06 << 6) | TX79_MMI_CLASS_MMI0,
2222 TX79_MMI0_PMAXH = (0x07 << 6) | TX79_MMI_CLASS_MMI0,
2223 TX79_MMI0_PADDB = (0x08 << 6) | TX79_MMI_CLASS_MMI0,
2224 TX79_MMI0_PSUBB = (0x09 << 6) | TX79_MMI_CLASS_MMI0,
2225 TX79_MMI0_PCGTB = (0x0A << 6) | TX79_MMI_CLASS_MMI0,
2226 TX79_MMI0_PADDSW = (0x10 << 6) | TX79_MMI_CLASS_MMI0,
2227 TX79_MMI0_PSUBSW = (0x11 << 6) | TX79_MMI_CLASS_MMI0,
2228 TX79_MMI0_PEXTLW = (0x12 << 6) | TX79_MMI_CLASS_MMI0,
2229 TX79_MMI0_PPACW = (0x13 << 6) | TX79_MMI_CLASS_MMI0,
2230 TX79_MMI0_PADDSH = (0x14 << 6) | TX79_MMI_CLASS_MMI0,
2231 TX79_MMI0_PSUBSH = (0x15 << 6) | TX79_MMI_CLASS_MMI0,
2232 TX79_MMI0_PEXTLH = (0x16 << 6) | TX79_MMI_CLASS_MMI0,
2233 TX79_MMI0_PPACH = (0x17 << 6) | TX79_MMI_CLASS_MMI0,
2234 TX79_MMI0_PADDSB = (0x18 << 6) | TX79_MMI_CLASS_MMI0,
2235 TX79_MMI0_PSUBSB = (0x19 << 6) | TX79_MMI_CLASS_MMI0,
2236 TX79_MMI0_PEXTLB = (0x1A << 6) | TX79_MMI_CLASS_MMI0,
2237 TX79_MMI0_PPACB = (0x1B << 6) | TX79_MMI_CLASS_MMI0,
2238 TX79_MMI0_PEXT5 = (0x1E << 6) | TX79_MMI_CLASS_MMI0,
2239 TX79_MMI0_PPAC5 = (0x1F << 6) | TX79_MMI_CLASS_MMI0,
2243 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI1:
2246 * +--------+----------------------+--------+--------+
2247 * | MMI | |function| MMI1 |
2248 * +--------+----------------------+--------+--------+
2250 * function bits 7..6
2251 * bits | 0 | 1 | 2 | 3
2252 * 10..8 | 00 | 01 | 10 | 11
2253 * -------+-------+-------+-------+-------
2254 * 0 000 | * | PABSW | PCEQW | PMINW
2255 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2256 * 2 010 | * | * | PCEQB | *
2257 * 3 011 | * | * | * | *
2258 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2259 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2260 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2261 * 7 111 | * | * | * | *
2264 #define MASK_TX79_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2266 TX79_MMI1_PABSW = (0x01 << 6) | TX79_MMI_CLASS_MMI1,
2267 TX79_MMI1_PCEQW = (0x02 << 6) | TX79_MMI_CLASS_MMI1,
2268 TX79_MMI1_PMINW = (0x03 << 6) | TX79_MMI_CLASS_MMI1,
2269 TX79_MMI1_PADSBH = (0x04 << 6) | TX79_MMI_CLASS_MMI1,
2270 TX79_MMI1_PABSH = (0x05 << 6) | TX79_MMI_CLASS_MMI1,
2271 TX79_MMI1_PCEQH = (0x06 << 6) | TX79_MMI_CLASS_MMI1,
2272 TX79_MMI1_PMINH = (0x07 << 6) | TX79_MMI_CLASS_MMI1,
2273 TX79_MMI1_PCEQB = (0x0A << 6) | TX79_MMI_CLASS_MMI1,
2274 TX79_MMI1_PADDUW = (0x10 << 6) | TX79_MMI_CLASS_MMI1,
2275 TX79_MMI1_PSUBUW = (0x11 << 6) | TX79_MMI_CLASS_MMI1,
2276 TX79_MMI1_PEXTUW = (0x12 << 6) | TX79_MMI_CLASS_MMI1,
2277 TX79_MMI1_PADDUH = (0x14 << 6) | TX79_MMI_CLASS_MMI1,
2278 TX79_MMI1_PSUBUH = (0x15 << 6) | TX79_MMI_CLASS_MMI1,
2279 TX79_MMI1_PEXTUH = (0x16 << 6) | TX79_MMI_CLASS_MMI1,
2280 TX79_MMI1_PADDUB = (0x18 << 6) | TX79_MMI_CLASS_MMI1,
2281 TX79_MMI1_PSUBUB = (0x19 << 6) | TX79_MMI_CLASS_MMI1,
2282 TX79_MMI1_PEXTUB = (0x1A << 6) | TX79_MMI_CLASS_MMI1,
2283 TX79_MMI1_QFSRV = (0x1B << 6) | TX79_MMI_CLASS_MMI1,
2287 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI2:
2290 * +--------+----------------------+--------+--------+
2291 * | MMI | |function| MMI2 |
2292 * +--------+----------------------+--------+--------+
2294 * function bits 7..6
2295 * bits | 0 | 1 | 2 | 3
2296 * 10..8 | 00 | 01 | 10 | 11
2297 * -------+-------+-------+-------+-------
2298 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2299 * 1 001 | PMSUBW| * | * | *
2300 * 2 010 | PMFHI | PMFLO | PINTH | *
2301 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2302 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2303 * 5 101 | PMSUBH| PHMSBH| * | *
2304 * 6 110 | * | * | PEXEH | PREVH
2305 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2308 #define MASK_TX79_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2310 TX79_MMI2_PMADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI2,
2311 TX79_MMI2_PSLLVW = (0x02 << 6) | TX79_MMI_CLASS_MMI2,
2312 TX79_MMI2_PSRLVW = (0x03 << 6) | TX79_MMI_CLASS_MMI2,
2313 TX79_MMI2_PMSUBW = (0x04 << 6) | TX79_MMI_CLASS_MMI2,
2314 TX79_MMI2_PMFHI = (0x08 << 6) | TX79_MMI_CLASS_MMI2,
2315 TX79_MMI2_PMFLO = (0x09 << 6) | TX79_MMI_CLASS_MMI2,
2316 TX79_MMI2_PINTH = (0x0A << 6) | TX79_MMI_CLASS_MMI2,
2317 TX79_MMI2_PMULTW = (0x0C << 6) | TX79_MMI_CLASS_MMI2,
2318 TX79_MMI2_PDIVW = (0x0D << 6) | TX79_MMI_CLASS_MMI2,
2319 TX79_MMI2_PCPYLD = (0x0E << 6) | TX79_MMI_CLASS_MMI2,
2320 TX79_MMI2_PMADDH = (0x10 << 6) | TX79_MMI_CLASS_MMI2,
2321 TX79_MMI2_PHMADH = (0x11 << 6) | TX79_MMI_CLASS_MMI2,
2322 TX79_MMI2_PAND = (0x12 << 6) | TX79_MMI_CLASS_MMI2,
2323 TX79_MMI2_PXOR = (0x13 << 6) | TX79_MMI_CLASS_MMI2,
2324 TX79_MMI2_PMSUBH = (0x14 << 6) | TX79_MMI_CLASS_MMI2,
2325 TX79_MMI2_PHMSBH = (0x15 << 6) | TX79_MMI_CLASS_MMI2,
2326 TX79_MMI2_PEXEH = (0x1A << 6) | TX79_MMI_CLASS_MMI2,
2327 TX79_MMI2_PREVH = (0x1B << 6) | TX79_MMI_CLASS_MMI2,
2328 TX79_MMI2_PMULTH = (0x1C << 6) | TX79_MMI_CLASS_MMI2,
2329 TX79_MMI2_PDIVBW = (0x1D << 6) | TX79_MMI_CLASS_MMI2,
2330 TX79_MMI2_PEXEW = (0x1E << 6) | TX79_MMI_CLASS_MMI2,
2331 TX79_MMI2_PROT3W = (0x1F << 6) | TX79_MMI_CLASS_MMI2,
2335 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI3:
2338 * +--------+----------------------+--------+--------+
2339 * | MMI | |function| MMI3 |
2340 * +--------+----------------------+--------+--------+
2342 * function bits 7..6
2343 * bits | 0 | 1 | 2 | 3
2344 * 10..8 | 00 | 01 | 10 | 11
2345 * -------+-------+-------+-------+-------
2346 * 0 000 |PMADDUW| * | * | PSRAVW
2347 * 1 001 | * | * | * | *
2348 * 2 010 | PMTHI | PMTLO | PINTEH| *
2349 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2350 * 4 100 | * | * | POR | PNOR
2351 * 5 101 | * | * | * | *
2352 * 6 110 | * | * | PEXCH | PCPYH
2353 * 7 111 | * | * | PEXCW | *
2356 #define MASK_TX79_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2358 TX79_MMI3_PMADDUW = (0x00 << 6) | TX79_MMI_CLASS_MMI3,
2359 TX79_MMI3_PSRAVW = (0x03 << 6) | TX79_MMI_CLASS_MMI3,
2360 TX79_MMI3_PMTHI = (0x08 << 6) | TX79_MMI_CLASS_MMI3,
2361 TX79_MMI3_PMTLO = (0x09 << 6) | TX79_MMI_CLASS_MMI3,
2362 TX79_MMI3_PINTEH = (0x0A << 6) | TX79_MMI_CLASS_MMI3,
2363 TX79_MMI3_PMULTUW = (0x0C << 6) | TX79_MMI_CLASS_MMI3,
2364 TX79_MMI3_PDIVUW = (0x0D << 6) | TX79_MMI_CLASS_MMI3,
2365 TX79_MMI3_PCPYUD = (0x0E << 6) | TX79_MMI_CLASS_MMI3,
2366 TX79_MMI3_POR = (0x12 << 6) | TX79_MMI_CLASS_MMI3,
2367 TX79_MMI3_PNOR = (0x13 << 6) | TX79_MMI_CLASS_MMI3,
2368 TX79_MMI3_PEXCH = (0x1A << 6) | TX79_MMI_CLASS_MMI3,
2369 TX79_MMI3_PCPYH = (0x1B << 6) | TX79_MMI_CLASS_MMI3,
2370 TX79_MMI3_PEXCW = (0x1E << 6) | TX79_MMI_CLASS_MMI3,
2373 /* global register indices */
2374 static TCGv cpu_gpr[32], cpu_PC;
2375 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2376 static TCGv cpu_dspctrl, btarget, bcond;
2377 static TCGv_i32 hflags;
2378 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2379 static TCGv_i64 fpu_f64[32];
2380 static TCGv_i64 msa_wr_d[64];
2382 #include "exec/gen-icount.h"
2384 #define gen_helper_0e0i(name, arg) do { \
2385 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2386 gen_helper_##name(cpu_env, helper_tmp); \
2387 tcg_temp_free_i32(helper_tmp); \
2390 #define gen_helper_0e1i(name, arg1, arg2) do { \
2391 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2392 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2393 tcg_temp_free_i32(helper_tmp); \
2396 #define gen_helper_1e0i(name, ret, arg1) do { \
2397 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2398 gen_helper_##name(ret, cpu_env, helper_tmp); \
2399 tcg_temp_free_i32(helper_tmp); \
2402 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2403 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2404 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2405 tcg_temp_free_i32(helper_tmp); \
2408 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2409 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2410 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2411 tcg_temp_free_i32(helper_tmp); \
2414 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2415 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2416 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2417 tcg_temp_free_i32(helper_tmp); \
2420 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2421 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2422 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2423 tcg_temp_free_i32(helper_tmp); \
2426 typedef struct DisasContext {
2427 DisasContextBase base;
2428 target_ulong saved_pc;
2429 target_ulong page_start;
2431 uint64_t insn_flags;
2432 int32_t CP0_Config1;
2433 int32_t CP0_Config2;
2434 int32_t CP0_Config3;
2435 int32_t CP0_Config5;
2436 /* Routine used to access memory */
2438 TCGMemOp default_tcg_memop_mask;
2439 uint32_t hflags, saved_hflags;
2440 target_ulong btarget;
2451 int CP0_LLAddr_shift;
2460 #define DISAS_STOP DISAS_TARGET_0
2461 #define DISAS_EXIT DISAS_TARGET_1
2463 static const char * const regnames[] = {
2464 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2465 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2466 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2467 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2470 static const char * const regnames_HI[] = {
2471 "HI0", "HI1", "HI2", "HI3",
2474 static const char * const regnames_LO[] = {
2475 "LO0", "LO1", "LO2", "LO3",
2478 static const char * const fregnames[] = {
2479 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2480 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2481 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2482 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2485 static const char * const msaregnames[] = {
2486 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2487 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2488 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2489 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2490 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2491 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2492 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2493 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2494 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2495 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2496 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2497 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2498 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2499 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2500 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2501 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2504 #define LOG_DISAS(...) \
2506 if (MIPS_DEBUG_DISAS) { \
2507 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2511 #define MIPS_INVAL(op) \
2513 if (MIPS_DEBUG_DISAS) { \
2514 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2515 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2516 ctx->base.pc_next, ctx->opcode, op, \
2517 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2518 ((ctx->opcode >> 16) & 0x1F)); \
2522 /* General purpose registers moves. */
2523 static inline void gen_load_gpr (TCGv t, int reg)
2526 tcg_gen_movi_tl(t, 0);
2528 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2531 static inline void gen_store_gpr (TCGv t, int reg)
2534 tcg_gen_mov_tl(cpu_gpr[reg], t);
2537 /* Moves to/from shadow registers. */
2538 static inline void gen_load_srsgpr (int from, int to)
2540 TCGv t0 = tcg_temp_new();
2543 tcg_gen_movi_tl(t0, 0);
2545 TCGv_i32 t2 = tcg_temp_new_i32();
2546 TCGv_ptr addr = tcg_temp_new_ptr();
2548 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2549 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2550 tcg_gen_andi_i32(t2, t2, 0xf);
2551 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2552 tcg_gen_ext_i32_ptr(addr, t2);
2553 tcg_gen_add_ptr(addr, cpu_env, addr);
2555 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2556 tcg_temp_free_ptr(addr);
2557 tcg_temp_free_i32(t2);
2559 gen_store_gpr(t0, to);
2563 static inline void gen_store_srsgpr (int from, int to)
2566 TCGv t0 = tcg_temp_new();
2567 TCGv_i32 t2 = tcg_temp_new_i32();
2568 TCGv_ptr addr = tcg_temp_new_ptr();
2570 gen_load_gpr(t0, from);
2571 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2572 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2573 tcg_gen_andi_i32(t2, t2, 0xf);
2574 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2575 tcg_gen_ext_i32_ptr(addr, t2);
2576 tcg_gen_add_ptr(addr, cpu_env, addr);
2578 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2579 tcg_temp_free_ptr(addr);
2580 tcg_temp_free_i32(t2);
2586 static inline void gen_save_pc(target_ulong pc)
2588 tcg_gen_movi_tl(cpu_PC, pc);
2591 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2593 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2594 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2595 gen_save_pc(ctx->base.pc_next);
2596 ctx->saved_pc = ctx->base.pc_next;
2598 if (ctx->hflags != ctx->saved_hflags) {
2599 tcg_gen_movi_i32(hflags, ctx->hflags);
2600 ctx->saved_hflags = ctx->hflags;
2601 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2607 tcg_gen_movi_tl(btarget, ctx->btarget);
2613 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2615 ctx->saved_hflags = ctx->hflags;
2616 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2622 ctx->btarget = env->btarget;
2627 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2629 TCGv_i32 texcp = tcg_const_i32(excp);
2630 TCGv_i32 terr = tcg_const_i32(err);
2631 save_cpu_state(ctx, 1);
2632 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2633 tcg_temp_free_i32(terr);
2634 tcg_temp_free_i32(texcp);
2635 ctx->base.is_jmp = DISAS_NORETURN;
2638 static inline void generate_exception(DisasContext *ctx, int excp)
2640 gen_helper_0e0i(raise_exception, excp);
2643 static inline void generate_exception_end(DisasContext *ctx, int excp)
2645 generate_exception_err(ctx, excp, 0);
2648 /* Floating point register moves. */
2649 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2651 if (ctx->hflags & MIPS_HFLAG_FRE) {
2652 generate_exception(ctx, EXCP_RI);
2654 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2657 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2660 if (ctx->hflags & MIPS_HFLAG_FRE) {
2661 generate_exception(ctx, EXCP_RI);
2663 t64 = tcg_temp_new_i64();
2664 tcg_gen_extu_i32_i64(t64, t);
2665 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2666 tcg_temp_free_i64(t64);
2669 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2671 if (ctx->hflags & MIPS_HFLAG_F64) {
2672 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2674 gen_load_fpr32(ctx, t, reg | 1);
2678 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2680 if (ctx->hflags & MIPS_HFLAG_F64) {
2681 TCGv_i64 t64 = tcg_temp_new_i64();
2682 tcg_gen_extu_i32_i64(t64, t);
2683 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2684 tcg_temp_free_i64(t64);
2686 gen_store_fpr32(ctx, t, reg | 1);
2690 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2692 if (ctx->hflags & MIPS_HFLAG_F64) {
2693 tcg_gen_mov_i64(t, fpu_f64[reg]);
2695 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2699 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2701 if (ctx->hflags & MIPS_HFLAG_F64) {
2702 tcg_gen_mov_i64(fpu_f64[reg], t);
2705 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2706 t0 = tcg_temp_new_i64();
2707 tcg_gen_shri_i64(t0, t, 32);
2708 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2709 tcg_temp_free_i64(t0);
2713 static inline int get_fp_bit (int cc)
2721 /* Addresses computation */
2722 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2724 tcg_gen_add_tl(ret, arg0, arg1);
2726 #if defined(TARGET_MIPS64)
2727 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2728 tcg_gen_ext32s_i64(ret, ret);
2733 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2736 tcg_gen_addi_tl(ret, base, ofs);
2738 #if defined(TARGET_MIPS64)
2739 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2740 tcg_gen_ext32s_i64(ret, ret);
2745 /* Addresses computation (translation time) */
2746 static target_long addr_add(DisasContext *ctx, target_long base,
2749 target_long sum = base + offset;
2751 #if defined(TARGET_MIPS64)
2752 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2759 /* Sign-extract the low 32-bits to a target_long. */
2760 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2762 #if defined(TARGET_MIPS64)
2763 tcg_gen_ext32s_i64(ret, arg);
2765 tcg_gen_extrl_i64_i32(ret, arg);
2769 /* Sign-extract the high 32-bits to a target_long. */
2770 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2772 #if defined(TARGET_MIPS64)
2773 tcg_gen_sari_i64(ret, arg, 32);
2775 tcg_gen_extrh_i64_i32(ret, arg);
2779 static inline void check_cp0_enabled(DisasContext *ctx)
2781 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2782 generate_exception_err(ctx, EXCP_CpU, 0);
2785 static inline void check_cp1_enabled(DisasContext *ctx)
2787 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2788 generate_exception_err(ctx, EXCP_CpU, 1);
2791 /* Verify that the processor is running with COP1X instructions enabled.
2792 This is associated with the nabla symbol in the MIPS32 and MIPS64
2795 static inline void check_cop1x(DisasContext *ctx)
2797 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2798 generate_exception_end(ctx, EXCP_RI);
2801 /* Verify that the processor is running with 64-bit floating-point
2802 operations enabled. */
2804 static inline void check_cp1_64bitmode(DisasContext *ctx)
2806 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2807 generate_exception_end(ctx, EXCP_RI);
2811 * Verify if floating point register is valid; an operation is not defined
2812 * if bit 0 of any register specification is set and the FR bit in the
2813 * Status register equals zero, since the register numbers specify an
2814 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2815 * in the Status register equals one, both even and odd register numbers
2816 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2818 * Multiple 64 bit wide registers can be checked by calling
2819 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2821 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2823 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2824 generate_exception_end(ctx, EXCP_RI);
2827 /* Verify that the processor is running with DSP instructions enabled.
2828 This is enabled by CP0 Status register MX(24) bit.
2831 static inline void check_dsp(DisasContext *ctx)
2833 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2834 if (ctx->insn_flags & ASE_DSP) {
2835 generate_exception_end(ctx, EXCP_DSPDIS);
2837 generate_exception_end(ctx, EXCP_RI);
2842 static inline void check_dsp_r2(DisasContext *ctx)
2844 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2845 if (ctx->insn_flags & ASE_DSP) {
2846 generate_exception_end(ctx, EXCP_DSPDIS);
2848 generate_exception_end(ctx, EXCP_RI);
2853 static inline void check_dsp_r3(DisasContext *ctx)
2855 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2856 if (ctx->insn_flags & ASE_DSP) {
2857 generate_exception_end(ctx, EXCP_DSPDIS);
2859 generate_exception_end(ctx, EXCP_RI);
2864 /* This code generates a "reserved instruction" exception if the
2865 CPU does not support the instruction set corresponding to flags. */
2866 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2868 if (unlikely(!(ctx->insn_flags & flags))) {
2869 generate_exception_end(ctx, EXCP_RI);
2873 /* This code generates a "reserved instruction" exception if the
2874 CPU has corresponding flag set which indicates that the instruction
2875 has been removed. */
2876 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2878 if (unlikely(ctx->insn_flags & flags)) {
2879 generate_exception_end(ctx, EXCP_RI);
2884 * The Linux kernel traps certain reserved instruction exceptions to
2885 * emulate the corresponding instructions. QEMU is the kernel in user
2886 * mode, so those traps are emulated by accepting the instructions.
2888 * A reserved instruction exception is generated for flagged CPUs if
2889 * QEMU runs in system mode.
2891 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
2893 #ifndef CONFIG_USER_ONLY
2894 check_insn_opc_removed(ctx, flags);
2898 /* This code generates a "reserved instruction" exception if the
2899 CPU does not support 64-bit paired-single (PS) floating point data type */
2900 static inline void check_ps(DisasContext *ctx)
2902 if (unlikely(!ctx->ps)) {
2903 generate_exception(ctx, EXCP_RI);
2905 check_cp1_64bitmode(ctx);
2908 #ifdef TARGET_MIPS64
2909 /* This code generates a "reserved instruction" exception if 64-bit
2910 instructions are not enabled. */
2911 static inline void check_mips_64(DisasContext *ctx)
2913 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
2914 generate_exception_end(ctx, EXCP_RI);
2918 #ifndef CONFIG_USER_ONLY
2919 static inline void check_mvh(DisasContext *ctx)
2921 if (unlikely(!ctx->mvh)) {
2922 generate_exception(ctx, EXCP_RI);
2928 * This code generates a "reserved instruction" exception if the
2929 * Config5 XNP bit is set.
2931 static inline void check_xnp(DisasContext *ctx)
2933 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2934 generate_exception_end(ctx, EXCP_RI);
2938 #ifndef CONFIG_USER_ONLY
2940 * This code generates a "reserved instruction" exception if the
2941 * Config3 PW bit is NOT set.
2943 static inline void check_pw(DisasContext *ctx)
2945 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
2946 generate_exception_end(ctx, EXCP_RI);
2952 * This code generates a "reserved instruction" exception if the
2953 * Config3 MT bit is NOT set.
2955 static inline void check_mt(DisasContext *ctx)
2957 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2958 generate_exception_end(ctx, EXCP_RI);
2962 #ifndef CONFIG_USER_ONLY
2964 * This code generates a "coprocessor unusable" exception if CP0 is not
2965 * available, and, if that is not the case, generates a "reserved instruction"
2966 * exception if the Config5 MT bit is NOT set. This is needed for availability
2967 * control of some of MT ASE instructions.
2969 static inline void check_cp0_mt(DisasContext *ctx)
2971 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2972 generate_exception_err(ctx, EXCP_CpU, 0);
2974 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2975 generate_exception_err(ctx, EXCP_RI, 0);
2982 * This code generates a "reserved instruction" exception if the
2983 * Config5 NMS bit is set.
2985 static inline void check_nms(DisasContext *ctx)
2987 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2988 generate_exception_end(ctx, EXCP_RI);
2993 * This code generates a "reserved instruction" exception if the
2994 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
2995 * Config2 TL, and Config5 L2C are unset.
2997 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
2999 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3000 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3001 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3002 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3003 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3004 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3006 generate_exception_end(ctx, EXCP_RI);
3011 * This code generates a "reserved instruction" exception if the
3012 * Config5 EVA bit is NOT set.
3014 static inline void check_eva(DisasContext *ctx)
3016 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3017 generate_exception_end(ctx, EXCP_RI);
3022 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3023 calling interface for 32 and 64-bit FPRs. No sense in changing
3024 all callers for gen_load_fpr32 when we need the CTX parameter for
3026 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3027 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3028 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3029 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3030 int ft, int fs, int cc) \
3032 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3033 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3042 check_cp1_registers(ctx, fs | ft); \
3050 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3051 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3053 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3054 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3055 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3056 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3057 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3058 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3059 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3060 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3061 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3062 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3063 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3064 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3065 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3066 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3067 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3068 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
3071 tcg_temp_free_i##bits (fp0); \
3072 tcg_temp_free_i##bits (fp1); \
3075 FOP_CONDS(, 0, d, FMT_D, 64)
3076 FOP_CONDS(abs, 1, d, FMT_D, 64)
3077 FOP_CONDS(, 0, s, FMT_S, 32)
3078 FOP_CONDS(abs, 1, s, FMT_S, 32)
3079 FOP_CONDS(, 0, ps, FMT_PS, 64)
3080 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3083 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3084 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3085 int ft, int fs, int fd) \
3087 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3088 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3089 if (ifmt == FMT_D) { \
3090 check_cp1_registers(ctx, fs | ft | fd); \
3092 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3093 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3096 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3099 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3102 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3105 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3108 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3111 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3114 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3117 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3120 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3123 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3126 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3129 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3132 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3135 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3138 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3141 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3144 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3147 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3150 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3153 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3156 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3159 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3165 tcg_temp_free_i ## bits (fp0); \
3166 tcg_temp_free_i ## bits (fp1); \
3169 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3170 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3172 #undef gen_ldcmp_fpr32
3173 #undef gen_ldcmp_fpr64
3175 /* load/store instructions. */
3176 #ifdef CONFIG_USER_ONLY
3177 #define OP_LD_ATOMIC(insn,fname) \
3178 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3179 DisasContext *ctx) \
3181 TCGv t0 = tcg_temp_new(); \
3182 tcg_gen_mov_tl(t0, arg1); \
3183 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3184 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3185 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3186 tcg_temp_free(t0); \
3189 #define OP_LD_ATOMIC(insn,fname) \
3190 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3191 DisasContext *ctx) \
3193 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3196 OP_LD_ATOMIC(ll,ld32s);
3197 #if defined(TARGET_MIPS64)
3198 OP_LD_ATOMIC(lld,ld64);
3202 #ifdef CONFIG_USER_ONLY
3203 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
3204 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3205 DisasContext *ctx) \
3207 TCGv t0 = tcg_temp_new(); \
3208 TCGLabel *l1 = gen_new_label(); \
3209 TCGLabel *l2 = gen_new_label(); \
3211 tcg_gen_andi_tl(t0, arg2, almask); \
3212 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
3213 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
3214 generate_exception(ctx, EXCP_AdES); \
3215 gen_set_label(l1); \
3216 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3217 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
3218 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
3219 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
3220 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
3221 generate_exception_end(ctx, EXCP_SC); \
3222 gen_set_label(l2); \
3223 tcg_gen_movi_tl(t0, 0); \
3224 gen_store_gpr(t0, rt); \
3225 tcg_temp_free(t0); \
3228 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
3229 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3230 DisasContext *ctx) \
3232 TCGv t0 = tcg_temp_new(); \
3233 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
3234 gen_store_gpr(t0, rt); \
3235 tcg_temp_free(t0); \
3238 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
3239 #if defined(TARGET_MIPS64)
3240 OP_ST_ATOMIC(scd,st64,ld64,0x7);
3244 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3245 int base, int offset)
3248 tcg_gen_movi_tl(addr, offset);
3249 } else if (offset == 0) {
3250 gen_load_gpr(addr, base);
3252 tcg_gen_movi_tl(addr, offset);
3253 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3257 static target_ulong pc_relative_pc (DisasContext *ctx)
3259 target_ulong pc = ctx->base.pc_next;
3261 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3262 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3267 pc &= ~(target_ulong)3;
3272 static void gen_ld(DisasContext *ctx, uint32_t opc,
3273 int rt, int base, int offset)
3276 int mem_idx = ctx->mem_idx;
3278 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3279 /* Loongson CPU uses a load to zero register for prefetch.
3280 We emulate it as a NOP. On other CPU we must perform the
3281 actual memory access. */
3285 t0 = tcg_temp_new();
3286 gen_base_offset_addr(ctx, t0, base, offset);
3289 #if defined(TARGET_MIPS64)
3291 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3292 ctx->default_tcg_memop_mask);
3293 gen_store_gpr(t0, rt);
3296 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3297 ctx->default_tcg_memop_mask);
3298 gen_store_gpr(t0, rt);
3302 op_ld_lld(t0, t0, mem_idx, ctx);
3303 gen_store_gpr(t0, rt);
3306 t1 = tcg_temp_new();
3307 /* Do a byte access to possibly trigger a page
3308 fault with the unaligned address. */
3309 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3310 tcg_gen_andi_tl(t1, t0, 7);
3311 #ifndef TARGET_WORDS_BIGENDIAN
3312 tcg_gen_xori_tl(t1, t1, 7);
3314 tcg_gen_shli_tl(t1, t1, 3);
3315 tcg_gen_andi_tl(t0, t0, ~7);
3316 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3317 tcg_gen_shl_tl(t0, t0, t1);
3318 t2 = tcg_const_tl(-1);
3319 tcg_gen_shl_tl(t2, t2, t1);
3320 gen_load_gpr(t1, rt);
3321 tcg_gen_andc_tl(t1, t1, t2);
3323 tcg_gen_or_tl(t0, t0, t1);
3325 gen_store_gpr(t0, rt);
3328 t1 = tcg_temp_new();
3329 /* Do a byte access to possibly trigger a page
3330 fault with the unaligned address. */
3331 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3332 tcg_gen_andi_tl(t1, t0, 7);
3333 #ifdef TARGET_WORDS_BIGENDIAN
3334 tcg_gen_xori_tl(t1, t1, 7);
3336 tcg_gen_shli_tl(t1, t1, 3);
3337 tcg_gen_andi_tl(t0, t0, ~7);
3338 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3339 tcg_gen_shr_tl(t0, t0, t1);
3340 tcg_gen_xori_tl(t1, t1, 63);
3341 t2 = tcg_const_tl(0xfffffffffffffffeull);
3342 tcg_gen_shl_tl(t2, t2, t1);
3343 gen_load_gpr(t1, rt);
3344 tcg_gen_and_tl(t1, t1, t2);
3346 tcg_gen_or_tl(t0, t0, t1);
3348 gen_store_gpr(t0, rt);
3351 t1 = tcg_const_tl(pc_relative_pc(ctx));
3352 gen_op_addr_add(ctx, t0, t0, t1);
3354 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3355 gen_store_gpr(t0, rt);
3359 t1 = tcg_const_tl(pc_relative_pc(ctx));
3360 gen_op_addr_add(ctx, t0, t0, t1);
3362 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3363 gen_store_gpr(t0, rt);
3366 mem_idx = MIPS_HFLAG_UM;
3369 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3370 ctx->default_tcg_memop_mask);
3371 gen_store_gpr(t0, rt);
3374 mem_idx = MIPS_HFLAG_UM;
3377 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3378 ctx->default_tcg_memop_mask);
3379 gen_store_gpr(t0, rt);
3382 mem_idx = MIPS_HFLAG_UM;
3385 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3386 ctx->default_tcg_memop_mask);
3387 gen_store_gpr(t0, rt);
3390 mem_idx = MIPS_HFLAG_UM;
3393 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3394 gen_store_gpr(t0, rt);
3397 mem_idx = MIPS_HFLAG_UM;
3400 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3401 gen_store_gpr(t0, rt);
3404 mem_idx = MIPS_HFLAG_UM;
3407 t1 = tcg_temp_new();
3408 /* Do a byte access to possibly trigger a page
3409 fault with the unaligned address. */
3410 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3411 tcg_gen_andi_tl(t1, t0, 3);
3412 #ifndef TARGET_WORDS_BIGENDIAN
3413 tcg_gen_xori_tl(t1, t1, 3);
3415 tcg_gen_shli_tl(t1, t1, 3);
3416 tcg_gen_andi_tl(t0, t0, ~3);
3417 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3418 tcg_gen_shl_tl(t0, t0, t1);
3419 t2 = tcg_const_tl(-1);
3420 tcg_gen_shl_tl(t2, t2, t1);
3421 gen_load_gpr(t1, rt);
3422 tcg_gen_andc_tl(t1, t1, t2);
3424 tcg_gen_or_tl(t0, t0, t1);
3426 tcg_gen_ext32s_tl(t0, t0);
3427 gen_store_gpr(t0, rt);
3430 mem_idx = MIPS_HFLAG_UM;
3433 t1 = tcg_temp_new();
3434 /* Do a byte access to possibly trigger a page
3435 fault with the unaligned address. */
3436 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3437 tcg_gen_andi_tl(t1, t0, 3);
3438 #ifdef TARGET_WORDS_BIGENDIAN
3439 tcg_gen_xori_tl(t1, t1, 3);
3441 tcg_gen_shli_tl(t1, t1, 3);
3442 tcg_gen_andi_tl(t0, t0, ~3);
3443 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3444 tcg_gen_shr_tl(t0, t0, t1);
3445 tcg_gen_xori_tl(t1, t1, 31);
3446 t2 = tcg_const_tl(0xfffffffeull);
3447 tcg_gen_shl_tl(t2, t2, t1);
3448 gen_load_gpr(t1, rt);
3449 tcg_gen_and_tl(t1, t1, t2);
3451 tcg_gen_or_tl(t0, t0, t1);
3453 tcg_gen_ext32s_tl(t0, t0);
3454 gen_store_gpr(t0, rt);
3457 mem_idx = MIPS_HFLAG_UM;
3461 op_ld_ll(t0, t0, mem_idx, ctx);
3462 gen_store_gpr(t0, rt);
3468 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3469 uint32_t reg1, uint32_t reg2)
3471 TCGv taddr = tcg_temp_new();
3472 TCGv_i64 tval = tcg_temp_new_i64();
3473 TCGv tmp1 = tcg_temp_new();
3474 TCGv tmp2 = tcg_temp_new();
3476 gen_base_offset_addr(ctx, taddr, base, offset);
3477 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3478 #ifdef TARGET_WORDS_BIGENDIAN
3479 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3481 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3483 gen_store_gpr(tmp1, reg1);
3484 tcg_temp_free(tmp1);
3485 gen_store_gpr(tmp2, reg2);
3486 tcg_temp_free(tmp2);
3487 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3488 tcg_temp_free_i64(tval);
3489 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3490 tcg_temp_free(taddr);
3494 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3495 int base, int offset)
3497 TCGv t0 = tcg_temp_new();
3498 TCGv t1 = tcg_temp_new();
3499 int mem_idx = ctx->mem_idx;
3501 gen_base_offset_addr(ctx, t0, base, offset);
3502 gen_load_gpr(t1, rt);
3504 #if defined(TARGET_MIPS64)
3506 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3507 ctx->default_tcg_memop_mask);
3510 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3513 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3517 mem_idx = MIPS_HFLAG_UM;
3520 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3521 ctx->default_tcg_memop_mask);
3524 mem_idx = MIPS_HFLAG_UM;
3527 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3528 ctx->default_tcg_memop_mask);
3531 mem_idx = MIPS_HFLAG_UM;
3534 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3537 mem_idx = MIPS_HFLAG_UM;
3540 gen_helper_0e2i(swl, t1, t0, mem_idx);
3543 mem_idx = MIPS_HFLAG_UM;
3546 gen_helper_0e2i(swr, t1, t0, mem_idx);
3554 /* Store conditional */
3555 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3556 int base, int16_t offset)
3559 int mem_idx = ctx->mem_idx;
3561 #ifdef CONFIG_USER_ONLY
3562 t0 = tcg_temp_local_new();
3563 t1 = tcg_temp_local_new();
3565 t0 = tcg_temp_new();
3566 t1 = tcg_temp_new();
3568 gen_base_offset_addr(ctx, t0, base, offset);
3569 gen_load_gpr(t1, rt);
3571 #if defined(TARGET_MIPS64)
3574 op_st_scd(t1, t0, rt, mem_idx, ctx);
3578 mem_idx = MIPS_HFLAG_UM;
3582 op_st_sc(t1, t0, rt, mem_idx, ctx);
3589 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3590 uint32_t reg1, uint32_t reg2)
3592 TCGv taddr = tcg_temp_local_new();
3593 TCGv lladdr = tcg_temp_local_new();
3594 TCGv_i64 tval = tcg_temp_new_i64();
3595 TCGv_i64 llval = tcg_temp_new_i64();
3596 TCGv_i64 val = tcg_temp_new_i64();
3597 TCGv tmp1 = tcg_temp_new();
3598 TCGv tmp2 = tcg_temp_new();
3599 TCGLabel *lab_fail = gen_new_label();
3600 TCGLabel *lab_done = gen_new_label();
3602 gen_base_offset_addr(ctx, taddr, base, offset);
3604 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3605 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3607 gen_load_gpr(tmp1, reg1);
3608 gen_load_gpr(tmp2, reg2);
3610 #ifdef TARGET_WORDS_BIGENDIAN
3611 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3613 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3616 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3617 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3618 ctx->mem_idx, MO_64);
3620 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3622 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3624 gen_set_label(lab_fail);
3627 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3629 gen_set_label(lab_done);
3630 tcg_gen_movi_tl(lladdr, -1);
3631 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3634 /* Load and store */
3635 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3638 /* Don't do NOP if destination is zero: we must perform the actual
3643 TCGv_i32 fp0 = tcg_temp_new_i32();
3644 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3645 ctx->default_tcg_memop_mask);
3646 gen_store_fpr32(ctx, fp0, ft);
3647 tcg_temp_free_i32(fp0);
3652 TCGv_i32 fp0 = tcg_temp_new_i32();
3653 gen_load_fpr32(ctx, fp0, ft);
3654 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3655 ctx->default_tcg_memop_mask);
3656 tcg_temp_free_i32(fp0);
3661 TCGv_i64 fp0 = tcg_temp_new_i64();
3662 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3663 ctx->default_tcg_memop_mask);
3664 gen_store_fpr64(ctx, fp0, ft);
3665 tcg_temp_free_i64(fp0);
3670 TCGv_i64 fp0 = tcg_temp_new_i64();
3671 gen_load_fpr64(ctx, fp0, ft);
3672 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3673 ctx->default_tcg_memop_mask);
3674 tcg_temp_free_i64(fp0);
3678 MIPS_INVAL("flt_ldst");
3679 generate_exception_end(ctx, EXCP_RI);
3684 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3685 int rs, int16_t imm)
3687 TCGv t0 = tcg_temp_new();
3689 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3690 check_cp1_enabled(ctx);
3694 check_insn(ctx, ISA_MIPS2);
3697 gen_base_offset_addr(ctx, t0, rs, imm);
3698 gen_flt_ldst(ctx, op, rt, t0);
3701 generate_exception_err(ctx, EXCP_CpU, 1);
3706 /* Arithmetic with immediate operand */
3707 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3708 int rt, int rs, int imm)
3710 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3712 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3713 /* If no destination, treat it as a NOP.
3714 For addi, we must generate the overflow exception when needed. */
3720 TCGv t0 = tcg_temp_local_new();
3721 TCGv t1 = tcg_temp_new();
3722 TCGv t2 = tcg_temp_new();
3723 TCGLabel *l1 = gen_new_label();
3725 gen_load_gpr(t1, rs);
3726 tcg_gen_addi_tl(t0, t1, uimm);
3727 tcg_gen_ext32s_tl(t0, t0);
3729 tcg_gen_xori_tl(t1, t1, ~uimm);
3730 tcg_gen_xori_tl(t2, t0, uimm);
3731 tcg_gen_and_tl(t1, t1, t2);
3733 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3735 /* operands of same sign, result different sign */
3736 generate_exception(ctx, EXCP_OVERFLOW);
3738 tcg_gen_ext32s_tl(t0, t0);
3739 gen_store_gpr(t0, rt);
3745 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3746 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3748 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3751 #if defined(TARGET_MIPS64)
3754 TCGv t0 = tcg_temp_local_new();
3755 TCGv t1 = tcg_temp_new();
3756 TCGv t2 = tcg_temp_new();
3757 TCGLabel *l1 = gen_new_label();
3759 gen_load_gpr(t1, rs);
3760 tcg_gen_addi_tl(t0, t1, uimm);
3762 tcg_gen_xori_tl(t1, t1, ~uimm);
3763 tcg_gen_xori_tl(t2, t0, uimm);
3764 tcg_gen_and_tl(t1, t1, t2);
3766 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3768 /* operands of same sign, result different sign */
3769 generate_exception(ctx, EXCP_OVERFLOW);
3771 gen_store_gpr(t0, rt);
3777 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3779 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3786 /* Logic with immediate operand */
3787 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3788 int rt, int rs, int16_t imm)
3793 /* If no destination, treat it as a NOP. */
3796 uimm = (uint16_t)imm;
3799 if (likely(rs != 0))
3800 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3802 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3806 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3808 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3811 if (likely(rs != 0))
3812 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3814 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3817 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3819 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3820 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3822 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3831 /* Set on less than with immediate operand */
3832 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3833 int rt, int rs, int16_t imm)
3835 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3839 /* If no destination, treat it as a NOP. */
3842 t0 = tcg_temp_new();
3843 gen_load_gpr(t0, rs);
3846 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3849 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3855 /* Shifts with immediate operand */
3856 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3857 int rt, int rs, int16_t imm)
3859 target_ulong uimm = ((uint16_t)imm) & 0x1f;
3863 /* If no destination, treat it as a NOP. */
3867 t0 = tcg_temp_new();
3868 gen_load_gpr(t0, rs);
3871 tcg_gen_shli_tl(t0, t0, uimm);
3872 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3875 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3879 tcg_gen_ext32u_tl(t0, t0);
3880 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3882 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3887 TCGv_i32 t1 = tcg_temp_new_i32();
3889 tcg_gen_trunc_tl_i32(t1, t0);
3890 tcg_gen_rotri_i32(t1, t1, uimm);
3891 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3892 tcg_temp_free_i32(t1);
3894 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3897 #if defined(TARGET_MIPS64)
3899 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3902 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3905 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3909 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3911 tcg_gen_mov_tl(cpu_gpr[rt], t0);
3915 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3918 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
3921 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
3924 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
3932 static void gen_arith(DisasContext *ctx, uint32_t opc,
3933 int rd, int rs, int rt)
3935 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3936 && opc != OPC_DADD && opc != OPC_DSUB) {
3937 /* If no destination, treat it as a NOP.
3938 For add & sub, we must generate the overflow exception when needed. */
3945 TCGv t0 = tcg_temp_local_new();
3946 TCGv t1 = tcg_temp_new();
3947 TCGv t2 = tcg_temp_new();
3948 TCGLabel *l1 = gen_new_label();
3950 gen_load_gpr(t1, rs);
3951 gen_load_gpr(t2, rt);
3952 tcg_gen_add_tl(t0, t1, t2);
3953 tcg_gen_ext32s_tl(t0, t0);
3954 tcg_gen_xor_tl(t1, t1, t2);
3955 tcg_gen_xor_tl(t2, t0, t2);
3956 tcg_gen_andc_tl(t1, t2, t1);
3958 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3960 /* operands of same sign, result different sign */
3961 generate_exception(ctx, EXCP_OVERFLOW);
3963 gen_store_gpr(t0, rd);
3968 if (rs != 0 && rt != 0) {
3969 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3970 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3971 } else if (rs == 0 && rt != 0) {
3972 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3973 } else if (rs != 0 && rt == 0) {
3974 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3976 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3981 TCGv t0 = tcg_temp_local_new();
3982 TCGv t1 = tcg_temp_new();
3983 TCGv t2 = tcg_temp_new();
3984 TCGLabel *l1 = gen_new_label();
3986 gen_load_gpr(t1, rs);
3987 gen_load_gpr(t2, rt);
3988 tcg_gen_sub_tl(t0, t1, t2);
3989 tcg_gen_ext32s_tl(t0, t0);
3990 tcg_gen_xor_tl(t2, t1, t2);
3991 tcg_gen_xor_tl(t1, t0, t1);
3992 tcg_gen_and_tl(t1, t1, t2);
3994 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3996 /* operands of different sign, first operand and result different sign */
3997 generate_exception(ctx, EXCP_OVERFLOW);
3999 gen_store_gpr(t0, rd);
4004 if (rs != 0 && rt != 0) {
4005 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4006 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4007 } else if (rs == 0 && rt != 0) {
4008 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4009 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4010 } else if (rs != 0 && rt == 0) {
4011 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4013 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4016 #if defined(TARGET_MIPS64)
4019 TCGv t0 = tcg_temp_local_new();
4020 TCGv t1 = tcg_temp_new();
4021 TCGv t2 = tcg_temp_new();
4022 TCGLabel *l1 = gen_new_label();
4024 gen_load_gpr(t1, rs);
4025 gen_load_gpr(t2, rt);
4026 tcg_gen_add_tl(t0, t1, t2);
4027 tcg_gen_xor_tl(t1, t1, t2);
4028 tcg_gen_xor_tl(t2, t0, t2);
4029 tcg_gen_andc_tl(t1, t2, t1);
4031 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4033 /* operands of same sign, result different sign */
4034 generate_exception(ctx, EXCP_OVERFLOW);
4036 gen_store_gpr(t0, rd);
4041 if (rs != 0 && rt != 0) {
4042 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4043 } else if (rs == 0 && rt != 0) {
4044 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4045 } else if (rs != 0 && rt == 0) {
4046 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4048 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4053 TCGv t0 = tcg_temp_local_new();
4054 TCGv t1 = tcg_temp_new();
4055 TCGv t2 = tcg_temp_new();
4056 TCGLabel *l1 = gen_new_label();
4058 gen_load_gpr(t1, rs);
4059 gen_load_gpr(t2, rt);
4060 tcg_gen_sub_tl(t0, t1, t2);
4061 tcg_gen_xor_tl(t2, t1, t2);
4062 tcg_gen_xor_tl(t1, t0, t1);
4063 tcg_gen_and_tl(t1, t1, t2);
4065 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4067 /* operands of different sign, first operand and result different sign */
4068 generate_exception(ctx, EXCP_OVERFLOW);
4070 gen_store_gpr(t0, rd);
4075 if (rs != 0 && rt != 0) {
4076 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4077 } else if (rs == 0 && rt != 0) {
4078 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4079 } else if (rs != 0 && rt == 0) {
4080 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4082 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4087 if (likely(rs != 0 && rt != 0)) {
4088 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4089 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4091 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4097 /* Conditional move */
4098 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4099 int rd, int rs, int rt)
4104 /* If no destination, treat it as a NOP. */
4108 t0 = tcg_temp_new();
4109 gen_load_gpr(t0, rt);
4110 t1 = tcg_const_tl(0);
4111 t2 = tcg_temp_new();
4112 gen_load_gpr(t2, rs);
4115 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4118 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4121 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4124 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4133 static void gen_logic(DisasContext *ctx, uint32_t opc,
4134 int rd, int rs, int rt)
4137 /* If no destination, treat it as a NOP. */
4143 if (likely(rs != 0 && rt != 0)) {
4144 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4146 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4150 if (rs != 0 && rt != 0) {
4151 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4152 } else if (rs == 0 && rt != 0) {
4153 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4154 } else if (rs != 0 && rt == 0) {
4155 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4157 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4161 if (likely(rs != 0 && rt != 0)) {
4162 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4163 } else if (rs == 0 && rt != 0) {
4164 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4165 } else if (rs != 0 && rt == 0) {
4166 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4168 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4172 if (likely(rs != 0 && rt != 0)) {
4173 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4174 } else if (rs == 0 && rt != 0) {
4175 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4176 } else if (rs != 0 && rt == 0) {
4177 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4179 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4185 /* Set on lower than */
4186 static void gen_slt(DisasContext *ctx, uint32_t opc,
4187 int rd, int rs, int rt)
4192 /* If no destination, treat it as a NOP. */
4196 t0 = tcg_temp_new();
4197 t1 = tcg_temp_new();
4198 gen_load_gpr(t0, rs);
4199 gen_load_gpr(t1, rt);
4202 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4205 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4213 static void gen_shift(DisasContext *ctx, uint32_t opc,
4214 int rd, int rs, int rt)
4219 /* If no destination, treat it as a NOP.
4220 For add & sub, we must generate the overflow exception when needed. */
4224 t0 = tcg_temp_new();
4225 t1 = tcg_temp_new();
4226 gen_load_gpr(t0, rs);
4227 gen_load_gpr(t1, rt);
4230 tcg_gen_andi_tl(t0, t0, 0x1f);
4231 tcg_gen_shl_tl(t0, t1, t0);
4232 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4235 tcg_gen_andi_tl(t0, t0, 0x1f);
4236 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4239 tcg_gen_ext32u_tl(t1, t1);
4240 tcg_gen_andi_tl(t0, t0, 0x1f);
4241 tcg_gen_shr_tl(t0, t1, t0);
4242 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4246 TCGv_i32 t2 = tcg_temp_new_i32();
4247 TCGv_i32 t3 = tcg_temp_new_i32();
4249 tcg_gen_trunc_tl_i32(t2, t0);
4250 tcg_gen_trunc_tl_i32(t3, t1);
4251 tcg_gen_andi_i32(t2, t2, 0x1f);
4252 tcg_gen_rotr_i32(t2, t3, t2);
4253 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4254 tcg_temp_free_i32(t2);
4255 tcg_temp_free_i32(t3);
4258 #if defined(TARGET_MIPS64)
4260 tcg_gen_andi_tl(t0, t0, 0x3f);
4261 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4264 tcg_gen_andi_tl(t0, t0, 0x3f);
4265 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4268 tcg_gen_andi_tl(t0, t0, 0x3f);
4269 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4272 tcg_gen_andi_tl(t0, t0, 0x3f);
4273 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4281 /* Arithmetic on HI/LO registers */
4282 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4284 if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 ||
4285 opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) {
4291 if (!(ctx->insn_flags & INSN_R5900)) {
4298 case TX79_MMI_MFHI1:
4299 #if defined(TARGET_MIPS64)
4301 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4305 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4309 case TX79_MMI_MFLO1:
4310 #if defined(TARGET_MIPS64)
4312 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4316 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4320 case TX79_MMI_MTHI1:
4322 #if defined(TARGET_MIPS64)
4324 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4328 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4331 tcg_gen_movi_tl(cpu_HI[acc], 0);
4335 case TX79_MMI_MTLO1:
4337 #if defined(TARGET_MIPS64)
4339 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4343 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4346 tcg_gen_movi_tl(cpu_LO[acc], 0);
4352 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4355 TCGv t0 = tcg_const_tl(addr);
4356 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4357 gen_store_gpr(t0, reg);
4361 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4367 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4370 offset = sextract32(ctx->opcode << 2, 0, 21);
4371 addr = addr_add(ctx, pc, offset);
4372 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4376 offset = sextract32(ctx->opcode << 2, 0, 21);
4377 addr = addr_add(ctx, pc, offset);
4378 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4380 #if defined(TARGET_MIPS64)
4383 offset = sextract32(ctx->opcode << 2, 0, 21);
4384 addr = addr_add(ctx, pc, offset);
4385 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4389 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4392 offset = sextract32(ctx->opcode, 0, 16) << 16;
4393 addr = addr_add(ctx, pc, offset);
4394 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4399 offset = sextract32(ctx->opcode, 0, 16) << 16;
4400 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4401 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4404 #if defined(TARGET_MIPS64)
4405 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4406 case R6_OPC_LDPC + (1 << 16):
4407 case R6_OPC_LDPC + (2 << 16):
4408 case R6_OPC_LDPC + (3 << 16):
4410 offset = sextract32(ctx->opcode << 3, 0, 21);
4411 addr = addr_add(ctx, (pc & ~0x7), offset);
4412 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4416 MIPS_INVAL("OPC_PCREL");
4417 generate_exception_end(ctx, EXCP_RI);
4424 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4433 t0 = tcg_temp_new();
4434 t1 = tcg_temp_new();
4436 gen_load_gpr(t0, rs);
4437 gen_load_gpr(t1, rt);
4442 TCGv t2 = tcg_temp_new();
4443 TCGv t3 = tcg_temp_new();
4444 tcg_gen_ext32s_tl(t0, t0);
4445 tcg_gen_ext32s_tl(t1, t1);
4446 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4447 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4448 tcg_gen_and_tl(t2, t2, t3);
4449 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4450 tcg_gen_or_tl(t2, t2, t3);
4451 tcg_gen_movi_tl(t3, 0);
4452 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4453 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4454 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4461 TCGv t2 = tcg_temp_new();
4462 TCGv t3 = tcg_temp_new();
4463 tcg_gen_ext32s_tl(t0, t0);
4464 tcg_gen_ext32s_tl(t1, t1);
4465 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4466 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4467 tcg_gen_and_tl(t2, t2, t3);
4468 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4469 tcg_gen_or_tl(t2, t2, t3);
4470 tcg_gen_movi_tl(t3, 0);
4471 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4472 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4473 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4480 TCGv t2 = tcg_const_tl(0);
4481 TCGv t3 = tcg_const_tl(1);
4482 tcg_gen_ext32u_tl(t0, t0);
4483 tcg_gen_ext32u_tl(t1, t1);
4484 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4485 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4486 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4493 TCGv t2 = tcg_const_tl(0);
4494 TCGv t3 = tcg_const_tl(1);
4495 tcg_gen_ext32u_tl(t0, t0);
4496 tcg_gen_ext32u_tl(t1, t1);
4497 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4498 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4499 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4506 TCGv_i32 t2 = tcg_temp_new_i32();
4507 TCGv_i32 t3 = tcg_temp_new_i32();
4508 tcg_gen_trunc_tl_i32(t2, t0);
4509 tcg_gen_trunc_tl_i32(t3, t1);
4510 tcg_gen_mul_i32(t2, t2, t3);
4511 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4512 tcg_temp_free_i32(t2);
4513 tcg_temp_free_i32(t3);
4518 TCGv_i32 t2 = tcg_temp_new_i32();
4519 TCGv_i32 t3 = tcg_temp_new_i32();
4520 tcg_gen_trunc_tl_i32(t2, t0);
4521 tcg_gen_trunc_tl_i32(t3, t1);
4522 tcg_gen_muls2_i32(t2, t3, t2, t3);
4523 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4524 tcg_temp_free_i32(t2);
4525 tcg_temp_free_i32(t3);
4530 TCGv_i32 t2 = tcg_temp_new_i32();
4531 TCGv_i32 t3 = tcg_temp_new_i32();
4532 tcg_gen_trunc_tl_i32(t2, t0);
4533 tcg_gen_trunc_tl_i32(t3, t1);
4534 tcg_gen_mul_i32(t2, t2, t3);
4535 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4536 tcg_temp_free_i32(t2);
4537 tcg_temp_free_i32(t3);
4542 TCGv_i32 t2 = tcg_temp_new_i32();
4543 TCGv_i32 t3 = tcg_temp_new_i32();
4544 tcg_gen_trunc_tl_i32(t2, t0);
4545 tcg_gen_trunc_tl_i32(t3, t1);
4546 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4547 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4548 tcg_temp_free_i32(t2);
4549 tcg_temp_free_i32(t3);
4552 #if defined(TARGET_MIPS64)
4555 TCGv t2 = tcg_temp_new();
4556 TCGv t3 = tcg_temp_new();
4557 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4558 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4559 tcg_gen_and_tl(t2, t2, t3);
4560 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4561 tcg_gen_or_tl(t2, t2, t3);
4562 tcg_gen_movi_tl(t3, 0);
4563 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4564 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4571 TCGv t2 = tcg_temp_new();
4572 TCGv t3 = tcg_temp_new();
4573 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4574 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4575 tcg_gen_and_tl(t2, t2, t3);
4576 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4577 tcg_gen_or_tl(t2, t2, t3);
4578 tcg_gen_movi_tl(t3, 0);
4579 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4580 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4587 TCGv t2 = tcg_const_tl(0);
4588 TCGv t3 = tcg_const_tl(1);
4589 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4590 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4597 TCGv t2 = tcg_const_tl(0);
4598 TCGv t3 = tcg_const_tl(1);
4599 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4600 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4606 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4610 TCGv t2 = tcg_temp_new();
4611 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4616 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4620 TCGv t2 = tcg_temp_new();
4621 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4627 MIPS_INVAL("r6 mul/div");
4628 generate_exception_end(ctx, EXCP_RI);
4636 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4637 int acc, int rs, int rt)
4641 t0 = tcg_temp_new();
4642 t1 = tcg_temp_new();
4644 gen_load_gpr(t0, rs);
4645 gen_load_gpr(t1, rt);
4648 if (!(ctx->insn_flags & INSN_R5900)) {
4657 TCGv t2 = tcg_temp_new();
4658 TCGv t3 = tcg_temp_new();
4659 tcg_gen_ext32s_tl(t0, t0);
4660 tcg_gen_ext32s_tl(t1, t1);
4661 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4662 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4663 tcg_gen_and_tl(t2, t2, t3);
4664 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4665 tcg_gen_or_tl(t2, t2, t3);
4666 tcg_gen_movi_tl(t3, 0);
4667 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4668 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4669 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4670 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4671 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4677 case TX79_MMI_DIVU1:
4679 TCGv t2 = tcg_const_tl(0);
4680 TCGv t3 = tcg_const_tl(1);
4681 tcg_gen_ext32u_tl(t0, t0);
4682 tcg_gen_ext32u_tl(t1, t1);
4683 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4684 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4685 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4686 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4687 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4694 TCGv_i32 t2 = tcg_temp_new_i32();
4695 TCGv_i32 t3 = tcg_temp_new_i32();
4696 tcg_gen_trunc_tl_i32(t2, t0);
4697 tcg_gen_trunc_tl_i32(t3, t1);
4698 tcg_gen_muls2_i32(t2, t3, t2, t3);
4699 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4700 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4701 tcg_temp_free_i32(t2);
4702 tcg_temp_free_i32(t3);
4707 TCGv_i32 t2 = tcg_temp_new_i32();
4708 TCGv_i32 t3 = tcg_temp_new_i32();
4709 tcg_gen_trunc_tl_i32(t2, t0);
4710 tcg_gen_trunc_tl_i32(t3, t1);
4711 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4712 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4713 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4714 tcg_temp_free_i32(t2);
4715 tcg_temp_free_i32(t3);
4718 #if defined(TARGET_MIPS64)
4721 TCGv t2 = tcg_temp_new();
4722 TCGv t3 = tcg_temp_new();
4723 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4724 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4725 tcg_gen_and_tl(t2, t2, t3);
4726 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4727 tcg_gen_or_tl(t2, t2, t3);
4728 tcg_gen_movi_tl(t3, 0);
4729 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4730 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4731 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4738 TCGv t2 = tcg_const_tl(0);
4739 TCGv t3 = tcg_const_tl(1);
4740 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4741 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4742 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4748 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4751 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4756 TCGv_i64 t2 = tcg_temp_new_i64();
4757 TCGv_i64 t3 = tcg_temp_new_i64();
4759 tcg_gen_ext_tl_i64(t2, t0);
4760 tcg_gen_ext_tl_i64(t3, t1);
4761 tcg_gen_mul_i64(t2, t2, t3);
4762 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4763 tcg_gen_add_i64(t2, t2, t3);
4764 tcg_temp_free_i64(t3);
4765 gen_move_low32(cpu_LO[acc], t2);
4766 gen_move_high32(cpu_HI[acc], t2);
4767 tcg_temp_free_i64(t2);
4772 TCGv_i64 t2 = tcg_temp_new_i64();
4773 TCGv_i64 t3 = tcg_temp_new_i64();
4775 tcg_gen_ext32u_tl(t0, t0);
4776 tcg_gen_ext32u_tl(t1, t1);
4777 tcg_gen_extu_tl_i64(t2, t0);
4778 tcg_gen_extu_tl_i64(t3, t1);
4779 tcg_gen_mul_i64(t2, t2, t3);
4780 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4781 tcg_gen_add_i64(t2, t2, t3);
4782 tcg_temp_free_i64(t3);
4783 gen_move_low32(cpu_LO[acc], t2);
4784 gen_move_high32(cpu_HI[acc], t2);
4785 tcg_temp_free_i64(t2);
4790 TCGv_i64 t2 = tcg_temp_new_i64();
4791 TCGv_i64 t3 = tcg_temp_new_i64();
4793 tcg_gen_ext_tl_i64(t2, t0);
4794 tcg_gen_ext_tl_i64(t3, t1);
4795 tcg_gen_mul_i64(t2, t2, t3);
4796 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4797 tcg_gen_sub_i64(t2, t3, t2);
4798 tcg_temp_free_i64(t3);
4799 gen_move_low32(cpu_LO[acc], t2);
4800 gen_move_high32(cpu_HI[acc], t2);
4801 tcg_temp_free_i64(t2);
4806 TCGv_i64 t2 = tcg_temp_new_i64();
4807 TCGv_i64 t3 = tcg_temp_new_i64();
4809 tcg_gen_ext32u_tl(t0, t0);
4810 tcg_gen_ext32u_tl(t1, t1);
4811 tcg_gen_extu_tl_i64(t2, t0);
4812 tcg_gen_extu_tl_i64(t3, t1);
4813 tcg_gen_mul_i64(t2, t2, t3);
4814 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4815 tcg_gen_sub_i64(t2, t3, t2);
4816 tcg_temp_free_i64(t3);
4817 gen_move_low32(cpu_LO[acc], t2);
4818 gen_move_high32(cpu_HI[acc], t2);
4819 tcg_temp_free_i64(t2);
4823 MIPS_INVAL("mul/div");
4824 generate_exception_end(ctx, EXCP_RI);
4833 * These MULT and MULTU instructions implemented in for example the
4834 * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
4835 * architectures are special three-operand variants with the syntax
4837 * MULT[U][1] rd, rs, rt
4841 * (rd, LO, HI) <- rs * rt
4843 * where the low-order 32-bits of the result is placed into both the
4844 * GPR rd and the special register LO. The high-order 32-bits of the
4845 * result is placed into the special register HI.
4847 * If the GPR rd is omitted in assembly language, it is taken to be 0,
4848 * which is the zero register that always reads as 0.
4850 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
4851 int rd, int rs, int rt)
4853 TCGv t0 = tcg_temp_new();
4854 TCGv t1 = tcg_temp_new();
4857 gen_load_gpr(t0, rs);
4858 gen_load_gpr(t1, rt);
4861 case TX79_MMI_MULT1:
4866 TCGv_i32 t2 = tcg_temp_new_i32();
4867 TCGv_i32 t3 = tcg_temp_new_i32();
4868 tcg_gen_trunc_tl_i32(t2, t0);
4869 tcg_gen_trunc_tl_i32(t3, t1);
4870 tcg_gen_muls2_i32(t2, t3, t2, t3);
4872 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4874 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4875 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4876 tcg_temp_free_i32(t2);
4877 tcg_temp_free_i32(t3);
4880 case TX79_MMI_MULTU1:
4885 TCGv_i32 t2 = tcg_temp_new_i32();
4886 TCGv_i32 t3 = tcg_temp_new_i32();
4887 tcg_gen_trunc_tl_i32(t2, t0);
4888 tcg_gen_trunc_tl_i32(t3, t1);
4889 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4891 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4893 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4894 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4895 tcg_temp_free_i32(t2);
4896 tcg_temp_free_i32(t3);
4900 MIPS_INVAL("mul TXx9");
4901 generate_exception_end(ctx, EXCP_RI);
4910 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4911 int rd, int rs, int rt)
4913 TCGv t0 = tcg_temp_new();
4914 TCGv t1 = tcg_temp_new();
4916 gen_load_gpr(t0, rs);
4917 gen_load_gpr(t1, rt);
4920 case OPC_VR54XX_MULS:
4921 gen_helper_muls(t0, cpu_env, t0, t1);
4923 case OPC_VR54XX_MULSU:
4924 gen_helper_mulsu(t0, cpu_env, t0, t1);
4926 case OPC_VR54XX_MACC:
4927 gen_helper_macc(t0, cpu_env, t0, t1);
4929 case OPC_VR54XX_MACCU:
4930 gen_helper_maccu(t0, cpu_env, t0, t1);
4932 case OPC_VR54XX_MSAC:
4933 gen_helper_msac(t0, cpu_env, t0, t1);
4935 case OPC_VR54XX_MSACU:
4936 gen_helper_msacu(t0, cpu_env, t0, t1);
4938 case OPC_VR54XX_MULHI:
4939 gen_helper_mulhi(t0, cpu_env, t0, t1);
4941 case OPC_VR54XX_MULHIU:
4942 gen_helper_mulhiu(t0, cpu_env, t0, t1);
4944 case OPC_VR54XX_MULSHI:
4945 gen_helper_mulshi(t0, cpu_env, t0, t1);
4947 case OPC_VR54XX_MULSHIU:
4948 gen_helper_mulshiu(t0, cpu_env, t0, t1);
4950 case OPC_VR54XX_MACCHI:
4951 gen_helper_macchi(t0, cpu_env, t0, t1);
4953 case OPC_VR54XX_MACCHIU:
4954 gen_helper_macchiu(t0, cpu_env, t0, t1);
4956 case OPC_VR54XX_MSACHI:
4957 gen_helper_msachi(t0, cpu_env, t0, t1);
4959 case OPC_VR54XX_MSACHIU:
4960 gen_helper_msachiu(t0, cpu_env, t0, t1);
4963 MIPS_INVAL("mul vr54xx");
4964 generate_exception_end(ctx, EXCP_RI);
4967 gen_store_gpr(t0, rd);
4974 static void gen_cl (DisasContext *ctx, uint32_t opc,
4984 gen_load_gpr(t0, rs);
4989 #if defined(TARGET_MIPS64)
4993 tcg_gen_not_tl(t0, t0);
5002 tcg_gen_ext32u_tl(t0, t0);
5003 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5004 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5006 #if defined(TARGET_MIPS64)
5011 tcg_gen_clzi_i64(t0, t0, 64);
5017 /* Godson integer instructions */
5018 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5019 int rd, int rs, int rt)
5031 case OPC_MULTU_G_2E:
5032 case OPC_MULTU_G_2F:
5033 #if defined(TARGET_MIPS64)
5034 case OPC_DMULT_G_2E:
5035 case OPC_DMULT_G_2F:
5036 case OPC_DMULTU_G_2E:
5037 case OPC_DMULTU_G_2F:
5039 t0 = tcg_temp_new();
5040 t1 = tcg_temp_new();
5043 t0 = tcg_temp_local_new();
5044 t1 = tcg_temp_local_new();
5048 gen_load_gpr(t0, rs);
5049 gen_load_gpr(t1, rt);
5054 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5055 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5057 case OPC_MULTU_G_2E:
5058 case OPC_MULTU_G_2F:
5059 tcg_gen_ext32u_tl(t0, t0);
5060 tcg_gen_ext32u_tl(t1, t1);
5061 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5062 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5067 TCGLabel *l1 = gen_new_label();
5068 TCGLabel *l2 = gen_new_label();
5069 TCGLabel *l3 = gen_new_label();
5070 tcg_gen_ext32s_tl(t0, t0);
5071 tcg_gen_ext32s_tl(t1, t1);
5072 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5073 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5076 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5077 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5078 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5081 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5082 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5089 TCGLabel *l1 = gen_new_label();
5090 TCGLabel *l2 = gen_new_label();
5091 tcg_gen_ext32u_tl(t0, t0);
5092 tcg_gen_ext32u_tl(t1, t1);
5093 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5094 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5097 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5098 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5105 TCGLabel *l1 = gen_new_label();
5106 TCGLabel *l2 = gen_new_label();
5107 TCGLabel *l3 = gen_new_label();
5108 tcg_gen_ext32u_tl(t0, t0);
5109 tcg_gen_ext32u_tl(t1, t1);
5110 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5111 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5112 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5114 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5117 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5118 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5125 TCGLabel *l1 = gen_new_label();
5126 TCGLabel *l2 = gen_new_label();
5127 tcg_gen_ext32u_tl(t0, t0);
5128 tcg_gen_ext32u_tl(t1, t1);
5129 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5130 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5133 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5134 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5138 #if defined(TARGET_MIPS64)
5139 case OPC_DMULT_G_2E:
5140 case OPC_DMULT_G_2F:
5141 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5143 case OPC_DMULTU_G_2E:
5144 case OPC_DMULTU_G_2F:
5145 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5150 TCGLabel *l1 = gen_new_label();
5151 TCGLabel *l2 = gen_new_label();
5152 TCGLabel *l3 = gen_new_label();
5153 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5154 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5157 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5158 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5159 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5162 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5166 case OPC_DDIVU_G_2E:
5167 case OPC_DDIVU_G_2F:
5169 TCGLabel *l1 = gen_new_label();
5170 TCGLabel *l2 = gen_new_label();
5171 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5172 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5175 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5182 TCGLabel *l1 = gen_new_label();
5183 TCGLabel *l2 = gen_new_label();
5184 TCGLabel *l3 = gen_new_label();
5185 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5186 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5187 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5189 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5192 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5196 case OPC_DMODU_G_2E:
5197 case OPC_DMODU_G_2F:
5199 TCGLabel *l1 = gen_new_label();
5200 TCGLabel *l2 = gen_new_label();
5201 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5202 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5205 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5216 /* Loongson multimedia instructions */
5217 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5219 uint32_t opc, shift_max;
5222 opc = MASK_LMI(ctx->opcode);
5228 t0 = tcg_temp_local_new_i64();
5229 t1 = tcg_temp_local_new_i64();
5232 t0 = tcg_temp_new_i64();
5233 t1 = tcg_temp_new_i64();
5237 check_cp1_enabled(ctx);
5238 gen_load_fpr64(ctx, t0, rs);
5239 gen_load_fpr64(ctx, t1, rt);
5241 #define LMI_HELPER(UP, LO) \
5242 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5243 #define LMI_HELPER_1(UP, LO) \
5244 case OPC_##UP: gen_helper_##LO(t0, t0); break
5245 #define LMI_DIRECT(UP, LO, OP) \
5246 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5249 LMI_HELPER(PADDSH, paddsh);
5250 LMI_HELPER(PADDUSH, paddush);
5251 LMI_HELPER(PADDH, paddh);
5252 LMI_HELPER(PADDW, paddw);
5253 LMI_HELPER(PADDSB, paddsb);
5254 LMI_HELPER(PADDUSB, paddusb);
5255 LMI_HELPER(PADDB, paddb);
5257 LMI_HELPER(PSUBSH, psubsh);
5258 LMI_HELPER(PSUBUSH, psubush);
5259 LMI_HELPER(PSUBH, psubh);
5260 LMI_HELPER(PSUBW, psubw);
5261 LMI_HELPER(PSUBSB, psubsb);
5262 LMI_HELPER(PSUBUSB, psubusb);
5263 LMI_HELPER(PSUBB, psubb);
5265 LMI_HELPER(PSHUFH, pshufh);
5266 LMI_HELPER(PACKSSWH, packsswh);
5267 LMI_HELPER(PACKSSHB, packsshb);
5268 LMI_HELPER(PACKUSHB, packushb);
5270 LMI_HELPER(PUNPCKLHW, punpcklhw);
5271 LMI_HELPER(PUNPCKHHW, punpckhhw);
5272 LMI_HELPER(PUNPCKLBH, punpcklbh);
5273 LMI_HELPER(PUNPCKHBH, punpckhbh);
5274 LMI_HELPER(PUNPCKLWD, punpcklwd);
5275 LMI_HELPER(PUNPCKHWD, punpckhwd);
5277 LMI_HELPER(PAVGH, pavgh);
5278 LMI_HELPER(PAVGB, pavgb);
5279 LMI_HELPER(PMAXSH, pmaxsh);
5280 LMI_HELPER(PMINSH, pminsh);
5281 LMI_HELPER(PMAXUB, pmaxub);
5282 LMI_HELPER(PMINUB, pminub);
5284 LMI_HELPER(PCMPEQW, pcmpeqw);
5285 LMI_HELPER(PCMPGTW, pcmpgtw);
5286 LMI_HELPER(PCMPEQH, pcmpeqh);
5287 LMI_HELPER(PCMPGTH, pcmpgth);
5288 LMI_HELPER(PCMPEQB, pcmpeqb);
5289 LMI_HELPER(PCMPGTB, pcmpgtb);
5291 LMI_HELPER(PSLLW, psllw);
5292 LMI_HELPER(PSLLH, psllh);
5293 LMI_HELPER(PSRLW, psrlw);
5294 LMI_HELPER(PSRLH, psrlh);
5295 LMI_HELPER(PSRAW, psraw);
5296 LMI_HELPER(PSRAH, psrah);
5298 LMI_HELPER(PMULLH, pmullh);
5299 LMI_HELPER(PMULHH, pmulhh);
5300 LMI_HELPER(PMULHUH, pmulhuh);
5301 LMI_HELPER(PMADDHW, pmaddhw);
5303 LMI_HELPER(PASUBUB, pasubub);
5304 LMI_HELPER_1(BIADD, biadd);
5305 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5307 LMI_DIRECT(PADDD, paddd, add);
5308 LMI_DIRECT(PSUBD, psubd, sub);
5309 LMI_DIRECT(XOR_CP2, xor, xor);
5310 LMI_DIRECT(NOR_CP2, nor, nor);
5311 LMI_DIRECT(AND_CP2, and, and);
5312 LMI_DIRECT(OR_CP2, or, or);
5315 tcg_gen_andc_i64(t0, t1, t0);
5319 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5322 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5325 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5328 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5332 tcg_gen_andi_i64(t1, t1, 3);
5333 tcg_gen_shli_i64(t1, t1, 4);
5334 tcg_gen_shr_i64(t0, t0, t1);
5335 tcg_gen_ext16u_i64(t0, t0);
5339 tcg_gen_add_i64(t0, t0, t1);
5340 tcg_gen_ext32s_i64(t0, t0);
5343 tcg_gen_sub_i64(t0, t0, t1);
5344 tcg_gen_ext32s_i64(t0, t0);
5366 /* Make sure shift count isn't TCG undefined behaviour. */
5367 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5372 tcg_gen_shl_i64(t0, t0, t1);
5376 /* Since SRA is UndefinedResult without sign-extended inputs,
5377 we can treat SRA and DSRA the same. */
5378 tcg_gen_sar_i64(t0, t0, t1);
5381 /* We want to shift in zeros for SRL; zero-extend first. */
5382 tcg_gen_ext32u_i64(t0, t0);
5385 tcg_gen_shr_i64(t0, t0, t1);
5389 if (shift_max == 32) {
5390 tcg_gen_ext32s_i64(t0, t0);
5393 /* Shifts larger than MAX produce zero. */
5394 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5395 tcg_gen_neg_i64(t1, t1);
5396 tcg_gen_and_i64(t0, t0, t1);
5402 TCGv_i64 t2 = tcg_temp_new_i64();
5403 TCGLabel *lab = gen_new_label();
5405 tcg_gen_mov_i64(t2, t0);
5406 tcg_gen_add_i64(t0, t1, t2);
5407 if (opc == OPC_ADD_CP2) {
5408 tcg_gen_ext32s_i64(t0, t0);
5410 tcg_gen_xor_i64(t1, t1, t2);
5411 tcg_gen_xor_i64(t2, t2, t0);
5412 tcg_gen_andc_i64(t1, t2, t1);
5413 tcg_temp_free_i64(t2);
5414 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5415 generate_exception(ctx, EXCP_OVERFLOW);
5423 TCGv_i64 t2 = tcg_temp_new_i64();
5424 TCGLabel *lab = gen_new_label();
5426 tcg_gen_mov_i64(t2, t0);
5427 tcg_gen_sub_i64(t0, t1, t2);
5428 if (opc == OPC_SUB_CP2) {
5429 tcg_gen_ext32s_i64(t0, t0);
5431 tcg_gen_xor_i64(t1, t1, t2);
5432 tcg_gen_xor_i64(t2, t2, t0);
5433 tcg_gen_and_i64(t1, t1, t2);
5434 tcg_temp_free_i64(t2);
5435 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5436 generate_exception(ctx, EXCP_OVERFLOW);
5442 tcg_gen_ext32u_i64(t0, t0);
5443 tcg_gen_ext32u_i64(t1, t1);
5444 tcg_gen_mul_i64(t0, t0, t1);
5453 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5454 FD field is the CC field? */
5456 MIPS_INVAL("loongson_cp2");
5457 generate_exception_end(ctx, EXCP_RI);
5464 gen_store_fpr64(ctx, t0, rd);
5466 tcg_temp_free_i64(t0);
5467 tcg_temp_free_i64(t1);
5471 static void gen_trap (DisasContext *ctx, uint32_t opc,
5472 int rs, int rt, int16_t imm)
5475 TCGv t0 = tcg_temp_new();
5476 TCGv t1 = tcg_temp_new();
5479 /* Load needed operands */
5487 /* Compare two registers */
5489 gen_load_gpr(t0, rs);
5490 gen_load_gpr(t1, rt);
5500 /* Compare register to immediate */
5501 if (rs != 0 || imm != 0) {
5502 gen_load_gpr(t0, rs);
5503 tcg_gen_movi_tl(t1, (int32_t)imm);
5510 case OPC_TEQ: /* rs == rs */
5511 case OPC_TEQI: /* r0 == 0 */
5512 case OPC_TGE: /* rs >= rs */
5513 case OPC_TGEI: /* r0 >= 0 */
5514 case OPC_TGEU: /* rs >= rs unsigned */
5515 case OPC_TGEIU: /* r0 >= 0 unsigned */
5517 generate_exception_end(ctx, EXCP_TRAP);
5519 case OPC_TLT: /* rs < rs */
5520 case OPC_TLTI: /* r0 < 0 */
5521 case OPC_TLTU: /* rs < rs unsigned */
5522 case OPC_TLTIU: /* r0 < 0 unsigned */
5523 case OPC_TNE: /* rs != rs */
5524 case OPC_TNEI: /* r0 != 0 */
5525 /* Never trap: treat as NOP. */
5529 TCGLabel *l1 = gen_new_label();
5534 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5538 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5542 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5546 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5550 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5554 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5557 generate_exception(ctx, EXCP_TRAP);
5564 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5566 if (unlikely(ctx->base.singlestep_enabled)) {
5570 #ifndef CONFIG_USER_ONLY
5571 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5577 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5579 if (use_goto_tb(ctx, dest)) {
5582 tcg_gen_exit_tb(ctx->base.tb, n);
5585 if (ctx->base.singlestep_enabled) {
5586 save_cpu_state(ctx, 0);
5587 gen_helper_raise_exception_debug(cpu_env);
5589 tcg_gen_lookup_and_goto_ptr();
5593 /* Branches (before delay slot) */
5594 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5596 int rs, int rt, int32_t offset,
5599 target_ulong btgt = -1;
5601 int bcond_compute = 0;
5602 TCGv t0 = tcg_temp_new();
5603 TCGv t1 = tcg_temp_new();
5605 if (ctx->hflags & MIPS_HFLAG_BMASK) {
5606 #ifdef MIPS_DEBUG_DISAS
5607 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5608 TARGET_FMT_lx "\n", ctx->base.pc_next);
5610 generate_exception_end(ctx, EXCP_RI);
5614 /* Load needed operands */
5620 /* Compare two registers */
5622 gen_load_gpr(t0, rs);
5623 gen_load_gpr(t1, rt);
5626 btgt = ctx->base.pc_next + insn_bytes + offset;
5640 /* Compare to zero */
5642 gen_load_gpr(t0, rs);
5645 btgt = ctx->base.pc_next + insn_bytes + offset;
5648 #if defined(TARGET_MIPS64)
5650 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5652 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5655 btgt = ctx->base.pc_next + insn_bytes + offset;
5660 /* Jump to immediate */
5661 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5666 /* Jump to register */
5667 if (offset != 0 && offset != 16) {
5668 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5669 others are reserved. */
5670 MIPS_INVAL("jump hint");
5671 generate_exception_end(ctx, EXCP_RI);
5674 gen_load_gpr(btarget, rs);
5677 MIPS_INVAL("branch/jump");
5678 generate_exception_end(ctx, EXCP_RI);
5681 if (bcond_compute == 0) {
5682 /* No condition to be computed */
5684 case OPC_BEQ: /* rx == rx */
5685 case OPC_BEQL: /* rx == rx likely */
5686 case OPC_BGEZ: /* 0 >= 0 */
5687 case OPC_BGEZL: /* 0 >= 0 likely */
5688 case OPC_BLEZ: /* 0 <= 0 */
5689 case OPC_BLEZL: /* 0 <= 0 likely */
5691 ctx->hflags |= MIPS_HFLAG_B;
5693 case OPC_BGEZAL: /* 0 >= 0 */
5694 case OPC_BGEZALL: /* 0 >= 0 likely */
5695 /* Always take and link */
5697 ctx->hflags |= MIPS_HFLAG_B;
5699 case OPC_BNE: /* rx != rx */
5700 case OPC_BGTZ: /* 0 > 0 */
5701 case OPC_BLTZ: /* 0 < 0 */
5704 case OPC_BLTZAL: /* 0 < 0 */
5705 /* Handle as an unconditional branch to get correct delay
5708 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5709 ctx->hflags |= MIPS_HFLAG_B;
5711 case OPC_BLTZALL: /* 0 < 0 likely */
5712 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5713 /* Skip the instruction in the delay slot */
5714 ctx->base.pc_next += 4;
5716 case OPC_BNEL: /* rx != rx likely */
5717 case OPC_BGTZL: /* 0 > 0 likely */
5718 case OPC_BLTZL: /* 0 < 0 likely */
5719 /* Skip the instruction in the delay slot */
5720 ctx->base.pc_next += 4;
5723 ctx->hflags |= MIPS_HFLAG_B;
5726 ctx->hflags |= MIPS_HFLAG_BX;
5730 ctx->hflags |= MIPS_HFLAG_B;
5733 ctx->hflags |= MIPS_HFLAG_BR;
5737 ctx->hflags |= MIPS_HFLAG_BR;
5740 MIPS_INVAL("branch/jump");
5741 generate_exception_end(ctx, EXCP_RI);
5747 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5750 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5753 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5756 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5759 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5762 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5765 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5769 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5773 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5776 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5779 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5782 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5785 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5788 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5791 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5793 #if defined(TARGET_MIPS64)
5795 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5799 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5802 ctx->hflags |= MIPS_HFLAG_BC;
5805 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5808 ctx->hflags |= MIPS_HFLAG_BL;
5811 MIPS_INVAL("conditional branch/jump");
5812 generate_exception_end(ctx, EXCP_RI);
5817 ctx->btarget = btgt;
5819 switch (delayslot_size) {
5821 ctx->hflags |= MIPS_HFLAG_BDS16;
5824 ctx->hflags |= MIPS_HFLAG_BDS32;
5829 int post_delay = insn_bytes + delayslot_size;
5830 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5832 tcg_gen_movi_tl(cpu_gpr[blink],
5833 ctx->base.pc_next + post_delay + lowbit);
5837 if (insn_bytes == 2)
5838 ctx->hflags |= MIPS_HFLAG_B16;
5844 /* nanoMIPS Branches */
5845 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5847 int rs, int rt, int32_t offset)
5849 target_ulong btgt = -1;
5850 int bcond_compute = 0;
5851 TCGv t0 = tcg_temp_new();
5852 TCGv t1 = tcg_temp_new();
5854 /* Load needed operands */
5858 /* Compare two registers */
5860 gen_load_gpr(t0, rs);
5861 gen_load_gpr(t1, rt);
5864 btgt = ctx->base.pc_next + insn_bytes + offset;
5867 /* Compare to zero */
5869 gen_load_gpr(t0, rs);
5872 btgt = ctx->base.pc_next + insn_bytes + offset;
5875 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5877 btgt = ctx->base.pc_next + insn_bytes + offset;
5881 /* Jump to register */
5882 if (offset != 0 && offset != 16) {
5883 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5884 others are reserved. */
5885 MIPS_INVAL("jump hint");
5886 generate_exception_end(ctx, EXCP_RI);
5889 gen_load_gpr(btarget, rs);
5892 MIPS_INVAL("branch/jump");
5893 generate_exception_end(ctx, EXCP_RI);
5896 if (bcond_compute == 0) {
5897 /* No condition to be computed */
5899 case OPC_BEQ: /* rx == rx */
5901 ctx->hflags |= MIPS_HFLAG_B;
5903 case OPC_BGEZAL: /* 0 >= 0 */
5904 /* Always take and link */
5905 tcg_gen_movi_tl(cpu_gpr[31],
5906 ctx->base.pc_next + insn_bytes);
5907 ctx->hflags |= MIPS_HFLAG_B;
5909 case OPC_BNE: /* rx != rx */
5910 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5911 /* Skip the instruction in the delay slot */
5912 ctx->base.pc_next += 4;
5915 ctx->hflags |= MIPS_HFLAG_BR;
5919 tcg_gen_movi_tl(cpu_gpr[rt],
5920 ctx->base.pc_next + insn_bytes);
5922 ctx->hflags |= MIPS_HFLAG_BR;
5925 MIPS_INVAL("branch/jump");
5926 generate_exception_end(ctx, EXCP_RI);
5932 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5935 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5938 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5939 tcg_gen_movi_tl(cpu_gpr[31],
5940 ctx->base.pc_next + insn_bytes);
5943 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5945 ctx->hflags |= MIPS_HFLAG_BC;
5948 MIPS_INVAL("conditional branch/jump");
5949 generate_exception_end(ctx, EXCP_RI);
5954 ctx->btarget = btgt;
5957 if (insn_bytes == 2) {
5958 ctx->hflags |= MIPS_HFLAG_B16;
5965 /* special3 bitfield operations */
5966 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
5967 int rs, int lsb, int msb)
5969 TCGv t0 = tcg_temp_new();
5970 TCGv t1 = tcg_temp_new();
5972 gen_load_gpr(t1, rs);
5975 if (lsb + msb > 31) {
5979 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5981 /* The two checks together imply that lsb == 0,
5982 so this is a simple sign-extension. */
5983 tcg_gen_ext32s_tl(t0, t1);
5986 #if defined(TARGET_MIPS64)
5995 if (lsb + msb > 63) {
5998 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6005 gen_load_gpr(t0, rt);
6006 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6007 tcg_gen_ext32s_tl(t0, t0);
6009 #if defined(TARGET_MIPS64)
6020 gen_load_gpr(t0, rt);
6021 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6026 MIPS_INVAL("bitops");
6027 generate_exception_end(ctx, EXCP_RI);
6032 gen_store_gpr(t0, rt);
6037 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6042 /* If no destination, treat it as a NOP. */
6046 t0 = tcg_temp_new();
6047 gen_load_gpr(t0, rt);
6051 TCGv t1 = tcg_temp_new();
6052 TCGv t2 = tcg_const_tl(0x00FF00FF);
6054 tcg_gen_shri_tl(t1, t0, 8);
6055 tcg_gen_and_tl(t1, t1, t2);
6056 tcg_gen_and_tl(t0, t0, t2);
6057 tcg_gen_shli_tl(t0, t0, 8);
6058 tcg_gen_or_tl(t0, t0, t1);
6061 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6065 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6068 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6070 #if defined(TARGET_MIPS64)
6073 TCGv t1 = tcg_temp_new();
6074 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6076 tcg_gen_shri_tl(t1, t0, 8);
6077 tcg_gen_and_tl(t1, t1, t2);
6078 tcg_gen_and_tl(t0, t0, t2);
6079 tcg_gen_shli_tl(t0, t0, 8);
6080 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6087 TCGv t1 = tcg_temp_new();
6088 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6090 tcg_gen_shri_tl(t1, t0, 16);
6091 tcg_gen_and_tl(t1, t1, t2);
6092 tcg_gen_and_tl(t0, t0, t2);
6093 tcg_gen_shli_tl(t0, t0, 16);
6094 tcg_gen_or_tl(t0, t0, t1);
6095 tcg_gen_shri_tl(t1, t0, 32);
6096 tcg_gen_shli_tl(t0, t0, 32);
6097 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6104 MIPS_INVAL("bsfhl");
6105 generate_exception_end(ctx, EXCP_RI);
6112 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6121 t0 = tcg_temp_new();
6122 t1 = tcg_temp_new();
6123 gen_load_gpr(t0, rs);
6124 gen_load_gpr(t1, rt);
6125 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6126 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6127 if (opc == OPC_LSA) {
6128 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6137 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6145 t0 = tcg_temp_new();
6146 if (bits == 0 || bits == wordsz) {
6148 gen_load_gpr(t0, rt);
6150 gen_load_gpr(t0, rs);
6154 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6156 #if defined(TARGET_MIPS64)
6158 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6163 TCGv t1 = tcg_temp_new();
6164 gen_load_gpr(t0, rt);
6165 gen_load_gpr(t1, rs);
6169 TCGv_i64 t2 = tcg_temp_new_i64();
6170 tcg_gen_concat_tl_i64(t2, t1, t0);
6171 tcg_gen_shri_i64(t2, t2, 32 - bits);
6172 gen_move_low32(cpu_gpr[rd], t2);
6173 tcg_temp_free_i64(t2);
6176 #if defined(TARGET_MIPS64)
6178 tcg_gen_shli_tl(t0, t0, bits);
6179 tcg_gen_shri_tl(t1, t1, 64 - bits);
6180 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6190 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6193 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6196 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6199 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6202 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6209 t0 = tcg_temp_new();
6210 gen_load_gpr(t0, rt);
6213 gen_helper_bitswap(cpu_gpr[rd], t0);
6215 #if defined(TARGET_MIPS64)
6217 gen_helper_dbitswap(cpu_gpr[rd], t0);
6224 #ifndef CONFIG_USER_ONLY
6225 /* CP0 (MMU and control) */
6226 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6228 TCGv_i64 t0 = tcg_temp_new_i64();
6229 TCGv_i64 t1 = tcg_temp_new_i64();
6231 tcg_gen_ext_tl_i64(t0, arg);
6232 tcg_gen_ld_i64(t1, cpu_env, off);
6233 #if defined(TARGET_MIPS64)
6234 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6236 tcg_gen_concat32_i64(t1, t1, t0);
6238 tcg_gen_st_i64(t1, cpu_env, off);
6239 tcg_temp_free_i64(t1);
6240 tcg_temp_free_i64(t0);
6243 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6245 TCGv_i64 t0 = tcg_temp_new_i64();
6246 TCGv_i64 t1 = tcg_temp_new_i64();
6248 tcg_gen_ext_tl_i64(t0, arg);
6249 tcg_gen_ld_i64(t1, cpu_env, off);
6250 tcg_gen_concat32_i64(t1, t1, t0);
6251 tcg_gen_st_i64(t1, cpu_env, off);
6252 tcg_temp_free_i64(t1);
6253 tcg_temp_free_i64(t0);
6256 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6258 TCGv_i64 t0 = tcg_temp_new_i64();
6260 tcg_gen_ld_i64(t0, cpu_env, off);
6261 #if defined(TARGET_MIPS64)
6262 tcg_gen_shri_i64(t0, t0, 30);
6264 tcg_gen_shri_i64(t0, t0, 32);
6266 gen_move_low32(arg, t0);
6267 tcg_temp_free_i64(t0);
6270 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6272 TCGv_i64 t0 = tcg_temp_new_i64();
6274 tcg_gen_ld_i64(t0, cpu_env, off);
6275 tcg_gen_shri_i64(t0, t0, 32 + shift);
6276 gen_move_low32(arg, t0);
6277 tcg_temp_free_i64(t0);
6280 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6282 TCGv_i32 t0 = tcg_temp_new_i32();
6284 tcg_gen_ld_i32(t0, cpu_env, off);
6285 tcg_gen_ext_i32_tl(arg, t0);
6286 tcg_temp_free_i32(t0);
6289 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6291 tcg_gen_ld_tl(arg, cpu_env, off);
6292 tcg_gen_ext32s_tl(arg, arg);
6295 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6297 TCGv_i32 t0 = tcg_temp_new_i32();
6299 tcg_gen_trunc_tl_i32(t0, arg);
6300 tcg_gen_st_i32(t0, cpu_env, off);
6301 tcg_temp_free_i32(t0);
6304 #define CP0_CHECK(c) \
6307 goto cp0_unimplemented; \
6311 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6313 const char *rn = "invalid";
6319 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6320 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6324 goto cp0_unimplemented;
6330 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6331 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6335 goto cp0_unimplemented;
6341 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6342 ctx->CP0_LLAddr_shift);
6346 CP0_CHECK(ctx->mrp);
6347 gen_helper_mfhc0_maar(arg, cpu_env);
6351 goto cp0_unimplemented;
6360 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6364 goto cp0_unimplemented;
6368 goto cp0_unimplemented;
6370 trace_mips_translate_c0("mfhc0", rn, reg, sel);
6374 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
6375 tcg_gen_movi_tl(arg, 0);
6378 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6380 const char *rn = "invalid";
6381 uint64_t mask = ctx->PAMask >> 36;
6387 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6388 tcg_gen_andi_tl(arg, arg, mask);
6389 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6393 goto cp0_unimplemented;
6399 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6400 tcg_gen_andi_tl(arg, arg, mask);
6401 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6405 goto cp0_unimplemented;
6411 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6412 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6413 relevant for modern MIPS cores supporting MTHC0, therefore
6414 treating MTHC0 to LLAddr as NOP. */
6418 CP0_CHECK(ctx->mrp);
6419 gen_helper_mthc0_maar(cpu_env, arg);
6423 goto cp0_unimplemented;
6432 tcg_gen_andi_tl(arg, arg, mask);
6433 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6437 goto cp0_unimplemented;
6441 goto cp0_unimplemented;
6443 trace_mips_translate_c0("mthc0", rn, reg, sel);
6446 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
6449 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6451 if (ctx->insn_flags & ISA_MIPS32R6) {
6452 tcg_gen_movi_tl(arg, 0);
6454 tcg_gen_movi_tl(arg, ~0);
6458 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6460 const char *rn = "invalid";
6463 check_insn(ctx, ISA_MIPS32);
6469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6473 CP0_CHECK(ctx->insn_flags & ASE_MT);
6474 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6478 CP0_CHECK(ctx->insn_flags & ASE_MT);
6479 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6483 CP0_CHECK(ctx->insn_flags & ASE_MT);
6484 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6489 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6493 goto cp0_unimplemented;
6499 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6500 gen_helper_mfc0_random(arg, cpu_env);
6504 CP0_CHECK(ctx->insn_flags & ASE_MT);
6505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6509 CP0_CHECK(ctx->insn_flags & ASE_MT);
6510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6514 CP0_CHECK(ctx->insn_flags & ASE_MT);
6515 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6519 CP0_CHECK(ctx->insn_flags & ASE_MT);
6520 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6524 CP0_CHECK(ctx->insn_flags & ASE_MT);
6525 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6529 CP0_CHECK(ctx->insn_flags & ASE_MT);
6530 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6531 rn = "VPEScheFBack";
6534 CP0_CHECK(ctx->insn_flags & ASE_MT);
6535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6539 goto cp0_unimplemented;
6546 TCGv_i64 tmp = tcg_temp_new_i64();
6547 tcg_gen_ld_i64(tmp, cpu_env,
6548 offsetof(CPUMIPSState, CP0_EntryLo0));
6549 #if defined(TARGET_MIPS64)
6551 /* Move RI/XI fields to bits 31:30 */
6552 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6553 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6556 gen_move_low32(arg, tmp);
6557 tcg_temp_free_i64(tmp);
6562 CP0_CHECK(ctx->insn_flags & ASE_MT);
6563 gen_helper_mfc0_tcstatus(arg, cpu_env);
6567 CP0_CHECK(ctx->insn_flags & ASE_MT);
6568 gen_helper_mfc0_tcbind(arg, cpu_env);
6572 CP0_CHECK(ctx->insn_flags & ASE_MT);
6573 gen_helper_mfc0_tcrestart(arg, cpu_env);
6577 CP0_CHECK(ctx->insn_flags & ASE_MT);
6578 gen_helper_mfc0_tchalt(arg, cpu_env);
6582 CP0_CHECK(ctx->insn_flags & ASE_MT);
6583 gen_helper_mfc0_tccontext(arg, cpu_env);
6587 CP0_CHECK(ctx->insn_flags & ASE_MT);
6588 gen_helper_mfc0_tcschedule(arg, cpu_env);
6592 CP0_CHECK(ctx->insn_flags & ASE_MT);
6593 gen_helper_mfc0_tcschefback(arg, cpu_env);
6597 goto cp0_unimplemented;
6604 TCGv_i64 tmp = tcg_temp_new_i64();
6605 tcg_gen_ld_i64(tmp, cpu_env,
6606 offsetof(CPUMIPSState, CP0_EntryLo1));
6607 #if defined(TARGET_MIPS64)
6609 /* Move RI/XI fields to bits 31:30 */
6610 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6611 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6614 gen_move_low32(arg, tmp);
6615 tcg_temp_free_i64(tmp);
6621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6622 rn = "GlobalNumber";
6625 goto cp0_unimplemented;
6631 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6632 tcg_gen_ext32s_tl(arg, arg);
6636 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6637 rn = "ContextConfig";
6638 goto cp0_unimplemented;
6640 CP0_CHECK(ctx->ulri);
6641 tcg_gen_ld_tl(arg, cpu_env,
6642 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6643 tcg_gen_ext32s_tl(arg, arg);
6647 goto cp0_unimplemented;
6653 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6657 check_insn(ctx, ISA_MIPS32R2);
6658 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6663 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6664 tcg_gen_ext32s_tl(arg, arg);
6669 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6670 tcg_gen_ext32s_tl(arg, arg);
6675 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6676 tcg_gen_ext32s_tl(arg, arg);
6681 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6691 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6695 goto cp0_unimplemented;
6701 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6705 check_insn(ctx, ISA_MIPS32R2);
6706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6710 check_insn(ctx, ISA_MIPS32R2);
6711 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6715 check_insn(ctx, ISA_MIPS32R2);
6716 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6720 check_insn(ctx, ISA_MIPS32R2);
6721 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6725 check_insn(ctx, ISA_MIPS32R2);
6726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6731 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6735 goto cp0_unimplemented;
6741 check_insn(ctx, ISA_MIPS32R2);
6742 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6746 goto cp0_unimplemented;
6752 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6753 tcg_gen_ext32s_tl(arg, arg);
6758 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6769 tcg_gen_andi_tl(arg, arg, ~0xffff);
6773 goto cp0_unimplemented;
6779 /* Mark as an IO operation because we read the time. */
6780 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6783 gen_helper_mfc0_count(arg, cpu_env);
6784 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6787 /* Break the TB to be able to take timer interrupts immediately
6788 after reading count. DISAS_STOP isn't sufficient, we need to
6789 ensure we break completely out of translated code. */
6790 gen_save_pc(ctx->base.pc_next + 4);
6791 ctx->base.is_jmp = DISAS_EXIT;
6794 /* 6,7 are implementation dependent */
6796 goto cp0_unimplemented;
6802 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6803 tcg_gen_ext32s_tl(arg, arg);
6807 goto cp0_unimplemented;
6813 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6816 /* 6,7 are implementation dependent */
6818 goto cp0_unimplemented;
6824 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6828 check_insn(ctx, ISA_MIPS32R2);
6829 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6833 check_insn(ctx, ISA_MIPS32R2);
6834 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6838 check_insn(ctx, ISA_MIPS32R2);
6839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6843 goto cp0_unimplemented;
6849 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6853 goto cp0_unimplemented;
6859 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6860 tcg_gen_ext32s_tl(arg, arg);
6864 goto cp0_unimplemented;
6870 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6874 check_insn(ctx, ISA_MIPS32R2);
6875 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6876 tcg_gen_ext32s_tl(arg, arg);
6880 check_insn(ctx, ISA_MIPS32R2);
6881 CP0_CHECK(ctx->cmgcr);
6882 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6883 tcg_gen_ext32s_tl(arg, arg);
6887 goto cp0_unimplemented;
6893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6897 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6901 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6905 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6909 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6913 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6916 /* 6,7 are implementation dependent */
6918 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6922 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6926 goto cp0_unimplemented;
6932 gen_helper_mfc0_lladdr(arg, cpu_env);
6936 CP0_CHECK(ctx->mrp);
6937 gen_helper_mfc0_maar(arg, cpu_env);
6941 CP0_CHECK(ctx->mrp);
6942 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6946 goto cp0_unimplemented;
6959 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6960 gen_helper_1e0i(mfc0_watchlo, arg, sel);
6964 goto cp0_unimplemented;
6977 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6978 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6982 goto cp0_unimplemented;
6988 #if defined(TARGET_MIPS64)
6989 check_insn(ctx, ISA_MIPS3);
6990 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6991 tcg_gen_ext32s_tl(arg, arg);
6996 goto cp0_unimplemented;
7000 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7001 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7004 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7008 goto cp0_unimplemented;
7012 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7013 rn = "'Diagnostic"; /* implementation dependent */
7018 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7022 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7023 rn = "TraceControl";
7024 goto cp0_unimplemented;
7026 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7027 rn = "TraceControl2";
7028 goto cp0_unimplemented;
7030 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7031 rn = "UserTraceData";
7032 goto cp0_unimplemented;
7034 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7036 goto cp0_unimplemented;
7038 goto cp0_unimplemented;
7045 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7046 tcg_gen_ext32s_tl(arg, arg);
7050 goto cp0_unimplemented;
7056 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7057 rn = "Performance0";
7060 // gen_helper_mfc0_performance1(arg);
7061 rn = "Performance1";
7062 goto cp0_unimplemented;
7064 // gen_helper_mfc0_performance2(arg);
7065 rn = "Performance2";
7066 goto cp0_unimplemented;
7068 // gen_helper_mfc0_performance3(arg);
7069 rn = "Performance3";
7070 goto cp0_unimplemented;
7072 // gen_helper_mfc0_performance4(arg);
7073 rn = "Performance4";
7074 goto cp0_unimplemented;
7076 // gen_helper_mfc0_performance5(arg);
7077 rn = "Performance5";
7078 goto cp0_unimplemented;
7080 // gen_helper_mfc0_performance6(arg);
7081 rn = "Performance6";
7082 goto cp0_unimplemented;
7084 // gen_helper_mfc0_performance7(arg);
7085 rn = "Performance7";
7086 goto cp0_unimplemented;
7088 goto cp0_unimplemented;
7094 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7098 goto cp0_unimplemented;
7107 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7111 goto cp0_unimplemented;
7121 TCGv_i64 tmp = tcg_temp_new_i64();
7122 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7123 gen_move_low32(arg, tmp);
7124 tcg_temp_free_i64(tmp);
7132 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7136 goto cp0_unimplemented;
7145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7156 goto cp0_unimplemented;
7162 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7163 tcg_gen_ext32s_tl(arg, arg);
7167 goto cp0_unimplemented;
7174 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7183 CP0_CHECK(ctx->kscrexist & (1 << sel));
7184 tcg_gen_ld_tl(arg, cpu_env,
7185 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7186 tcg_gen_ext32s_tl(arg, arg);
7190 goto cp0_unimplemented;
7194 goto cp0_unimplemented;
7196 trace_mips_translate_c0("mfc0", rn, reg, sel);
7200 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
7201 gen_mfc0_unimplemented(ctx, arg);
7204 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7206 const char *rn = "invalid";
7209 check_insn(ctx, ISA_MIPS32);
7211 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7219 gen_helper_mtc0_index(cpu_env, arg);
7223 CP0_CHECK(ctx->insn_flags & ASE_MT);
7224 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7228 CP0_CHECK(ctx->insn_flags & ASE_MT);
7233 CP0_CHECK(ctx->insn_flags & ASE_MT);
7243 goto cp0_unimplemented;
7253 CP0_CHECK(ctx->insn_flags & ASE_MT);
7254 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7258 CP0_CHECK(ctx->insn_flags & ASE_MT);
7259 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7263 CP0_CHECK(ctx->insn_flags & ASE_MT);
7264 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7268 CP0_CHECK(ctx->insn_flags & ASE_MT);
7269 gen_helper_mtc0_yqmask(cpu_env, arg);
7273 CP0_CHECK(ctx->insn_flags & ASE_MT);
7274 tcg_gen_st_tl(arg, cpu_env,
7275 offsetof(CPUMIPSState, CP0_VPESchedule));
7279 CP0_CHECK(ctx->insn_flags & ASE_MT);
7280 tcg_gen_st_tl(arg, cpu_env,
7281 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7282 rn = "VPEScheFBack";
7285 CP0_CHECK(ctx->insn_flags & ASE_MT);
7286 gen_helper_mtc0_vpeopt(cpu_env, arg);
7290 goto cp0_unimplemented;
7296 gen_helper_mtc0_entrylo0(cpu_env, arg);
7300 CP0_CHECK(ctx->insn_flags & ASE_MT);
7301 gen_helper_mtc0_tcstatus(cpu_env, arg);
7305 CP0_CHECK(ctx->insn_flags & ASE_MT);
7306 gen_helper_mtc0_tcbind(cpu_env, arg);
7310 CP0_CHECK(ctx->insn_flags & ASE_MT);
7311 gen_helper_mtc0_tcrestart(cpu_env, arg);
7315 CP0_CHECK(ctx->insn_flags & ASE_MT);
7316 gen_helper_mtc0_tchalt(cpu_env, arg);
7320 CP0_CHECK(ctx->insn_flags & ASE_MT);
7321 gen_helper_mtc0_tccontext(cpu_env, arg);
7325 CP0_CHECK(ctx->insn_flags & ASE_MT);
7326 gen_helper_mtc0_tcschedule(cpu_env, arg);
7330 CP0_CHECK(ctx->insn_flags & ASE_MT);
7331 gen_helper_mtc0_tcschefback(cpu_env, arg);
7335 goto cp0_unimplemented;
7341 gen_helper_mtc0_entrylo1(cpu_env, arg);
7347 rn = "GlobalNumber";
7350 goto cp0_unimplemented;
7356 gen_helper_mtc0_context(cpu_env, arg);
7360 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7361 rn = "ContextConfig";
7362 goto cp0_unimplemented;
7364 CP0_CHECK(ctx->ulri);
7365 tcg_gen_st_tl(arg, cpu_env,
7366 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7370 goto cp0_unimplemented;
7376 gen_helper_mtc0_pagemask(cpu_env, arg);
7380 check_insn(ctx, ISA_MIPS32R2);
7381 gen_helper_mtc0_pagegrain(cpu_env, arg);
7383 ctx->base.is_jmp = DISAS_STOP;
7387 gen_helper_mtc0_segctl0(cpu_env, arg);
7392 gen_helper_mtc0_segctl1(cpu_env, arg);
7397 gen_helper_mtc0_segctl2(cpu_env, arg);
7402 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7407 gen_helper_mtc0_pwfield(cpu_env, arg);
7412 gen_helper_mtc0_pwsize(cpu_env, arg);
7416 goto cp0_unimplemented;
7422 gen_helper_mtc0_wired(cpu_env, arg);
7426 check_insn(ctx, ISA_MIPS32R2);
7427 gen_helper_mtc0_srsconf0(cpu_env, arg);
7431 check_insn(ctx, ISA_MIPS32R2);
7432 gen_helper_mtc0_srsconf1(cpu_env, arg);
7436 check_insn(ctx, ISA_MIPS32R2);
7437 gen_helper_mtc0_srsconf2(cpu_env, arg);
7441 check_insn(ctx, ISA_MIPS32R2);
7442 gen_helper_mtc0_srsconf3(cpu_env, arg);
7446 check_insn(ctx, ISA_MIPS32R2);
7447 gen_helper_mtc0_srsconf4(cpu_env, arg);
7452 gen_helper_mtc0_pwctl(cpu_env, arg);
7456 goto cp0_unimplemented;
7462 check_insn(ctx, ISA_MIPS32R2);
7463 gen_helper_mtc0_hwrena(cpu_env, arg);
7464 ctx->base.is_jmp = DISAS_STOP;
7468 goto cp0_unimplemented;
7490 goto cp0_unimplemented;
7496 gen_helper_mtc0_count(cpu_env, arg);
7499 /* 6,7 are implementation dependent */
7501 goto cp0_unimplemented;
7507 gen_helper_mtc0_entryhi(cpu_env, arg);
7511 goto cp0_unimplemented;
7517 gen_helper_mtc0_compare(cpu_env, arg);
7520 /* 6,7 are implementation dependent */
7522 goto cp0_unimplemented;
7528 save_cpu_state(ctx, 1);
7529 gen_helper_mtc0_status(cpu_env, arg);
7530 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7531 gen_save_pc(ctx->base.pc_next + 4);
7532 ctx->base.is_jmp = DISAS_EXIT;
7536 check_insn(ctx, ISA_MIPS32R2);
7537 gen_helper_mtc0_intctl(cpu_env, arg);
7538 /* Stop translation as we may have switched the execution mode */
7539 ctx->base.is_jmp = DISAS_STOP;
7543 check_insn(ctx, ISA_MIPS32R2);
7544 gen_helper_mtc0_srsctl(cpu_env, arg);
7545 /* Stop translation as we may have switched the execution mode */
7546 ctx->base.is_jmp = DISAS_STOP;
7550 check_insn(ctx, ISA_MIPS32R2);
7551 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7552 /* Stop translation as we may have switched the execution mode */
7553 ctx->base.is_jmp = DISAS_STOP;
7557 goto cp0_unimplemented;
7563 save_cpu_state(ctx, 1);
7564 gen_helper_mtc0_cause(cpu_env, arg);
7565 /* Stop translation as we may have triggered an interrupt.
7566 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7567 * translated code to check for pending interrupts. */
7568 gen_save_pc(ctx->base.pc_next + 4);
7569 ctx->base.is_jmp = DISAS_EXIT;
7573 goto cp0_unimplemented;
7579 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7583 goto cp0_unimplemented;
7593 check_insn(ctx, ISA_MIPS32R2);
7594 gen_helper_mtc0_ebase(cpu_env, arg);
7598 goto cp0_unimplemented;
7604 gen_helper_mtc0_config0(cpu_env, arg);
7606 /* Stop translation as we may have switched the execution mode */
7607 ctx->base.is_jmp = DISAS_STOP;
7610 /* ignored, read only */
7614 gen_helper_mtc0_config2(cpu_env, arg);
7616 /* Stop translation as we may have switched the execution mode */
7617 ctx->base.is_jmp = DISAS_STOP;
7620 gen_helper_mtc0_config3(cpu_env, arg);
7622 /* Stop translation as we may have switched the execution mode */
7623 ctx->base.is_jmp = DISAS_STOP;
7626 gen_helper_mtc0_config4(cpu_env, arg);
7628 ctx->base.is_jmp = DISAS_STOP;
7631 gen_helper_mtc0_config5(cpu_env, arg);
7633 /* Stop translation as we may have switched the execution mode */
7634 ctx->base.is_jmp = DISAS_STOP;
7636 /* 6,7 are implementation dependent */
7646 rn = "Invalid config selector";
7647 goto cp0_unimplemented;
7653 gen_helper_mtc0_lladdr(cpu_env, arg);
7657 CP0_CHECK(ctx->mrp);
7658 gen_helper_mtc0_maar(cpu_env, arg);
7662 CP0_CHECK(ctx->mrp);
7663 gen_helper_mtc0_maari(cpu_env, arg);
7667 goto cp0_unimplemented;
7680 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7681 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7685 goto cp0_unimplemented;
7698 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7699 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7703 goto cp0_unimplemented;
7709 #if defined(TARGET_MIPS64)
7710 check_insn(ctx, ISA_MIPS3);
7711 gen_helper_mtc0_xcontext(cpu_env, arg);
7716 goto cp0_unimplemented;
7720 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7721 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7724 gen_helper_mtc0_framemask(cpu_env, arg);
7728 goto cp0_unimplemented;
7733 rn = "Diagnostic"; /* implementation dependent */
7738 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7739 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7740 gen_save_pc(ctx->base.pc_next + 4);
7741 ctx->base.is_jmp = DISAS_EXIT;
7745 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7746 rn = "TraceControl";
7747 /* Stop translation as we may have switched the execution mode */
7748 ctx->base.is_jmp = DISAS_STOP;
7749 goto cp0_unimplemented;
7751 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7752 rn = "TraceControl2";
7753 /* Stop translation as we may have switched the execution mode */
7754 ctx->base.is_jmp = DISAS_STOP;
7755 goto cp0_unimplemented;
7757 /* Stop translation as we may have switched the execution mode */
7758 ctx->base.is_jmp = DISAS_STOP;
7759 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7760 rn = "UserTraceData";
7761 /* Stop translation as we may have switched the execution mode */
7762 ctx->base.is_jmp = DISAS_STOP;
7763 goto cp0_unimplemented;
7765 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7766 /* Stop translation as we may have switched the execution mode */
7767 ctx->base.is_jmp = DISAS_STOP;
7769 goto cp0_unimplemented;
7771 goto cp0_unimplemented;
7778 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7782 goto cp0_unimplemented;
7788 gen_helper_mtc0_performance0(cpu_env, arg);
7789 rn = "Performance0";
7792 // gen_helper_mtc0_performance1(arg);
7793 rn = "Performance1";
7794 goto cp0_unimplemented;
7796 // gen_helper_mtc0_performance2(arg);
7797 rn = "Performance2";
7798 goto cp0_unimplemented;
7800 // gen_helper_mtc0_performance3(arg);
7801 rn = "Performance3";
7802 goto cp0_unimplemented;
7804 // gen_helper_mtc0_performance4(arg);
7805 rn = "Performance4";
7806 goto cp0_unimplemented;
7808 // gen_helper_mtc0_performance5(arg);
7809 rn = "Performance5";
7810 goto cp0_unimplemented;
7812 // gen_helper_mtc0_performance6(arg);
7813 rn = "Performance6";
7814 goto cp0_unimplemented;
7816 // gen_helper_mtc0_performance7(arg);
7817 rn = "Performance7";
7818 goto cp0_unimplemented;
7820 goto cp0_unimplemented;
7826 gen_helper_mtc0_errctl(cpu_env, arg);
7827 ctx->base.is_jmp = DISAS_STOP;
7831 goto cp0_unimplemented;
7844 goto cp0_unimplemented;
7853 gen_helper_mtc0_taglo(cpu_env, arg);
7860 gen_helper_mtc0_datalo(cpu_env, arg);
7864 goto cp0_unimplemented;
7873 gen_helper_mtc0_taghi(cpu_env, arg);
7880 gen_helper_mtc0_datahi(cpu_env, arg);
7885 goto cp0_unimplemented;
7891 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7895 goto cp0_unimplemented;
7902 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7911 CP0_CHECK(ctx->kscrexist & (1 << sel));
7912 tcg_gen_st_tl(arg, cpu_env,
7913 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7917 goto cp0_unimplemented;
7921 goto cp0_unimplemented;
7923 trace_mips_translate_c0("mtc0", rn, reg, sel);
7925 /* For simplicity assume that all writes can cause interrupts. */
7926 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7928 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
7929 * translated code to check for pending interrupts. */
7930 gen_save_pc(ctx->base.pc_next + 4);
7931 ctx->base.is_jmp = DISAS_EXIT;
7936 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7939 #if defined(TARGET_MIPS64)
7940 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7942 const char *rn = "invalid";
7945 check_insn(ctx, ISA_MIPS64);
7951 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7955 CP0_CHECK(ctx->insn_flags & ASE_MT);
7956 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7960 CP0_CHECK(ctx->insn_flags & ASE_MT);
7961 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7965 CP0_CHECK(ctx->insn_flags & ASE_MT);
7966 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7971 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7975 goto cp0_unimplemented;
7981 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7982 gen_helper_mfc0_random(arg, cpu_env);
7986 CP0_CHECK(ctx->insn_flags & ASE_MT);
7987 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7991 CP0_CHECK(ctx->insn_flags & ASE_MT);
7992 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7996 CP0_CHECK(ctx->insn_flags & ASE_MT);
7997 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8001 CP0_CHECK(ctx->insn_flags & ASE_MT);
8002 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8006 CP0_CHECK(ctx->insn_flags & ASE_MT);
8007 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8011 CP0_CHECK(ctx->insn_flags & ASE_MT);
8012 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8013 rn = "VPEScheFBack";
8016 CP0_CHECK(ctx->insn_flags & ASE_MT);
8017 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8021 goto cp0_unimplemented;
8027 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8031 CP0_CHECK(ctx->insn_flags & ASE_MT);
8032 gen_helper_mfc0_tcstatus(arg, cpu_env);
8036 CP0_CHECK(ctx->insn_flags & ASE_MT);
8037 gen_helper_mfc0_tcbind(arg, cpu_env);
8041 CP0_CHECK(ctx->insn_flags & ASE_MT);
8042 gen_helper_dmfc0_tcrestart(arg, cpu_env);
8046 CP0_CHECK(ctx->insn_flags & ASE_MT);
8047 gen_helper_dmfc0_tchalt(arg, cpu_env);
8051 CP0_CHECK(ctx->insn_flags & ASE_MT);
8052 gen_helper_dmfc0_tccontext(arg, cpu_env);
8056 CP0_CHECK(ctx->insn_flags & ASE_MT);
8057 gen_helper_dmfc0_tcschedule(arg, cpu_env);
8061 CP0_CHECK(ctx->insn_flags & ASE_MT);
8062 gen_helper_dmfc0_tcschefback(arg, cpu_env);
8066 goto cp0_unimplemented;
8072 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8077 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8078 rn = "GlobalNumber";
8081 goto cp0_unimplemented;
8087 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8091 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8092 rn = "ContextConfig";
8093 goto cp0_unimplemented;
8095 CP0_CHECK(ctx->ulri);
8096 tcg_gen_ld_tl(arg, cpu_env,
8097 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8101 goto cp0_unimplemented;
8107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8111 check_insn(ctx, ISA_MIPS32R2);
8112 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8117 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8122 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8127 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8132 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8137 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8142 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8146 goto cp0_unimplemented;
8152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8156 check_insn(ctx, ISA_MIPS32R2);
8157 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8161 check_insn(ctx, ISA_MIPS32R2);
8162 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8166 check_insn(ctx, ISA_MIPS32R2);
8167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8171 check_insn(ctx, ISA_MIPS32R2);
8172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8176 check_insn(ctx, ISA_MIPS32R2);
8177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8182 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8186 goto cp0_unimplemented;
8192 check_insn(ctx, ISA_MIPS32R2);
8193 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8197 goto cp0_unimplemented;
8203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8208 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8213 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8219 tcg_gen_andi_tl(arg, arg, ~0xffff);
8223 goto cp0_unimplemented;
8229 /* Mark as an IO operation because we read the time. */
8230 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8233 gen_helper_mfc0_count(arg, cpu_env);
8234 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8237 /* Break the TB to be able to take timer interrupts immediately
8238 after reading count. DISAS_STOP isn't sufficient, we need to
8239 ensure we break completely out of translated code. */
8240 gen_save_pc(ctx->base.pc_next + 4);
8241 ctx->base.is_jmp = DISAS_EXIT;
8244 /* 6,7 are implementation dependent */
8246 goto cp0_unimplemented;
8252 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8256 goto cp0_unimplemented;
8262 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8265 /* 6,7 are implementation dependent */
8267 goto cp0_unimplemented;
8273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8277 check_insn(ctx, ISA_MIPS32R2);
8278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8282 check_insn(ctx, ISA_MIPS32R2);
8283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8287 check_insn(ctx, ISA_MIPS32R2);
8288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8292 goto cp0_unimplemented;
8298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8302 goto cp0_unimplemented;
8308 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8312 goto cp0_unimplemented;
8318 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8322 check_insn(ctx, ISA_MIPS32R2);
8323 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8327 check_insn(ctx, ISA_MIPS32R2);
8328 CP0_CHECK(ctx->cmgcr);
8329 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8333 goto cp0_unimplemented;
8339 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8347 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8355 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8362 /* 6,7 are implementation dependent */
8364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8372 goto cp0_unimplemented;
8378 gen_helper_dmfc0_lladdr(arg, cpu_env);
8382 CP0_CHECK(ctx->mrp);
8383 gen_helper_dmfc0_maar(arg, cpu_env);
8387 CP0_CHECK(ctx->mrp);
8388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8392 goto cp0_unimplemented;
8405 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8406 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8410 goto cp0_unimplemented;
8423 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8424 gen_helper_1e0i(mfc0_watchhi, arg, sel);
8428 goto cp0_unimplemented;
8434 check_insn(ctx, ISA_MIPS3);
8435 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8439 goto cp0_unimplemented;
8443 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8444 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8451 goto cp0_unimplemented;
8455 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8456 rn = "'Diagnostic"; /* implementation dependent */
8461 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8465 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8466 rn = "TraceControl";
8467 goto cp0_unimplemented;
8469 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8470 rn = "TraceControl2";
8471 goto cp0_unimplemented;
8473 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8474 rn = "UserTraceData";
8475 goto cp0_unimplemented;
8477 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8479 goto cp0_unimplemented;
8481 goto cp0_unimplemented;
8488 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8492 goto cp0_unimplemented;
8498 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8499 rn = "Performance0";
8502 // gen_helper_dmfc0_performance1(arg);
8503 rn = "Performance1";
8504 goto cp0_unimplemented;
8506 // gen_helper_dmfc0_performance2(arg);
8507 rn = "Performance2";
8508 goto cp0_unimplemented;
8510 // gen_helper_dmfc0_performance3(arg);
8511 rn = "Performance3";
8512 goto cp0_unimplemented;
8514 // gen_helper_dmfc0_performance4(arg);
8515 rn = "Performance4";
8516 goto cp0_unimplemented;
8518 // gen_helper_dmfc0_performance5(arg);
8519 rn = "Performance5";
8520 goto cp0_unimplemented;
8522 // gen_helper_dmfc0_performance6(arg);
8523 rn = "Performance6";
8524 goto cp0_unimplemented;
8526 // gen_helper_dmfc0_performance7(arg);
8527 rn = "Performance7";
8528 goto cp0_unimplemented;
8530 goto cp0_unimplemented;
8536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8540 goto cp0_unimplemented;
8550 tcg_gen_movi_tl(arg, 0); /* unimplemented */
8554 goto cp0_unimplemented;
8563 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8574 goto cp0_unimplemented;
8583 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8590 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8594 goto cp0_unimplemented;
8600 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8604 goto cp0_unimplemented;
8611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8620 CP0_CHECK(ctx->kscrexist & (1 << sel));
8621 tcg_gen_ld_tl(arg, cpu_env,
8622 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8626 goto cp0_unimplemented;
8630 goto cp0_unimplemented;
8632 trace_mips_translate_c0("dmfc0", rn, reg, sel);
8636 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
8637 gen_mfc0_unimplemented(ctx, arg);
8640 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8642 const char *rn = "invalid";
8645 check_insn(ctx, ISA_MIPS64);
8647 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8655 gen_helper_mtc0_index(cpu_env, arg);
8659 CP0_CHECK(ctx->insn_flags & ASE_MT);
8660 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8664 CP0_CHECK(ctx->insn_flags & ASE_MT);
8669 CP0_CHECK(ctx->insn_flags & ASE_MT);
8679 goto cp0_unimplemented;
8689 CP0_CHECK(ctx->insn_flags & ASE_MT);
8690 gen_helper_mtc0_vpecontrol(cpu_env, arg);
8694 CP0_CHECK(ctx->insn_flags & ASE_MT);
8695 gen_helper_mtc0_vpeconf0(cpu_env, arg);
8699 CP0_CHECK(ctx->insn_flags & ASE_MT);
8700 gen_helper_mtc0_vpeconf1(cpu_env, arg);
8704 CP0_CHECK(ctx->insn_flags & ASE_MT);
8705 gen_helper_mtc0_yqmask(cpu_env, arg);
8709 CP0_CHECK(ctx->insn_flags & ASE_MT);
8710 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8714 CP0_CHECK(ctx->insn_flags & ASE_MT);
8715 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8716 rn = "VPEScheFBack";
8719 CP0_CHECK(ctx->insn_flags & ASE_MT);
8720 gen_helper_mtc0_vpeopt(cpu_env, arg);
8724 goto cp0_unimplemented;
8730 gen_helper_dmtc0_entrylo0(cpu_env, arg);
8734 CP0_CHECK(ctx->insn_flags & ASE_MT);
8735 gen_helper_mtc0_tcstatus(cpu_env, arg);
8739 CP0_CHECK(ctx->insn_flags & ASE_MT);
8740 gen_helper_mtc0_tcbind(cpu_env, arg);
8744 CP0_CHECK(ctx->insn_flags & ASE_MT);
8745 gen_helper_mtc0_tcrestart(cpu_env, arg);
8749 CP0_CHECK(ctx->insn_flags & ASE_MT);
8750 gen_helper_mtc0_tchalt(cpu_env, arg);
8754 CP0_CHECK(ctx->insn_flags & ASE_MT);
8755 gen_helper_mtc0_tccontext(cpu_env, arg);
8759 CP0_CHECK(ctx->insn_flags & ASE_MT);
8760 gen_helper_mtc0_tcschedule(cpu_env, arg);
8764 CP0_CHECK(ctx->insn_flags & ASE_MT);
8765 gen_helper_mtc0_tcschefback(cpu_env, arg);
8769 goto cp0_unimplemented;
8775 gen_helper_dmtc0_entrylo1(cpu_env, arg);
8781 rn = "GlobalNumber";
8784 goto cp0_unimplemented;
8790 gen_helper_mtc0_context(cpu_env, arg);
8794 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8795 rn = "ContextConfig";
8796 goto cp0_unimplemented;
8798 CP0_CHECK(ctx->ulri);
8799 tcg_gen_st_tl(arg, cpu_env,
8800 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8804 goto cp0_unimplemented;
8810 gen_helper_mtc0_pagemask(cpu_env, arg);
8814 check_insn(ctx, ISA_MIPS32R2);
8815 gen_helper_mtc0_pagegrain(cpu_env, arg);
8820 gen_helper_mtc0_segctl0(cpu_env, arg);
8825 gen_helper_mtc0_segctl1(cpu_env, arg);
8830 gen_helper_mtc0_segctl2(cpu_env, arg);
8835 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8840 gen_helper_mtc0_pwfield(cpu_env, arg);
8845 gen_helper_mtc0_pwsize(cpu_env, arg);
8849 goto cp0_unimplemented;
8855 gen_helper_mtc0_wired(cpu_env, arg);
8859 check_insn(ctx, ISA_MIPS32R2);
8860 gen_helper_mtc0_srsconf0(cpu_env, arg);
8864 check_insn(ctx, ISA_MIPS32R2);
8865 gen_helper_mtc0_srsconf1(cpu_env, arg);
8869 check_insn(ctx, ISA_MIPS32R2);
8870 gen_helper_mtc0_srsconf2(cpu_env, arg);
8874 check_insn(ctx, ISA_MIPS32R2);
8875 gen_helper_mtc0_srsconf3(cpu_env, arg);
8879 check_insn(ctx, ISA_MIPS32R2);
8880 gen_helper_mtc0_srsconf4(cpu_env, arg);
8885 gen_helper_mtc0_pwctl(cpu_env, arg);
8889 goto cp0_unimplemented;
8895 check_insn(ctx, ISA_MIPS32R2);
8896 gen_helper_mtc0_hwrena(cpu_env, arg);
8897 ctx->base.is_jmp = DISAS_STOP;
8901 goto cp0_unimplemented;
8923 goto cp0_unimplemented;
8929 gen_helper_mtc0_count(cpu_env, arg);
8932 /* 6,7 are implementation dependent */
8934 goto cp0_unimplemented;
8936 /* Stop translation as we may have switched the execution mode */
8937 ctx->base.is_jmp = DISAS_STOP;
8942 gen_helper_mtc0_entryhi(cpu_env, arg);
8946 goto cp0_unimplemented;
8952 gen_helper_mtc0_compare(cpu_env, arg);
8955 /* 6,7 are implementation dependent */
8957 goto cp0_unimplemented;
8959 /* Stop translation as we may have switched the execution mode */
8960 ctx->base.is_jmp = DISAS_STOP;
8965 save_cpu_state(ctx, 1);
8966 gen_helper_mtc0_status(cpu_env, arg);
8967 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8968 gen_save_pc(ctx->base.pc_next + 4);
8969 ctx->base.is_jmp = DISAS_EXIT;
8973 check_insn(ctx, ISA_MIPS32R2);
8974 gen_helper_mtc0_intctl(cpu_env, arg);
8975 /* Stop translation as we may have switched the execution mode */
8976 ctx->base.is_jmp = DISAS_STOP;
8980 check_insn(ctx, ISA_MIPS32R2);
8981 gen_helper_mtc0_srsctl(cpu_env, arg);
8982 /* Stop translation as we may have switched the execution mode */
8983 ctx->base.is_jmp = DISAS_STOP;
8987 check_insn(ctx, ISA_MIPS32R2);
8988 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8989 /* Stop translation as we may have switched the execution mode */
8990 ctx->base.is_jmp = DISAS_STOP;
8994 goto cp0_unimplemented;
9000 save_cpu_state(ctx, 1);
9001 gen_helper_mtc0_cause(cpu_env, arg);
9002 /* Stop translation as we may have triggered an interrupt.
9003 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9004 * translated code to check for pending interrupts. */
9005 gen_save_pc(ctx->base.pc_next + 4);
9006 ctx->base.is_jmp = DISAS_EXIT;
9010 goto cp0_unimplemented;
9016 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9020 goto cp0_unimplemented;
9030 check_insn(ctx, ISA_MIPS32R2);
9031 gen_helper_mtc0_ebase(cpu_env, arg);
9035 goto cp0_unimplemented;
9041 gen_helper_mtc0_config0(cpu_env, arg);
9043 /* Stop translation as we may have switched the execution mode */
9044 ctx->base.is_jmp = DISAS_STOP;
9047 /* ignored, read only */
9051 gen_helper_mtc0_config2(cpu_env, arg);
9053 /* Stop translation as we may have switched the execution mode */
9054 ctx->base.is_jmp = DISAS_STOP;
9057 gen_helper_mtc0_config3(cpu_env, arg);
9059 /* Stop translation as we may have switched the execution mode */
9060 ctx->base.is_jmp = DISAS_STOP;
9063 /* currently ignored */
9067 gen_helper_mtc0_config5(cpu_env, arg);
9069 /* Stop translation as we may have switched the execution mode */
9070 ctx->base.is_jmp = DISAS_STOP;
9072 /* 6,7 are implementation dependent */
9074 rn = "Invalid config selector";
9075 goto cp0_unimplemented;
9081 gen_helper_mtc0_lladdr(cpu_env, arg);
9085 CP0_CHECK(ctx->mrp);
9086 gen_helper_mtc0_maar(cpu_env, arg);
9090 CP0_CHECK(ctx->mrp);
9091 gen_helper_mtc0_maari(cpu_env, arg);
9095 goto cp0_unimplemented;
9108 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9109 gen_helper_0e1i(mtc0_watchlo, arg, sel);
9113 goto cp0_unimplemented;
9126 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9127 gen_helper_0e1i(mtc0_watchhi, arg, sel);
9131 goto cp0_unimplemented;
9137 check_insn(ctx, ISA_MIPS3);
9138 gen_helper_mtc0_xcontext(cpu_env, arg);
9142 goto cp0_unimplemented;
9146 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9147 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9150 gen_helper_mtc0_framemask(cpu_env, arg);
9154 goto cp0_unimplemented;
9159 rn = "Diagnostic"; /* implementation dependent */
9164 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9165 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9166 gen_save_pc(ctx->base.pc_next + 4);
9167 ctx->base.is_jmp = DISAS_EXIT;
9171 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9172 /* Stop translation as we may have switched the execution mode */
9173 ctx->base.is_jmp = DISAS_STOP;
9174 rn = "TraceControl";
9175 goto cp0_unimplemented;
9177 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9178 /* Stop translation as we may have switched the execution mode */
9179 ctx->base.is_jmp = DISAS_STOP;
9180 rn = "TraceControl2";
9181 goto cp0_unimplemented;
9183 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9184 /* Stop translation as we may have switched the execution mode */
9185 ctx->base.is_jmp = DISAS_STOP;
9186 rn = "UserTraceData";
9187 goto cp0_unimplemented;
9189 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9190 /* Stop translation as we may have switched the execution mode */
9191 ctx->base.is_jmp = DISAS_STOP;
9193 goto cp0_unimplemented;
9195 goto cp0_unimplemented;
9202 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9206 goto cp0_unimplemented;
9212 gen_helper_mtc0_performance0(cpu_env, arg);
9213 rn = "Performance0";
9216 // gen_helper_mtc0_performance1(cpu_env, arg);
9217 rn = "Performance1";
9218 goto cp0_unimplemented;
9220 // gen_helper_mtc0_performance2(cpu_env, arg);
9221 rn = "Performance2";
9222 goto cp0_unimplemented;
9224 // gen_helper_mtc0_performance3(cpu_env, arg);
9225 rn = "Performance3";
9226 goto cp0_unimplemented;
9228 // gen_helper_mtc0_performance4(cpu_env, arg);
9229 rn = "Performance4";
9230 goto cp0_unimplemented;
9232 // gen_helper_mtc0_performance5(cpu_env, arg);
9233 rn = "Performance5";
9234 goto cp0_unimplemented;
9236 // gen_helper_mtc0_performance6(cpu_env, arg);
9237 rn = "Performance6";
9238 goto cp0_unimplemented;
9240 // gen_helper_mtc0_performance7(cpu_env, arg);
9241 rn = "Performance7";
9242 goto cp0_unimplemented;
9244 goto cp0_unimplemented;
9250 gen_helper_mtc0_errctl(cpu_env, arg);
9251 ctx->base.is_jmp = DISAS_STOP;
9255 goto cp0_unimplemented;
9268 goto cp0_unimplemented;
9277 gen_helper_mtc0_taglo(cpu_env, arg);
9284 gen_helper_mtc0_datalo(cpu_env, arg);
9288 goto cp0_unimplemented;
9297 gen_helper_mtc0_taghi(cpu_env, arg);
9304 gen_helper_mtc0_datahi(cpu_env, arg);
9309 goto cp0_unimplemented;
9315 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9319 goto cp0_unimplemented;
9326 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9335 CP0_CHECK(ctx->kscrexist & (1 << sel));
9336 tcg_gen_st_tl(arg, cpu_env,
9337 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9341 goto cp0_unimplemented;
9345 goto cp0_unimplemented;
9347 trace_mips_translate_c0("dmtc0", rn, reg, sel);
9349 /* For simplicity assume that all writes can cause interrupts. */
9350 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9352 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9353 * translated code to check for pending interrupts. */
9354 gen_save_pc(ctx->base.pc_next + 4);
9355 ctx->base.is_jmp = DISAS_EXIT;
9360 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9362 #endif /* TARGET_MIPS64 */
9364 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9365 int u, int sel, int h)
9367 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9368 TCGv t0 = tcg_temp_local_new();
9370 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9371 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9372 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9373 tcg_gen_movi_tl(t0, -1);
9374 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9375 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9376 tcg_gen_movi_tl(t0, -1);
9382 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9385 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9395 gen_helper_mftc0_tcstatus(t0, cpu_env);
9398 gen_helper_mftc0_tcbind(t0, cpu_env);
9401 gen_helper_mftc0_tcrestart(t0, cpu_env);
9404 gen_helper_mftc0_tchalt(t0, cpu_env);
9407 gen_helper_mftc0_tccontext(t0, cpu_env);
9410 gen_helper_mftc0_tcschedule(t0, cpu_env);
9413 gen_helper_mftc0_tcschefback(t0, cpu_env);
9416 gen_mfc0(ctx, t0, rt, sel);
9423 gen_helper_mftc0_entryhi(t0, cpu_env);
9426 gen_mfc0(ctx, t0, rt, sel);
9432 gen_helper_mftc0_status(t0, cpu_env);
9435 gen_mfc0(ctx, t0, rt, sel);
9441 gen_helper_mftc0_cause(t0, cpu_env);
9451 gen_helper_mftc0_epc(t0, cpu_env);
9461 gen_helper_mftc0_ebase(t0, cpu_env);
9478 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9488 gen_helper_mftc0_debug(t0, cpu_env);
9491 gen_mfc0(ctx, t0, rt, sel);
9496 gen_mfc0(ctx, t0, rt, sel);
9498 } else switch (sel) {
9499 /* GPR registers. */
9501 gen_helper_1e0i(mftgpr, t0, rt);
9503 /* Auxiliary CPU registers */
9507 gen_helper_1e0i(mftlo, t0, 0);
9510 gen_helper_1e0i(mfthi, t0, 0);
9513 gen_helper_1e0i(mftacx, t0, 0);
9516 gen_helper_1e0i(mftlo, t0, 1);
9519 gen_helper_1e0i(mfthi, t0, 1);
9522 gen_helper_1e0i(mftacx, t0, 1);
9525 gen_helper_1e0i(mftlo, t0, 2);
9528 gen_helper_1e0i(mfthi, t0, 2);
9531 gen_helper_1e0i(mftacx, t0, 2);
9534 gen_helper_1e0i(mftlo, t0, 3);
9537 gen_helper_1e0i(mfthi, t0, 3);
9540 gen_helper_1e0i(mftacx, t0, 3);
9543 gen_helper_mftdsp(t0, cpu_env);
9549 /* Floating point (COP1). */
9551 /* XXX: For now we support only a single FPU context. */
9553 TCGv_i32 fp0 = tcg_temp_new_i32();
9555 gen_load_fpr32(ctx, fp0, rt);
9556 tcg_gen_ext_i32_tl(t0, fp0);
9557 tcg_temp_free_i32(fp0);
9559 TCGv_i32 fp0 = tcg_temp_new_i32();
9561 gen_load_fpr32h(ctx, fp0, rt);
9562 tcg_gen_ext_i32_tl(t0, fp0);
9563 tcg_temp_free_i32(fp0);
9567 /* XXX: For now we support only a single FPU context. */
9568 gen_helper_1e0i(cfc1, t0, rt);
9570 /* COP2: Not implemented. */
9577 trace_mips_translate_tr("mftr", rt, u, sel, h);
9578 gen_store_gpr(t0, rd);
9584 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9585 generate_exception_end(ctx, EXCP_RI);
9588 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9589 int u, int sel, int h)
9591 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9592 TCGv t0 = tcg_temp_local_new();
9594 gen_load_gpr(t0, rt);
9595 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9596 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9597 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9599 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9600 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9607 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9610 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9620 gen_helper_mttc0_tcstatus(cpu_env, t0);
9623 gen_helper_mttc0_tcbind(cpu_env, t0);
9626 gen_helper_mttc0_tcrestart(cpu_env, t0);
9629 gen_helper_mttc0_tchalt(cpu_env, t0);
9632 gen_helper_mttc0_tccontext(cpu_env, t0);
9635 gen_helper_mttc0_tcschedule(cpu_env, t0);
9638 gen_helper_mttc0_tcschefback(cpu_env, t0);
9641 gen_mtc0(ctx, t0, rd, sel);
9648 gen_helper_mttc0_entryhi(cpu_env, t0);
9651 gen_mtc0(ctx, t0, rd, sel);
9657 gen_helper_mttc0_status(cpu_env, t0);
9660 gen_mtc0(ctx, t0, rd, sel);
9666 gen_helper_mttc0_cause(cpu_env, t0);
9676 gen_helper_mttc0_ebase(cpu_env, t0);
9686 gen_helper_mttc0_debug(cpu_env, t0);
9689 gen_mtc0(ctx, t0, rd, sel);
9694 gen_mtc0(ctx, t0, rd, sel);
9696 } else switch (sel) {
9697 /* GPR registers. */
9699 gen_helper_0e1i(mttgpr, t0, rd);
9701 /* Auxiliary CPU registers */
9705 gen_helper_0e1i(mttlo, t0, 0);
9708 gen_helper_0e1i(mtthi, t0, 0);
9711 gen_helper_0e1i(mttacx, t0, 0);
9714 gen_helper_0e1i(mttlo, t0, 1);
9717 gen_helper_0e1i(mtthi, t0, 1);
9720 gen_helper_0e1i(mttacx, t0, 1);
9723 gen_helper_0e1i(mttlo, t0, 2);
9726 gen_helper_0e1i(mtthi, t0, 2);
9729 gen_helper_0e1i(mttacx, t0, 2);
9732 gen_helper_0e1i(mttlo, t0, 3);
9735 gen_helper_0e1i(mtthi, t0, 3);
9738 gen_helper_0e1i(mttacx, t0, 3);
9741 gen_helper_mttdsp(cpu_env, t0);
9747 /* Floating point (COP1). */
9749 /* XXX: For now we support only a single FPU context. */
9751 TCGv_i32 fp0 = tcg_temp_new_i32();
9753 tcg_gen_trunc_tl_i32(fp0, t0);
9754 gen_store_fpr32(ctx, fp0, rd);
9755 tcg_temp_free_i32(fp0);
9757 TCGv_i32 fp0 = tcg_temp_new_i32();
9759 tcg_gen_trunc_tl_i32(fp0, t0);
9760 gen_store_fpr32h(ctx, fp0, rd);
9761 tcg_temp_free_i32(fp0);
9765 /* XXX: For now we support only a single FPU context. */
9767 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9769 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9770 tcg_temp_free_i32(fs_tmp);
9772 /* Stop translation as we may have changed hflags */
9773 ctx->base.is_jmp = DISAS_STOP;
9775 /* COP2: Not implemented. */
9782 trace_mips_translate_tr("mttr", rd, u, sel, h);
9788 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9789 generate_exception_end(ctx, EXCP_RI);
9792 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9794 const char *opn = "ldst";
9796 check_cp0_enabled(ctx);
9803 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9808 TCGv t0 = tcg_temp_new();
9810 gen_load_gpr(t0, rt);
9811 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9816 #if defined(TARGET_MIPS64)
9818 check_insn(ctx, ISA_MIPS3);
9823 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9827 check_insn(ctx, ISA_MIPS3);
9829 TCGv t0 = tcg_temp_new();
9831 gen_load_gpr(t0, rt);
9832 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9844 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9850 TCGv t0 = tcg_temp_new();
9851 gen_load_gpr(t0, rt);
9852 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9858 check_cp0_enabled(ctx);
9863 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9864 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9868 check_cp0_enabled(ctx);
9869 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9870 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9875 if (!env->tlb->helper_tlbwi)
9877 gen_helper_tlbwi(cpu_env);
9882 if (!env->tlb->helper_tlbinv) {
9885 gen_helper_tlbinv(cpu_env);
9886 } /* treat as nop if TLBINV not supported */
9891 if (!env->tlb->helper_tlbinvf) {
9894 gen_helper_tlbinvf(cpu_env);
9895 } /* treat as nop if TLBINV not supported */
9899 if (!env->tlb->helper_tlbwr)
9901 gen_helper_tlbwr(cpu_env);
9905 if (!env->tlb->helper_tlbp)
9907 gen_helper_tlbp(cpu_env);
9911 if (!env->tlb->helper_tlbr)
9913 gen_helper_tlbr(cpu_env);
9915 case OPC_ERET: /* OPC_ERETNC */
9916 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9917 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9920 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9921 if (ctx->opcode & (1 << bit_shift)) {
9924 check_insn(ctx, ISA_MIPS32R5);
9925 gen_helper_eretnc(cpu_env);
9929 check_insn(ctx, ISA_MIPS2);
9930 gen_helper_eret(cpu_env);
9932 ctx->base.is_jmp = DISAS_EXIT;
9937 check_insn(ctx, ISA_MIPS32);
9938 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9939 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9942 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9944 generate_exception_end(ctx, EXCP_RI);
9946 gen_helper_deret(cpu_env);
9947 ctx->base.is_jmp = DISAS_EXIT;
9952 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
9953 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9954 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9957 /* If we get an exception, we want to restart at next instruction */
9958 ctx->base.pc_next += 4;
9959 save_cpu_state(ctx, 1);
9960 ctx->base.pc_next -= 4;
9961 gen_helper_wait(cpu_env);
9962 ctx->base.is_jmp = DISAS_NORETURN;
9967 generate_exception_end(ctx, EXCP_RI);
9970 (void)opn; /* avoid a compiler warning */
9972 #endif /* !CONFIG_USER_ONLY */
9974 /* CP1 Branches (before delay slot) */
9975 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9976 int32_t cc, int32_t offset)
9978 target_ulong btarget;
9979 TCGv_i32 t0 = tcg_temp_new_i32();
9981 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9982 generate_exception_end(ctx, EXCP_RI);
9987 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
9989 btarget = ctx->base.pc_next + 4 + offset;
9993 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9994 tcg_gen_not_i32(t0, t0);
9995 tcg_gen_andi_i32(t0, t0, 1);
9996 tcg_gen_extu_i32_tl(bcond, t0);
9999 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10000 tcg_gen_not_i32(t0, t0);
10001 tcg_gen_andi_i32(t0, t0, 1);
10002 tcg_gen_extu_i32_tl(bcond, t0);
10005 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10006 tcg_gen_andi_i32(t0, t0, 1);
10007 tcg_gen_extu_i32_tl(bcond, t0);
10010 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10011 tcg_gen_andi_i32(t0, t0, 1);
10012 tcg_gen_extu_i32_tl(bcond, t0);
10014 ctx->hflags |= MIPS_HFLAG_BL;
10018 TCGv_i32 t1 = tcg_temp_new_i32();
10019 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10020 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10021 tcg_gen_nand_i32(t0, t0, t1);
10022 tcg_temp_free_i32(t1);
10023 tcg_gen_andi_i32(t0, t0, 1);
10024 tcg_gen_extu_i32_tl(bcond, t0);
10029 TCGv_i32 t1 = tcg_temp_new_i32();
10030 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10031 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10032 tcg_gen_or_i32(t0, t0, t1);
10033 tcg_temp_free_i32(t1);
10034 tcg_gen_andi_i32(t0, t0, 1);
10035 tcg_gen_extu_i32_tl(bcond, t0);
10040 TCGv_i32 t1 = tcg_temp_new_i32();
10041 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10042 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10043 tcg_gen_and_i32(t0, t0, t1);
10044 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10045 tcg_gen_and_i32(t0, t0, t1);
10046 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10047 tcg_gen_nand_i32(t0, t0, t1);
10048 tcg_temp_free_i32(t1);
10049 tcg_gen_andi_i32(t0, t0, 1);
10050 tcg_gen_extu_i32_tl(bcond, t0);
10055 TCGv_i32 t1 = tcg_temp_new_i32();
10056 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10057 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10058 tcg_gen_or_i32(t0, t0, t1);
10059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10060 tcg_gen_or_i32(t0, t0, t1);
10061 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10062 tcg_gen_or_i32(t0, t0, t1);
10063 tcg_temp_free_i32(t1);
10064 tcg_gen_andi_i32(t0, t0, 1);
10065 tcg_gen_extu_i32_tl(bcond, t0);
10068 ctx->hflags |= MIPS_HFLAG_BC;
10071 MIPS_INVAL("cp1 cond branch");
10072 generate_exception_end(ctx, EXCP_RI);
10075 ctx->btarget = btarget;
10076 ctx->hflags |= MIPS_HFLAG_BDS32;
10078 tcg_temp_free_i32(t0);
10081 /* R6 CP1 Branches */
10082 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10083 int32_t ft, int32_t offset,
10084 int delayslot_size)
10086 target_ulong btarget;
10087 TCGv_i64 t0 = tcg_temp_new_i64();
10089 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10090 #ifdef MIPS_DEBUG_DISAS
10091 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10092 "\n", ctx->base.pc_next);
10094 generate_exception_end(ctx, EXCP_RI);
10098 gen_load_fpr64(ctx, t0, ft);
10099 tcg_gen_andi_i64(t0, t0, 1);
10101 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10105 tcg_gen_xori_i64(t0, t0, 1);
10106 ctx->hflags |= MIPS_HFLAG_BC;
10109 /* t0 already set */
10110 ctx->hflags |= MIPS_HFLAG_BC;
10113 MIPS_INVAL("cp1 cond branch");
10114 generate_exception_end(ctx, EXCP_RI);
10118 tcg_gen_trunc_i64_tl(bcond, t0);
10120 ctx->btarget = btarget;
10122 switch (delayslot_size) {
10124 ctx->hflags |= MIPS_HFLAG_BDS16;
10127 ctx->hflags |= MIPS_HFLAG_BDS32;
10132 tcg_temp_free_i64(t0);
10135 /* Coprocessor 1 (FPU) */
10137 #define FOP(func, fmt) (((fmt) << 21) | (func))
10140 OPC_ADD_S = FOP(0, FMT_S),
10141 OPC_SUB_S = FOP(1, FMT_S),
10142 OPC_MUL_S = FOP(2, FMT_S),
10143 OPC_DIV_S = FOP(3, FMT_S),
10144 OPC_SQRT_S = FOP(4, FMT_S),
10145 OPC_ABS_S = FOP(5, FMT_S),
10146 OPC_MOV_S = FOP(6, FMT_S),
10147 OPC_NEG_S = FOP(7, FMT_S),
10148 OPC_ROUND_L_S = FOP(8, FMT_S),
10149 OPC_TRUNC_L_S = FOP(9, FMT_S),
10150 OPC_CEIL_L_S = FOP(10, FMT_S),
10151 OPC_FLOOR_L_S = FOP(11, FMT_S),
10152 OPC_ROUND_W_S = FOP(12, FMT_S),
10153 OPC_TRUNC_W_S = FOP(13, FMT_S),
10154 OPC_CEIL_W_S = FOP(14, FMT_S),
10155 OPC_FLOOR_W_S = FOP(15, FMT_S),
10156 OPC_SEL_S = FOP(16, FMT_S),
10157 OPC_MOVCF_S = FOP(17, FMT_S),
10158 OPC_MOVZ_S = FOP(18, FMT_S),
10159 OPC_MOVN_S = FOP(19, FMT_S),
10160 OPC_SELEQZ_S = FOP(20, FMT_S),
10161 OPC_RECIP_S = FOP(21, FMT_S),
10162 OPC_RSQRT_S = FOP(22, FMT_S),
10163 OPC_SELNEZ_S = FOP(23, FMT_S),
10164 OPC_MADDF_S = FOP(24, FMT_S),
10165 OPC_MSUBF_S = FOP(25, FMT_S),
10166 OPC_RINT_S = FOP(26, FMT_S),
10167 OPC_CLASS_S = FOP(27, FMT_S),
10168 OPC_MIN_S = FOP(28, FMT_S),
10169 OPC_RECIP2_S = FOP(28, FMT_S),
10170 OPC_MINA_S = FOP(29, FMT_S),
10171 OPC_RECIP1_S = FOP(29, FMT_S),
10172 OPC_MAX_S = FOP(30, FMT_S),
10173 OPC_RSQRT1_S = FOP(30, FMT_S),
10174 OPC_MAXA_S = FOP(31, FMT_S),
10175 OPC_RSQRT2_S = FOP(31, FMT_S),
10176 OPC_CVT_D_S = FOP(33, FMT_S),
10177 OPC_CVT_W_S = FOP(36, FMT_S),
10178 OPC_CVT_L_S = FOP(37, FMT_S),
10179 OPC_CVT_PS_S = FOP(38, FMT_S),
10180 OPC_CMP_F_S = FOP (48, FMT_S),
10181 OPC_CMP_UN_S = FOP (49, FMT_S),
10182 OPC_CMP_EQ_S = FOP (50, FMT_S),
10183 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10184 OPC_CMP_OLT_S = FOP (52, FMT_S),
10185 OPC_CMP_ULT_S = FOP (53, FMT_S),
10186 OPC_CMP_OLE_S = FOP (54, FMT_S),
10187 OPC_CMP_ULE_S = FOP (55, FMT_S),
10188 OPC_CMP_SF_S = FOP (56, FMT_S),
10189 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10190 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10191 OPC_CMP_NGL_S = FOP (59, FMT_S),
10192 OPC_CMP_LT_S = FOP (60, FMT_S),
10193 OPC_CMP_NGE_S = FOP (61, FMT_S),
10194 OPC_CMP_LE_S = FOP (62, FMT_S),
10195 OPC_CMP_NGT_S = FOP (63, FMT_S),
10197 OPC_ADD_D = FOP(0, FMT_D),
10198 OPC_SUB_D = FOP(1, FMT_D),
10199 OPC_MUL_D = FOP(2, FMT_D),
10200 OPC_DIV_D = FOP(3, FMT_D),
10201 OPC_SQRT_D = FOP(4, FMT_D),
10202 OPC_ABS_D = FOP(5, FMT_D),
10203 OPC_MOV_D = FOP(6, FMT_D),
10204 OPC_NEG_D = FOP(7, FMT_D),
10205 OPC_ROUND_L_D = FOP(8, FMT_D),
10206 OPC_TRUNC_L_D = FOP(9, FMT_D),
10207 OPC_CEIL_L_D = FOP(10, FMT_D),
10208 OPC_FLOOR_L_D = FOP(11, FMT_D),
10209 OPC_ROUND_W_D = FOP(12, FMT_D),
10210 OPC_TRUNC_W_D = FOP(13, FMT_D),
10211 OPC_CEIL_W_D = FOP(14, FMT_D),
10212 OPC_FLOOR_W_D = FOP(15, FMT_D),
10213 OPC_SEL_D = FOP(16, FMT_D),
10214 OPC_MOVCF_D = FOP(17, FMT_D),
10215 OPC_MOVZ_D = FOP(18, FMT_D),
10216 OPC_MOVN_D = FOP(19, FMT_D),
10217 OPC_SELEQZ_D = FOP(20, FMT_D),
10218 OPC_RECIP_D = FOP(21, FMT_D),
10219 OPC_RSQRT_D = FOP(22, FMT_D),
10220 OPC_SELNEZ_D = FOP(23, FMT_D),
10221 OPC_MADDF_D = FOP(24, FMT_D),
10222 OPC_MSUBF_D = FOP(25, FMT_D),
10223 OPC_RINT_D = FOP(26, FMT_D),
10224 OPC_CLASS_D = FOP(27, FMT_D),
10225 OPC_MIN_D = FOP(28, FMT_D),
10226 OPC_RECIP2_D = FOP(28, FMT_D),
10227 OPC_MINA_D = FOP(29, FMT_D),
10228 OPC_RECIP1_D = FOP(29, FMT_D),
10229 OPC_MAX_D = FOP(30, FMT_D),
10230 OPC_RSQRT1_D = FOP(30, FMT_D),
10231 OPC_MAXA_D = FOP(31, FMT_D),
10232 OPC_RSQRT2_D = FOP(31, FMT_D),
10233 OPC_CVT_S_D = FOP(32, FMT_D),
10234 OPC_CVT_W_D = FOP(36, FMT_D),
10235 OPC_CVT_L_D = FOP(37, FMT_D),
10236 OPC_CMP_F_D = FOP (48, FMT_D),
10237 OPC_CMP_UN_D = FOP (49, FMT_D),
10238 OPC_CMP_EQ_D = FOP (50, FMT_D),
10239 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10240 OPC_CMP_OLT_D = FOP (52, FMT_D),
10241 OPC_CMP_ULT_D = FOP (53, FMT_D),
10242 OPC_CMP_OLE_D = FOP (54, FMT_D),
10243 OPC_CMP_ULE_D = FOP (55, FMT_D),
10244 OPC_CMP_SF_D = FOP (56, FMT_D),
10245 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10246 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10247 OPC_CMP_NGL_D = FOP (59, FMT_D),
10248 OPC_CMP_LT_D = FOP (60, FMT_D),
10249 OPC_CMP_NGE_D = FOP (61, FMT_D),
10250 OPC_CMP_LE_D = FOP (62, FMT_D),
10251 OPC_CMP_NGT_D = FOP (63, FMT_D),
10253 OPC_CVT_S_W = FOP(32, FMT_W),
10254 OPC_CVT_D_W = FOP(33, FMT_W),
10255 OPC_CVT_S_L = FOP(32, FMT_L),
10256 OPC_CVT_D_L = FOP(33, FMT_L),
10257 OPC_CVT_PS_PW = FOP(38, FMT_W),
10259 OPC_ADD_PS = FOP(0, FMT_PS),
10260 OPC_SUB_PS = FOP(1, FMT_PS),
10261 OPC_MUL_PS = FOP(2, FMT_PS),
10262 OPC_DIV_PS = FOP(3, FMT_PS),
10263 OPC_ABS_PS = FOP(5, FMT_PS),
10264 OPC_MOV_PS = FOP(6, FMT_PS),
10265 OPC_NEG_PS = FOP(7, FMT_PS),
10266 OPC_MOVCF_PS = FOP(17, FMT_PS),
10267 OPC_MOVZ_PS = FOP(18, FMT_PS),
10268 OPC_MOVN_PS = FOP(19, FMT_PS),
10269 OPC_ADDR_PS = FOP(24, FMT_PS),
10270 OPC_MULR_PS = FOP(26, FMT_PS),
10271 OPC_RECIP2_PS = FOP(28, FMT_PS),
10272 OPC_RECIP1_PS = FOP(29, FMT_PS),
10273 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10274 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10276 OPC_CVT_S_PU = FOP(32, FMT_PS),
10277 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10278 OPC_CVT_S_PL = FOP(40, FMT_PS),
10279 OPC_PLL_PS = FOP(44, FMT_PS),
10280 OPC_PLU_PS = FOP(45, FMT_PS),
10281 OPC_PUL_PS = FOP(46, FMT_PS),
10282 OPC_PUU_PS = FOP(47, FMT_PS),
10283 OPC_CMP_F_PS = FOP (48, FMT_PS),
10284 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10285 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10286 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10287 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10288 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10289 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10290 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10291 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10292 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10293 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10294 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10295 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10296 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10297 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10298 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10302 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10303 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10304 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10305 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10306 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10307 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10308 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10309 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10310 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10311 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10312 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10313 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10314 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10315 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10316 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10317 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10318 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10319 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10320 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10321 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10322 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10323 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10325 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10326 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10327 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10328 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10329 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10330 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10331 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10332 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10333 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10334 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10335 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10336 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10337 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10338 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10339 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10340 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10341 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10342 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10343 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10344 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10345 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10346 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10348 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10350 TCGv t0 = tcg_temp_new();
10355 TCGv_i32 fp0 = tcg_temp_new_i32();
10357 gen_load_fpr32(ctx, fp0, fs);
10358 tcg_gen_ext_i32_tl(t0, fp0);
10359 tcg_temp_free_i32(fp0);
10361 gen_store_gpr(t0, rt);
10364 gen_load_gpr(t0, rt);
10366 TCGv_i32 fp0 = tcg_temp_new_i32();
10368 tcg_gen_trunc_tl_i32(fp0, t0);
10369 gen_store_fpr32(ctx, fp0, fs);
10370 tcg_temp_free_i32(fp0);
10374 gen_helper_1e0i(cfc1, t0, fs);
10375 gen_store_gpr(t0, rt);
10378 gen_load_gpr(t0, rt);
10379 save_cpu_state(ctx, 0);
10381 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10383 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10384 tcg_temp_free_i32(fs_tmp);
10386 /* Stop translation as we may have changed hflags */
10387 ctx->base.is_jmp = DISAS_STOP;
10389 #if defined(TARGET_MIPS64)
10391 gen_load_fpr64(ctx, t0, fs);
10392 gen_store_gpr(t0, rt);
10395 gen_load_gpr(t0, rt);
10396 gen_store_fpr64(ctx, t0, fs);
10401 TCGv_i32 fp0 = tcg_temp_new_i32();
10403 gen_load_fpr32h(ctx, fp0, fs);
10404 tcg_gen_ext_i32_tl(t0, fp0);
10405 tcg_temp_free_i32(fp0);
10407 gen_store_gpr(t0, rt);
10410 gen_load_gpr(t0, rt);
10412 TCGv_i32 fp0 = tcg_temp_new_i32();
10414 tcg_gen_trunc_tl_i32(fp0, t0);
10415 gen_store_fpr32h(ctx, fp0, fs);
10416 tcg_temp_free_i32(fp0);
10420 MIPS_INVAL("cp1 move");
10421 generate_exception_end(ctx, EXCP_RI);
10429 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10436 /* Treat as NOP. */
10441 cond = TCG_COND_EQ;
10443 cond = TCG_COND_NE;
10445 l1 = gen_new_label();
10446 t0 = tcg_temp_new_i32();
10447 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10448 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10449 tcg_temp_free_i32(t0);
10451 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10453 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10458 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10462 TCGv_i32 t0 = tcg_temp_new_i32();
10463 TCGLabel *l1 = gen_new_label();
10466 cond = TCG_COND_EQ;
10468 cond = TCG_COND_NE;
10470 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10471 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10472 gen_load_fpr32(ctx, t0, fs);
10473 gen_store_fpr32(ctx, t0, fd);
10475 tcg_temp_free_i32(t0);
10478 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10481 TCGv_i32 t0 = tcg_temp_new_i32();
10483 TCGLabel *l1 = gen_new_label();
10486 cond = TCG_COND_EQ;
10488 cond = TCG_COND_NE;
10490 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10491 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10492 tcg_temp_free_i32(t0);
10493 fp0 = tcg_temp_new_i64();
10494 gen_load_fpr64(ctx, fp0, fs);
10495 gen_store_fpr64(ctx, fp0, fd);
10496 tcg_temp_free_i64(fp0);
10500 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10504 TCGv_i32 t0 = tcg_temp_new_i32();
10505 TCGLabel *l1 = gen_new_label();
10506 TCGLabel *l2 = gen_new_label();
10509 cond = TCG_COND_EQ;
10511 cond = TCG_COND_NE;
10513 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10514 tcg_gen_brcondi_i32(cond, t0, 0, l1);
10515 gen_load_fpr32(ctx, t0, fs);
10516 gen_store_fpr32(ctx, t0, fd);
10519 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10520 tcg_gen_brcondi_i32(cond, t0, 0, l2);
10521 gen_load_fpr32h(ctx, t0, fs);
10522 gen_store_fpr32h(ctx, t0, fd);
10523 tcg_temp_free_i32(t0);
10527 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10530 TCGv_i32 t1 = tcg_const_i32(0);
10531 TCGv_i32 fp0 = tcg_temp_new_i32();
10532 TCGv_i32 fp1 = tcg_temp_new_i32();
10533 TCGv_i32 fp2 = tcg_temp_new_i32();
10534 gen_load_fpr32(ctx, fp0, fd);
10535 gen_load_fpr32(ctx, fp1, ft);
10536 gen_load_fpr32(ctx, fp2, fs);
10540 tcg_gen_andi_i32(fp0, fp0, 1);
10541 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10544 tcg_gen_andi_i32(fp1, fp1, 1);
10545 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10548 tcg_gen_andi_i32(fp1, fp1, 1);
10549 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10552 MIPS_INVAL("gen_sel_s");
10553 generate_exception_end(ctx, EXCP_RI);
10557 gen_store_fpr32(ctx, fp0, fd);
10558 tcg_temp_free_i32(fp2);
10559 tcg_temp_free_i32(fp1);
10560 tcg_temp_free_i32(fp0);
10561 tcg_temp_free_i32(t1);
10564 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10567 TCGv_i64 t1 = tcg_const_i64(0);
10568 TCGv_i64 fp0 = tcg_temp_new_i64();
10569 TCGv_i64 fp1 = tcg_temp_new_i64();
10570 TCGv_i64 fp2 = tcg_temp_new_i64();
10571 gen_load_fpr64(ctx, fp0, fd);
10572 gen_load_fpr64(ctx, fp1, ft);
10573 gen_load_fpr64(ctx, fp2, fs);
10577 tcg_gen_andi_i64(fp0, fp0, 1);
10578 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10581 tcg_gen_andi_i64(fp1, fp1, 1);
10582 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10585 tcg_gen_andi_i64(fp1, fp1, 1);
10586 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10589 MIPS_INVAL("gen_sel_d");
10590 generate_exception_end(ctx, EXCP_RI);
10594 gen_store_fpr64(ctx, fp0, fd);
10595 tcg_temp_free_i64(fp2);
10596 tcg_temp_free_i64(fp1);
10597 tcg_temp_free_i64(fp0);
10598 tcg_temp_free_i64(t1);
10601 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10602 int ft, int fs, int fd, int cc)
10604 uint32_t func = ctx->opcode & 0x3f;
10608 TCGv_i32 fp0 = tcg_temp_new_i32();
10609 TCGv_i32 fp1 = tcg_temp_new_i32();
10611 gen_load_fpr32(ctx, fp0, fs);
10612 gen_load_fpr32(ctx, fp1, ft);
10613 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10614 tcg_temp_free_i32(fp1);
10615 gen_store_fpr32(ctx, fp0, fd);
10616 tcg_temp_free_i32(fp0);
10621 TCGv_i32 fp0 = tcg_temp_new_i32();
10622 TCGv_i32 fp1 = tcg_temp_new_i32();
10624 gen_load_fpr32(ctx, fp0, fs);
10625 gen_load_fpr32(ctx, fp1, ft);
10626 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10627 tcg_temp_free_i32(fp1);
10628 gen_store_fpr32(ctx, fp0, fd);
10629 tcg_temp_free_i32(fp0);
10634 TCGv_i32 fp0 = tcg_temp_new_i32();
10635 TCGv_i32 fp1 = tcg_temp_new_i32();
10637 gen_load_fpr32(ctx, fp0, fs);
10638 gen_load_fpr32(ctx, fp1, ft);
10639 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10640 tcg_temp_free_i32(fp1);
10641 gen_store_fpr32(ctx, fp0, fd);
10642 tcg_temp_free_i32(fp0);
10647 TCGv_i32 fp0 = tcg_temp_new_i32();
10648 TCGv_i32 fp1 = tcg_temp_new_i32();
10650 gen_load_fpr32(ctx, fp0, fs);
10651 gen_load_fpr32(ctx, fp1, ft);
10652 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10653 tcg_temp_free_i32(fp1);
10654 gen_store_fpr32(ctx, fp0, fd);
10655 tcg_temp_free_i32(fp0);
10660 TCGv_i32 fp0 = tcg_temp_new_i32();
10662 gen_load_fpr32(ctx, fp0, fs);
10663 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10664 gen_store_fpr32(ctx, fp0, fd);
10665 tcg_temp_free_i32(fp0);
10670 TCGv_i32 fp0 = tcg_temp_new_i32();
10672 gen_load_fpr32(ctx, fp0, fs);
10673 if (ctx->abs2008) {
10674 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10676 gen_helper_float_abs_s(fp0, fp0);
10678 gen_store_fpr32(ctx, fp0, fd);
10679 tcg_temp_free_i32(fp0);
10684 TCGv_i32 fp0 = tcg_temp_new_i32();
10686 gen_load_fpr32(ctx, fp0, fs);
10687 gen_store_fpr32(ctx, fp0, fd);
10688 tcg_temp_free_i32(fp0);
10693 TCGv_i32 fp0 = tcg_temp_new_i32();
10695 gen_load_fpr32(ctx, fp0, fs);
10696 if (ctx->abs2008) {
10697 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10699 gen_helper_float_chs_s(fp0, fp0);
10701 gen_store_fpr32(ctx, fp0, fd);
10702 tcg_temp_free_i32(fp0);
10705 case OPC_ROUND_L_S:
10706 check_cp1_64bitmode(ctx);
10708 TCGv_i32 fp32 = tcg_temp_new_i32();
10709 TCGv_i64 fp64 = tcg_temp_new_i64();
10711 gen_load_fpr32(ctx, fp32, fs);
10712 if (ctx->nan2008) {
10713 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10715 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10717 tcg_temp_free_i32(fp32);
10718 gen_store_fpr64(ctx, fp64, fd);
10719 tcg_temp_free_i64(fp64);
10722 case OPC_TRUNC_L_S:
10723 check_cp1_64bitmode(ctx);
10725 TCGv_i32 fp32 = tcg_temp_new_i32();
10726 TCGv_i64 fp64 = tcg_temp_new_i64();
10728 gen_load_fpr32(ctx, fp32, fs);
10729 if (ctx->nan2008) {
10730 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10732 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10734 tcg_temp_free_i32(fp32);
10735 gen_store_fpr64(ctx, fp64, fd);
10736 tcg_temp_free_i64(fp64);
10740 check_cp1_64bitmode(ctx);
10742 TCGv_i32 fp32 = tcg_temp_new_i32();
10743 TCGv_i64 fp64 = tcg_temp_new_i64();
10745 gen_load_fpr32(ctx, fp32, fs);
10746 if (ctx->nan2008) {
10747 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10749 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10751 tcg_temp_free_i32(fp32);
10752 gen_store_fpr64(ctx, fp64, fd);
10753 tcg_temp_free_i64(fp64);
10756 case OPC_FLOOR_L_S:
10757 check_cp1_64bitmode(ctx);
10759 TCGv_i32 fp32 = tcg_temp_new_i32();
10760 TCGv_i64 fp64 = tcg_temp_new_i64();
10762 gen_load_fpr32(ctx, fp32, fs);
10763 if (ctx->nan2008) {
10764 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10766 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10768 tcg_temp_free_i32(fp32);
10769 gen_store_fpr64(ctx, fp64, fd);
10770 tcg_temp_free_i64(fp64);
10773 case OPC_ROUND_W_S:
10775 TCGv_i32 fp0 = tcg_temp_new_i32();
10777 gen_load_fpr32(ctx, fp0, fs);
10778 if (ctx->nan2008) {
10779 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10781 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10783 gen_store_fpr32(ctx, fp0, fd);
10784 tcg_temp_free_i32(fp0);
10787 case OPC_TRUNC_W_S:
10789 TCGv_i32 fp0 = tcg_temp_new_i32();
10791 gen_load_fpr32(ctx, fp0, fs);
10792 if (ctx->nan2008) {
10793 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10795 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10797 gen_store_fpr32(ctx, fp0, fd);
10798 tcg_temp_free_i32(fp0);
10803 TCGv_i32 fp0 = tcg_temp_new_i32();
10805 gen_load_fpr32(ctx, fp0, fs);
10806 if (ctx->nan2008) {
10807 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10809 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10811 gen_store_fpr32(ctx, fp0, fd);
10812 tcg_temp_free_i32(fp0);
10815 case OPC_FLOOR_W_S:
10817 TCGv_i32 fp0 = tcg_temp_new_i32();
10819 gen_load_fpr32(ctx, fp0, fs);
10820 if (ctx->nan2008) {
10821 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10823 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10825 gen_store_fpr32(ctx, fp0, fd);
10826 tcg_temp_free_i32(fp0);
10830 check_insn(ctx, ISA_MIPS32R6);
10831 gen_sel_s(ctx, op1, fd, ft, fs);
10834 check_insn(ctx, ISA_MIPS32R6);
10835 gen_sel_s(ctx, op1, fd, ft, fs);
10838 check_insn(ctx, ISA_MIPS32R6);
10839 gen_sel_s(ctx, op1, fd, ft, fs);
10842 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10843 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10846 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10848 TCGLabel *l1 = gen_new_label();
10852 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10854 fp0 = tcg_temp_new_i32();
10855 gen_load_fpr32(ctx, fp0, fs);
10856 gen_store_fpr32(ctx, fp0, fd);
10857 tcg_temp_free_i32(fp0);
10862 check_insn_opc_removed(ctx, ISA_MIPS32R6);
10864 TCGLabel *l1 = gen_new_label();
10868 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10869 fp0 = tcg_temp_new_i32();
10870 gen_load_fpr32(ctx, fp0, fs);
10871 gen_store_fpr32(ctx, fp0, fd);
10872 tcg_temp_free_i32(fp0);
10879 TCGv_i32 fp0 = tcg_temp_new_i32();
10881 gen_load_fpr32(ctx, fp0, fs);
10882 gen_helper_float_recip_s(fp0, cpu_env, fp0);
10883 gen_store_fpr32(ctx, fp0, fd);
10884 tcg_temp_free_i32(fp0);
10889 TCGv_i32 fp0 = tcg_temp_new_i32();
10891 gen_load_fpr32(ctx, fp0, fs);
10892 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10893 gen_store_fpr32(ctx, fp0, fd);
10894 tcg_temp_free_i32(fp0);
10898 check_insn(ctx, ISA_MIPS32R6);
10900 TCGv_i32 fp0 = tcg_temp_new_i32();
10901 TCGv_i32 fp1 = tcg_temp_new_i32();
10902 TCGv_i32 fp2 = tcg_temp_new_i32();
10903 gen_load_fpr32(ctx, fp0, fs);
10904 gen_load_fpr32(ctx, fp1, ft);
10905 gen_load_fpr32(ctx, fp2, fd);
10906 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10907 gen_store_fpr32(ctx, fp2, fd);
10908 tcg_temp_free_i32(fp2);
10909 tcg_temp_free_i32(fp1);
10910 tcg_temp_free_i32(fp0);
10914 check_insn(ctx, ISA_MIPS32R6);
10916 TCGv_i32 fp0 = tcg_temp_new_i32();
10917 TCGv_i32 fp1 = tcg_temp_new_i32();
10918 TCGv_i32 fp2 = tcg_temp_new_i32();
10919 gen_load_fpr32(ctx, fp0, fs);
10920 gen_load_fpr32(ctx, fp1, ft);
10921 gen_load_fpr32(ctx, fp2, fd);
10922 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10923 gen_store_fpr32(ctx, fp2, fd);
10924 tcg_temp_free_i32(fp2);
10925 tcg_temp_free_i32(fp1);
10926 tcg_temp_free_i32(fp0);
10930 check_insn(ctx, ISA_MIPS32R6);
10932 TCGv_i32 fp0 = tcg_temp_new_i32();
10933 gen_load_fpr32(ctx, fp0, fs);
10934 gen_helper_float_rint_s(fp0, cpu_env, fp0);
10935 gen_store_fpr32(ctx, fp0, fd);
10936 tcg_temp_free_i32(fp0);
10940 check_insn(ctx, ISA_MIPS32R6);
10942 TCGv_i32 fp0 = tcg_temp_new_i32();
10943 gen_load_fpr32(ctx, fp0, fs);
10944 gen_helper_float_class_s(fp0, cpu_env, fp0);
10945 gen_store_fpr32(ctx, fp0, fd);
10946 tcg_temp_free_i32(fp0);
10949 case OPC_MIN_S: /* OPC_RECIP2_S */
10950 if (ctx->insn_flags & ISA_MIPS32R6) {
10952 TCGv_i32 fp0 = tcg_temp_new_i32();
10953 TCGv_i32 fp1 = tcg_temp_new_i32();
10954 TCGv_i32 fp2 = tcg_temp_new_i32();
10955 gen_load_fpr32(ctx, fp0, fs);
10956 gen_load_fpr32(ctx, fp1, ft);
10957 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10958 gen_store_fpr32(ctx, fp2, fd);
10959 tcg_temp_free_i32(fp2);
10960 tcg_temp_free_i32(fp1);
10961 tcg_temp_free_i32(fp0);
10964 check_cp1_64bitmode(ctx);
10966 TCGv_i32 fp0 = tcg_temp_new_i32();
10967 TCGv_i32 fp1 = tcg_temp_new_i32();
10969 gen_load_fpr32(ctx, fp0, fs);
10970 gen_load_fpr32(ctx, fp1, ft);
10971 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10972 tcg_temp_free_i32(fp1);
10973 gen_store_fpr32(ctx, fp0, fd);
10974 tcg_temp_free_i32(fp0);
10978 case OPC_MINA_S: /* OPC_RECIP1_S */
10979 if (ctx->insn_flags & ISA_MIPS32R6) {
10981 TCGv_i32 fp0 = tcg_temp_new_i32();
10982 TCGv_i32 fp1 = tcg_temp_new_i32();
10983 TCGv_i32 fp2 = tcg_temp_new_i32();
10984 gen_load_fpr32(ctx, fp0, fs);
10985 gen_load_fpr32(ctx, fp1, ft);
10986 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10987 gen_store_fpr32(ctx, fp2, fd);
10988 tcg_temp_free_i32(fp2);
10989 tcg_temp_free_i32(fp1);
10990 tcg_temp_free_i32(fp0);
10993 check_cp1_64bitmode(ctx);
10995 TCGv_i32 fp0 = tcg_temp_new_i32();
10997 gen_load_fpr32(ctx, fp0, fs);
10998 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10999 gen_store_fpr32(ctx, fp0, fd);
11000 tcg_temp_free_i32(fp0);
11004 case OPC_MAX_S: /* OPC_RSQRT1_S */
11005 if (ctx->insn_flags & ISA_MIPS32R6) {
11007 TCGv_i32 fp0 = tcg_temp_new_i32();
11008 TCGv_i32 fp1 = tcg_temp_new_i32();
11009 gen_load_fpr32(ctx, fp0, fs);
11010 gen_load_fpr32(ctx, fp1, ft);
11011 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11012 gen_store_fpr32(ctx, fp1, fd);
11013 tcg_temp_free_i32(fp1);
11014 tcg_temp_free_i32(fp0);
11017 check_cp1_64bitmode(ctx);
11019 TCGv_i32 fp0 = tcg_temp_new_i32();
11021 gen_load_fpr32(ctx, fp0, fs);
11022 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11023 gen_store_fpr32(ctx, fp0, fd);
11024 tcg_temp_free_i32(fp0);
11028 case OPC_MAXA_S: /* OPC_RSQRT2_S */
11029 if (ctx->insn_flags & ISA_MIPS32R6) {
11031 TCGv_i32 fp0 = tcg_temp_new_i32();
11032 TCGv_i32 fp1 = tcg_temp_new_i32();
11033 gen_load_fpr32(ctx, fp0, fs);
11034 gen_load_fpr32(ctx, fp1, ft);
11035 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11036 gen_store_fpr32(ctx, fp1, fd);
11037 tcg_temp_free_i32(fp1);
11038 tcg_temp_free_i32(fp0);
11041 check_cp1_64bitmode(ctx);
11043 TCGv_i32 fp0 = tcg_temp_new_i32();
11044 TCGv_i32 fp1 = tcg_temp_new_i32();
11046 gen_load_fpr32(ctx, fp0, fs);
11047 gen_load_fpr32(ctx, fp1, ft);
11048 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11049 tcg_temp_free_i32(fp1);
11050 gen_store_fpr32(ctx, fp0, fd);
11051 tcg_temp_free_i32(fp0);
11056 check_cp1_registers(ctx, fd);
11058 TCGv_i32 fp32 = tcg_temp_new_i32();
11059 TCGv_i64 fp64 = tcg_temp_new_i64();
11061 gen_load_fpr32(ctx, fp32, fs);
11062 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11063 tcg_temp_free_i32(fp32);
11064 gen_store_fpr64(ctx, fp64, fd);
11065 tcg_temp_free_i64(fp64);
11070 TCGv_i32 fp0 = tcg_temp_new_i32();
11072 gen_load_fpr32(ctx, fp0, fs);
11073 if (ctx->nan2008) {
11074 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11076 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11078 gen_store_fpr32(ctx, fp0, fd);
11079 tcg_temp_free_i32(fp0);
11083 check_cp1_64bitmode(ctx);
11085 TCGv_i32 fp32 = tcg_temp_new_i32();
11086 TCGv_i64 fp64 = tcg_temp_new_i64();
11088 gen_load_fpr32(ctx, fp32, fs);
11089 if (ctx->nan2008) {
11090 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11092 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11094 tcg_temp_free_i32(fp32);
11095 gen_store_fpr64(ctx, fp64, fd);
11096 tcg_temp_free_i64(fp64);
11102 TCGv_i64 fp64 = tcg_temp_new_i64();
11103 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11104 TCGv_i32 fp32_1 = tcg_temp_new_i32();
11106 gen_load_fpr32(ctx, fp32_0, fs);
11107 gen_load_fpr32(ctx, fp32_1, ft);
11108 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11109 tcg_temp_free_i32(fp32_1);
11110 tcg_temp_free_i32(fp32_0);
11111 gen_store_fpr64(ctx, fp64, fd);
11112 tcg_temp_free_i64(fp64);
11118 case OPC_CMP_UEQ_S:
11119 case OPC_CMP_OLT_S:
11120 case OPC_CMP_ULT_S:
11121 case OPC_CMP_OLE_S:
11122 case OPC_CMP_ULE_S:
11124 case OPC_CMP_NGLE_S:
11125 case OPC_CMP_SEQ_S:
11126 case OPC_CMP_NGL_S:
11128 case OPC_CMP_NGE_S:
11130 case OPC_CMP_NGT_S:
11131 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11132 if (ctx->opcode & (1 << 6)) {
11133 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11135 gen_cmp_s(ctx, func-48, ft, fs, cc);
11139 check_cp1_registers(ctx, fs | ft | fd);
11141 TCGv_i64 fp0 = tcg_temp_new_i64();
11142 TCGv_i64 fp1 = tcg_temp_new_i64();
11144 gen_load_fpr64(ctx, fp0, fs);
11145 gen_load_fpr64(ctx, fp1, ft);
11146 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11147 tcg_temp_free_i64(fp1);
11148 gen_store_fpr64(ctx, fp0, fd);
11149 tcg_temp_free_i64(fp0);
11153 check_cp1_registers(ctx, fs | ft | fd);
11155 TCGv_i64 fp0 = tcg_temp_new_i64();
11156 TCGv_i64 fp1 = tcg_temp_new_i64();
11158 gen_load_fpr64(ctx, fp0, fs);
11159 gen_load_fpr64(ctx, fp1, ft);
11160 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11161 tcg_temp_free_i64(fp1);
11162 gen_store_fpr64(ctx, fp0, fd);
11163 tcg_temp_free_i64(fp0);
11167 check_cp1_registers(ctx, fs | ft | fd);
11169 TCGv_i64 fp0 = tcg_temp_new_i64();
11170 TCGv_i64 fp1 = tcg_temp_new_i64();
11172 gen_load_fpr64(ctx, fp0, fs);
11173 gen_load_fpr64(ctx, fp1, ft);
11174 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11175 tcg_temp_free_i64(fp1);
11176 gen_store_fpr64(ctx, fp0, fd);
11177 tcg_temp_free_i64(fp0);
11181 check_cp1_registers(ctx, fs | ft | fd);
11183 TCGv_i64 fp0 = tcg_temp_new_i64();
11184 TCGv_i64 fp1 = tcg_temp_new_i64();
11186 gen_load_fpr64(ctx, fp0, fs);
11187 gen_load_fpr64(ctx, fp1, ft);
11188 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11189 tcg_temp_free_i64(fp1);
11190 gen_store_fpr64(ctx, fp0, fd);
11191 tcg_temp_free_i64(fp0);
11195 check_cp1_registers(ctx, fs | fd);
11197 TCGv_i64 fp0 = tcg_temp_new_i64();
11199 gen_load_fpr64(ctx, fp0, fs);
11200 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11201 gen_store_fpr64(ctx, fp0, fd);
11202 tcg_temp_free_i64(fp0);
11206 check_cp1_registers(ctx, fs | fd);
11208 TCGv_i64 fp0 = tcg_temp_new_i64();
11210 gen_load_fpr64(ctx, fp0, fs);
11211 if (ctx->abs2008) {
11212 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11214 gen_helper_float_abs_d(fp0, fp0);
11216 gen_store_fpr64(ctx, fp0, fd);
11217 tcg_temp_free_i64(fp0);
11221 check_cp1_registers(ctx, fs | fd);
11223 TCGv_i64 fp0 = tcg_temp_new_i64();
11225 gen_load_fpr64(ctx, fp0, fs);
11226 gen_store_fpr64(ctx, fp0, fd);
11227 tcg_temp_free_i64(fp0);
11231 check_cp1_registers(ctx, fs | fd);
11233 TCGv_i64 fp0 = tcg_temp_new_i64();
11235 gen_load_fpr64(ctx, fp0, fs);
11236 if (ctx->abs2008) {
11237 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11239 gen_helper_float_chs_d(fp0, fp0);
11241 gen_store_fpr64(ctx, fp0, fd);
11242 tcg_temp_free_i64(fp0);
11245 case OPC_ROUND_L_D:
11246 check_cp1_64bitmode(ctx);
11248 TCGv_i64 fp0 = tcg_temp_new_i64();
11250 gen_load_fpr64(ctx, fp0, fs);
11251 if (ctx->nan2008) {
11252 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11254 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11256 gen_store_fpr64(ctx, fp0, fd);
11257 tcg_temp_free_i64(fp0);
11260 case OPC_TRUNC_L_D:
11261 check_cp1_64bitmode(ctx);
11263 TCGv_i64 fp0 = tcg_temp_new_i64();
11265 gen_load_fpr64(ctx, fp0, fs);
11266 if (ctx->nan2008) {
11267 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11269 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11271 gen_store_fpr64(ctx, fp0, fd);
11272 tcg_temp_free_i64(fp0);
11276 check_cp1_64bitmode(ctx);
11278 TCGv_i64 fp0 = tcg_temp_new_i64();
11280 gen_load_fpr64(ctx, fp0, fs);
11281 if (ctx->nan2008) {
11282 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11284 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11286 gen_store_fpr64(ctx, fp0, fd);
11287 tcg_temp_free_i64(fp0);
11290 case OPC_FLOOR_L_D:
11291 check_cp1_64bitmode(ctx);
11293 TCGv_i64 fp0 = tcg_temp_new_i64();
11295 gen_load_fpr64(ctx, fp0, fs);
11296 if (ctx->nan2008) {
11297 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11299 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11301 gen_store_fpr64(ctx, fp0, fd);
11302 tcg_temp_free_i64(fp0);
11305 case OPC_ROUND_W_D:
11306 check_cp1_registers(ctx, fs);
11308 TCGv_i32 fp32 = tcg_temp_new_i32();
11309 TCGv_i64 fp64 = tcg_temp_new_i64();
11311 gen_load_fpr64(ctx, fp64, fs);
11312 if (ctx->nan2008) {
11313 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11315 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11317 tcg_temp_free_i64(fp64);
11318 gen_store_fpr32(ctx, fp32, fd);
11319 tcg_temp_free_i32(fp32);
11322 case OPC_TRUNC_W_D:
11323 check_cp1_registers(ctx, fs);
11325 TCGv_i32 fp32 = tcg_temp_new_i32();
11326 TCGv_i64 fp64 = tcg_temp_new_i64();
11328 gen_load_fpr64(ctx, fp64, fs);
11329 if (ctx->nan2008) {
11330 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11332 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11334 tcg_temp_free_i64(fp64);
11335 gen_store_fpr32(ctx, fp32, fd);
11336 tcg_temp_free_i32(fp32);
11340 check_cp1_registers(ctx, fs);
11342 TCGv_i32 fp32 = tcg_temp_new_i32();
11343 TCGv_i64 fp64 = tcg_temp_new_i64();
11345 gen_load_fpr64(ctx, fp64, fs);
11346 if (ctx->nan2008) {
11347 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11349 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11351 tcg_temp_free_i64(fp64);
11352 gen_store_fpr32(ctx, fp32, fd);
11353 tcg_temp_free_i32(fp32);
11356 case OPC_FLOOR_W_D:
11357 check_cp1_registers(ctx, fs);
11359 TCGv_i32 fp32 = tcg_temp_new_i32();
11360 TCGv_i64 fp64 = tcg_temp_new_i64();
11362 gen_load_fpr64(ctx, fp64, fs);
11363 if (ctx->nan2008) {
11364 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11366 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11368 tcg_temp_free_i64(fp64);
11369 gen_store_fpr32(ctx, fp32, fd);
11370 tcg_temp_free_i32(fp32);
11374 check_insn(ctx, ISA_MIPS32R6);
11375 gen_sel_d(ctx, op1, fd, ft, fs);
11378 check_insn(ctx, ISA_MIPS32R6);
11379 gen_sel_d(ctx, op1, fd, ft, fs);
11382 check_insn(ctx, ISA_MIPS32R6);
11383 gen_sel_d(ctx, op1, fd, ft, fs);
11386 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11387 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11390 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11392 TCGLabel *l1 = gen_new_label();
11396 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11398 fp0 = tcg_temp_new_i64();
11399 gen_load_fpr64(ctx, fp0, fs);
11400 gen_store_fpr64(ctx, fp0, fd);
11401 tcg_temp_free_i64(fp0);
11406 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11408 TCGLabel *l1 = gen_new_label();
11412 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11413 fp0 = tcg_temp_new_i64();
11414 gen_load_fpr64(ctx, fp0, fs);
11415 gen_store_fpr64(ctx, fp0, fd);
11416 tcg_temp_free_i64(fp0);
11422 check_cp1_registers(ctx, fs | fd);
11424 TCGv_i64 fp0 = tcg_temp_new_i64();
11426 gen_load_fpr64(ctx, fp0, fs);
11427 gen_helper_float_recip_d(fp0, cpu_env, fp0);
11428 gen_store_fpr64(ctx, fp0, fd);
11429 tcg_temp_free_i64(fp0);
11433 check_cp1_registers(ctx, fs | fd);
11435 TCGv_i64 fp0 = tcg_temp_new_i64();
11437 gen_load_fpr64(ctx, fp0, fs);
11438 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11439 gen_store_fpr64(ctx, fp0, fd);
11440 tcg_temp_free_i64(fp0);
11444 check_insn(ctx, ISA_MIPS32R6);
11446 TCGv_i64 fp0 = tcg_temp_new_i64();
11447 TCGv_i64 fp1 = tcg_temp_new_i64();
11448 TCGv_i64 fp2 = tcg_temp_new_i64();
11449 gen_load_fpr64(ctx, fp0, fs);
11450 gen_load_fpr64(ctx, fp1, ft);
11451 gen_load_fpr64(ctx, fp2, fd);
11452 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11453 gen_store_fpr64(ctx, fp2, fd);
11454 tcg_temp_free_i64(fp2);
11455 tcg_temp_free_i64(fp1);
11456 tcg_temp_free_i64(fp0);
11460 check_insn(ctx, ISA_MIPS32R6);
11462 TCGv_i64 fp0 = tcg_temp_new_i64();
11463 TCGv_i64 fp1 = tcg_temp_new_i64();
11464 TCGv_i64 fp2 = tcg_temp_new_i64();
11465 gen_load_fpr64(ctx, fp0, fs);
11466 gen_load_fpr64(ctx, fp1, ft);
11467 gen_load_fpr64(ctx, fp2, fd);
11468 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11469 gen_store_fpr64(ctx, fp2, fd);
11470 tcg_temp_free_i64(fp2);
11471 tcg_temp_free_i64(fp1);
11472 tcg_temp_free_i64(fp0);
11476 check_insn(ctx, ISA_MIPS32R6);
11478 TCGv_i64 fp0 = tcg_temp_new_i64();
11479 gen_load_fpr64(ctx, fp0, fs);
11480 gen_helper_float_rint_d(fp0, cpu_env, fp0);
11481 gen_store_fpr64(ctx, fp0, fd);
11482 tcg_temp_free_i64(fp0);
11486 check_insn(ctx, ISA_MIPS32R6);
11488 TCGv_i64 fp0 = tcg_temp_new_i64();
11489 gen_load_fpr64(ctx, fp0, fs);
11490 gen_helper_float_class_d(fp0, cpu_env, fp0);
11491 gen_store_fpr64(ctx, fp0, fd);
11492 tcg_temp_free_i64(fp0);
11495 case OPC_MIN_D: /* OPC_RECIP2_D */
11496 if (ctx->insn_flags & ISA_MIPS32R6) {
11498 TCGv_i64 fp0 = tcg_temp_new_i64();
11499 TCGv_i64 fp1 = tcg_temp_new_i64();
11500 gen_load_fpr64(ctx, fp0, fs);
11501 gen_load_fpr64(ctx, fp1, ft);
11502 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11503 gen_store_fpr64(ctx, fp1, fd);
11504 tcg_temp_free_i64(fp1);
11505 tcg_temp_free_i64(fp0);
11508 check_cp1_64bitmode(ctx);
11510 TCGv_i64 fp0 = tcg_temp_new_i64();
11511 TCGv_i64 fp1 = tcg_temp_new_i64();
11513 gen_load_fpr64(ctx, fp0, fs);
11514 gen_load_fpr64(ctx, fp1, ft);
11515 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11516 tcg_temp_free_i64(fp1);
11517 gen_store_fpr64(ctx, fp0, fd);
11518 tcg_temp_free_i64(fp0);
11522 case OPC_MINA_D: /* OPC_RECIP1_D */
11523 if (ctx->insn_flags & ISA_MIPS32R6) {
11525 TCGv_i64 fp0 = tcg_temp_new_i64();
11526 TCGv_i64 fp1 = tcg_temp_new_i64();
11527 gen_load_fpr64(ctx, fp0, fs);
11528 gen_load_fpr64(ctx, fp1, ft);
11529 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11530 gen_store_fpr64(ctx, fp1, fd);
11531 tcg_temp_free_i64(fp1);
11532 tcg_temp_free_i64(fp0);
11535 check_cp1_64bitmode(ctx);
11537 TCGv_i64 fp0 = tcg_temp_new_i64();
11539 gen_load_fpr64(ctx, fp0, fs);
11540 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11541 gen_store_fpr64(ctx, fp0, fd);
11542 tcg_temp_free_i64(fp0);
11546 case OPC_MAX_D: /* OPC_RSQRT1_D */
11547 if (ctx->insn_flags & ISA_MIPS32R6) {
11549 TCGv_i64 fp0 = tcg_temp_new_i64();
11550 TCGv_i64 fp1 = tcg_temp_new_i64();
11551 gen_load_fpr64(ctx, fp0, fs);
11552 gen_load_fpr64(ctx, fp1, ft);
11553 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11554 gen_store_fpr64(ctx, fp1, fd);
11555 tcg_temp_free_i64(fp1);
11556 tcg_temp_free_i64(fp0);
11559 check_cp1_64bitmode(ctx);
11561 TCGv_i64 fp0 = tcg_temp_new_i64();
11563 gen_load_fpr64(ctx, fp0, fs);
11564 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11565 gen_store_fpr64(ctx, fp0, fd);
11566 tcg_temp_free_i64(fp0);
11570 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11571 if (ctx->insn_flags & ISA_MIPS32R6) {
11573 TCGv_i64 fp0 = tcg_temp_new_i64();
11574 TCGv_i64 fp1 = tcg_temp_new_i64();
11575 gen_load_fpr64(ctx, fp0, fs);
11576 gen_load_fpr64(ctx, fp1, ft);
11577 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11578 gen_store_fpr64(ctx, fp1, fd);
11579 tcg_temp_free_i64(fp1);
11580 tcg_temp_free_i64(fp0);
11583 check_cp1_64bitmode(ctx);
11585 TCGv_i64 fp0 = tcg_temp_new_i64();
11586 TCGv_i64 fp1 = tcg_temp_new_i64();
11588 gen_load_fpr64(ctx, fp0, fs);
11589 gen_load_fpr64(ctx, fp1, ft);
11590 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11591 tcg_temp_free_i64(fp1);
11592 gen_store_fpr64(ctx, fp0, fd);
11593 tcg_temp_free_i64(fp0);
11600 case OPC_CMP_UEQ_D:
11601 case OPC_CMP_OLT_D:
11602 case OPC_CMP_ULT_D:
11603 case OPC_CMP_OLE_D:
11604 case OPC_CMP_ULE_D:
11606 case OPC_CMP_NGLE_D:
11607 case OPC_CMP_SEQ_D:
11608 case OPC_CMP_NGL_D:
11610 case OPC_CMP_NGE_D:
11612 case OPC_CMP_NGT_D:
11613 check_insn_opc_removed(ctx, ISA_MIPS32R6);
11614 if (ctx->opcode & (1 << 6)) {
11615 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11617 gen_cmp_d(ctx, func-48, ft, fs, cc);
11621 check_cp1_registers(ctx, fs);
11623 TCGv_i32 fp32 = tcg_temp_new_i32();
11624 TCGv_i64 fp64 = tcg_temp_new_i64();
11626 gen_load_fpr64(ctx, fp64, fs);
11627 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11628 tcg_temp_free_i64(fp64);
11629 gen_store_fpr32(ctx, fp32, fd);
11630 tcg_temp_free_i32(fp32);
11634 check_cp1_registers(ctx, fs);
11636 TCGv_i32 fp32 = tcg_temp_new_i32();
11637 TCGv_i64 fp64 = tcg_temp_new_i64();
11639 gen_load_fpr64(ctx, fp64, fs);
11640 if (ctx->nan2008) {
11641 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11643 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11645 tcg_temp_free_i64(fp64);
11646 gen_store_fpr32(ctx, fp32, fd);
11647 tcg_temp_free_i32(fp32);
11651 check_cp1_64bitmode(ctx);
11653 TCGv_i64 fp0 = tcg_temp_new_i64();
11655 gen_load_fpr64(ctx, fp0, fs);
11656 if (ctx->nan2008) {
11657 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11659 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11661 gen_store_fpr64(ctx, fp0, fd);
11662 tcg_temp_free_i64(fp0);
11667 TCGv_i32 fp0 = tcg_temp_new_i32();
11669 gen_load_fpr32(ctx, fp0, fs);
11670 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11671 gen_store_fpr32(ctx, fp0, fd);
11672 tcg_temp_free_i32(fp0);
11676 check_cp1_registers(ctx, fd);
11678 TCGv_i32 fp32 = tcg_temp_new_i32();
11679 TCGv_i64 fp64 = tcg_temp_new_i64();
11681 gen_load_fpr32(ctx, fp32, fs);
11682 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11683 tcg_temp_free_i32(fp32);
11684 gen_store_fpr64(ctx, fp64, fd);
11685 tcg_temp_free_i64(fp64);
11689 check_cp1_64bitmode(ctx);
11691 TCGv_i32 fp32 = tcg_temp_new_i32();
11692 TCGv_i64 fp64 = tcg_temp_new_i64();
11694 gen_load_fpr64(ctx, fp64, fs);
11695 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11696 tcg_temp_free_i64(fp64);
11697 gen_store_fpr32(ctx, fp32, fd);
11698 tcg_temp_free_i32(fp32);
11702 check_cp1_64bitmode(ctx);
11704 TCGv_i64 fp0 = tcg_temp_new_i64();
11706 gen_load_fpr64(ctx, fp0, fs);
11707 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11708 gen_store_fpr64(ctx, fp0, fd);
11709 tcg_temp_free_i64(fp0);
11712 case OPC_CVT_PS_PW:
11715 TCGv_i64 fp0 = tcg_temp_new_i64();
11717 gen_load_fpr64(ctx, fp0, fs);
11718 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11719 gen_store_fpr64(ctx, fp0, fd);
11720 tcg_temp_free_i64(fp0);
11726 TCGv_i64 fp0 = tcg_temp_new_i64();
11727 TCGv_i64 fp1 = tcg_temp_new_i64();
11729 gen_load_fpr64(ctx, fp0, fs);
11730 gen_load_fpr64(ctx, fp1, ft);
11731 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11732 tcg_temp_free_i64(fp1);
11733 gen_store_fpr64(ctx, fp0, fd);
11734 tcg_temp_free_i64(fp0);
11740 TCGv_i64 fp0 = tcg_temp_new_i64();
11741 TCGv_i64 fp1 = tcg_temp_new_i64();
11743 gen_load_fpr64(ctx, fp0, fs);
11744 gen_load_fpr64(ctx, fp1, ft);
11745 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11746 tcg_temp_free_i64(fp1);
11747 gen_store_fpr64(ctx, fp0, fd);
11748 tcg_temp_free_i64(fp0);
11754 TCGv_i64 fp0 = tcg_temp_new_i64();
11755 TCGv_i64 fp1 = tcg_temp_new_i64();
11757 gen_load_fpr64(ctx, fp0, fs);
11758 gen_load_fpr64(ctx, fp1, ft);
11759 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11760 tcg_temp_free_i64(fp1);
11761 gen_store_fpr64(ctx, fp0, fd);
11762 tcg_temp_free_i64(fp0);
11768 TCGv_i64 fp0 = tcg_temp_new_i64();
11770 gen_load_fpr64(ctx, fp0, fs);
11771 gen_helper_float_abs_ps(fp0, fp0);
11772 gen_store_fpr64(ctx, fp0, fd);
11773 tcg_temp_free_i64(fp0);
11779 TCGv_i64 fp0 = tcg_temp_new_i64();
11781 gen_load_fpr64(ctx, fp0, fs);
11782 gen_store_fpr64(ctx, fp0, fd);
11783 tcg_temp_free_i64(fp0);
11789 TCGv_i64 fp0 = tcg_temp_new_i64();
11791 gen_load_fpr64(ctx, fp0, fs);
11792 gen_helper_float_chs_ps(fp0, fp0);
11793 gen_store_fpr64(ctx, fp0, fd);
11794 tcg_temp_free_i64(fp0);
11799 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11804 TCGLabel *l1 = gen_new_label();
11808 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11809 fp0 = tcg_temp_new_i64();
11810 gen_load_fpr64(ctx, fp0, fs);
11811 gen_store_fpr64(ctx, fp0, fd);
11812 tcg_temp_free_i64(fp0);
11819 TCGLabel *l1 = gen_new_label();
11823 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11824 fp0 = tcg_temp_new_i64();
11825 gen_load_fpr64(ctx, fp0, fs);
11826 gen_store_fpr64(ctx, fp0, fd);
11827 tcg_temp_free_i64(fp0);
11835 TCGv_i64 fp0 = tcg_temp_new_i64();
11836 TCGv_i64 fp1 = tcg_temp_new_i64();
11838 gen_load_fpr64(ctx, fp0, ft);
11839 gen_load_fpr64(ctx, fp1, fs);
11840 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11841 tcg_temp_free_i64(fp1);
11842 gen_store_fpr64(ctx, fp0, fd);
11843 tcg_temp_free_i64(fp0);
11849 TCGv_i64 fp0 = tcg_temp_new_i64();
11850 TCGv_i64 fp1 = tcg_temp_new_i64();
11852 gen_load_fpr64(ctx, fp0, ft);
11853 gen_load_fpr64(ctx, fp1, fs);
11854 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11855 tcg_temp_free_i64(fp1);
11856 gen_store_fpr64(ctx, fp0, fd);
11857 tcg_temp_free_i64(fp0);
11860 case OPC_RECIP2_PS:
11863 TCGv_i64 fp0 = tcg_temp_new_i64();
11864 TCGv_i64 fp1 = tcg_temp_new_i64();
11866 gen_load_fpr64(ctx, fp0, fs);
11867 gen_load_fpr64(ctx, fp1, ft);
11868 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11869 tcg_temp_free_i64(fp1);
11870 gen_store_fpr64(ctx, fp0, fd);
11871 tcg_temp_free_i64(fp0);
11874 case OPC_RECIP1_PS:
11877 TCGv_i64 fp0 = tcg_temp_new_i64();
11879 gen_load_fpr64(ctx, fp0, fs);
11880 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11881 gen_store_fpr64(ctx, fp0, fd);
11882 tcg_temp_free_i64(fp0);
11885 case OPC_RSQRT1_PS:
11888 TCGv_i64 fp0 = tcg_temp_new_i64();
11890 gen_load_fpr64(ctx, fp0, fs);
11891 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11892 gen_store_fpr64(ctx, fp0, fd);
11893 tcg_temp_free_i64(fp0);
11896 case OPC_RSQRT2_PS:
11899 TCGv_i64 fp0 = tcg_temp_new_i64();
11900 TCGv_i64 fp1 = tcg_temp_new_i64();
11902 gen_load_fpr64(ctx, fp0, fs);
11903 gen_load_fpr64(ctx, fp1, ft);
11904 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11905 tcg_temp_free_i64(fp1);
11906 gen_store_fpr64(ctx, fp0, fd);
11907 tcg_temp_free_i64(fp0);
11911 check_cp1_64bitmode(ctx);
11913 TCGv_i32 fp0 = tcg_temp_new_i32();
11915 gen_load_fpr32h(ctx, fp0, fs);
11916 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11917 gen_store_fpr32(ctx, fp0, fd);
11918 tcg_temp_free_i32(fp0);
11921 case OPC_CVT_PW_PS:
11924 TCGv_i64 fp0 = tcg_temp_new_i64();
11926 gen_load_fpr64(ctx, fp0, fs);
11927 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11928 gen_store_fpr64(ctx, fp0, fd);
11929 tcg_temp_free_i64(fp0);
11933 check_cp1_64bitmode(ctx);
11935 TCGv_i32 fp0 = tcg_temp_new_i32();
11937 gen_load_fpr32(ctx, fp0, fs);
11938 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11939 gen_store_fpr32(ctx, fp0, fd);
11940 tcg_temp_free_i32(fp0);
11946 TCGv_i32 fp0 = tcg_temp_new_i32();
11947 TCGv_i32 fp1 = tcg_temp_new_i32();
11949 gen_load_fpr32(ctx, fp0, fs);
11950 gen_load_fpr32(ctx, fp1, ft);
11951 gen_store_fpr32h(ctx, fp0, fd);
11952 gen_store_fpr32(ctx, fp1, fd);
11953 tcg_temp_free_i32(fp0);
11954 tcg_temp_free_i32(fp1);
11960 TCGv_i32 fp0 = tcg_temp_new_i32();
11961 TCGv_i32 fp1 = tcg_temp_new_i32();
11963 gen_load_fpr32(ctx, fp0, fs);
11964 gen_load_fpr32h(ctx, fp1, ft);
11965 gen_store_fpr32(ctx, fp1, fd);
11966 gen_store_fpr32h(ctx, fp0, fd);
11967 tcg_temp_free_i32(fp0);
11968 tcg_temp_free_i32(fp1);
11974 TCGv_i32 fp0 = tcg_temp_new_i32();
11975 TCGv_i32 fp1 = tcg_temp_new_i32();
11977 gen_load_fpr32h(ctx, fp0, fs);
11978 gen_load_fpr32(ctx, fp1, ft);
11979 gen_store_fpr32(ctx, fp1, fd);
11980 gen_store_fpr32h(ctx, fp0, fd);
11981 tcg_temp_free_i32(fp0);
11982 tcg_temp_free_i32(fp1);
11988 TCGv_i32 fp0 = tcg_temp_new_i32();
11989 TCGv_i32 fp1 = tcg_temp_new_i32();
11991 gen_load_fpr32h(ctx, fp0, fs);
11992 gen_load_fpr32h(ctx, fp1, ft);
11993 gen_store_fpr32(ctx, fp1, fd);
11994 gen_store_fpr32h(ctx, fp0, fd);
11995 tcg_temp_free_i32(fp0);
11996 tcg_temp_free_i32(fp1);
12000 case OPC_CMP_UN_PS:
12001 case OPC_CMP_EQ_PS:
12002 case OPC_CMP_UEQ_PS:
12003 case OPC_CMP_OLT_PS:
12004 case OPC_CMP_ULT_PS:
12005 case OPC_CMP_OLE_PS:
12006 case OPC_CMP_ULE_PS:
12007 case OPC_CMP_SF_PS:
12008 case OPC_CMP_NGLE_PS:
12009 case OPC_CMP_SEQ_PS:
12010 case OPC_CMP_NGL_PS:
12011 case OPC_CMP_LT_PS:
12012 case OPC_CMP_NGE_PS:
12013 case OPC_CMP_LE_PS:
12014 case OPC_CMP_NGT_PS:
12015 if (ctx->opcode & (1 << 6)) {
12016 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12018 gen_cmp_ps(ctx, func-48, ft, fs, cc);
12022 MIPS_INVAL("farith");
12023 generate_exception_end(ctx, EXCP_RI);
12028 /* Coprocessor 3 (FPU) */
12029 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12030 int fd, int fs, int base, int index)
12032 TCGv t0 = tcg_temp_new();
12035 gen_load_gpr(t0, index);
12036 } else if (index == 0) {
12037 gen_load_gpr(t0, base);
12039 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12041 /* Don't do NOP if destination is zero: we must perform the actual
12047 TCGv_i32 fp0 = tcg_temp_new_i32();
12049 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12050 tcg_gen_trunc_tl_i32(fp0, t0);
12051 gen_store_fpr32(ctx, fp0, fd);
12052 tcg_temp_free_i32(fp0);
12057 check_cp1_registers(ctx, fd);
12059 TCGv_i64 fp0 = tcg_temp_new_i64();
12060 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12061 gen_store_fpr64(ctx, fp0, fd);
12062 tcg_temp_free_i64(fp0);
12066 check_cp1_64bitmode(ctx);
12067 tcg_gen_andi_tl(t0, t0, ~0x7);
12069 TCGv_i64 fp0 = tcg_temp_new_i64();
12071 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12072 gen_store_fpr64(ctx, fp0, fd);
12073 tcg_temp_free_i64(fp0);
12079 TCGv_i32 fp0 = tcg_temp_new_i32();
12080 gen_load_fpr32(ctx, fp0, fs);
12081 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12082 tcg_temp_free_i32(fp0);
12087 check_cp1_registers(ctx, fs);
12089 TCGv_i64 fp0 = tcg_temp_new_i64();
12090 gen_load_fpr64(ctx, fp0, fs);
12091 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12092 tcg_temp_free_i64(fp0);
12096 check_cp1_64bitmode(ctx);
12097 tcg_gen_andi_tl(t0, t0, ~0x7);
12099 TCGv_i64 fp0 = tcg_temp_new_i64();
12100 gen_load_fpr64(ctx, fp0, fs);
12101 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12102 tcg_temp_free_i64(fp0);
12109 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12110 int fd, int fr, int fs, int ft)
12116 TCGv t0 = tcg_temp_local_new();
12117 TCGv_i32 fp = tcg_temp_new_i32();
12118 TCGv_i32 fph = tcg_temp_new_i32();
12119 TCGLabel *l1 = gen_new_label();
12120 TCGLabel *l2 = gen_new_label();
12122 gen_load_gpr(t0, fr);
12123 tcg_gen_andi_tl(t0, t0, 0x7);
12125 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12126 gen_load_fpr32(ctx, fp, fs);
12127 gen_load_fpr32h(ctx, fph, fs);
12128 gen_store_fpr32(ctx, fp, fd);
12129 gen_store_fpr32h(ctx, fph, fd);
12132 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12134 #ifdef TARGET_WORDS_BIGENDIAN
12135 gen_load_fpr32(ctx, fp, fs);
12136 gen_load_fpr32h(ctx, fph, ft);
12137 gen_store_fpr32h(ctx, fp, fd);
12138 gen_store_fpr32(ctx, fph, fd);
12140 gen_load_fpr32h(ctx, fph, fs);
12141 gen_load_fpr32(ctx, fp, ft);
12142 gen_store_fpr32(ctx, fph, fd);
12143 gen_store_fpr32h(ctx, fp, fd);
12146 tcg_temp_free_i32(fp);
12147 tcg_temp_free_i32(fph);
12153 TCGv_i32 fp0 = tcg_temp_new_i32();
12154 TCGv_i32 fp1 = tcg_temp_new_i32();
12155 TCGv_i32 fp2 = tcg_temp_new_i32();
12157 gen_load_fpr32(ctx, fp0, fs);
12158 gen_load_fpr32(ctx, fp1, ft);
12159 gen_load_fpr32(ctx, fp2, fr);
12160 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12161 tcg_temp_free_i32(fp0);
12162 tcg_temp_free_i32(fp1);
12163 gen_store_fpr32(ctx, fp2, fd);
12164 tcg_temp_free_i32(fp2);
12169 check_cp1_registers(ctx, fd | fs | ft | fr);
12171 TCGv_i64 fp0 = tcg_temp_new_i64();
12172 TCGv_i64 fp1 = tcg_temp_new_i64();
12173 TCGv_i64 fp2 = tcg_temp_new_i64();
12175 gen_load_fpr64(ctx, fp0, fs);
12176 gen_load_fpr64(ctx, fp1, ft);
12177 gen_load_fpr64(ctx, fp2, fr);
12178 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12179 tcg_temp_free_i64(fp0);
12180 tcg_temp_free_i64(fp1);
12181 gen_store_fpr64(ctx, fp2, fd);
12182 tcg_temp_free_i64(fp2);
12188 TCGv_i64 fp0 = tcg_temp_new_i64();
12189 TCGv_i64 fp1 = tcg_temp_new_i64();
12190 TCGv_i64 fp2 = tcg_temp_new_i64();
12192 gen_load_fpr64(ctx, fp0, fs);
12193 gen_load_fpr64(ctx, fp1, ft);
12194 gen_load_fpr64(ctx, fp2, fr);
12195 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12196 tcg_temp_free_i64(fp0);
12197 tcg_temp_free_i64(fp1);
12198 gen_store_fpr64(ctx, fp2, fd);
12199 tcg_temp_free_i64(fp2);
12205 TCGv_i32 fp0 = tcg_temp_new_i32();
12206 TCGv_i32 fp1 = tcg_temp_new_i32();
12207 TCGv_i32 fp2 = tcg_temp_new_i32();
12209 gen_load_fpr32(ctx, fp0, fs);
12210 gen_load_fpr32(ctx, fp1, ft);
12211 gen_load_fpr32(ctx, fp2, fr);
12212 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12213 tcg_temp_free_i32(fp0);
12214 tcg_temp_free_i32(fp1);
12215 gen_store_fpr32(ctx, fp2, fd);
12216 tcg_temp_free_i32(fp2);
12221 check_cp1_registers(ctx, fd | fs | ft | fr);
12223 TCGv_i64 fp0 = tcg_temp_new_i64();
12224 TCGv_i64 fp1 = tcg_temp_new_i64();
12225 TCGv_i64 fp2 = tcg_temp_new_i64();
12227 gen_load_fpr64(ctx, fp0, fs);
12228 gen_load_fpr64(ctx, fp1, ft);
12229 gen_load_fpr64(ctx, fp2, fr);
12230 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12231 tcg_temp_free_i64(fp0);
12232 tcg_temp_free_i64(fp1);
12233 gen_store_fpr64(ctx, fp2, fd);
12234 tcg_temp_free_i64(fp2);
12240 TCGv_i64 fp0 = tcg_temp_new_i64();
12241 TCGv_i64 fp1 = tcg_temp_new_i64();
12242 TCGv_i64 fp2 = tcg_temp_new_i64();
12244 gen_load_fpr64(ctx, fp0, fs);
12245 gen_load_fpr64(ctx, fp1, ft);
12246 gen_load_fpr64(ctx, fp2, fr);
12247 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12248 tcg_temp_free_i64(fp0);
12249 tcg_temp_free_i64(fp1);
12250 gen_store_fpr64(ctx, fp2, fd);
12251 tcg_temp_free_i64(fp2);
12257 TCGv_i32 fp0 = tcg_temp_new_i32();
12258 TCGv_i32 fp1 = tcg_temp_new_i32();
12259 TCGv_i32 fp2 = tcg_temp_new_i32();
12261 gen_load_fpr32(ctx, fp0, fs);
12262 gen_load_fpr32(ctx, fp1, ft);
12263 gen_load_fpr32(ctx, fp2, fr);
12264 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12265 tcg_temp_free_i32(fp0);
12266 tcg_temp_free_i32(fp1);
12267 gen_store_fpr32(ctx, fp2, fd);
12268 tcg_temp_free_i32(fp2);
12273 check_cp1_registers(ctx, fd | fs | ft | fr);
12275 TCGv_i64 fp0 = tcg_temp_new_i64();
12276 TCGv_i64 fp1 = tcg_temp_new_i64();
12277 TCGv_i64 fp2 = tcg_temp_new_i64();
12279 gen_load_fpr64(ctx, fp0, fs);
12280 gen_load_fpr64(ctx, fp1, ft);
12281 gen_load_fpr64(ctx, fp2, fr);
12282 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12283 tcg_temp_free_i64(fp0);
12284 tcg_temp_free_i64(fp1);
12285 gen_store_fpr64(ctx, fp2, fd);
12286 tcg_temp_free_i64(fp2);
12292 TCGv_i64 fp0 = tcg_temp_new_i64();
12293 TCGv_i64 fp1 = tcg_temp_new_i64();
12294 TCGv_i64 fp2 = tcg_temp_new_i64();
12296 gen_load_fpr64(ctx, fp0, fs);
12297 gen_load_fpr64(ctx, fp1, ft);
12298 gen_load_fpr64(ctx, fp2, fr);
12299 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12300 tcg_temp_free_i64(fp0);
12301 tcg_temp_free_i64(fp1);
12302 gen_store_fpr64(ctx, fp2, fd);
12303 tcg_temp_free_i64(fp2);
12309 TCGv_i32 fp0 = tcg_temp_new_i32();
12310 TCGv_i32 fp1 = tcg_temp_new_i32();
12311 TCGv_i32 fp2 = tcg_temp_new_i32();
12313 gen_load_fpr32(ctx, fp0, fs);
12314 gen_load_fpr32(ctx, fp1, ft);
12315 gen_load_fpr32(ctx, fp2, fr);
12316 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12317 tcg_temp_free_i32(fp0);
12318 tcg_temp_free_i32(fp1);
12319 gen_store_fpr32(ctx, fp2, fd);
12320 tcg_temp_free_i32(fp2);
12325 check_cp1_registers(ctx, fd | fs | ft | fr);
12327 TCGv_i64 fp0 = tcg_temp_new_i64();
12328 TCGv_i64 fp1 = tcg_temp_new_i64();
12329 TCGv_i64 fp2 = tcg_temp_new_i64();
12331 gen_load_fpr64(ctx, fp0, fs);
12332 gen_load_fpr64(ctx, fp1, ft);
12333 gen_load_fpr64(ctx, fp2, fr);
12334 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12335 tcg_temp_free_i64(fp0);
12336 tcg_temp_free_i64(fp1);
12337 gen_store_fpr64(ctx, fp2, fd);
12338 tcg_temp_free_i64(fp2);
12344 TCGv_i64 fp0 = tcg_temp_new_i64();
12345 TCGv_i64 fp1 = tcg_temp_new_i64();
12346 TCGv_i64 fp2 = tcg_temp_new_i64();
12348 gen_load_fpr64(ctx, fp0, fs);
12349 gen_load_fpr64(ctx, fp1, ft);
12350 gen_load_fpr64(ctx, fp2, fr);
12351 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12352 tcg_temp_free_i64(fp0);
12353 tcg_temp_free_i64(fp1);
12354 gen_store_fpr64(ctx, fp2, fd);
12355 tcg_temp_free_i64(fp2);
12359 MIPS_INVAL("flt3_arith");
12360 generate_exception_end(ctx, EXCP_RI);
12365 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12369 #if !defined(CONFIG_USER_ONLY)
12370 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12371 Therefore only check the ISA in system mode. */
12372 check_insn(ctx, ISA_MIPS32R2);
12374 t0 = tcg_temp_new();
12378 gen_helper_rdhwr_cpunum(t0, cpu_env);
12379 gen_store_gpr(t0, rt);
12382 gen_helper_rdhwr_synci_step(t0, cpu_env);
12383 gen_store_gpr(t0, rt);
12386 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12389 gen_helper_rdhwr_cc(t0, cpu_env);
12390 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12393 gen_store_gpr(t0, rt);
12394 /* Break the TB to be able to take timer interrupts immediately
12395 after reading count. DISAS_STOP isn't sufficient, we need to ensure
12396 we break completely out of translated code. */
12397 gen_save_pc(ctx->base.pc_next + 4);
12398 ctx->base.is_jmp = DISAS_EXIT;
12401 gen_helper_rdhwr_ccres(t0, cpu_env);
12402 gen_store_gpr(t0, rt);
12405 check_insn(ctx, ISA_MIPS32R6);
12407 /* Performance counter registers are not implemented other than
12408 * control register 0.
12410 generate_exception(ctx, EXCP_RI);
12412 gen_helper_rdhwr_performance(t0, cpu_env);
12413 gen_store_gpr(t0, rt);
12416 check_insn(ctx, ISA_MIPS32R6);
12417 gen_helper_rdhwr_xnp(t0, cpu_env);
12418 gen_store_gpr(t0, rt);
12421 #if defined(CONFIG_USER_ONLY)
12422 tcg_gen_ld_tl(t0, cpu_env,
12423 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12424 gen_store_gpr(t0, rt);
12427 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12428 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12429 tcg_gen_ld_tl(t0, cpu_env,
12430 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12431 gen_store_gpr(t0, rt);
12433 generate_exception_end(ctx, EXCP_RI);
12437 default: /* Invalid */
12438 MIPS_INVAL("rdhwr");
12439 generate_exception_end(ctx, EXCP_RI);
12445 static inline void clear_branch_hflags(DisasContext *ctx)
12447 ctx->hflags &= ~MIPS_HFLAG_BMASK;
12448 if (ctx->base.is_jmp == DISAS_NEXT) {
12449 save_cpu_state(ctx, 0);
12451 /* it is not safe to save ctx->hflags as hflags may be changed
12452 in execution time by the instruction in delay / forbidden slot. */
12453 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12457 static void gen_branch(DisasContext *ctx, int insn_bytes)
12459 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12460 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12461 /* Branches completion */
12462 clear_branch_hflags(ctx);
12463 ctx->base.is_jmp = DISAS_NORETURN;
12464 /* FIXME: Need to clear can_do_io. */
12465 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12466 case MIPS_HFLAG_FBNSLOT:
12467 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12470 /* unconditional branch */
12471 if (proc_hflags & MIPS_HFLAG_BX) {
12472 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12474 gen_goto_tb(ctx, 0, ctx->btarget);
12476 case MIPS_HFLAG_BL:
12477 /* blikely taken case */
12478 gen_goto_tb(ctx, 0, ctx->btarget);
12480 case MIPS_HFLAG_BC:
12481 /* Conditional branch */
12483 TCGLabel *l1 = gen_new_label();
12485 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12486 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12488 gen_goto_tb(ctx, 0, ctx->btarget);
12491 case MIPS_HFLAG_BR:
12492 /* unconditional branch to register */
12493 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12494 TCGv t0 = tcg_temp_new();
12495 TCGv_i32 t1 = tcg_temp_new_i32();
12497 tcg_gen_andi_tl(t0, btarget, 0x1);
12498 tcg_gen_trunc_tl_i32(t1, t0);
12500 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12501 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12502 tcg_gen_or_i32(hflags, hflags, t1);
12503 tcg_temp_free_i32(t1);
12505 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12507 tcg_gen_mov_tl(cpu_PC, btarget);
12509 if (ctx->base.singlestep_enabled) {
12510 save_cpu_state(ctx, 0);
12511 gen_helper_raise_exception_debug(cpu_env);
12513 tcg_gen_lookup_and_goto_ptr();
12516 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12522 /* Compact Branches */
12523 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12524 int rs, int rt, int32_t offset)
12526 int bcond_compute = 0;
12527 TCGv t0 = tcg_temp_new();
12528 TCGv t1 = tcg_temp_new();
12529 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12531 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12532 #ifdef MIPS_DEBUG_DISAS
12533 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12534 "\n", ctx->base.pc_next);
12536 generate_exception_end(ctx, EXCP_RI);
12540 /* Load needed operands and calculate btarget */
12542 /* compact branch */
12543 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12544 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12545 gen_load_gpr(t0, rs);
12546 gen_load_gpr(t1, rt);
12548 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12549 if (rs <= rt && rs == 0) {
12550 /* OPC_BEQZALC, OPC_BNEZALC */
12551 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12554 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12555 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12556 gen_load_gpr(t0, rs);
12557 gen_load_gpr(t1, rt);
12559 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12561 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12562 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12563 if (rs == 0 || rs == rt) {
12564 /* OPC_BLEZALC, OPC_BGEZALC */
12565 /* OPC_BGTZALC, OPC_BLTZALC */
12566 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12568 gen_load_gpr(t0, rs);
12569 gen_load_gpr(t1, rt);
12571 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12575 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12580 /* OPC_BEQZC, OPC_BNEZC */
12581 gen_load_gpr(t0, rs);
12583 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12585 /* OPC_JIC, OPC_JIALC */
12586 TCGv tbase = tcg_temp_new();
12587 TCGv toffset = tcg_temp_new();
12589 gen_load_gpr(tbase, rt);
12590 tcg_gen_movi_tl(toffset, offset);
12591 gen_op_addr_add(ctx, btarget, tbase, toffset);
12592 tcg_temp_free(tbase);
12593 tcg_temp_free(toffset);
12597 MIPS_INVAL("Compact branch/jump");
12598 generate_exception_end(ctx, EXCP_RI);
12602 if (bcond_compute == 0) {
12603 /* Uncoditional compact branch */
12606 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12609 ctx->hflags |= MIPS_HFLAG_BR;
12612 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12615 ctx->hflags |= MIPS_HFLAG_B;
12618 MIPS_INVAL("Compact branch/jump");
12619 generate_exception_end(ctx, EXCP_RI);
12623 /* Generating branch here as compact branches don't have delay slot */
12624 gen_branch(ctx, 4);
12626 /* Conditional compact branch */
12627 TCGLabel *fs = gen_new_label();
12628 save_cpu_state(ctx, 0);
12631 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12632 if (rs == 0 && rt != 0) {
12634 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12635 } else if (rs != 0 && rt != 0 && rs == rt) {
12637 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12640 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12643 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12644 if (rs == 0 && rt != 0) {
12646 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12647 } else if (rs != 0 && rt != 0 && rs == rt) {
12649 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12652 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12655 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12656 if (rs == 0 && rt != 0) {
12658 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12659 } else if (rs != 0 && rt != 0 && rs == rt) {
12661 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12664 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12667 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12668 if (rs == 0 && rt != 0) {
12670 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12671 } else if (rs != 0 && rt != 0 && rs == rt) {
12673 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12676 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12679 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12680 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12682 /* OPC_BOVC, OPC_BNVC */
12683 TCGv t2 = tcg_temp_new();
12684 TCGv t3 = tcg_temp_new();
12685 TCGv t4 = tcg_temp_new();
12686 TCGv input_overflow = tcg_temp_new();
12688 gen_load_gpr(t0, rs);
12689 gen_load_gpr(t1, rt);
12690 tcg_gen_ext32s_tl(t2, t0);
12691 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12692 tcg_gen_ext32s_tl(t3, t1);
12693 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12694 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12696 tcg_gen_add_tl(t4, t2, t3);
12697 tcg_gen_ext32s_tl(t4, t4);
12698 tcg_gen_xor_tl(t2, t2, t3);
12699 tcg_gen_xor_tl(t3, t4, t3);
12700 tcg_gen_andc_tl(t2, t3, t2);
12701 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12702 tcg_gen_or_tl(t4, t4, input_overflow);
12703 if (opc == OPC_BOVC) {
12705 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12708 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12710 tcg_temp_free(input_overflow);
12714 } else if (rs < rt && rs == 0) {
12715 /* OPC_BEQZALC, OPC_BNEZALC */
12716 if (opc == OPC_BEQZALC) {
12718 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12721 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12724 /* OPC_BEQC, OPC_BNEC */
12725 if (opc == OPC_BEQC) {
12727 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12730 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12735 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12738 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12741 MIPS_INVAL("Compact conditional branch/jump");
12742 generate_exception_end(ctx, EXCP_RI);
12746 /* Generating branch here as compact branches don't have delay slot */
12747 gen_goto_tb(ctx, 1, ctx->btarget);
12750 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12758 /* ISA extensions (ASEs) */
12759 /* MIPS16 extension to MIPS32 */
12761 /* MIPS16 major opcodes */
12763 M16_OPC_ADDIUSP = 0x00,
12764 M16_OPC_ADDIUPC = 0x01,
12766 M16_OPC_JAL = 0x03,
12767 M16_OPC_BEQZ = 0x04,
12768 M16_OPC_BNEQZ = 0x05,
12769 M16_OPC_SHIFT = 0x06,
12771 M16_OPC_RRIA = 0x08,
12772 M16_OPC_ADDIU8 = 0x09,
12773 M16_OPC_SLTI = 0x0a,
12774 M16_OPC_SLTIU = 0x0b,
12777 M16_OPC_CMPI = 0x0e,
12781 M16_OPC_LWSP = 0x12,
12783 M16_OPC_LBU = 0x14,
12784 M16_OPC_LHU = 0x15,
12785 M16_OPC_LWPC = 0x16,
12786 M16_OPC_LWU = 0x17,
12789 M16_OPC_SWSP = 0x1a,
12791 M16_OPC_RRR = 0x1c,
12793 M16_OPC_EXTEND = 0x1e,
12797 /* I8 funct field */
12816 /* RR funct field */
12850 /* I64 funct field */
12858 I64_DADDIUPC = 0x6,
12862 /* RR ry field for CNVT */
12864 RR_RY_CNVT_ZEB = 0x0,
12865 RR_RY_CNVT_ZEH = 0x1,
12866 RR_RY_CNVT_ZEW = 0x2,
12867 RR_RY_CNVT_SEB = 0x4,
12868 RR_RY_CNVT_SEH = 0x5,
12869 RR_RY_CNVT_SEW = 0x6,
12872 static int xlat (int r)
12874 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12879 static void gen_mips16_save (DisasContext *ctx,
12880 int xsregs, int aregs,
12881 int do_ra, int do_s0, int do_s1,
12884 TCGv t0 = tcg_temp_new();
12885 TCGv t1 = tcg_temp_new();
12886 TCGv t2 = tcg_temp_new();
12916 generate_exception_end(ctx, EXCP_RI);
12922 gen_base_offset_addr(ctx, t0, 29, 12);
12923 gen_load_gpr(t1, 7);
12924 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12927 gen_base_offset_addr(ctx, t0, 29, 8);
12928 gen_load_gpr(t1, 6);
12929 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12932 gen_base_offset_addr(ctx, t0, 29, 4);
12933 gen_load_gpr(t1, 5);
12934 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12937 gen_base_offset_addr(ctx, t0, 29, 0);
12938 gen_load_gpr(t1, 4);
12939 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12942 gen_load_gpr(t0, 29);
12944 #define DECR_AND_STORE(reg) do { \
12945 tcg_gen_movi_tl(t2, -4); \
12946 gen_op_addr_add(ctx, t0, t0, t2); \
12947 gen_load_gpr(t1, reg); \
12948 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12952 DECR_AND_STORE(31);
12957 DECR_AND_STORE(30);
12960 DECR_AND_STORE(23);
12963 DECR_AND_STORE(22);
12966 DECR_AND_STORE(21);
12969 DECR_AND_STORE(20);
12972 DECR_AND_STORE(19);
12975 DECR_AND_STORE(18);
12979 DECR_AND_STORE(17);
12982 DECR_AND_STORE(16);
13012 generate_exception_end(ctx, EXCP_RI);
13028 #undef DECR_AND_STORE
13030 tcg_gen_movi_tl(t2, -framesize);
13031 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13037 static void gen_mips16_restore (DisasContext *ctx,
13038 int xsregs, int aregs,
13039 int do_ra, int do_s0, int do_s1,
13043 TCGv t0 = tcg_temp_new();
13044 TCGv t1 = tcg_temp_new();
13045 TCGv t2 = tcg_temp_new();
13047 tcg_gen_movi_tl(t2, framesize);
13048 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13050 #define DECR_AND_LOAD(reg) do { \
13051 tcg_gen_movi_tl(t2, -4); \
13052 gen_op_addr_add(ctx, t0, t0, t2); \
13053 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13054 gen_store_gpr(t1, reg); \
13118 generate_exception_end(ctx, EXCP_RI);
13134 #undef DECR_AND_LOAD
13136 tcg_gen_movi_tl(t2, framesize);
13137 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13143 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13144 int is_64_bit, int extended)
13148 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13149 generate_exception_end(ctx, EXCP_RI);
13153 t0 = tcg_temp_new();
13155 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13156 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13158 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13164 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13167 TCGv_i32 t0 = tcg_const_i32(op);
13168 TCGv t1 = tcg_temp_new();
13169 gen_base_offset_addr(ctx, t1, base, offset);
13170 gen_helper_cache(cpu_env, t1, t0);
13173 #if defined(TARGET_MIPS64)
13174 static void decode_i64_mips16 (DisasContext *ctx,
13175 int ry, int funct, int16_t offset,
13180 check_insn(ctx, ISA_MIPS3);
13181 check_mips_64(ctx);
13182 offset = extended ? offset : offset << 3;
13183 gen_ld(ctx, OPC_LD, ry, 29, offset);
13186 check_insn(ctx, ISA_MIPS3);
13187 check_mips_64(ctx);
13188 offset = extended ? offset : offset << 3;
13189 gen_st(ctx, OPC_SD, ry, 29, offset);
13192 check_insn(ctx, ISA_MIPS3);
13193 check_mips_64(ctx);
13194 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13195 gen_st(ctx, OPC_SD, 31, 29, offset);
13198 check_insn(ctx, ISA_MIPS3);
13199 check_mips_64(ctx);
13200 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13201 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13204 check_insn(ctx, ISA_MIPS3);
13205 check_mips_64(ctx);
13206 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13207 generate_exception_end(ctx, EXCP_RI);
13209 offset = extended ? offset : offset << 3;
13210 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13214 check_insn(ctx, ISA_MIPS3);
13215 check_mips_64(ctx);
13216 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13217 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13220 check_insn(ctx, ISA_MIPS3);
13221 check_mips_64(ctx);
13222 offset = extended ? offset : offset << 2;
13223 gen_addiupc(ctx, ry, offset, 1, extended);
13226 check_insn(ctx, ISA_MIPS3);
13227 check_mips_64(ctx);
13228 offset = extended ? offset : offset << 2;
13229 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13235 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13237 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13238 int op, rx, ry, funct, sa;
13239 int16_t imm, offset;
13241 ctx->opcode = (ctx->opcode << 16) | extend;
13242 op = (ctx->opcode >> 11) & 0x1f;
13243 sa = (ctx->opcode >> 22) & 0x1f;
13244 funct = (ctx->opcode >> 8) & 0x7;
13245 rx = xlat((ctx->opcode >> 8) & 0x7);
13246 ry = xlat((ctx->opcode >> 5) & 0x7);
13247 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13248 | ((ctx->opcode >> 21) & 0x3f) << 5
13249 | (ctx->opcode & 0x1f));
13251 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13254 case M16_OPC_ADDIUSP:
13255 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13257 case M16_OPC_ADDIUPC:
13258 gen_addiupc(ctx, rx, imm, 0, 1);
13261 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13262 /* No delay slot, so just process as a normal instruction */
13265 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13266 /* No delay slot, so just process as a normal instruction */
13268 case M16_OPC_BNEQZ:
13269 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13270 /* No delay slot, so just process as a normal instruction */
13272 case M16_OPC_SHIFT:
13273 switch (ctx->opcode & 0x3) {
13275 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13278 #if defined(TARGET_MIPS64)
13279 check_mips_64(ctx);
13280 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13282 generate_exception_end(ctx, EXCP_RI);
13286 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13289 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13293 #if defined(TARGET_MIPS64)
13295 check_insn(ctx, ISA_MIPS3);
13296 check_mips_64(ctx);
13297 gen_ld(ctx, OPC_LD, ry, rx, offset);
13301 imm = ctx->opcode & 0xf;
13302 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13303 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13304 imm = (int16_t) (imm << 1) >> 1;
13305 if ((ctx->opcode >> 4) & 0x1) {
13306 #if defined(TARGET_MIPS64)
13307 check_mips_64(ctx);
13308 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13310 generate_exception_end(ctx, EXCP_RI);
13313 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13316 case M16_OPC_ADDIU8:
13317 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13320 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13322 case M16_OPC_SLTIU:
13323 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13328 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13331 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13334 gen_st(ctx, OPC_SW, 31, 29, imm);
13337 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13340 check_insn(ctx, ISA_MIPS32);
13342 int xsregs = (ctx->opcode >> 24) & 0x7;
13343 int aregs = (ctx->opcode >> 16) & 0xf;
13344 int do_ra = (ctx->opcode >> 6) & 0x1;
13345 int do_s0 = (ctx->opcode >> 5) & 0x1;
13346 int do_s1 = (ctx->opcode >> 4) & 0x1;
13347 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13348 | (ctx->opcode & 0xf)) << 3;
13350 if (ctx->opcode & (1 << 7)) {
13351 gen_mips16_save(ctx, xsregs, aregs,
13352 do_ra, do_s0, do_s1,
13355 gen_mips16_restore(ctx, xsregs, aregs,
13356 do_ra, do_s0, do_s1,
13362 generate_exception_end(ctx, EXCP_RI);
13367 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13370 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13372 #if defined(TARGET_MIPS64)
13374 check_insn(ctx, ISA_MIPS3);
13375 check_mips_64(ctx);
13376 gen_st(ctx, OPC_SD, ry, rx, offset);
13380 gen_ld(ctx, OPC_LB, ry, rx, offset);
13383 gen_ld(ctx, OPC_LH, ry, rx, offset);
13386 gen_ld(ctx, OPC_LW, rx, 29, offset);
13389 gen_ld(ctx, OPC_LW, ry, rx, offset);
13392 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13395 gen_ld(ctx, OPC_LHU, ry, rx, offset);
13398 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13400 #if defined(TARGET_MIPS64)
13402 check_insn(ctx, ISA_MIPS3);
13403 check_mips_64(ctx);
13404 gen_ld(ctx, OPC_LWU, ry, rx, offset);
13408 gen_st(ctx, OPC_SB, ry, rx, offset);
13411 gen_st(ctx, OPC_SH, ry, rx, offset);
13414 gen_st(ctx, OPC_SW, rx, 29, offset);
13417 gen_st(ctx, OPC_SW, ry, rx, offset);
13419 #if defined(TARGET_MIPS64)
13421 decode_i64_mips16(ctx, ry, funct, offset, 1);
13425 generate_exception_end(ctx, EXCP_RI);
13432 static inline bool is_uhi(int sdbbp_code)
13434 #ifdef CONFIG_USER_ONLY
13437 return semihosting_enabled() && sdbbp_code == 1;
13441 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13445 int op, cnvt_op, op1, offset;
13449 op = (ctx->opcode >> 11) & 0x1f;
13450 sa = (ctx->opcode >> 2) & 0x7;
13451 sa = sa == 0 ? 8 : sa;
13452 rx = xlat((ctx->opcode >> 8) & 0x7);
13453 cnvt_op = (ctx->opcode >> 5) & 0x7;
13454 ry = xlat((ctx->opcode >> 5) & 0x7);
13455 op1 = offset = ctx->opcode & 0x1f;
13460 case M16_OPC_ADDIUSP:
13462 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13464 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13467 case M16_OPC_ADDIUPC:
13468 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13471 offset = (ctx->opcode & 0x7ff) << 1;
13472 offset = (int16_t)(offset << 4) >> 4;
13473 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13474 /* No delay slot, so just process as a normal instruction */
13477 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13478 offset = (((ctx->opcode & 0x1f) << 21)
13479 | ((ctx->opcode >> 5) & 0x1f) << 16
13481 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13482 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13486 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13487 ((int8_t)ctx->opcode) << 1, 0);
13488 /* No delay slot, so just process as a normal instruction */
13490 case M16_OPC_BNEQZ:
13491 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13492 ((int8_t)ctx->opcode) << 1, 0);
13493 /* No delay slot, so just process as a normal instruction */
13495 case M16_OPC_SHIFT:
13496 switch (ctx->opcode & 0x3) {
13498 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13501 #if defined(TARGET_MIPS64)
13502 check_insn(ctx, ISA_MIPS3);
13503 check_mips_64(ctx);
13504 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13506 generate_exception_end(ctx, EXCP_RI);
13510 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13513 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13517 #if defined(TARGET_MIPS64)
13519 check_insn(ctx, ISA_MIPS3);
13520 check_mips_64(ctx);
13521 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13526 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13528 if ((ctx->opcode >> 4) & 1) {
13529 #if defined(TARGET_MIPS64)
13530 check_insn(ctx, ISA_MIPS3);
13531 check_mips_64(ctx);
13532 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13534 generate_exception_end(ctx, EXCP_RI);
13537 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13541 case M16_OPC_ADDIU8:
13543 int16_t imm = (int8_t) ctx->opcode;
13545 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13550 int16_t imm = (uint8_t) ctx->opcode;
13551 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13554 case M16_OPC_SLTIU:
13556 int16_t imm = (uint8_t) ctx->opcode;
13557 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13564 funct = (ctx->opcode >> 8) & 0x7;
13567 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13568 ((int8_t)ctx->opcode) << 1, 0);
13571 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13572 ((int8_t)ctx->opcode) << 1, 0);
13575 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13578 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13579 ((int8_t)ctx->opcode) << 3);
13582 check_insn(ctx, ISA_MIPS32);
13584 int do_ra = ctx->opcode & (1 << 6);
13585 int do_s0 = ctx->opcode & (1 << 5);
13586 int do_s1 = ctx->opcode & (1 << 4);
13587 int framesize = ctx->opcode & 0xf;
13589 if (framesize == 0) {
13592 framesize = framesize << 3;
13595 if (ctx->opcode & (1 << 7)) {
13596 gen_mips16_save(ctx, 0, 0,
13597 do_ra, do_s0, do_s1, framesize);
13599 gen_mips16_restore(ctx, 0, 0,
13600 do_ra, do_s0, do_s1, framesize);
13606 int rz = xlat(ctx->opcode & 0x7);
13608 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13609 ((ctx->opcode >> 5) & 0x7);
13610 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13614 reg32 = ctx->opcode & 0x1f;
13615 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13618 generate_exception_end(ctx, EXCP_RI);
13625 int16_t imm = (uint8_t) ctx->opcode;
13627 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13632 int16_t imm = (uint8_t) ctx->opcode;
13633 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13636 #if defined(TARGET_MIPS64)
13638 check_insn(ctx, ISA_MIPS3);
13639 check_mips_64(ctx);
13640 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13644 gen_ld(ctx, OPC_LB, ry, rx, offset);
13647 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13650 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13653 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13656 gen_ld(ctx, OPC_LBU, ry, rx, offset);
13659 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13662 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13664 #if defined (TARGET_MIPS64)
13666 check_insn(ctx, ISA_MIPS3);
13667 check_mips_64(ctx);
13668 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13672 gen_st(ctx, OPC_SB, ry, rx, offset);
13675 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13678 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13681 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13685 int rz = xlat((ctx->opcode >> 2) & 0x7);
13688 switch (ctx->opcode & 0x3) {
13690 mips32_op = OPC_ADDU;
13693 mips32_op = OPC_SUBU;
13695 #if defined(TARGET_MIPS64)
13697 mips32_op = OPC_DADDU;
13698 check_insn(ctx, ISA_MIPS3);
13699 check_mips_64(ctx);
13702 mips32_op = OPC_DSUBU;
13703 check_insn(ctx, ISA_MIPS3);
13704 check_mips_64(ctx);
13708 generate_exception_end(ctx, EXCP_RI);
13712 gen_arith(ctx, mips32_op, rz, rx, ry);
13721 int nd = (ctx->opcode >> 7) & 0x1;
13722 int link = (ctx->opcode >> 6) & 0x1;
13723 int ra = (ctx->opcode >> 5) & 0x1;
13726 check_insn(ctx, ISA_MIPS32);
13735 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13740 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13741 gen_helper_do_semihosting(cpu_env);
13743 /* XXX: not clear which exception should be raised
13744 * when in debug mode...
13746 check_insn(ctx, ISA_MIPS32);
13747 generate_exception_end(ctx, EXCP_DBp);
13751 gen_slt(ctx, OPC_SLT, 24, rx, ry);
13754 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13757 generate_exception_end(ctx, EXCP_BREAK);
13760 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13763 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13766 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13768 #if defined (TARGET_MIPS64)
13770 check_insn(ctx, ISA_MIPS3);
13771 check_mips_64(ctx);
13772 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13776 gen_logic(ctx, OPC_XOR, 24, rx, ry);
13779 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13782 gen_logic(ctx, OPC_AND, rx, rx, ry);
13785 gen_logic(ctx, OPC_OR, rx, rx, ry);
13788 gen_logic(ctx, OPC_XOR, rx, rx, ry);
13791 gen_logic(ctx, OPC_NOR, rx, ry, 0);
13794 gen_HILO(ctx, OPC_MFHI, 0, rx);
13797 check_insn(ctx, ISA_MIPS32);
13799 case RR_RY_CNVT_ZEB:
13800 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13802 case RR_RY_CNVT_ZEH:
13803 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13805 case RR_RY_CNVT_SEB:
13806 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13808 case RR_RY_CNVT_SEH:
13809 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13811 #if defined (TARGET_MIPS64)
13812 case RR_RY_CNVT_ZEW:
13813 check_insn(ctx, ISA_MIPS64);
13814 check_mips_64(ctx);
13815 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13817 case RR_RY_CNVT_SEW:
13818 check_insn(ctx, ISA_MIPS64);
13819 check_mips_64(ctx);
13820 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13824 generate_exception_end(ctx, EXCP_RI);
13829 gen_HILO(ctx, OPC_MFLO, 0, rx);
13831 #if defined (TARGET_MIPS64)
13833 check_insn(ctx, ISA_MIPS3);
13834 check_mips_64(ctx);
13835 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13838 check_insn(ctx, ISA_MIPS3);
13839 check_mips_64(ctx);
13840 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
13843 check_insn(ctx, ISA_MIPS3);
13844 check_mips_64(ctx);
13845 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
13848 check_insn(ctx, ISA_MIPS3);
13849 check_mips_64(ctx);
13850 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
13854 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
13857 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
13860 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
13863 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
13865 #if defined (TARGET_MIPS64)
13867 check_insn(ctx, ISA_MIPS3);
13868 check_mips_64(ctx);
13869 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
13872 check_insn(ctx, ISA_MIPS3);
13873 check_mips_64(ctx);
13874 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
13877 check_insn(ctx, ISA_MIPS3);
13878 check_mips_64(ctx);
13879 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
13882 check_insn(ctx, ISA_MIPS3);
13883 check_mips_64(ctx);
13884 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
13888 generate_exception_end(ctx, EXCP_RI);
13892 case M16_OPC_EXTEND:
13893 decode_extended_mips16_opc(env, ctx);
13896 #if defined(TARGET_MIPS64)
13898 funct = (ctx->opcode >> 8) & 0x7;
13899 decode_i64_mips16(ctx, ry, funct, offset, 0);
13903 generate_exception_end(ctx, EXCP_RI);
13910 /* microMIPS extension to MIPS32/MIPS64 */
13913 * microMIPS32/microMIPS64 major opcodes
13915 * 1. MIPS Architecture for Programmers Volume II-B:
13916 * The microMIPS32 Instruction Set (Revision 3.05)
13918 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13920 * 2. MIPS Architecture For Programmers Volume II-A:
13921 * The MIPS64 Instruction Set (Revision 3.51)
13951 POOL32S = 0x16, /* MIPS64 */
13952 DADDIU32 = 0x17, /* MIPS64 */
13981 /* 0x29 is reserved */
13994 /* 0x31 is reserved */
14007 SD32 = 0x36, /* MIPS64 */
14008 LD32 = 0x37, /* MIPS64 */
14010 /* 0x39 is reserved */
14026 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14048 /* POOL32A encoding of minor opcode field */
14051 /* These opcodes are distinguished only by bits 9..6; those bits are
14052 * what are recorded below. */
14089 /* The following can be distinguished by their lower 6 bits. */
14099 /* POOL32AXF encoding of minor opcode field extension */
14102 * 1. MIPS Architecture for Programmers Volume II-B:
14103 * The microMIPS32 Instruction Set (Revision 3.05)
14105 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14107 * 2. MIPS Architecture for Programmers VolumeIV-e:
14108 * The MIPS DSP Application-Specific Extension
14109 * to the microMIPS32 Architecture (Revision 2.34)
14111 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14126 /* begin of microMIPS32 DSP */
14128 /* bits 13..12 for 0x01 */
14134 /* bits 13..12 for 0x2a */
14140 /* bits 13..12 for 0x32 */
14144 /* end of microMIPS32 DSP */
14146 /* bits 15..12 for 0x2c */
14163 /* bits 15..12 for 0x34 */
14171 /* bits 15..12 for 0x3c */
14173 JR = 0x0, /* alias */
14181 /* bits 15..12 for 0x05 */
14185 /* bits 15..12 for 0x0d */
14197 /* bits 15..12 for 0x15 */
14203 /* bits 15..12 for 0x1d */
14207 /* bits 15..12 for 0x2d */
14212 /* bits 15..12 for 0x35 */
14219 /* POOL32B encoding of minor opcode field (bits 15..12) */
14235 /* POOL32C encoding of minor opcode field (bits 15..12) */
14256 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14269 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14282 /* POOL32F encoding of minor opcode field (bits 5..0) */
14285 /* These are the bit 7..6 values */
14294 /* These are the bit 8..6 values */
14319 MOVZ_FMT_05 = 0x05,
14353 CABS_COND_FMT = 0x1c, /* MIPS3D */
14360 /* POOL32Fxf encoding of minor opcode extension field */
14398 /* POOL32I encoding of minor opcode field (bits 25..21) */
14428 /* These overlap and are distinguished by bit16 of the instruction */
14437 /* POOL16A encoding of minor opcode field */
14444 /* POOL16B encoding of minor opcode field */
14451 /* POOL16C encoding of minor opcode field */
14471 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14495 /* POOL16D encoding of minor opcode field */
14502 /* POOL16E encoding of minor opcode field */
14509 static int mmreg (int r)
14511 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14516 /* Used for 16-bit store instructions. */
14517 static int mmreg2 (int r)
14519 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14524 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14525 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14526 #define uMIPS_RS2(op) uMIPS_RS(op)
14527 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14528 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14529 #define uMIPS_RS5(op) (op & 0x1f)
14531 /* Signed immediate */
14532 #define SIMM(op, start, width) \
14533 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14536 /* Zero-extended immediate */
14537 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14539 static void gen_addiur1sp(DisasContext *ctx)
14541 int rd = mmreg(uMIPS_RD(ctx->opcode));
14543 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14546 static void gen_addiur2(DisasContext *ctx)
14548 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14549 int rd = mmreg(uMIPS_RD(ctx->opcode));
14550 int rs = mmreg(uMIPS_RS(ctx->opcode));
14552 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14555 static void gen_addiusp(DisasContext *ctx)
14557 int encoded = ZIMM(ctx->opcode, 1, 9);
14560 if (encoded <= 1) {
14561 decoded = 256 + encoded;
14562 } else if (encoded <= 255) {
14564 } else if (encoded <= 509) {
14565 decoded = encoded - 512;
14567 decoded = encoded - 768;
14570 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14573 static void gen_addius5(DisasContext *ctx)
14575 int imm = SIMM(ctx->opcode, 1, 4);
14576 int rd = (ctx->opcode >> 5) & 0x1f;
14578 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14581 static void gen_andi16(DisasContext *ctx)
14583 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14584 31, 32, 63, 64, 255, 32768, 65535 };
14585 int rd = mmreg(uMIPS_RD(ctx->opcode));
14586 int rs = mmreg(uMIPS_RS(ctx->opcode));
14587 int encoded = ZIMM(ctx->opcode, 0, 4);
14589 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14592 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14593 int base, int16_t offset)
14598 if (ctx->hflags & MIPS_HFLAG_BMASK) {
14599 generate_exception_end(ctx, EXCP_RI);
14603 t0 = tcg_temp_new();
14605 gen_base_offset_addr(ctx, t0, base, offset);
14607 t1 = tcg_const_tl(reglist);
14608 t2 = tcg_const_i32(ctx->mem_idx);
14610 save_cpu_state(ctx, 1);
14613 gen_helper_lwm(cpu_env, t0, t1, t2);
14616 gen_helper_swm(cpu_env, t0, t1, t2);
14618 #ifdef TARGET_MIPS64
14620 gen_helper_ldm(cpu_env, t0, t1, t2);
14623 gen_helper_sdm(cpu_env, t0, t1, t2);
14629 tcg_temp_free_i32(t2);
14633 static void gen_pool16c_insn(DisasContext *ctx)
14635 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14636 int rs = mmreg(ctx->opcode & 0x7);
14638 switch (((ctx->opcode) >> 4) & 0x3f) {
14643 gen_logic(ctx, OPC_NOR, rd, rs, 0);
14649 gen_logic(ctx, OPC_XOR, rd, rd, rs);
14655 gen_logic(ctx, OPC_AND, rd, rd, rs);
14661 gen_logic(ctx, OPC_OR, rd, rd, rs);
14668 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14669 int offset = ZIMM(ctx->opcode, 0, 4);
14671 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14680 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14681 int offset = ZIMM(ctx->opcode, 0, 4);
14683 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14690 int reg = ctx->opcode & 0x1f;
14692 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14698 int reg = ctx->opcode & 0x1f;
14699 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14700 /* Let normal delay slot handling in our caller take us
14701 to the branch target. */
14706 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14707 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14711 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14712 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14716 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14720 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14723 generate_exception_end(ctx, EXCP_BREAK);
14726 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14727 gen_helper_do_semihosting(cpu_env);
14729 /* XXX: not clear which exception should be raised
14730 * when in debug mode...
14732 check_insn(ctx, ISA_MIPS32);
14733 generate_exception_end(ctx, EXCP_DBp);
14736 case JRADDIUSP + 0:
14737 case JRADDIUSP + 1:
14739 int imm = ZIMM(ctx->opcode, 0, 5);
14740 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14741 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14742 /* Let normal delay slot handling in our caller take us
14743 to the branch target. */
14747 generate_exception_end(ctx, EXCP_RI);
14752 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14755 int rd, rs, re, rt;
14756 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14757 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14758 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14759 rd = rd_enc[enc_dest];
14760 re = re_enc[enc_dest];
14761 rs = rs_rt_enc[enc_rs];
14762 rt = rs_rt_enc[enc_rt];
14764 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14766 tcg_gen_movi_tl(cpu_gpr[rd], 0);
14769 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14771 tcg_gen_movi_tl(cpu_gpr[re], 0);
14775 static void gen_pool16c_r6_insn(DisasContext *ctx)
14777 int rt = mmreg((ctx->opcode >> 7) & 0x7);
14778 int rs = mmreg((ctx->opcode >> 4) & 0x7);
14780 switch (ctx->opcode & 0xf) {
14782 gen_logic(ctx, OPC_NOR, rt, rs, 0);
14785 gen_logic(ctx, OPC_AND, rt, rt, rs);
14789 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14790 int offset = extract32(ctx->opcode, 4, 4);
14791 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14794 case R6_JRC16: /* JRCADDIUSP */
14795 if ((ctx->opcode >> 4) & 1) {
14797 int imm = extract32(ctx->opcode, 5, 5);
14798 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14799 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14802 rs = extract32(ctx->opcode, 5, 5);
14803 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14815 int enc_dest = uMIPS_RD(ctx->opcode);
14816 int enc_rt = uMIPS_RS2(ctx->opcode);
14817 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14818 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14822 gen_logic(ctx, OPC_XOR, rt, rt, rs);
14825 gen_logic(ctx, OPC_OR, rt, rt, rs);
14829 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14830 int offset = extract32(ctx->opcode, 4, 4);
14831 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14834 case JALRC16: /* BREAK16, SDBBP16 */
14835 switch (ctx->opcode & 0x3f) {
14837 case JALRC16 + 0x20:
14839 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14844 generate_exception(ctx, EXCP_BREAK);
14848 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14849 gen_helper_do_semihosting(cpu_env);
14851 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14852 generate_exception(ctx, EXCP_RI);
14854 generate_exception(ctx, EXCP_DBp);
14861 generate_exception(ctx, EXCP_RI);
14866 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14868 TCGv t0 = tcg_temp_new();
14869 TCGv t1 = tcg_temp_new();
14871 gen_load_gpr(t0, base);
14874 gen_load_gpr(t1, index);
14875 tcg_gen_shli_tl(t1, t1, 2);
14876 gen_op_addr_add(ctx, t0, t1, t0);
14879 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14880 gen_store_gpr(t1, rd);
14886 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14887 int base, int16_t offset)
14891 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
14892 generate_exception_end(ctx, EXCP_RI);
14896 t0 = tcg_temp_new();
14897 t1 = tcg_temp_new();
14899 gen_base_offset_addr(ctx, t0, base, offset);
14904 generate_exception_end(ctx, EXCP_RI);
14907 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14908 gen_store_gpr(t1, rd);
14909 tcg_gen_movi_tl(t1, 4);
14910 gen_op_addr_add(ctx, t0, t0, t1);
14911 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14912 gen_store_gpr(t1, rd+1);
14915 gen_load_gpr(t1, rd);
14916 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14917 tcg_gen_movi_tl(t1, 4);
14918 gen_op_addr_add(ctx, t0, t0, t1);
14919 gen_load_gpr(t1, rd+1);
14920 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14922 #ifdef TARGET_MIPS64
14925 generate_exception_end(ctx, EXCP_RI);
14928 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14929 gen_store_gpr(t1, rd);
14930 tcg_gen_movi_tl(t1, 8);
14931 gen_op_addr_add(ctx, t0, t0, t1);
14932 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14933 gen_store_gpr(t1, rd+1);
14936 gen_load_gpr(t1, rd);
14937 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14938 tcg_gen_movi_tl(t1, 8);
14939 gen_op_addr_add(ctx, t0, t0, t1);
14940 gen_load_gpr(t1, rd+1);
14941 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14949 static void gen_sync(int stype)
14951 TCGBar tcg_mo = TCG_BAR_SC;
14954 case 0x4: /* SYNC_WMB */
14955 tcg_mo |= TCG_MO_ST_ST;
14957 case 0x10: /* SYNC_MB */
14958 tcg_mo |= TCG_MO_ALL;
14960 case 0x11: /* SYNC_ACQUIRE */
14961 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14963 case 0x12: /* SYNC_RELEASE */
14964 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14966 case 0x13: /* SYNC_RMB */
14967 tcg_mo |= TCG_MO_LD_LD;
14970 tcg_mo |= TCG_MO_ALL;
14974 tcg_gen_mb(tcg_mo);
14977 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
14979 int extension = (ctx->opcode >> 6) & 0x3f;
14980 int minor = (ctx->opcode >> 12) & 0xf;
14981 uint32_t mips32_op;
14983 switch (extension) {
14985 mips32_op = OPC_TEQ;
14988 mips32_op = OPC_TGE;
14991 mips32_op = OPC_TGEU;
14994 mips32_op = OPC_TLT;
14997 mips32_op = OPC_TLTU;
15000 mips32_op = OPC_TNE;
15002 gen_trap(ctx, mips32_op, rs, rt, -1);
15004 #ifndef CONFIG_USER_ONLY
15007 check_cp0_enabled(ctx);
15009 /* Treat as NOP. */
15012 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15016 check_cp0_enabled(ctx);
15018 TCGv t0 = tcg_temp_new();
15020 gen_load_gpr(t0, rt);
15021 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15027 switch (minor & 3) {
15029 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15032 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15035 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15038 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15041 goto pool32axf_invalid;
15045 switch (minor & 3) {
15047 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15050 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15053 goto pool32axf_invalid;
15059 check_insn(ctx, ISA_MIPS32R6);
15060 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15063 gen_bshfl(ctx, OPC_SEB, rs, rt);
15066 gen_bshfl(ctx, OPC_SEH, rs, rt);
15069 mips32_op = OPC_CLO;
15072 mips32_op = OPC_CLZ;
15074 check_insn(ctx, ISA_MIPS32);
15075 gen_cl(ctx, mips32_op, rt, rs);
15078 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15079 gen_rdhwr(ctx, rt, rs, 0);
15082 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15085 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15086 mips32_op = OPC_MULT;
15089 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15090 mips32_op = OPC_MULTU;
15093 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15094 mips32_op = OPC_DIV;
15097 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15098 mips32_op = OPC_DIVU;
15101 check_insn(ctx, ISA_MIPS32);
15102 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15105 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15106 mips32_op = OPC_MADD;
15109 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15110 mips32_op = OPC_MADDU;
15113 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15114 mips32_op = OPC_MSUB;
15117 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15118 mips32_op = OPC_MSUBU;
15120 check_insn(ctx, ISA_MIPS32);
15121 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15124 goto pool32axf_invalid;
15135 generate_exception_err(ctx, EXCP_CpU, 2);
15138 goto pool32axf_invalid;
15143 case JALR: /* JALRC */
15144 case JALR_HB: /* JALRC_HB */
15145 if (ctx->insn_flags & ISA_MIPS32R6) {
15146 /* JALRC, JALRC_HB */
15147 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15149 /* JALR, JALR_HB */
15150 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15151 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15156 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15157 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15158 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15161 goto pool32axf_invalid;
15167 check_cp0_enabled(ctx);
15168 check_insn(ctx, ISA_MIPS32R2);
15169 gen_load_srsgpr(rs, rt);
15172 check_cp0_enabled(ctx);
15173 check_insn(ctx, ISA_MIPS32R2);
15174 gen_store_srsgpr(rs, rt);
15177 goto pool32axf_invalid;
15180 #ifndef CONFIG_USER_ONLY
15184 mips32_op = OPC_TLBP;
15187 mips32_op = OPC_TLBR;
15190 mips32_op = OPC_TLBWI;
15193 mips32_op = OPC_TLBWR;
15196 mips32_op = OPC_TLBINV;
15199 mips32_op = OPC_TLBINVF;
15202 mips32_op = OPC_WAIT;
15205 mips32_op = OPC_DERET;
15208 mips32_op = OPC_ERET;
15210 gen_cp0(env, ctx, mips32_op, rt, rs);
15213 goto pool32axf_invalid;
15219 check_cp0_enabled(ctx);
15221 TCGv t0 = tcg_temp_new();
15223 save_cpu_state(ctx, 1);
15224 gen_helper_di(t0, cpu_env);
15225 gen_store_gpr(t0, rs);
15226 /* Stop translation as we may have switched the execution mode */
15227 ctx->base.is_jmp = DISAS_STOP;
15232 check_cp0_enabled(ctx);
15234 TCGv t0 = tcg_temp_new();
15236 save_cpu_state(ctx, 1);
15237 gen_helper_ei(t0, cpu_env);
15238 gen_store_gpr(t0, rs);
15239 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15240 of translated code to check for pending interrupts. */
15241 gen_save_pc(ctx->base.pc_next + 4);
15242 ctx->base.is_jmp = DISAS_EXIT;
15247 goto pool32axf_invalid;
15254 gen_sync(extract32(ctx->opcode, 16, 5));
15257 generate_exception_end(ctx, EXCP_SYSCALL);
15260 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15261 gen_helper_do_semihosting(cpu_env);
15263 check_insn(ctx, ISA_MIPS32);
15264 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15265 generate_exception_end(ctx, EXCP_RI);
15267 generate_exception_end(ctx, EXCP_DBp);
15272 goto pool32axf_invalid;
15276 switch (minor & 3) {
15278 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15281 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15284 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15287 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15290 goto pool32axf_invalid;
15294 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15297 gen_HILO(ctx, OPC_MFHI, 0, rs);
15300 gen_HILO(ctx, OPC_MFLO, 0, rs);
15303 gen_HILO(ctx, OPC_MTHI, 0, rs);
15306 gen_HILO(ctx, OPC_MTLO, 0, rs);
15309 goto pool32axf_invalid;
15314 MIPS_INVAL("pool32axf");
15315 generate_exception_end(ctx, EXCP_RI);
15320 /* Values for microMIPS fmt field. Variable-width, depending on which
15321 formats the instruction supports. */
15340 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15342 int extension = (ctx->opcode >> 6) & 0x3ff;
15343 uint32_t mips32_op;
15345 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15346 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15347 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15349 switch (extension) {
15350 case FLOAT_1BIT_FMT(CFC1, 0):
15351 mips32_op = OPC_CFC1;
15353 case FLOAT_1BIT_FMT(CTC1, 0):
15354 mips32_op = OPC_CTC1;
15356 case FLOAT_1BIT_FMT(MFC1, 0):
15357 mips32_op = OPC_MFC1;
15359 case FLOAT_1BIT_FMT(MTC1, 0):
15360 mips32_op = OPC_MTC1;
15362 case FLOAT_1BIT_FMT(MFHC1, 0):
15363 mips32_op = OPC_MFHC1;
15365 case FLOAT_1BIT_FMT(MTHC1, 0):
15366 mips32_op = OPC_MTHC1;
15368 gen_cp1(ctx, mips32_op, rt, rs);
15371 /* Reciprocal square root */
15372 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15373 mips32_op = OPC_RSQRT_S;
15375 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15376 mips32_op = OPC_RSQRT_D;
15380 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15381 mips32_op = OPC_SQRT_S;
15383 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15384 mips32_op = OPC_SQRT_D;
15388 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15389 mips32_op = OPC_RECIP_S;
15391 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15392 mips32_op = OPC_RECIP_D;
15396 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15397 mips32_op = OPC_FLOOR_L_S;
15399 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15400 mips32_op = OPC_FLOOR_L_D;
15402 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15403 mips32_op = OPC_FLOOR_W_S;
15405 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15406 mips32_op = OPC_FLOOR_W_D;
15410 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15411 mips32_op = OPC_CEIL_L_S;
15413 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15414 mips32_op = OPC_CEIL_L_D;
15416 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15417 mips32_op = OPC_CEIL_W_S;
15419 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15420 mips32_op = OPC_CEIL_W_D;
15424 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15425 mips32_op = OPC_TRUNC_L_S;
15427 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15428 mips32_op = OPC_TRUNC_L_D;
15430 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15431 mips32_op = OPC_TRUNC_W_S;
15433 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15434 mips32_op = OPC_TRUNC_W_D;
15438 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15439 mips32_op = OPC_ROUND_L_S;
15441 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15442 mips32_op = OPC_ROUND_L_D;
15444 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15445 mips32_op = OPC_ROUND_W_S;
15447 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15448 mips32_op = OPC_ROUND_W_D;
15451 /* Integer to floating-point conversion */
15452 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15453 mips32_op = OPC_CVT_L_S;
15455 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15456 mips32_op = OPC_CVT_L_D;
15458 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15459 mips32_op = OPC_CVT_W_S;
15461 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15462 mips32_op = OPC_CVT_W_D;
15465 /* Paired-foo conversions */
15466 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15467 mips32_op = OPC_CVT_S_PL;
15469 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15470 mips32_op = OPC_CVT_S_PU;
15472 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15473 mips32_op = OPC_CVT_PW_PS;
15475 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15476 mips32_op = OPC_CVT_PS_PW;
15479 /* Floating-point moves */
15480 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15481 mips32_op = OPC_MOV_S;
15483 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15484 mips32_op = OPC_MOV_D;
15486 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15487 mips32_op = OPC_MOV_PS;
15490 /* Absolute value */
15491 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15492 mips32_op = OPC_ABS_S;
15494 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15495 mips32_op = OPC_ABS_D;
15497 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15498 mips32_op = OPC_ABS_PS;
15502 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15503 mips32_op = OPC_NEG_S;
15505 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15506 mips32_op = OPC_NEG_D;
15508 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15509 mips32_op = OPC_NEG_PS;
15512 /* Reciprocal square root step */
15513 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15514 mips32_op = OPC_RSQRT1_S;
15516 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15517 mips32_op = OPC_RSQRT1_D;
15519 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15520 mips32_op = OPC_RSQRT1_PS;
15523 /* Reciprocal step */
15524 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15525 mips32_op = OPC_RECIP1_S;
15527 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15528 mips32_op = OPC_RECIP1_S;
15530 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15531 mips32_op = OPC_RECIP1_PS;
15534 /* Conversions from double */
15535 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15536 mips32_op = OPC_CVT_D_S;
15538 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15539 mips32_op = OPC_CVT_D_W;
15541 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15542 mips32_op = OPC_CVT_D_L;
15545 /* Conversions from single */
15546 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15547 mips32_op = OPC_CVT_S_D;
15549 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15550 mips32_op = OPC_CVT_S_W;
15552 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15553 mips32_op = OPC_CVT_S_L;
15555 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15558 /* Conditional moves on floating-point codes */
15559 case COND_FLOAT_MOV(MOVT, 0):
15560 case COND_FLOAT_MOV(MOVT, 1):
15561 case COND_FLOAT_MOV(MOVT, 2):
15562 case COND_FLOAT_MOV(MOVT, 3):
15563 case COND_FLOAT_MOV(MOVT, 4):
15564 case COND_FLOAT_MOV(MOVT, 5):
15565 case COND_FLOAT_MOV(MOVT, 6):
15566 case COND_FLOAT_MOV(MOVT, 7):
15567 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15568 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15570 case COND_FLOAT_MOV(MOVF, 0):
15571 case COND_FLOAT_MOV(MOVF, 1):
15572 case COND_FLOAT_MOV(MOVF, 2):
15573 case COND_FLOAT_MOV(MOVF, 3):
15574 case COND_FLOAT_MOV(MOVF, 4):
15575 case COND_FLOAT_MOV(MOVF, 5):
15576 case COND_FLOAT_MOV(MOVF, 6):
15577 case COND_FLOAT_MOV(MOVF, 7):
15578 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15579 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15582 MIPS_INVAL("pool32fxf");
15583 generate_exception_end(ctx, EXCP_RI);
15588 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15592 int rt, rs, rd, rr;
15594 uint32_t op, minor, minor2, mips32_op;
15595 uint32_t cond, fmt, cc;
15597 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15598 ctx->opcode = (ctx->opcode << 16) | insn;
15600 rt = (ctx->opcode >> 21) & 0x1f;
15601 rs = (ctx->opcode >> 16) & 0x1f;
15602 rd = (ctx->opcode >> 11) & 0x1f;
15603 rr = (ctx->opcode >> 6) & 0x1f;
15604 imm = (int16_t) ctx->opcode;
15606 op = (ctx->opcode >> 26) & 0x3f;
15609 minor = ctx->opcode & 0x3f;
15612 minor = (ctx->opcode >> 6) & 0xf;
15615 mips32_op = OPC_SLL;
15618 mips32_op = OPC_SRA;
15621 mips32_op = OPC_SRL;
15624 mips32_op = OPC_ROTR;
15626 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15629 check_insn(ctx, ISA_MIPS32R6);
15630 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15633 check_insn(ctx, ISA_MIPS32R6);
15634 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15637 check_insn(ctx, ISA_MIPS32R6);
15638 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15641 goto pool32a_invalid;
15645 minor = (ctx->opcode >> 6) & 0xf;
15649 mips32_op = OPC_ADD;
15652 mips32_op = OPC_ADDU;
15655 mips32_op = OPC_SUB;
15658 mips32_op = OPC_SUBU;
15661 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15662 mips32_op = OPC_MUL;
15664 gen_arith(ctx, mips32_op, rd, rs, rt);
15668 mips32_op = OPC_SLLV;
15671 mips32_op = OPC_SRLV;
15674 mips32_op = OPC_SRAV;
15677 mips32_op = OPC_ROTRV;
15679 gen_shift(ctx, mips32_op, rd, rs, rt);
15681 /* Logical operations */
15683 mips32_op = OPC_AND;
15686 mips32_op = OPC_OR;
15689 mips32_op = OPC_NOR;
15692 mips32_op = OPC_XOR;
15694 gen_logic(ctx, mips32_op, rd, rs, rt);
15696 /* Set less than */
15698 mips32_op = OPC_SLT;
15701 mips32_op = OPC_SLTU;
15703 gen_slt(ctx, mips32_op, rd, rs, rt);
15706 goto pool32a_invalid;
15710 minor = (ctx->opcode >> 6) & 0xf;
15712 /* Conditional moves */
15713 case MOVN: /* MUL */
15714 if (ctx->insn_flags & ISA_MIPS32R6) {
15716 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15719 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15722 case MOVZ: /* MUH */
15723 if (ctx->insn_flags & ISA_MIPS32R6) {
15725 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15728 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15732 check_insn(ctx, ISA_MIPS32R6);
15733 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15736 check_insn(ctx, ISA_MIPS32R6);
15737 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15739 case LWXS: /* DIV */
15740 if (ctx->insn_flags & ISA_MIPS32R6) {
15742 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15745 gen_ldxs(ctx, rs, rt, rd);
15749 check_insn(ctx, ISA_MIPS32R6);
15750 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15753 check_insn(ctx, ISA_MIPS32R6);
15754 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15757 check_insn(ctx, ISA_MIPS32R6);
15758 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15761 goto pool32a_invalid;
15765 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15768 check_insn(ctx, ISA_MIPS32R6);
15769 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15770 extract32(ctx->opcode, 9, 2));
15773 check_insn(ctx, ISA_MIPS32R6);
15774 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15777 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15780 gen_pool32axf(env, ctx, rt, rs);
15783 generate_exception_end(ctx, EXCP_BREAK);
15786 check_insn(ctx, ISA_MIPS32R6);
15787 generate_exception_end(ctx, EXCP_RI);
15791 MIPS_INVAL("pool32a");
15792 generate_exception_end(ctx, EXCP_RI);
15797 minor = (ctx->opcode >> 12) & 0xf;
15800 check_cp0_enabled(ctx);
15801 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15802 gen_cache_operation(ctx, rt, rs, imm);
15807 /* COP2: Not implemented. */
15808 generate_exception_err(ctx, EXCP_CpU, 2);
15810 #ifdef TARGET_MIPS64
15813 check_insn(ctx, ISA_MIPS3);
15814 check_mips_64(ctx);
15819 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15821 #ifdef TARGET_MIPS64
15824 check_insn(ctx, ISA_MIPS3);
15825 check_mips_64(ctx);
15830 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15833 MIPS_INVAL("pool32b");
15834 generate_exception_end(ctx, EXCP_RI);
15839 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15840 minor = ctx->opcode & 0x3f;
15841 check_cp1_enabled(ctx);
15844 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15845 mips32_op = OPC_ALNV_PS;
15848 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15849 mips32_op = OPC_MADD_S;
15852 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15853 mips32_op = OPC_MADD_D;
15856 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15857 mips32_op = OPC_MADD_PS;
15860 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15861 mips32_op = OPC_MSUB_S;
15864 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15865 mips32_op = OPC_MSUB_D;
15868 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15869 mips32_op = OPC_MSUB_PS;
15872 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15873 mips32_op = OPC_NMADD_S;
15876 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15877 mips32_op = OPC_NMADD_D;
15880 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15881 mips32_op = OPC_NMADD_PS;
15884 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15885 mips32_op = OPC_NMSUB_S;
15888 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15889 mips32_op = OPC_NMSUB_D;
15892 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15893 mips32_op = OPC_NMSUB_PS;
15895 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15897 case CABS_COND_FMT:
15898 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15899 cond = (ctx->opcode >> 6) & 0xf;
15900 cc = (ctx->opcode >> 13) & 0x7;
15901 fmt = (ctx->opcode >> 10) & 0x3;
15904 gen_cmpabs_s(ctx, cond, rt, rs, cc);
15907 gen_cmpabs_d(ctx, cond, rt, rs, cc);
15910 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15913 goto pool32f_invalid;
15917 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15918 cond = (ctx->opcode >> 6) & 0xf;
15919 cc = (ctx->opcode >> 13) & 0x7;
15920 fmt = (ctx->opcode >> 10) & 0x3;
15923 gen_cmp_s(ctx, cond, rt, rs, cc);
15926 gen_cmp_d(ctx, cond, rt, rs, cc);
15929 gen_cmp_ps(ctx, cond, rt, rs, cc);
15932 goto pool32f_invalid;
15936 check_insn(ctx, ISA_MIPS32R6);
15937 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15940 check_insn(ctx, ISA_MIPS32R6);
15941 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15944 gen_pool32fxf(ctx, rt, rs);
15948 switch ((ctx->opcode >> 6) & 0x7) {
15950 mips32_op = OPC_PLL_PS;
15953 mips32_op = OPC_PLU_PS;
15956 mips32_op = OPC_PUL_PS;
15959 mips32_op = OPC_PUU_PS;
15962 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15963 mips32_op = OPC_CVT_PS_S;
15965 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15968 goto pool32f_invalid;
15972 check_insn(ctx, ISA_MIPS32R6);
15973 switch ((ctx->opcode >> 9) & 0x3) {
15975 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15978 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15981 goto pool32f_invalid;
15986 switch ((ctx->opcode >> 6) & 0x7) {
15988 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15989 mips32_op = OPC_LWXC1;
15992 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15993 mips32_op = OPC_SWXC1;
15996 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15997 mips32_op = OPC_LDXC1;
16000 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16001 mips32_op = OPC_SDXC1;
16004 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16005 mips32_op = OPC_LUXC1;
16008 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16009 mips32_op = OPC_SUXC1;
16011 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16014 goto pool32f_invalid;
16018 check_insn(ctx, ISA_MIPS32R6);
16019 switch ((ctx->opcode >> 9) & 0x3) {
16021 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16024 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16027 goto pool32f_invalid;
16032 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16033 fmt = (ctx->opcode >> 9) & 0x3;
16034 switch ((ctx->opcode >> 6) & 0x7) {
16038 mips32_op = OPC_RSQRT2_S;
16041 mips32_op = OPC_RSQRT2_D;
16044 mips32_op = OPC_RSQRT2_PS;
16047 goto pool32f_invalid;
16053 mips32_op = OPC_RECIP2_S;
16056 mips32_op = OPC_RECIP2_D;
16059 mips32_op = OPC_RECIP2_PS;
16062 goto pool32f_invalid;
16066 mips32_op = OPC_ADDR_PS;
16069 mips32_op = OPC_MULR_PS;
16071 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16074 goto pool32f_invalid;
16078 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16079 cc = (ctx->opcode >> 13) & 0x7;
16080 fmt = (ctx->opcode >> 9) & 0x3;
16081 switch ((ctx->opcode >> 6) & 0x7) {
16082 case MOVF_FMT: /* RINT_FMT */
16083 if (ctx->insn_flags & ISA_MIPS32R6) {
16087 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16090 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16093 goto pool32f_invalid;
16099 gen_movcf_s(ctx, rs, rt, cc, 0);
16102 gen_movcf_d(ctx, rs, rt, cc, 0);
16106 gen_movcf_ps(ctx, rs, rt, cc, 0);
16109 goto pool32f_invalid;
16113 case MOVT_FMT: /* CLASS_FMT */
16114 if (ctx->insn_flags & ISA_MIPS32R6) {
16118 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16121 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16124 goto pool32f_invalid;
16130 gen_movcf_s(ctx, rs, rt, cc, 1);
16133 gen_movcf_d(ctx, rs, rt, cc, 1);
16137 gen_movcf_ps(ctx, rs, rt, cc, 1);
16140 goto pool32f_invalid;
16145 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16148 goto pool32f_invalid;
16151 #define FINSN_3ARG_SDPS(prfx) \
16152 switch ((ctx->opcode >> 8) & 0x3) { \
16154 mips32_op = OPC_##prfx##_S; \
16157 mips32_op = OPC_##prfx##_D; \
16159 case FMT_SDPS_PS: \
16161 mips32_op = OPC_##prfx##_PS; \
16164 goto pool32f_invalid; \
16167 check_insn(ctx, ISA_MIPS32R6);
16168 switch ((ctx->opcode >> 9) & 0x3) {
16170 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16173 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16176 goto pool32f_invalid;
16180 check_insn(ctx, ISA_MIPS32R6);
16181 switch ((ctx->opcode >> 9) & 0x3) {
16183 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16186 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16189 goto pool32f_invalid;
16193 /* regular FP ops */
16194 switch ((ctx->opcode >> 6) & 0x3) {
16196 FINSN_3ARG_SDPS(ADD);
16199 FINSN_3ARG_SDPS(SUB);
16202 FINSN_3ARG_SDPS(MUL);
16205 fmt = (ctx->opcode >> 8) & 0x3;
16207 mips32_op = OPC_DIV_D;
16208 } else if (fmt == 0) {
16209 mips32_op = OPC_DIV_S;
16211 goto pool32f_invalid;
16215 goto pool32f_invalid;
16220 switch ((ctx->opcode >> 6) & 0x7) {
16221 case MOVN_FMT: /* SELEQZ_FMT */
16222 if (ctx->insn_flags & ISA_MIPS32R6) {
16224 switch ((ctx->opcode >> 9) & 0x3) {
16226 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16229 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16232 goto pool32f_invalid;
16236 FINSN_3ARG_SDPS(MOVN);
16240 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16241 FINSN_3ARG_SDPS(MOVN);
16243 case MOVZ_FMT: /* SELNEZ_FMT */
16244 if (ctx->insn_flags & ISA_MIPS32R6) {
16246 switch ((ctx->opcode >> 9) & 0x3) {
16248 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16251 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16254 goto pool32f_invalid;
16258 FINSN_3ARG_SDPS(MOVZ);
16262 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16263 FINSN_3ARG_SDPS(MOVZ);
16266 check_insn(ctx, ISA_MIPS32R6);
16267 switch ((ctx->opcode >> 9) & 0x3) {
16269 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16272 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16275 goto pool32f_invalid;
16279 check_insn(ctx, ISA_MIPS32R6);
16280 switch ((ctx->opcode >> 9) & 0x3) {
16282 mips32_op = OPC_MADDF_S;
16285 mips32_op = OPC_MADDF_D;
16288 goto pool32f_invalid;
16292 check_insn(ctx, ISA_MIPS32R6);
16293 switch ((ctx->opcode >> 9) & 0x3) {
16295 mips32_op = OPC_MSUBF_S;
16298 mips32_op = OPC_MSUBF_D;
16301 goto pool32f_invalid;
16305 goto pool32f_invalid;
16309 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16313 MIPS_INVAL("pool32f");
16314 generate_exception_end(ctx, EXCP_RI);
16318 generate_exception_err(ctx, EXCP_CpU, 1);
16322 minor = (ctx->opcode >> 21) & 0x1f;
16325 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16326 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16329 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16330 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16331 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16334 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16335 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16336 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16339 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16340 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16343 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16344 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16345 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16348 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16349 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16350 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16353 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16354 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16357 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16358 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16362 case TLTI: /* BC1EQZC */
16363 if (ctx->insn_flags & ISA_MIPS32R6) {
16365 check_cp1_enabled(ctx);
16366 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16369 mips32_op = OPC_TLTI;
16373 case TGEI: /* BC1NEZC */
16374 if (ctx->insn_flags & ISA_MIPS32R6) {
16376 check_cp1_enabled(ctx);
16377 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16380 mips32_op = OPC_TGEI;
16385 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16386 mips32_op = OPC_TLTIU;
16389 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16390 mips32_op = OPC_TGEIU;
16392 case TNEI: /* SYNCI */
16393 if (ctx->insn_flags & ISA_MIPS32R6) {
16395 /* Break the TB to be able to sync copied instructions
16397 ctx->base.is_jmp = DISAS_STOP;
16400 mips32_op = OPC_TNEI;
16405 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16406 mips32_op = OPC_TEQI;
16408 gen_trap(ctx, mips32_op, rs, -1, imm);
16413 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16414 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16415 4, rs, 0, imm << 1, 0);
16416 /* Compact branches don't have a delay slot, so just let
16417 the normal delay slot handling take us to the branch
16421 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16422 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16425 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16426 /* Break the TB to be able to sync copied instructions
16428 ctx->base.is_jmp = DISAS_STOP;
16432 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16433 /* COP2: Not implemented. */
16434 generate_exception_err(ctx, EXCP_CpU, 2);
16437 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16438 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16441 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16442 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16445 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16446 mips32_op = OPC_BC1FANY4;
16449 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16450 mips32_op = OPC_BC1TANY4;
16453 check_insn(ctx, ASE_MIPS3D);
16456 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16457 check_cp1_enabled(ctx);
16458 gen_compute_branch1(ctx, mips32_op,
16459 (ctx->opcode >> 18) & 0x7, imm << 1);
16461 generate_exception_err(ctx, EXCP_CpU, 1);
16466 /* MIPS DSP: not implemented */
16469 MIPS_INVAL("pool32i");
16470 generate_exception_end(ctx, EXCP_RI);
16475 minor = (ctx->opcode >> 12) & 0xf;
16476 offset = sextract32(ctx->opcode, 0,
16477 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16480 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16481 mips32_op = OPC_LWL;
16484 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16485 mips32_op = OPC_SWL;
16488 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16489 mips32_op = OPC_LWR;
16492 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16493 mips32_op = OPC_SWR;
16495 #if defined(TARGET_MIPS64)
16497 check_insn(ctx, ISA_MIPS3);
16498 check_mips_64(ctx);
16499 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16500 mips32_op = OPC_LDL;
16503 check_insn(ctx, ISA_MIPS3);
16504 check_mips_64(ctx);
16505 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16506 mips32_op = OPC_SDL;
16509 check_insn(ctx, ISA_MIPS3);
16510 check_mips_64(ctx);
16511 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16512 mips32_op = OPC_LDR;
16515 check_insn(ctx, ISA_MIPS3);
16516 check_mips_64(ctx);
16517 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16518 mips32_op = OPC_SDR;
16521 check_insn(ctx, ISA_MIPS3);
16522 check_mips_64(ctx);
16523 mips32_op = OPC_LWU;
16526 check_insn(ctx, ISA_MIPS3);
16527 check_mips_64(ctx);
16528 mips32_op = OPC_LLD;
16532 mips32_op = OPC_LL;
16535 gen_ld(ctx, mips32_op, rt, rs, offset);
16538 gen_st(ctx, mips32_op, rt, rs, offset);
16541 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
16543 #if defined(TARGET_MIPS64)
16545 check_insn(ctx, ISA_MIPS3);
16546 check_mips_64(ctx);
16547 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
16552 MIPS_INVAL("pool32c ld-eva");
16553 generate_exception_end(ctx, EXCP_RI);
16556 check_cp0_enabled(ctx);
16558 minor2 = (ctx->opcode >> 9) & 0x7;
16559 offset = sextract32(ctx->opcode, 0, 9);
16562 mips32_op = OPC_LBUE;
16565 mips32_op = OPC_LHUE;
16568 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16569 mips32_op = OPC_LWLE;
16572 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16573 mips32_op = OPC_LWRE;
16576 mips32_op = OPC_LBE;
16579 mips32_op = OPC_LHE;
16582 mips32_op = OPC_LLE;
16585 mips32_op = OPC_LWE;
16591 MIPS_INVAL("pool32c st-eva");
16592 generate_exception_end(ctx, EXCP_RI);
16595 check_cp0_enabled(ctx);
16597 minor2 = (ctx->opcode >> 9) & 0x7;
16598 offset = sextract32(ctx->opcode, 0, 9);
16601 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16602 mips32_op = OPC_SWLE;
16605 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16606 mips32_op = OPC_SWRE;
16609 /* Treat as no-op */
16610 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16611 /* hint codes 24-31 are reserved and signal RI */
16612 generate_exception(ctx, EXCP_RI);
16616 /* Treat as no-op */
16617 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16618 gen_cache_operation(ctx, rt, rs, offset);
16622 mips32_op = OPC_SBE;
16625 mips32_op = OPC_SHE;
16628 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16631 mips32_op = OPC_SWE;
16636 /* Treat as no-op */
16637 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16638 /* hint codes 24-31 are reserved and signal RI */
16639 generate_exception(ctx, EXCP_RI);
16643 MIPS_INVAL("pool32c");
16644 generate_exception_end(ctx, EXCP_RI);
16648 case ADDI32: /* AUI, LUI */
16649 if (ctx->insn_flags & ISA_MIPS32R6) {
16651 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16654 mips32_op = OPC_ADDI;
16659 mips32_op = OPC_ADDIU;
16661 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16664 /* Logical operations */
16666 mips32_op = OPC_ORI;
16669 mips32_op = OPC_XORI;
16672 mips32_op = OPC_ANDI;
16674 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16677 /* Set less than immediate */
16679 mips32_op = OPC_SLTI;
16682 mips32_op = OPC_SLTIU;
16684 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16687 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16688 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16689 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16690 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16692 case JALS32: /* BOVC, BEQC, BEQZALC */
16693 if (ctx->insn_flags & ISA_MIPS32R6) {
16696 mips32_op = OPC_BOVC;
16697 } else if (rs < rt && rs == 0) {
16699 mips32_op = OPC_BEQZALC;
16702 mips32_op = OPC_BEQC;
16704 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16707 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16708 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16709 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16712 case BEQ32: /* BC */
16713 if (ctx->insn_flags & ISA_MIPS32R6) {
16715 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16716 sextract32(ctx->opcode << 1, 0, 27));
16719 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16722 case BNE32: /* BALC */
16723 if (ctx->insn_flags & ISA_MIPS32R6) {
16725 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16726 sextract32(ctx->opcode << 1, 0, 27));
16729 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16732 case J32: /* BGTZC, BLTZC, BLTC */
16733 if (ctx->insn_flags & ISA_MIPS32R6) {
16734 if (rs == 0 && rt != 0) {
16736 mips32_op = OPC_BGTZC;
16737 } else if (rs != 0 && rt != 0 && rs == rt) {
16739 mips32_op = OPC_BLTZC;
16742 mips32_op = OPC_BLTC;
16744 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16747 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16748 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16751 case JAL32: /* BLEZC, BGEZC, BGEC */
16752 if (ctx->insn_flags & ISA_MIPS32R6) {
16753 if (rs == 0 && rt != 0) {
16755 mips32_op = OPC_BLEZC;
16756 } else if (rs != 0 && rt != 0 && rs == rt) {
16758 mips32_op = OPC_BGEZC;
16761 mips32_op = OPC_BGEC;
16763 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16766 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16767 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16768 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16771 /* Floating point (COP1) */
16773 mips32_op = OPC_LWC1;
16776 mips32_op = OPC_LDC1;
16779 mips32_op = OPC_SWC1;
16782 mips32_op = OPC_SDC1;
16784 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16786 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16787 if (ctx->insn_flags & ISA_MIPS32R6) {
16788 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16789 switch ((ctx->opcode >> 16) & 0x1f) {
16798 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16801 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16804 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16814 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16817 generate_exception(ctx, EXCP_RI);
16822 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16823 offset = SIMM(ctx->opcode, 0, 23) << 2;
16825 gen_addiupc(ctx, reg, offset, 0, 0);
16828 case BNVC: /* BNEC, BNEZALC */
16829 check_insn(ctx, ISA_MIPS32R6);
16832 mips32_op = OPC_BNVC;
16833 } else if (rs < rt && rs == 0) {
16835 mips32_op = OPC_BNEZALC;
16838 mips32_op = OPC_BNEC;
16840 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16842 case R6_BNEZC: /* JIALC */
16843 check_insn(ctx, ISA_MIPS32R6);
16846 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16847 sextract32(ctx->opcode << 1, 0, 22));
16850 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16853 case R6_BEQZC: /* JIC */
16854 check_insn(ctx, ISA_MIPS32R6);
16857 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16858 sextract32(ctx->opcode << 1, 0, 22));
16861 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16864 case BLEZALC: /* BGEZALC, BGEUC */
16865 check_insn(ctx, ISA_MIPS32R6);
16866 if (rs == 0 && rt != 0) {
16868 mips32_op = OPC_BLEZALC;
16869 } else if (rs != 0 && rt != 0 && rs == rt) {
16871 mips32_op = OPC_BGEZALC;
16874 mips32_op = OPC_BGEUC;
16876 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16878 case BGTZALC: /* BLTZALC, BLTUC */
16879 check_insn(ctx, ISA_MIPS32R6);
16880 if (rs == 0 && rt != 0) {
16882 mips32_op = OPC_BGTZALC;
16883 } else if (rs != 0 && rt != 0 && rs == rt) {
16885 mips32_op = OPC_BLTZALC;
16888 mips32_op = OPC_BLTUC;
16890 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16892 /* Loads and stores */
16894 mips32_op = OPC_LB;
16897 mips32_op = OPC_LBU;
16900 mips32_op = OPC_LH;
16903 mips32_op = OPC_LHU;
16906 mips32_op = OPC_LW;
16908 #ifdef TARGET_MIPS64
16910 check_insn(ctx, ISA_MIPS3);
16911 check_mips_64(ctx);
16912 mips32_op = OPC_LD;
16915 check_insn(ctx, ISA_MIPS3);
16916 check_mips_64(ctx);
16917 mips32_op = OPC_SD;
16921 mips32_op = OPC_SB;
16924 mips32_op = OPC_SH;
16927 mips32_op = OPC_SW;
16930 gen_ld(ctx, mips32_op, rt, rs, imm);
16933 gen_st(ctx, mips32_op, rt, rs, imm);
16936 generate_exception_end(ctx, EXCP_RI);
16941 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
16945 /* make sure instructions are on a halfword boundary */
16946 if (ctx->base.pc_next & 0x1) {
16947 env->CP0_BadVAddr = ctx->base.pc_next;
16948 generate_exception_end(ctx, EXCP_AdEL);
16952 op = (ctx->opcode >> 10) & 0x3f;
16953 /* Enforce properly-sized instructions in a delay slot */
16954 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16955 switch (op & 0x7) { /* MSB-3..MSB-5 */
16957 /* POOL32A, POOL32B, POOL32I, POOL32C */
16959 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16961 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16963 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16965 /* LB32, LH32, LWC132, LDC132, LW32 */
16966 if (ctx->hflags & MIPS_HFLAG_BDS16) {
16967 generate_exception_end(ctx, EXCP_RI);
16972 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16974 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16976 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16977 if (ctx->hflags & MIPS_HFLAG_BDS32) {
16978 generate_exception_end(ctx, EXCP_RI);
16988 int rd = mmreg(uMIPS_RD(ctx->opcode));
16989 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16990 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16993 switch (ctx->opcode & 0x1) {
17001 if (ctx->insn_flags & ISA_MIPS32R6) {
17002 /* In the Release 6 the register number location in
17003 * the instruction encoding has changed.
17005 gen_arith(ctx, opc, rs1, rd, rs2);
17007 gen_arith(ctx, opc, rd, rs1, rs2);
17013 int rd = mmreg(uMIPS_RD(ctx->opcode));
17014 int rs = mmreg(uMIPS_RS(ctx->opcode));
17015 int amount = (ctx->opcode >> 1) & 0x7;
17017 amount = amount == 0 ? 8 : amount;
17019 switch (ctx->opcode & 0x1) {
17028 gen_shift_imm(ctx, opc, rd, rs, amount);
17032 if (ctx->insn_flags & ISA_MIPS32R6) {
17033 gen_pool16c_r6_insn(ctx);
17035 gen_pool16c_insn(ctx);
17040 int rd = mmreg(uMIPS_RD(ctx->opcode));
17041 int rb = 28; /* GP */
17042 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17044 gen_ld(ctx, OPC_LW, rd, rb, offset);
17048 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17049 if (ctx->opcode & 1) {
17050 generate_exception_end(ctx, EXCP_RI);
17053 int enc_dest = uMIPS_RD(ctx->opcode);
17054 int enc_rt = uMIPS_RS2(ctx->opcode);
17055 int enc_rs = uMIPS_RS1(ctx->opcode);
17056 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17061 int rd = mmreg(uMIPS_RD(ctx->opcode));
17062 int rb = mmreg(uMIPS_RS(ctx->opcode));
17063 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17064 offset = (offset == 0xf ? -1 : offset);
17066 gen_ld(ctx, OPC_LBU, rd, rb, offset);
17071 int rd = mmreg(uMIPS_RD(ctx->opcode));
17072 int rb = mmreg(uMIPS_RS(ctx->opcode));
17073 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17075 gen_ld(ctx, OPC_LHU, rd, rb, offset);
17080 int rd = (ctx->opcode >> 5) & 0x1f;
17081 int rb = 29; /* SP */
17082 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17084 gen_ld(ctx, OPC_LW, rd, rb, offset);
17089 int rd = mmreg(uMIPS_RD(ctx->opcode));
17090 int rb = mmreg(uMIPS_RS(ctx->opcode));
17091 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17093 gen_ld(ctx, OPC_LW, rd, rb, offset);
17098 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17099 int rb = mmreg(uMIPS_RS(ctx->opcode));
17100 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17102 gen_st(ctx, OPC_SB, rd, rb, offset);
17107 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17108 int rb = mmreg(uMIPS_RS(ctx->opcode));
17109 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17111 gen_st(ctx, OPC_SH, rd, rb, offset);
17116 int rd = (ctx->opcode >> 5) & 0x1f;
17117 int rb = 29; /* SP */
17118 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17120 gen_st(ctx, OPC_SW, rd, rb, offset);
17125 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17126 int rb = mmreg(uMIPS_RS(ctx->opcode));
17127 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17129 gen_st(ctx, OPC_SW, rd, rb, offset);
17134 int rd = uMIPS_RD5(ctx->opcode);
17135 int rs = uMIPS_RS5(ctx->opcode);
17137 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17144 switch (ctx->opcode & 0x1) {
17154 switch (ctx->opcode & 0x1) {
17159 gen_addiur1sp(ctx);
17163 case B16: /* BC16 */
17164 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17165 sextract32(ctx->opcode, 0, 10) << 1,
17166 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17168 case BNEZ16: /* BNEZC16 */
17169 case BEQZ16: /* BEQZC16 */
17170 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17171 mmreg(uMIPS_RD(ctx->opcode)),
17172 0, sextract32(ctx->opcode, 0, 7) << 1,
17173 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17178 int reg = mmreg(uMIPS_RD(ctx->opcode));
17179 int imm = ZIMM(ctx->opcode, 0, 7);
17181 imm = (imm == 0x7f ? -1 : imm);
17182 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17188 generate_exception_end(ctx, EXCP_RI);
17191 decode_micromips32_opc(env, ctx);
17204 /* MAJOR, P16, and P32 pools opcodes */
17208 NM_MOVE_BALC = 0x02,
17216 NM_P16_SHIFT = 0x0c,
17234 NM_P_LS_U12 = 0x21,
17244 NM_P16_ADDU = 0x2c,
17258 NM_MOVEPREV = 0x3f,
17261 /* POOL32A instruction pool */
17263 NM_POOL32A0 = 0x00,
17264 NM_SPECIAL2 = 0x01,
17267 NM_POOL32A5 = 0x05,
17268 NM_POOL32A7 = 0x07,
17271 /* P.GP.W instruction pool */
17273 NM_ADDIUGP_W = 0x00,
17278 /* P48I instruction pool */
17282 NM_ADDIUGP48 = 0x02,
17283 NM_ADDIUPC48 = 0x03,
17288 /* P.U12 instruction pool */
17297 NM_ADDIUNEG = 0x08,
17304 /* POOL32F instruction pool */
17306 NM_POOL32F_0 = 0x00,
17307 NM_POOL32F_3 = 0x03,
17308 NM_POOL32F_5 = 0x05,
17311 /* POOL32S instruction pool */
17313 NM_POOL32S_0 = 0x00,
17314 NM_POOL32S_4 = 0x04,
17317 /* P.LUI instruction pool */
17323 /* P.GP.BH instruction pool */
17328 NM_ADDIUGP_B = 0x03,
17331 NM_P_GP_CP1 = 0x06,
17334 /* P.LS.U12 instruction pool */
17339 NM_P_PREFU12 = 0x03,
17352 /* P.LS.S9 instruction pool */
17358 NM_P_LS_UAWM = 0x05,
17361 /* P.BAL instruction pool */
17367 /* P.J instruction pool */
17370 NM_JALRC_HB = 0x01,
17371 NM_P_BALRSC = 0x08,
17374 /* P.BR1 instruction pool */
17382 /* P.BR2 instruction pool */
17389 /* P.BRI instruction pool */
17401 /* P16.SHIFT instruction pool */
17407 /* POOL16C instruction pool */
17409 NM_POOL16C_0 = 0x00,
17413 /* P16.A1 instruction pool */
17415 NM_ADDIUR1SP = 0x01,
17418 /* P16.A2 instruction pool */
17421 NM_P_ADDIURS5 = 0x01,
17424 /* P16.ADDU instruction pool */
17430 /* P16.SR instruction pool */
17433 NM_RESTORE_JRC16 = 0x01,
17436 /* P16.4X4 instruction pool */
17442 /* P16.LB instruction pool */
17449 /* P16.LH instruction pool */
17456 /* P.RI instruction pool */
17459 NM_P_SYSCALL = 0x01,
17464 /* POOL32A0 instruction pool */
17499 NM_D_E_MT_VPE = 0x56,
17507 /* CRC32 instruction pool */
17517 /* POOL32A5 instruction pool */
17519 NM_CMP_EQ_PH = 0x00,
17520 NM_CMP_LT_PH = 0x08,
17521 NM_CMP_LE_PH = 0x10,
17522 NM_CMPGU_EQ_QB = 0x18,
17523 NM_CMPGU_LT_QB = 0x20,
17524 NM_CMPGU_LE_QB = 0x28,
17525 NM_CMPGDU_EQ_QB = 0x30,
17526 NM_CMPGDU_LT_QB = 0x38,
17527 NM_CMPGDU_LE_QB = 0x40,
17528 NM_CMPU_EQ_QB = 0x48,
17529 NM_CMPU_LT_QB = 0x50,
17530 NM_CMPU_LE_QB = 0x58,
17531 NM_ADDQ_S_W = 0x60,
17532 NM_SUBQ_S_W = 0x68,
17536 NM_ADDQ_S_PH = 0x01,
17537 NM_ADDQH_R_PH = 0x09,
17538 NM_ADDQH_R_W = 0x11,
17539 NM_ADDU_S_QB = 0x19,
17540 NM_ADDU_S_PH = 0x21,
17541 NM_ADDUH_R_QB = 0x29,
17542 NM_SHRAV_R_PH = 0x31,
17543 NM_SHRAV_R_QB = 0x39,
17544 NM_SUBQ_S_PH = 0x41,
17545 NM_SUBQH_R_PH = 0x49,
17546 NM_SUBQH_R_W = 0x51,
17547 NM_SUBU_S_QB = 0x59,
17548 NM_SUBU_S_PH = 0x61,
17549 NM_SUBUH_R_QB = 0x69,
17550 NM_SHLLV_S_PH = 0x71,
17551 NM_PRECR_SRA_R_PH_W = 0x79,
17553 NM_MULEU_S_PH_QBL = 0x12,
17554 NM_MULEU_S_PH_QBR = 0x1a,
17555 NM_MULQ_RS_PH = 0x22,
17556 NM_MULQ_S_PH = 0x2a,
17557 NM_MULQ_RS_W = 0x32,
17558 NM_MULQ_S_W = 0x3a,
17561 NM_SHRAV_R_W = 0x5a,
17562 NM_SHRLV_PH = 0x62,
17563 NM_SHRLV_QB = 0x6a,
17564 NM_SHLLV_QB = 0x72,
17565 NM_SHLLV_S_W = 0x7a,
17569 NM_MULEQ_S_W_PHL = 0x04,
17570 NM_MULEQ_S_W_PHR = 0x0c,
17572 NM_MUL_S_PH = 0x05,
17573 NM_PRECR_QB_PH = 0x0d,
17574 NM_PRECRQ_QB_PH = 0x15,
17575 NM_PRECRQ_PH_W = 0x1d,
17576 NM_PRECRQ_RS_PH_W = 0x25,
17577 NM_PRECRQU_S_QB_PH = 0x2d,
17578 NM_PACKRL_PH = 0x35,
17582 NM_SHRA_R_W = 0x5e,
17583 NM_SHRA_R_PH = 0x66,
17584 NM_SHLL_S_PH = 0x76,
17585 NM_SHLL_S_W = 0x7e,
17590 /* POOL32A7 instruction pool */
17595 NM_POOL32AXF = 0x07,
17598 /* P.SR instruction pool */
17604 /* P.SHIFT instruction pool */
17612 /* P.ROTX instruction pool */
17617 /* P.INS instruction pool */
17622 /* P.EXT instruction pool */
17627 /* POOL32F_0 (fmt) instruction pool */
17632 NM_SELEQZ_S = 0x07,
17633 NM_SELEQZ_D = 0x47,
17637 NM_SELNEZ_S = 0x0f,
17638 NM_SELNEZ_D = 0x4f,
17653 /* POOL32F_3 instruction pool */
17657 NM_MINA_FMT = 0x04,
17658 NM_MAXA_FMT = 0x05,
17659 NM_POOL32FXF = 0x07,
17662 /* POOL32F_5 instruction pool */
17664 NM_CMP_CONDN_S = 0x00,
17665 NM_CMP_CONDN_D = 0x02,
17668 /* P.GP.LH instruction pool */
17674 /* P.GP.SH instruction pool */
17679 /* P.GP.CP1 instruction pool */
17687 /* P.LS.S0 instruction pool */
17704 NM_P_PREFS9 = 0x03,
17710 /* P.LS.S1 instruction pool */
17712 NM_ASET_ACLR = 0x02,
17720 /* P.LS.E0 instruction pool */
17736 /* P.PREFE instruction pool */
17742 /* P.LLE instruction pool */
17748 /* P.SCE instruction pool */
17754 /* P.LS.WM instruction pool */
17760 /* P.LS.UAWM instruction pool */
17766 /* P.BR3A instruction pool */
17772 NM_BPOSGE32C = 0x04,
17775 /* P16.RI instruction pool */
17777 NM_P16_SYSCALL = 0x01,
17782 /* POOL16C_0 instruction pool */
17784 NM_POOL16C_00 = 0x00,
17787 /* P16.JRC instruction pool */
17793 /* P.SYSCALL instruction pool */
17799 /* P.TRAP instruction pool */
17805 /* P.CMOVE instruction pool */
17811 /* POOL32Axf instruction pool */
17813 NM_POOL32AXF_1 = 0x01,
17814 NM_POOL32AXF_2 = 0x02,
17815 NM_POOL32AXF_4 = 0x04,
17816 NM_POOL32AXF_5 = 0x05,
17817 NM_POOL32AXF_7 = 0x07,
17820 /* POOL32Axf_1 instruction pool */
17822 NM_POOL32AXF_1_0 = 0x00,
17823 NM_POOL32AXF_1_1 = 0x01,
17824 NM_POOL32AXF_1_3 = 0x03,
17825 NM_POOL32AXF_1_4 = 0x04,
17826 NM_POOL32AXF_1_5 = 0x05,
17827 NM_POOL32AXF_1_7 = 0x07,
17830 /* POOL32Axf_2 instruction pool */
17832 NM_POOL32AXF_2_0_7 = 0x00,
17833 NM_POOL32AXF_2_8_15 = 0x01,
17834 NM_POOL32AXF_2_16_23 = 0x02,
17835 NM_POOL32AXF_2_24_31 = 0x03,
17838 /* POOL32Axf_7 instruction pool */
17840 NM_SHRA_R_QB = 0x0,
17845 /* POOL32Axf_1_0 instruction pool */
17853 /* POOL32Axf_1_1 instruction pool */
17859 /* POOL32Axf_1_3 instruction pool */
17867 /* POOL32Axf_1_4 instruction pool */
17873 /* POOL32Axf_1_5 instruction pool */
17875 NM_MAQ_S_W_PHR = 0x0,
17876 NM_MAQ_S_W_PHL = 0x1,
17877 NM_MAQ_SA_W_PHR = 0x2,
17878 NM_MAQ_SA_W_PHL = 0x3,
17881 /* POOL32Axf_1_7 instruction pool */
17885 NM_EXTR_RS_W = 0x2,
17889 /* POOL32Axf_2_0_7 instruction pool */
17892 NM_DPAQ_S_W_PH = 0x1,
17894 NM_DPSQ_S_W_PH = 0x3,
17901 /* POOL32Axf_2_8_15 instruction pool */
17903 NM_DPAX_W_PH = 0x0,
17904 NM_DPAQ_SA_L_W = 0x1,
17905 NM_DPSX_W_PH = 0x2,
17906 NM_DPSQ_SA_L_W = 0x3,
17909 NM_EXTRV_R_W = 0x7,
17912 /* POOL32Axf_2_16_23 instruction pool */
17914 NM_DPAU_H_QBL = 0x0,
17915 NM_DPAQX_S_W_PH = 0x1,
17916 NM_DPSU_H_QBL = 0x2,
17917 NM_DPSQX_S_W_PH = 0x3,
17920 NM_MULSA_W_PH = 0x6,
17921 NM_EXTRV_RS_W = 0x7,
17924 /* POOL32Axf_2_24_31 instruction pool */
17926 NM_DPAU_H_QBR = 0x0,
17927 NM_DPAQX_SA_W_PH = 0x1,
17928 NM_DPSU_H_QBR = 0x2,
17929 NM_DPSQX_SA_W_PH = 0x3,
17932 NM_MULSAQ_S_W_PH = 0x6,
17933 NM_EXTRV_S_H = 0x7,
17936 /* POOL32Axf_{4, 5} instruction pool */
17955 /* nanoMIPS DSP instructions */
17956 NM_ABSQ_S_QB = 0x00,
17957 NM_ABSQ_S_PH = 0x08,
17958 NM_ABSQ_S_W = 0x10,
17959 NM_PRECEQ_W_PHL = 0x28,
17960 NM_PRECEQ_W_PHR = 0x30,
17961 NM_PRECEQU_PH_QBL = 0x38,
17962 NM_PRECEQU_PH_QBR = 0x48,
17963 NM_PRECEU_PH_QBL = 0x58,
17964 NM_PRECEU_PH_QBR = 0x68,
17965 NM_PRECEQU_PH_QBLA = 0x39,
17966 NM_PRECEQU_PH_QBRA = 0x49,
17967 NM_PRECEU_PH_QBLA = 0x59,
17968 NM_PRECEU_PH_QBRA = 0x69,
17969 NM_REPLV_PH = 0x01,
17970 NM_REPLV_QB = 0x09,
17973 NM_RADDU_W_QB = 0x78,
17979 /* PP.SR instruction pool */
17983 NM_RESTORE_JRC = 0x03,
17986 /* P.SR.F instruction pool */
17989 NM_RESTOREF = 0x01,
17992 /* P16.SYSCALL instruction pool */
17994 NM_SYSCALL16 = 0x00,
17995 NM_HYPCALL16 = 0x01,
17998 /* POOL16C_00 instruction pool */
18006 /* PP.LSX and PP.LSXS instruction pool */
18044 /* ERETx instruction pool */
18050 /* POOL32FxF_{0, 1} insturction pool */
18059 NM_CVT_S_PL = 0x84,
18060 NM_CVT_S_PU = 0xa4,
18062 NM_CVT_L_S = 0x004,
18063 NM_CVT_L_D = 0x104,
18064 NM_CVT_W_S = 0x024,
18065 NM_CVT_W_D = 0x124,
18067 NM_RSQRT_S = 0x008,
18068 NM_RSQRT_D = 0x108,
18073 NM_RECIP_S = 0x048,
18074 NM_RECIP_D = 0x148,
18076 NM_FLOOR_L_S = 0x00c,
18077 NM_FLOOR_L_D = 0x10c,
18079 NM_FLOOR_W_S = 0x02c,
18080 NM_FLOOR_W_D = 0x12c,
18082 NM_CEIL_L_S = 0x04c,
18083 NM_CEIL_L_D = 0x14c,
18084 NM_CEIL_W_S = 0x06c,
18085 NM_CEIL_W_D = 0x16c,
18086 NM_TRUNC_L_S = 0x08c,
18087 NM_TRUNC_L_D = 0x18c,
18088 NM_TRUNC_W_S = 0x0ac,
18089 NM_TRUNC_W_D = 0x1ac,
18090 NM_ROUND_L_S = 0x0cc,
18091 NM_ROUND_L_D = 0x1cc,
18092 NM_ROUND_W_S = 0x0ec,
18093 NM_ROUND_W_D = 0x1ec,
18101 NM_CVT_D_S = 0x04d,
18102 NM_CVT_D_W = 0x0cd,
18103 NM_CVT_D_L = 0x14d,
18104 NM_CVT_S_D = 0x06d,
18105 NM_CVT_S_W = 0x0ed,
18106 NM_CVT_S_L = 0x16d,
18109 /* P.LL instruction pool */
18115 /* P.SC instruction pool */
18121 /* P.DVP instruction pool */
18130 * nanoMIPS decoding engine
18135 /* extraction utilities */
18137 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18138 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18139 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18140 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18141 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18142 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18144 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18145 static inline int decode_gpr_gpr3(int r)
18147 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18149 return map[r & 0x7];
18152 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18153 static inline int decode_gpr_gpr3_src_store(int r)
18155 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18157 return map[r & 0x7];
18160 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18161 static inline int decode_gpr_gpr4(int r)
18163 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18164 16, 17, 18, 19, 20, 21, 22, 23 };
18166 return map[r & 0xf];
18169 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18170 static inline int decode_gpr_gpr4_zero(int r)
18172 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18173 16, 17, 18, 19, 20, 21, 22, 23 };
18175 return map[r & 0xf];
18179 /* extraction utilities */
18181 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18182 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18183 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18184 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18185 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18186 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18189 static void gen_adjust_sp(DisasContext *ctx, int u)
18191 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18194 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18195 uint8_t gp, uint16_t u)
18198 TCGv va = tcg_temp_new();
18199 TCGv t0 = tcg_temp_new();
18201 while (counter != count) {
18202 bool use_gp = gp && (counter == count - 1);
18203 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18204 int this_offset = -((counter + 1) << 2);
18205 gen_base_offset_addr(ctx, va, 29, this_offset);
18206 gen_load_gpr(t0, this_rt);
18207 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18208 (MO_TEUL | ctx->default_tcg_memop_mask));
18212 /* adjust stack pointer */
18213 gen_adjust_sp(ctx, -u);
18219 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18220 uint8_t gp, uint16_t u)
18223 TCGv va = tcg_temp_new();
18224 TCGv t0 = tcg_temp_new();
18226 while (counter != count) {
18227 bool use_gp = gp && (counter == count - 1);
18228 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18229 int this_offset = u - ((counter + 1) << 2);
18230 gen_base_offset_addr(ctx, va, 29, this_offset);
18231 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18232 ctx->default_tcg_memop_mask);
18233 tcg_gen_ext32s_tl(t0, t0);
18234 gen_store_gpr(t0, this_rt);
18238 /* adjust stack pointer */
18239 gen_adjust_sp(ctx, u);
18245 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18247 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18248 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18250 switch (extract32(ctx->opcode, 2, 2)) {
18252 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18255 gen_logic(ctx, OPC_AND, rt, rt, rs);
18258 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18261 gen_logic(ctx, OPC_OR, rt, rt, rs);
18266 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18268 int rt = extract32(ctx->opcode, 21, 5);
18269 int rs = extract32(ctx->opcode, 16, 5);
18270 int rd = extract32(ctx->opcode, 11, 5);
18272 switch (extract32(ctx->opcode, 3, 7)) {
18274 switch (extract32(ctx->opcode, 10, 1)) {
18277 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18281 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18287 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18291 gen_bshfl(ctx, OPC_SEB, rs, rt);
18294 gen_bshfl(ctx, OPC_SEH, rs, rt);
18297 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18300 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18303 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18306 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18309 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18312 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18316 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18319 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18322 switch (extract32(ctx->opcode, 10, 1)) {
18324 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18327 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18332 gen_logic(ctx, OPC_AND, rd, rs, rt);
18335 gen_logic(ctx, OPC_OR, rd, rs, rt);
18338 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18341 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18344 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18349 #ifndef CONFIG_USER_ONLY
18350 TCGv t0 = tcg_temp_new();
18351 switch (extract32(ctx->opcode, 10, 1)) {
18354 check_cp0_enabled(ctx);
18355 gen_helper_dvp(t0, cpu_env);
18356 gen_store_gpr(t0, rt);
18361 check_cp0_enabled(ctx);
18362 gen_helper_evp(t0, cpu_env);
18363 gen_store_gpr(t0, rt);
18370 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18375 TCGv t0 = tcg_temp_new();
18376 TCGv t1 = tcg_temp_new();
18377 TCGv t2 = tcg_temp_new();
18379 gen_load_gpr(t1, rs);
18380 gen_load_gpr(t2, rt);
18381 tcg_gen_add_tl(t0, t1, t2);
18382 tcg_gen_ext32s_tl(t0, t0);
18383 tcg_gen_xor_tl(t1, t1, t2);
18384 tcg_gen_xor_tl(t2, t0, t2);
18385 tcg_gen_andc_tl(t1, t2, t1);
18387 /* operands of same sign, result different sign */
18388 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18389 gen_store_gpr(t0, rd);
18397 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18400 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18403 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18406 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18409 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18412 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18415 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18418 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18420 #ifndef CONFIG_USER_ONLY
18422 check_cp0_enabled(ctx);
18424 /* Treat as NOP. */
18427 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18430 check_cp0_enabled(ctx);
18432 TCGv t0 = tcg_temp_new();
18434 gen_load_gpr(t0, rt);
18435 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18439 case NM_D_E_MT_VPE:
18441 uint8_t sc = extract32(ctx->opcode, 10, 1);
18442 TCGv t0 = tcg_temp_new();
18449 gen_helper_dmt(t0);
18450 gen_store_gpr(t0, rt);
18451 } else if (rs == 0) {
18454 gen_helper_dvpe(t0, cpu_env);
18455 gen_store_gpr(t0, rt);
18457 generate_exception_end(ctx, EXCP_RI);
18464 gen_helper_emt(t0);
18465 gen_store_gpr(t0, rt);
18466 } else if (rs == 0) {
18469 gen_helper_evpe(t0, cpu_env);
18470 gen_store_gpr(t0, rt);
18472 generate_exception_end(ctx, EXCP_RI);
18483 TCGv t0 = tcg_temp_new();
18484 TCGv t1 = tcg_temp_new();
18486 gen_load_gpr(t0, rt);
18487 gen_load_gpr(t1, rs);
18488 gen_helper_fork(t0, t1);
18495 check_cp0_enabled(ctx);
18497 /* Treat as NOP. */
18500 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18501 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18505 check_cp0_enabled(ctx);
18506 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18507 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18512 TCGv t0 = tcg_temp_new();
18514 gen_load_gpr(t0, rs);
18515 gen_helper_yield(t0, cpu_env, t0);
18516 gen_store_gpr(t0, rt);
18522 generate_exception_end(ctx, EXCP_RI);
18528 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18529 int ret, int v1, int v2)
18535 t0 = tcg_temp_new_i32();
18537 v0_t = tcg_temp_new();
18538 v1_t = tcg_temp_new();
18540 tcg_gen_movi_i32(t0, v2 >> 3);
18542 gen_load_gpr(v0_t, ret);
18543 gen_load_gpr(v1_t, v1);
18546 case NM_MAQ_S_W_PHR:
18548 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18550 case NM_MAQ_S_W_PHL:
18552 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18554 case NM_MAQ_SA_W_PHR:
18556 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18558 case NM_MAQ_SA_W_PHL:
18560 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18563 generate_exception_end(ctx, EXCP_RI);
18567 tcg_temp_free_i32(t0);
18569 tcg_temp_free(v0_t);
18570 tcg_temp_free(v1_t);
18574 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18575 int ret, int v1, int v2)
18578 TCGv t0 = tcg_temp_new();
18579 TCGv t1 = tcg_temp_new();
18580 TCGv v0_t = tcg_temp_new();
18582 gen_load_gpr(v0_t, v1);
18585 case NM_POOL32AXF_1_0:
18587 switch (extract32(ctx->opcode, 12, 2)) {
18589 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18592 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18595 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18598 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18602 case NM_POOL32AXF_1_1:
18604 switch (extract32(ctx->opcode, 12, 2)) {
18606 tcg_gen_movi_tl(t0, v2);
18607 gen_helper_mthlip(t0, v0_t, cpu_env);
18610 tcg_gen_movi_tl(t0, v2 >> 3);
18611 gen_helper_shilo(t0, v0_t, cpu_env);
18614 generate_exception_end(ctx, EXCP_RI);
18618 case NM_POOL32AXF_1_3:
18620 imm = extract32(ctx->opcode, 14, 7);
18621 switch (extract32(ctx->opcode, 12, 2)) {
18623 tcg_gen_movi_tl(t0, imm);
18624 gen_helper_rddsp(t0, t0, cpu_env);
18625 gen_store_gpr(t0, ret);
18628 gen_load_gpr(t0, ret);
18629 tcg_gen_movi_tl(t1, imm);
18630 gen_helper_wrdsp(t0, t1, cpu_env);
18633 tcg_gen_movi_tl(t0, v2 >> 3);
18634 tcg_gen_movi_tl(t1, v1);
18635 gen_helper_extp(t0, t0, t1, cpu_env);
18636 gen_store_gpr(t0, ret);
18639 tcg_gen_movi_tl(t0, v2 >> 3);
18640 tcg_gen_movi_tl(t1, v1);
18641 gen_helper_extpdp(t0, t0, t1, cpu_env);
18642 gen_store_gpr(t0, ret);
18646 case NM_POOL32AXF_1_4:
18648 tcg_gen_movi_tl(t0, v2 >> 2);
18649 switch (extract32(ctx->opcode, 12, 1)) {
18651 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18652 gen_store_gpr(t0, ret);
18655 gen_helper_shrl_qb(t0, t0, v0_t);
18656 gen_store_gpr(t0, ret);
18660 case NM_POOL32AXF_1_5:
18661 opc = extract32(ctx->opcode, 12, 2);
18662 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18664 case NM_POOL32AXF_1_7:
18666 tcg_gen_movi_tl(t0, v2 >> 3);
18667 tcg_gen_movi_tl(t1, v1);
18668 switch (extract32(ctx->opcode, 12, 2)) {
18670 gen_helper_extr_w(t0, t0, t1, cpu_env);
18671 gen_store_gpr(t0, ret);
18674 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18675 gen_store_gpr(t0, ret);
18678 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18679 gen_store_gpr(t0, ret);
18682 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18683 gen_store_gpr(t0, ret);
18688 generate_exception_end(ctx, EXCP_RI);
18694 tcg_temp_free(v0_t);
18697 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18698 TCGv v0, TCGv v1, int rd)
18702 t0 = tcg_temp_new_i32();
18704 tcg_gen_movi_i32(t0, rd >> 3);
18707 case NM_POOL32AXF_2_0_7:
18708 switch (extract32(ctx->opcode, 9, 3)) {
18711 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18713 case NM_DPAQ_S_W_PH:
18715 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18719 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18721 case NM_DPSQ_S_W_PH:
18723 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18726 generate_exception_end(ctx, EXCP_RI);
18730 case NM_POOL32AXF_2_8_15:
18731 switch (extract32(ctx->opcode, 9, 3)) {
18734 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18736 case NM_DPAQ_SA_L_W:
18738 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18742 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18744 case NM_DPSQ_SA_L_W:
18746 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18749 generate_exception_end(ctx, EXCP_RI);
18753 case NM_POOL32AXF_2_16_23:
18754 switch (extract32(ctx->opcode, 9, 3)) {
18755 case NM_DPAU_H_QBL:
18757 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18759 case NM_DPAQX_S_W_PH:
18761 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18763 case NM_DPSU_H_QBL:
18765 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18767 case NM_DPSQX_S_W_PH:
18769 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18771 case NM_MULSA_W_PH:
18773 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18776 generate_exception_end(ctx, EXCP_RI);
18780 case NM_POOL32AXF_2_24_31:
18781 switch (extract32(ctx->opcode, 9, 3)) {
18782 case NM_DPAU_H_QBR:
18784 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18786 case NM_DPAQX_SA_W_PH:
18788 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18790 case NM_DPSU_H_QBR:
18792 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18794 case NM_DPSQX_SA_W_PH:
18796 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18798 case NM_MULSAQ_S_W_PH:
18800 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18803 generate_exception_end(ctx, EXCP_RI);
18808 generate_exception_end(ctx, EXCP_RI);
18812 tcg_temp_free_i32(t0);
18815 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18816 int rt, int rs, int rd)
18819 TCGv t0 = tcg_temp_new();
18820 TCGv t1 = tcg_temp_new();
18821 TCGv v0_t = tcg_temp_new();
18822 TCGv v1_t = tcg_temp_new();
18824 gen_load_gpr(v0_t, rt);
18825 gen_load_gpr(v1_t, rs);
18828 case NM_POOL32AXF_2_0_7:
18829 switch (extract32(ctx->opcode, 9, 3)) {
18831 case NM_DPAQ_S_W_PH:
18833 case NM_DPSQ_S_W_PH:
18834 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18839 gen_load_gpr(t0, rs);
18841 if (rd != 0 && rd != 2) {
18842 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18843 tcg_gen_ext32u_tl(t0, t0);
18844 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18845 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18847 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18853 int acc = extract32(ctx->opcode, 14, 2);
18854 TCGv_i64 t2 = tcg_temp_new_i64();
18855 TCGv_i64 t3 = tcg_temp_new_i64();
18857 gen_load_gpr(t0, rt);
18858 gen_load_gpr(t1, rs);
18859 tcg_gen_ext_tl_i64(t2, t0);
18860 tcg_gen_ext_tl_i64(t3, t1);
18861 tcg_gen_mul_i64(t2, t2, t3);
18862 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18863 tcg_gen_add_i64(t2, t2, t3);
18864 tcg_temp_free_i64(t3);
18865 gen_move_low32(cpu_LO[acc], t2);
18866 gen_move_high32(cpu_HI[acc], t2);
18867 tcg_temp_free_i64(t2);
18873 int acc = extract32(ctx->opcode, 14, 2);
18874 TCGv_i32 t2 = tcg_temp_new_i32();
18875 TCGv_i32 t3 = tcg_temp_new_i32();
18877 gen_load_gpr(t0, rs);
18878 gen_load_gpr(t1, rt);
18879 tcg_gen_trunc_tl_i32(t2, t0);
18880 tcg_gen_trunc_tl_i32(t3, t1);
18881 tcg_gen_muls2_i32(t2, t3, t2, t3);
18882 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18883 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18884 tcg_temp_free_i32(t2);
18885 tcg_temp_free_i32(t3);
18890 gen_load_gpr(v1_t, rs);
18891 tcg_gen_movi_tl(t0, rd >> 3);
18892 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18893 gen_store_gpr(t0, ret);
18897 case NM_POOL32AXF_2_8_15:
18898 switch (extract32(ctx->opcode, 9, 3)) {
18900 case NM_DPAQ_SA_L_W:
18902 case NM_DPSQ_SA_L_W:
18903 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18908 int acc = extract32(ctx->opcode, 14, 2);
18909 TCGv_i64 t2 = tcg_temp_new_i64();
18910 TCGv_i64 t3 = tcg_temp_new_i64();
18912 gen_load_gpr(t0, rs);
18913 gen_load_gpr(t1, rt);
18914 tcg_gen_ext32u_tl(t0, t0);
18915 tcg_gen_ext32u_tl(t1, t1);
18916 tcg_gen_extu_tl_i64(t2, t0);
18917 tcg_gen_extu_tl_i64(t3, t1);
18918 tcg_gen_mul_i64(t2, t2, t3);
18919 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18920 tcg_gen_add_i64(t2, t2, t3);
18921 tcg_temp_free_i64(t3);
18922 gen_move_low32(cpu_LO[acc], t2);
18923 gen_move_high32(cpu_HI[acc], t2);
18924 tcg_temp_free_i64(t2);
18930 int acc = extract32(ctx->opcode, 14, 2);
18931 TCGv_i32 t2 = tcg_temp_new_i32();
18932 TCGv_i32 t3 = tcg_temp_new_i32();
18934 gen_load_gpr(t0, rs);
18935 gen_load_gpr(t1, rt);
18936 tcg_gen_trunc_tl_i32(t2, t0);
18937 tcg_gen_trunc_tl_i32(t3, t1);
18938 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18939 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18940 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18941 tcg_temp_free_i32(t2);
18942 tcg_temp_free_i32(t3);
18947 tcg_gen_movi_tl(t0, rd >> 3);
18948 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18949 gen_store_gpr(t0, ret);
18952 generate_exception_end(ctx, EXCP_RI);
18956 case NM_POOL32AXF_2_16_23:
18957 switch (extract32(ctx->opcode, 9, 3)) {
18958 case NM_DPAU_H_QBL:
18959 case NM_DPAQX_S_W_PH:
18960 case NM_DPSU_H_QBL:
18961 case NM_DPSQX_S_W_PH:
18962 case NM_MULSA_W_PH:
18963 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18967 tcg_gen_movi_tl(t0, rd >> 3);
18968 gen_helper_extp(t0, t0, v1_t, cpu_env);
18969 gen_store_gpr(t0, ret);
18974 int acc = extract32(ctx->opcode, 14, 2);
18975 TCGv_i64 t2 = tcg_temp_new_i64();
18976 TCGv_i64 t3 = tcg_temp_new_i64();
18978 gen_load_gpr(t0, rs);
18979 gen_load_gpr(t1, rt);
18980 tcg_gen_ext_tl_i64(t2, t0);
18981 tcg_gen_ext_tl_i64(t3, t1);
18982 tcg_gen_mul_i64(t2, t2, t3);
18983 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18984 tcg_gen_sub_i64(t2, t3, t2);
18985 tcg_temp_free_i64(t3);
18986 gen_move_low32(cpu_LO[acc], t2);
18987 gen_move_high32(cpu_HI[acc], t2);
18988 tcg_temp_free_i64(t2);
18991 case NM_EXTRV_RS_W:
18993 tcg_gen_movi_tl(t0, rd >> 3);
18994 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18995 gen_store_gpr(t0, ret);
18999 case NM_POOL32AXF_2_24_31:
19000 switch (extract32(ctx->opcode, 9, 3)) {
19001 case NM_DPAU_H_QBR:
19002 case NM_DPAQX_SA_W_PH:
19003 case NM_DPSU_H_QBR:
19004 case NM_DPSQX_SA_W_PH:
19005 case NM_MULSAQ_S_W_PH:
19006 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19010 tcg_gen_movi_tl(t0, rd >> 3);
19011 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19012 gen_store_gpr(t0, ret);
19017 int acc = extract32(ctx->opcode, 14, 2);
19018 TCGv_i64 t2 = tcg_temp_new_i64();
19019 TCGv_i64 t3 = tcg_temp_new_i64();
19021 gen_load_gpr(t0, rs);
19022 gen_load_gpr(t1, rt);
19023 tcg_gen_ext32u_tl(t0, t0);
19024 tcg_gen_ext32u_tl(t1, t1);
19025 tcg_gen_extu_tl_i64(t2, t0);
19026 tcg_gen_extu_tl_i64(t3, t1);
19027 tcg_gen_mul_i64(t2, t2, t3);
19028 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19029 tcg_gen_sub_i64(t2, t3, t2);
19030 tcg_temp_free_i64(t3);
19031 gen_move_low32(cpu_LO[acc], t2);
19032 gen_move_high32(cpu_HI[acc], t2);
19033 tcg_temp_free_i64(t2);
19038 tcg_gen_movi_tl(t0, rd >> 3);
19039 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19040 gen_store_gpr(t0, ret);
19045 generate_exception_end(ctx, EXCP_RI);
19052 tcg_temp_free(v0_t);
19053 tcg_temp_free(v1_t);
19056 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19060 TCGv t0 = tcg_temp_new();
19061 TCGv v0_t = tcg_temp_new();
19063 gen_load_gpr(v0_t, rs);
19068 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19069 gen_store_gpr(v0_t, ret);
19073 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19074 gen_store_gpr(v0_t, ret);
19078 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19079 gen_store_gpr(v0_t, ret);
19081 case NM_PRECEQ_W_PHL:
19083 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19084 tcg_gen_ext32s_tl(v0_t, v0_t);
19085 gen_store_gpr(v0_t, ret);
19087 case NM_PRECEQ_W_PHR:
19089 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19090 tcg_gen_shli_tl(v0_t, v0_t, 16);
19091 tcg_gen_ext32s_tl(v0_t, v0_t);
19092 gen_store_gpr(v0_t, ret);
19094 case NM_PRECEQU_PH_QBL:
19096 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19097 gen_store_gpr(v0_t, ret);
19099 case NM_PRECEQU_PH_QBR:
19101 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19102 gen_store_gpr(v0_t, ret);
19104 case NM_PRECEQU_PH_QBLA:
19106 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19107 gen_store_gpr(v0_t, ret);
19109 case NM_PRECEQU_PH_QBRA:
19111 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19112 gen_store_gpr(v0_t, ret);
19114 case NM_PRECEU_PH_QBL:
19116 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19117 gen_store_gpr(v0_t, ret);
19119 case NM_PRECEU_PH_QBR:
19121 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19122 gen_store_gpr(v0_t, ret);
19124 case NM_PRECEU_PH_QBLA:
19126 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19127 gen_store_gpr(v0_t, ret);
19129 case NM_PRECEU_PH_QBRA:
19131 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19132 gen_store_gpr(v0_t, ret);
19136 tcg_gen_ext16u_tl(v0_t, v0_t);
19137 tcg_gen_shli_tl(t0, v0_t, 16);
19138 tcg_gen_or_tl(v0_t, v0_t, t0);
19139 tcg_gen_ext32s_tl(v0_t, v0_t);
19140 gen_store_gpr(v0_t, ret);
19144 tcg_gen_ext8u_tl(v0_t, v0_t);
19145 tcg_gen_shli_tl(t0, v0_t, 8);
19146 tcg_gen_or_tl(v0_t, v0_t, t0);
19147 tcg_gen_shli_tl(t0, v0_t, 16);
19148 tcg_gen_or_tl(v0_t, v0_t, t0);
19149 tcg_gen_ext32s_tl(v0_t, v0_t);
19150 gen_store_gpr(v0_t, ret);
19154 gen_helper_bitrev(v0_t, v0_t);
19155 gen_store_gpr(v0_t, ret);
19160 TCGv tv0 = tcg_temp_new();
19162 gen_load_gpr(tv0, rt);
19163 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19164 gen_store_gpr(v0_t, ret);
19165 tcg_temp_free(tv0);
19168 case NM_RADDU_W_QB:
19170 gen_helper_raddu_w_qb(v0_t, v0_t);
19171 gen_store_gpr(v0_t, ret);
19174 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19178 gen_cl(ctx, OPC_CLO, ret, rs);
19182 gen_cl(ctx, OPC_CLZ, ret, rs);
19185 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19188 generate_exception_end(ctx, EXCP_RI);
19192 tcg_temp_free(v0_t);
19196 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19197 int rt, int rs, int rd)
19199 TCGv t0 = tcg_temp_new();
19200 TCGv rs_t = tcg_temp_new();
19202 gen_load_gpr(rs_t, rs);
19207 tcg_gen_movi_tl(t0, rd >> 2);
19208 switch (extract32(ctx->opcode, 12, 1)) {
19211 gen_helper_shra_qb(t0, t0, rs_t);
19212 gen_store_gpr(t0, rt);
19216 gen_helper_shra_r_qb(t0, t0, rs_t);
19217 gen_store_gpr(t0, rt);
19223 tcg_gen_movi_tl(t0, rd >> 1);
19224 gen_helper_shrl_ph(t0, t0, rs_t);
19225 gen_store_gpr(t0, rt);
19231 target_long result;
19232 imm = extract32(ctx->opcode, 13, 8);
19233 result = (uint32_t)imm << 24 |
19234 (uint32_t)imm << 16 |
19235 (uint32_t)imm << 8 |
19237 result = (int32_t)result;
19238 tcg_gen_movi_tl(t0, result);
19239 gen_store_gpr(t0, rt);
19243 generate_exception_end(ctx, EXCP_RI);
19247 tcg_temp_free(rs_t);
19251 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19253 int rt = extract32(ctx->opcode, 21, 5);
19254 int rs = extract32(ctx->opcode, 16, 5);
19255 int rd = extract32(ctx->opcode, 11, 5);
19257 switch (extract32(ctx->opcode, 6, 3)) {
19258 case NM_POOL32AXF_1:
19260 int32_t op1 = extract32(ctx->opcode, 9, 3);
19261 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19264 case NM_POOL32AXF_2:
19266 int32_t op1 = extract32(ctx->opcode, 12, 2);
19267 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19270 case NM_POOL32AXF_4:
19272 int32_t op1 = extract32(ctx->opcode, 9, 7);
19273 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19276 case NM_POOL32AXF_5:
19277 switch (extract32(ctx->opcode, 9, 7)) {
19278 #ifndef CONFIG_USER_ONLY
19280 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19283 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19286 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19289 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19292 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19295 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19298 check_cp0_enabled(ctx);
19300 TCGv t0 = tcg_temp_new();
19302 save_cpu_state(ctx, 1);
19303 gen_helper_di(t0, cpu_env);
19304 gen_store_gpr(t0, rt);
19305 /* Stop translation as we may have switched the execution mode */
19306 ctx->base.is_jmp = DISAS_STOP;
19311 check_cp0_enabled(ctx);
19313 TCGv t0 = tcg_temp_new();
19315 save_cpu_state(ctx, 1);
19316 gen_helper_ei(t0, cpu_env);
19317 gen_store_gpr(t0, rt);
19318 /* Stop translation as we may have switched the execution mode */
19319 ctx->base.is_jmp = DISAS_STOP;
19324 gen_load_srsgpr(rs, rt);
19327 gen_store_srsgpr(rs, rt);
19330 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19333 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19336 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19340 generate_exception_end(ctx, EXCP_RI);
19344 case NM_POOL32AXF_7:
19346 int32_t op1 = extract32(ctx->opcode, 9, 3);
19347 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19351 generate_exception_end(ctx, EXCP_RI);
19356 /* Immediate Value Compact Branches */
19357 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19358 int rt, int32_t imm, int32_t offset)
19361 int bcond_compute = 0;
19362 TCGv t0 = tcg_temp_new();
19363 TCGv t1 = tcg_temp_new();
19365 gen_load_gpr(t0, rt);
19366 tcg_gen_movi_tl(t1, imm);
19367 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19369 /* Load needed operands and calculate btarget */
19372 if (rt == 0 && imm == 0) {
19373 /* Unconditional branch */
19374 } else if (rt == 0 && imm != 0) {
19379 cond = TCG_COND_EQ;
19385 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19386 generate_exception_end(ctx, EXCP_RI);
19388 } else if (rt == 0 && opc == NM_BBEQZC) {
19389 /* Unconditional branch */
19390 } else if (rt == 0 && opc == NM_BBNEZC) {
19394 tcg_gen_shri_tl(t0, t0, imm);
19395 tcg_gen_andi_tl(t0, t0, 1);
19396 tcg_gen_movi_tl(t1, 0);
19398 if (opc == NM_BBEQZC) {
19399 cond = TCG_COND_EQ;
19401 cond = TCG_COND_NE;
19406 if (rt == 0 && imm == 0) {
19409 } else if (rt == 0 && imm != 0) {
19410 /* Unconditional branch */
19413 cond = TCG_COND_NE;
19417 if (rt == 0 && imm == 0) {
19418 /* Unconditional branch */
19421 cond = TCG_COND_GE;
19426 cond = TCG_COND_LT;
19429 if (rt == 0 && imm == 0) {
19430 /* Unconditional branch */
19433 cond = TCG_COND_GEU;
19438 cond = TCG_COND_LTU;
19441 MIPS_INVAL("Immediate Value Compact branch");
19442 generate_exception_end(ctx, EXCP_RI);
19446 if (bcond_compute == 0) {
19447 /* Uncoditional compact branch */
19448 gen_goto_tb(ctx, 0, ctx->btarget);
19450 /* Conditional compact branch */
19451 TCGLabel *fs = gen_new_label();
19453 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19455 gen_goto_tb(ctx, 1, ctx->btarget);
19458 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19466 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19467 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19470 TCGv t0 = tcg_temp_new();
19471 TCGv t1 = tcg_temp_new();
19474 gen_load_gpr(t0, rs);
19478 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19481 /* calculate btarget */
19482 tcg_gen_shli_tl(t0, t0, 1);
19483 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19484 gen_op_addr_add(ctx, btarget, t1, t0);
19486 /* unconditional branch to register */
19487 tcg_gen_mov_tl(cpu_PC, btarget);
19488 tcg_gen_lookup_and_goto_ptr();
19494 /* nanoMIPS Branches */
19495 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19496 int rs, int rt, int32_t offset)
19498 int bcond_compute = 0;
19499 TCGv t0 = tcg_temp_new();
19500 TCGv t1 = tcg_temp_new();
19502 /* Load needed operands and calculate btarget */
19504 /* compact branch */
19507 gen_load_gpr(t0, rs);
19508 gen_load_gpr(t1, rt);
19510 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19514 if (rs == 0 || rs == rt) {
19515 /* OPC_BLEZALC, OPC_BGEZALC */
19516 /* OPC_BGTZALC, OPC_BLTZALC */
19517 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19519 gen_load_gpr(t0, rs);
19520 gen_load_gpr(t1, rt);
19522 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19525 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19529 /* OPC_BEQZC, OPC_BNEZC */
19530 gen_load_gpr(t0, rs);
19532 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19534 /* OPC_JIC, OPC_JIALC */
19535 TCGv tbase = tcg_temp_new();
19536 TCGv toffset = tcg_temp_new();
19538 gen_load_gpr(tbase, rt);
19539 tcg_gen_movi_tl(toffset, offset);
19540 gen_op_addr_add(ctx, btarget, tbase, toffset);
19541 tcg_temp_free(tbase);
19542 tcg_temp_free(toffset);
19546 MIPS_INVAL("Compact branch/jump");
19547 generate_exception_end(ctx, EXCP_RI);
19551 if (bcond_compute == 0) {
19552 /* Uncoditional compact branch */
19555 gen_goto_tb(ctx, 0, ctx->btarget);
19558 MIPS_INVAL("Compact branch/jump");
19559 generate_exception_end(ctx, EXCP_RI);
19563 /* Conditional compact branch */
19564 TCGLabel *fs = gen_new_label();
19568 if (rs == 0 && rt != 0) {
19570 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19571 } else if (rs != 0 && rt != 0 && rs == rt) {
19573 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19576 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19580 if (rs == 0 && rt != 0) {
19582 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19583 } else if (rs != 0 && rt != 0 && rs == rt) {
19585 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19588 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19592 if (rs == 0 && rt != 0) {
19594 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19595 } else if (rs != 0 && rt != 0 && rs == rt) {
19597 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19600 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19604 if (rs == 0 && rt != 0) {
19606 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19607 } else if (rs != 0 && rt != 0 && rs == rt) {
19609 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19612 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19616 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19619 MIPS_INVAL("Compact conditional branch/jump");
19620 generate_exception_end(ctx, EXCP_RI);
19624 /* Generating branch here as compact branches don't have delay slot */
19625 gen_goto_tb(ctx, 1, ctx->btarget);
19628 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19637 /* nanoMIPS CP1 Branches */
19638 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19639 int32_t ft, int32_t offset)
19641 target_ulong btarget;
19642 TCGv_i64 t0 = tcg_temp_new_i64();
19644 gen_load_fpr64(ctx, t0, ft);
19645 tcg_gen_andi_i64(t0, t0, 1);
19647 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19651 tcg_gen_xori_i64(t0, t0, 1);
19652 ctx->hflags |= MIPS_HFLAG_BC;
19655 /* t0 already set */
19656 ctx->hflags |= MIPS_HFLAG_BC;
19659 MIPS_INVAL("cp1 cond branch");
19660 generate_exception_end(ctx, EXCP_RI);
19664 tcg_gen_trunc_i64_tl(bcond, t0);
19666 ctx->btarget = btarget;
19669 tcg_temp_free_i64(t0);
19673 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19676 t0 = tcg_temp_new();
19677 t1 = tcg_temp_new();
19679 gen_load_gpr(t0, rs);
19680 gen_load_gpr(t1, rt);
19682 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19683 /* PP.LSXS instructions require shifting */
19684 switch (extract32(ctx->opcode, 7, 4)) {
19689 tcg_gen_shli_tl(t0, t0, 1);
19696 tcg_gen_shli_tl(t0, t0, 2);
19700 tcg_gen_shli_tl(t0, t0, 3);
19704 gen_op_addr_add(ctx, t0, t0, t1);
19706 switch (extract32(ctx->opcode, 7, 4)) {
19708 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19710 gen_store_gpr(t0, rd);
19714 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19716 gen_store_gpr(t0, rd);
19720 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19722 gen_store_gpr(t0, rd);
19725 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19727 gen_store_gpr(t0, rd);
19731 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19733 gen_store_gpr(t0, rd);
19737 gen_load_gpr(t1, rd);
19738 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19744 gen_load_gpr(t1, rd);
19745 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19751 gen_load_gpr(t1, rd);
19752 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19756 /*case NM_LWC1XS:*/
19758 /*case NM_LDC1XS:*/
19760 /*case NM_SWC1XS:*/
19762 /*case NM_SDC1XS:*/
19763 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19764 check_cp1_enabled(ctx);
19765 switch (extract32(ctx->opcode, 7, 4)) {
19767 /*case NM_LWC1XS:*/
19768 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19771 /*case NM_LDC1XS:*/
19772 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19775 /*case NM_SWC1XS:*/
19776 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19779 /*case NM_SDC1XS:*/
19780 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19784 generate_exception_err(ctx, EXCP_CpU, 1);
19788 generate_exception_end(ctx, EXCP_RI);
19796 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19800 rt = extract32(ctx->opcode, 21, 5);
19801 rs = extract32(ctx->opcode, 16, 5);
19802 rd = extract32(ctx->opcode, 11, 5);
19804 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19805 generate_exception_end(ctx, EXCP_RI);
19808 check_cp1_enabled(ctx);
19809 switch (extract32(ctx->opcode, 0, 3)) {
19811 switch (extract32(ctx->opcode, 3, 7)) {
19813 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19816 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19819 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19822 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19825 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19828 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19831 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19834 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19837 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19840 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19843 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19846 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19849 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19852 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19855 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19858 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19861 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19864 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19867 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19870 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19873 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19876 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19879 generate_exception_end(ctx, EXCP_RI);
19884 switch (extract32(ctx->opcode, 3, 3)) {
19886 switch (extract32(ctx->opcode, 9, 1)) {
19888 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19891 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19896 switch (extract32(ctx->opcode, 9, 1)) {
19898 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19901 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19906 switch (extract32(ctx->opcode, 9, 1)) {
19908 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19911 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19916 switch (extract32(ctx->opcode, 9, 1)) {
19918 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19921 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19926 switch (extract32(ctx->opcode, 6, 8)) {
19928 gen_cp1(ctx, OPC_CFC1, rt, rs);
19931 gen_cp1(ctx, OPC_CTC1, rt, rs);
19934 gen_cp1(ctx, OPC_MFC1, rt, rs);
19937 gen_cp1(ctx, OPC_MTC1, rt, rs);
19940 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19943 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19946 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19949 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19952 switch (extract32(ctx->opcode, 6, 9)) {
19954 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19957 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19960 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19963 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19966 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19969 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19972 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19975 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19978 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19981 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19984 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19987 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19990 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19993 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19996 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19999 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20002 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20005 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20008 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20011 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20014 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20017 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20020 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20023 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20026 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20029 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20032 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20035 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20038 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20041 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20044 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20047 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20050 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20053 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20056 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20059 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20062 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20065 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20068 generate_exception_end(ctx, EXCP_RI);
20077 switch (extract32(ctx->opcode, 3, 3)) {
20078 case NM_CMP_CONDN_S:
20079 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20081 case NM_CMP_CONDN_D:
20082 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20085 generate_exception_end(ctx, EXCP_RI);
20090 generate_exception_end(ctx, EXCP_RI);
20095 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20096 int rd, int rs, int rt)
20099 TCGv t0 = tcg_temp_new();
20100 TCGv v1_t = tcg_temp_new();
20101 TCGv v2_t = tcg_temp_new();
20103 gen_load_gpr(v1_t, rs);
20104 gen_load_gpr(v2_t, rt);
20109 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20113 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20117 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20119 case NM_CMPU_EQ_QB:
20121 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20123 case NM_CMPU_LT_QB:
20125 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20127 case NM_CMPU_LE_QB:
20129 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20131 case NM_CMPGU_EQ_QB:
20133 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20134 gen_store_gpr(v1_t, ret);
20136 case NM_CMPGU_LT_QB:
20138 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20139 gen_store_gpr(v1_t, ret);
20141 case NM_CMPGU_LE_QB:
20143 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20144 gen_store_gpr(v1_t, ret);
20146 case NM_CMPGDU_EQ_QB:
20148 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20149 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20150 gen_store_gpr(v1_t, ret);
20152 case NM_CMPGDU_LT_QB:
20154 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20155 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20156 gen_store_gpr(v1_t, ret);
20158 case NM_CMPGDU_LE_QB:
20160 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20161 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20162 gen_store_gpr(v1_t, ret);
20166 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20167 gen_store_gpr(v1_t, ret);
20171 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20172 gen_store_gpr(v1_t, ret);
20176 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20177 gen_store_gpr(v1_t, ret);
20181 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20182 gen_store_gpr(v1_t, ret);
20186 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20187 gen_store_gpr(v1_t, ret);
20191 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20192 gen_store_gpr(v1_t, ret);
20196 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20197 gen_store_gpr(v1_t, ret);
20201 switch (extract32(ctx->opcode, 10, 1)) {
20204 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20205 gen_store_gpr(v1_t, ret);
20209 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20210 gen_store_gpr(v1_t, ret);
20214 case NM_ADDQH_R_PH:
20216 switch (extract32(ctx->opcode, 10, 1)) {
20219 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20220 gen_store_gpr(v1_t, ret);
20224 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20225 gen_store_gpr(v1_t, ret);
20231 switch (extract32(ctx->opcode, 10, 1)) {
20234 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20235 gen_store_gpr(v1_t, ret);
20239 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20240 gen_store_gpr(v1_t, ret);
20246 switch (extract32(ctx->opcode, 10, 1)) {
20249 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20250 gen_store_gpr(v1_t, ret);
20254 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20255 gen_store_gpr(v1_t, ret);
20261 switch (extract32(ctx->opcode, 10, 1)) {
20264 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20265 gen_store_gpr(v1_t, ret);
20269 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20270 gen_store_gpr(v1_t, ret);
20274 case NM_ADDUH_R_QB:
20276 switch (extract32(ctx->opcode, 10, 1)) {
20279 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20280 gen_store_gpr(v1_t, ret);
20284 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20285 gen_store_gpr(v1_t, ret);
20289 case NM_SHRAV_R_PH:
20291 switch (extract32(ctx->opcode, 10, 1)) {
20294 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20295 gen_store_gpr(v1_t, ret);
20299 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20300 gen_store_gpr(v1_t, ret);
20304 case NM_SHRAV_R_QB:
20306 switch (extract32(ctx->opcode, 10, 1)) {
20309 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20310 gen_store_gpr(v1_t, ret);
20314 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20315 gen_store_gpr(v1_t, ret);
20321 switch (extract32(ctx->opcode, 10, 1)) {
20324 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20325 gen_store_gpr(v1_t, ret);
20329 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20330 gen_store_gpr(v1_t, ret);
20334 case NM_SUBQH_R_PH:
20336 switch (extract32(ctx->opcode, 10, 1)) {
20339 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20340 gen_store_gpr(v1_t, ret);
20344 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20345 gen_store_gpr(v1_t, ret);
20351 switch (extract32(ctx->opcode, 10, 1)) {
20354 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20355 gen_store_gpr(v1_t, ret);
20359 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20360 gen_store_gpr(v1_t, ret);
20366 switch (extract32(ctx->opcode, 10, 1)) {
20369 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20370 gen_store_gpr(v1_t, ret);
20374 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20375 gen_store_gpr(v1_t, ret);
20381 switch (extract32(ctx->opcode, 10, 1)) {
20384 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20385 gen_store_gpr(v1_t, ret);
20389 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20390 gen_store_gpr(v1_t, ret);
20394 case NM_SUBUH_R_QB:
20396 switch (extract32(ctx->opcode, 10, 1)) {
20399 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20400 gen_store_gpr(v1_t, ret);
20404 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20405 gen_store_gpr(v1_t, ret);
20409 case NM_SHLLV_S_PH:
20411 switch (extract32(ctx->opcode, 10, 1)) {
20414 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20415 gen_store_gpr(v1_t, ret);
20419 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20420 gen_store_gpr(v1_t, ret);
20424 case NM_PRECR_SRA_R_PH_W:
20426 switch (extract32(ctx->opcode, 10, 1)) {
20428 /* PRECR_SRA_PH_W */
20430 TCGv_i32 sa_t = tcg_const_i32(rd);
20431 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20433 gen_store_gpr(v1_t, rt);
20434 tcg_temp_free_i32(sa_t);
20438 /* PRECR_SRA_R_PH_W */
20440 TCGv_i32 sa_t = tcg_const_i32(rd);
20441 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20443 gen_store_gpr(v1_t, rt);
20444 tcg_temp_free_i32(sa_t);
20449 case NM_MULEU_S_PH_QBL:
20451 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20452 gen_store_gpr(v1_t, ret);
20454 case NM_MULEU_S_PH_QBR:
20456 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20457 gen_store_gpr(v1_t, ret);
20459 case NM_MULQ_RS_PH:
20461 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20462 gen_store_gpr(v1_t, ret);
20466 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20467 gen_store_gpr(v1_t, ret);
20471 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20472 gen_store_gpr(v1_t, ret);
20476 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20477 gen_store_gpr(v1_t, ret);
20481 gen_load_gpr(t0, rs);
20483 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20485 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20489 gen_helper_modsub(v1_t, v1_t, v2_t);
20490 gen_store_gpr(v1_t, ret);
20494 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20495 gen_store_gpr(v1_t, ret);
20499 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20500 gen_store_gpr(v1_t, ret);
20504 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20505 gen_store_gpr(v1_t, ret);
20509 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20510 gen_store_gpr(v1_t, ret);
20514 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20515 gen_store_gpr(v1_t, ret);
20520 TCGv tv0 = tcg_temp_new();
20521 TCGv tv1 = tcg_temp_new();
20522 int16_t imm = extract32(ctx->opcode, 16, 7);
20524 tcg_gen_movi_tl(tv0, rd >> 3);
20525 tcg_gen_movi_tl(tv1, imm);
20526 gen_helper_shilo(tv0, tv1, cpu_env);
20529 case NM_MULEQ_S_W_PHL:
20531 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20532 gen_store_gpr(v1_t, ret);
20534 case NM_MULEQ_S_W_PHR:
20536 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20537 gen_store_gpr(v1_t, ret);
20541 switch (extract32(ctx->opcode, 10, 1)) {
20544 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20545 gen_store_gpr(v1_t, ret);
20549 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20550 gen_store_gpr(v1_t, ret);
20554 case NM_PRECR_QB_PH:
20556 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20557 gen_store_gpr(v1_t, ret);
20559 case NM_PRECRQ_QB_PH:
20561 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20562 gen_store_gpr(v1_t, ret);
20564 case NM_PRECRQ_PH_W:
20566 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20567 gen_store_gpr(v1_t, ret);
20569 case NM_PRECRQ_RS_PH_W:
20571 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20572 gen_store_gpr(v1_t, ret);
20574 case NM_PRECRQU_S_QB_PH:
20576 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20577 gen_store_gpr(v1_t, ret);
20581 tcg_gen_movi_tl(t0, rd);
20582 gen_helper_shra_r_w(v1_t, t0, v1_t);
20583 gen_store_gpr(v1_t, rt);
20587 tcg_gen_movi_tl(t0, rd >> 1);
20588 switch (extract32(ctx->opcode, 10, 1)) {
20591 gen_helper_shra_ph(v1_t, t0, v1_t);
20592 gen_store_gpr(v1_t, rt);
20596 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20597 gen_store_gpr(v1_t, rt);
20603 tcg_gen_movi_tl(t0, rd >> 1);
20604 switch (extract32(ctx->opcode, 10, 2)) {
20607 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20608 gen_store_gpr(v1_t, rt);
20612 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20613 gen_store_gpr(v1_t, rt);
20616 generate_exception_end(ctx, EXCP_RI);
20622 tcg_gen_movi_tl(t0, rd);
20623 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20624 gen_store_gpr(v1_t, rt);
20630 imm = sextract32(ctx->opcode, 11, 11);
20631 imm = (int16_t)(imm << 6) >> 6;
20633 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20638 generate_exception_end(ctx, EXCP_RI);
20643 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20651 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20652 ctx->opcode = (ctx->opcode << 16) | insn;
20654 rt = extract32(ctx->opcode, 21, 5);
20655 rs = extract32(ctx->opcode, 16, 5);
20656 rd = extract32(ctx->opcode, 11, 5);
20658 op = extract32(ctx->opcode, 26, 6);
20663 switch (extract32(ctx->opcode, 19, 2)) {
20666 generate_exception_end(ctx, EXCP_RI);
20669 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20670 generate_exception_end(ctx, EXCP_SYSCALL);
20672 generate_exception_end(ctx, EXCP_RI);
20676 generate_exception_end(ctx, EXCP_BREAK);
20679 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20680 gen_helper_do_semihosting(cpu_env);
20682 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20683 generate_exception_end(ctx, EXCP_RI);
20685 generate_exception_end(ctx, EXCP_DBp);
20692 imm = extract32(ctx->opcode, 0, 16);
20694 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20696 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20698 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20703 offset = sextract32(ctx->opcode, 0, 1) << 21 |
20704 extract32(ctx->opcode, 1, 20) << 1;
20705 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20706 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20710 switch (ctx->opcode & 0x07) {
20712 gen_pool32a0_nanomips_insn(env, ctx);
20716 int32_t op1 = extract32(ctx->opcode, 3, 7);
20717 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20721 switch (extract32(ctx->opcode, 3, 3)) {
20723 gen_p_lsx(ctx, rd, rs, rt);
20726 /* In nanoMIPS, the shift field directly encodes the shift
20727 * amount, meaning that the supported shift values are in
20728 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20729 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20730 extract32(ctx->opcode, 9, 2) - 1);
20733 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20736 gen_pool32axf_nanomips_insn(env, ctx);
20739 generate_exception_end(ctx, EXCP_RI);
20744 generate_exception_end(ctx, EXCP_RI);
20749 switch (ctx->opcode & 0x03) {
20752 offset = extract32(ctx->opcode, 0, 21);
20753 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20757 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20760 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20763 generate_exception_end(ctx, EXCP_RI);
20769 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20770 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20771 switch (extract32(ctx->opcode, 16, 5)) {
20775 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20781 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20782 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20788 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20794 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20797 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20804 t0 = tcg_temp_new();
20806 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20809 tcg_gen_movi_tl(t0, addr);
20810 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20818 t0 = tcg_temp_new();
20819 t1 = tcg_temp_new();
20821 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20824 tcg_gen_movi_tl(t0, addr);
20825 gen_load_gpr(t1, rt);
20827 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20834 generate_exception_end(ctx, EXCP_RI);
20840 switch (extract32(ctx->opcode, 12, 4)) {
20842 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20845 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20848 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20851 switch (extract32(ctx->opcode, 20, 1)) {
20853 switch (ctx->opcode & 3) {
20855 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20856 extract32(ctx->opcode, 2, 1),
20857 extract32(ctx->opcode, 3, 9) << 3);
20860 case NM_RESTORE_JRC:
20861 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20862 extract32(ctx->opcode, 2, 1),
20863 extract32(ctx->opcode, 3, 9) << 3);
20864 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20865 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20869 generate_exception_end(ctx, EXCP_RI);
20874 generate_exception_end(ctx, EXCP_RI);
20879 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20882 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20886 TCGv t0 = tcg_temp_new();
20888 imm = extract32(ctx->opcode, 0, 12);
20889 gen_load_gpr(t0, rs);
20890 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20891 gen_store_gpr(t0, rt);
20897 imm = (int16_t) extract32(ctx->opcode, 0, 12);
20898 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20902 int shift = extract32(ctx->opcode, 0, 5);
20903 switch (extract32(ctx->opcode, 5, 4)) {
20905 if (rt == 0 && shift == 0) {
20907 } else if (rt == 0 && shift == 3) {
20908 /* EHB - treat as NOP */
20909 } else if (rt == 0 && shift == 5) {
20910 /* PAUSE - treat as NOP */
20911 } else if (rt == 0 && shift == 6) {
20913 gen_sync(extract32(ctx->opcode, 16, 5));
20916 gen_shift_imm(ctx, OPC_SLL, rt, rs,
20917 extract32(ctx->opcode, 0, 5));
20921 gen_shift_imm(ctx, OPC_SRL, rt, rs,
20922 extract32(ctx->opcode, 0, 5));
20925 gen_shift_imm(ctx, OPC_SRA, rt, rs,
20926 extract32(ctx->opcode, 0, 5));
20929 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20930 extract32(ctx->opcode, 0, 5));
20938 TCGv t0 = tcg_temp_new();
20939 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20940 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20942 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20944 gen_load_gpr(t0, rs);
20945 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20948 tcg_temp_free_i32(shift);
20949 tcg_temp_free_i32(shiftx);
20950 tcg_temp_free_i32(stripe);
20954 switch (((ctx->opcode >> 10) & 2) |
20955 (extract32(ctx->opcode, 5, 1))) {
20958 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20959 extract32(ctx->opcode, 6, 5));
20962 generate_exception_end(ctx, EXCP_RI);
20967 switch (((ctx->opcode >> 10) & 2) |
20968 (extract32(ctx->opcode, 5, 1))) {
20971 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20972 extract32(ctx->opcode, 6, 5));
20975 generate_exception_end(ctx, EXCP_RI);
20980 generate_exception_end(ctx, EXCP_RI);
20985 gen_pool32f_nanomips_insn(ctx);
20990 switch (extract32(ctx->opcode, 1, 1)) {
20993 tcg_gen_movi_tl(cpu_gpr[rt],
20994 sextract32(ctx->opcode, 0, 1) << 31 |
20995 extract32(ctx->opcode, 2, 10) << 21 |
20996 extract32(ctx->opcode, 12, 9) << 12);
21001 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21002 extract32(ctx->opcode, 2, 10) << 21 |
21003 extract32(ctx->opcode, 12, 9) << 12;
21005 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21006 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21013 uint32_t u = extract32(ctx->opcode, 0, 18);
21015 switch (extract32(ctx->opcode, 18, 3)) {
21017 gen_ld(ctx, OPC_LB, rt, 28, u);
21020 gen_st(ctx, OPC_SB, rt, 28, u);
21023 gen_ld(ctx, OPC_LBU, rt, 28, u);
21027 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21032 switch (ctx->opcode & 1) {
21034 gen_ld(ctx, OPC_LH, rt, 28, u);
21037 gen_ld(ctx, OPC_LHU, rt, 28, u);
21043 switch (ctx->opcode & 1) {
21045 gen_st(ctx, OPC_SH, rt, 28, u);
21048 generate_exception_end(ctx, EXCP_RI);
21054 switch (ctx->opcode & 0x3) {
21056 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21059 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21062 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21065 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21070 generate_exception_end(ctx, EXCP_RI);
21077 uint32_t u = extract32(ctx->opcode, 0, 12);
21079 switch (extract32(ctx->opcode, 12, 4)) {
21083 /* Break the TB to be able to sync copied instructions
21085 ctx->base.is_jmp = DISAS_STOP;
21088 /* Treat as NOP. */
21092 gen_ld(ctx, OPC_LB, rt, rs, u);
21095 gen_ld(ctx, OPC_LH, rt, rs, u);
21098 gen_ld(ctx, OPC_LW, rt, rs, u);
21101 gen_ld(ctx, OPC_LBU, rt, rs, u);
21104 gen_ld(ctx, OPC_LHU, rt, rs, u);
21107 gen_st(ctx, OPC_SB, rt, rs, u);
21110 gen_st(ctx, OPC_SH, rt, rs, u);
21113 gen_st(ctx, OPC_SW, rt, rs, u);
21116 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21119 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21122 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21125 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21128 generate_exception_end(ctx, EXCP_RI);
21135 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21136 extract32(ctx->opcode, 0, 8);
21138 switch (extract32(ctx->opcode, 8, 3)) {
21140 switch (extract32(ctx->opcode, 11, 4)) {
21142 gen_ld(ctx, OPC_LB, rt, rs, s);
21145 gen_ld(ctx, OPC_LH, rt, rs, s);
21148 gen_ld(ctx, OPC_LW, rt, rs, s);
21151 gen_ld(ctx, OPC_LBU, rt, rs, s);
21154 gen_ld(ctx, OPC_LHU, rt, rs, s);
21157 gen_st(ctx, OPC_SB, rt, rs, s);
21160 gen_st(ctx, OPC_SH, rt, rs, s);
21163 gen_st(ctx, OPC_SW, rt, rs, s);
21166 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21169 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21172 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21175 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21180 /* Break the TB to be able to sync copied instructions
21182 ctx->base.is_jmp = DISAS_STOP;
21185 /* Treat as NOP. */
21189 generate_exception_end(ctx, EXCP_RI);
21194 switch (extract32(ctx->opcode, 11, 4)) {
21199 TCGv t0 = tcg_temp_new();
21200 TCGv t1 = tcg_temp_new();
21202 gen_base_offset_addr(ctx, t0, rs, s);
21204 switch (extract32(ctx->opcode, 11, 4)) {
21206 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21208 gen_store_gpr(t0, rt);
21211 gen_load_gpr(t1, rt);
21212 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21221 switch (ctx->opcode & 0x03) {
21223 gen_ld(ctx, OPC_LL, rt, rs, s);
21227 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21232 switch (ctx->opcode & 0x03) {
21234 gen_st_cond(ctx, OPC_SC, rt, rs, s);
21238 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21243 check_cp0_enabled(ctx);
21244 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21245 gen_cache_operation(ctx, rt, rs, s);
21251 switch (extract32(ctx->opcode, 11, 4)) {
21254 check_cp0_enabled(ctx);
21255 gen_ld(ctx, OPC_LBE, rt, rs, s);
21259 check_cp0_enabled(ctx);
21260 gen_st(ctx, OPC_SBE, rt, rs, s);
21264 check_cp0_enabled(ctx);
21265 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21269 /* case NM_SYNCIE */
21271 check_cp0_enabled(ctx);
21272 /* Break the TB to be able to sync copied instructions
21274 ctx->base.is_jmp = DISAS_STOP;
21276 /* case NM_PREFE */
21278 check_cp0_enabled(ctx);
21279 /* Treat as NOP. */
21284 check_cp0_enabled(ctx);
21285 gen_ld(ctx, OPC_LHE, rt, rs, s);
21289 check_cp0_enabled(ctx);
21290 gen_st(ctx, OPC_SHE, rt, rs, s);
21294 check_cp0_enabled(ctx);
21295 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21298 check_nms_dl_il_sl_tl_l2c(ctx);
21299 gen_cache_operation(ctx, rt, rs, s);
21303 check_cp0_enabled(ctx);
21304 gen_ld(ctx, OPC_LWE, rt, rs, s);
21308 check_cp0_enabled(ctx);
21309 gen_st(ctx, OPC_SWE, rt, rs, s);
21312 switch (extract32(ctx->opcode, 2, 2)) {
21316 check_cp0_enabled(ctx);
21317 gen_ld(ctx, OPC_LLE, rt, rs, s);
21322 check_cp0_enabled(ctx);
21323 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21325 generate_exception_end(ctx, EXCP_RI);
21330 switch (extract32(ctx->opcode, 2, 2)) {
21334 check_cp0_enabled(ctx);
21335 gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21340 check_cp0_enabled(ctx);
21341 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21343 generate_exception_end(ctx, EXCP_RI);
21353 int count = extract32(ctx->opcode, 12, 3);
21356 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21357 extract32(ctx->opcode, 0, 8);
21358 TCGv va = tcg_temp_new();
21359 TCGv t1 = tcg_temp_new();
21360 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21361 NM_P_LS_UAWM ? MO_UNALN : 0;
21363 count = (count == 0) ? 8 : count;
21364 while (counter != count) {
21365 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21366 int this_offset = offset + (counter << 2);
21368 gen_base_offset_addr(ctx, va, rs, this_offset);
21370 switch (extract32(ctx->opcode, 11, 1)) {
21372 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21374 gen_store_gpr(t1, this_rt);
21375 if ((this_rt == rs) &&
21376 (counter != (count - 1))) {
21377 /* UNPREDICTABLE */
21381 this_rt = (rt == 0) ? 0 : this_rt;
21382 gen_load_gpr(t1, this_rt);
21383 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21394 generate_exception_end(ctx, EXCP_RI);
21402 TCGv t0 = tcg_temp_new();
21403 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21404 extract32(ctx->opcode, 1, 20) << 1;
21405 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21406 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21407 extract32(ctx->opcode, 21, 3));
21408 gen_load_gpr(t0, rt);
21409 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21410 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21416 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21417 extract32(ctx->opcode, 1, 24) << 1;
21419 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21421 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21424 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21429 switch (extract32(ctx->opcode, 12, 4)) {
21432 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21435 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21438 generate_exception_end(ctx, EXCP_RI);
21444 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21445 extract32(ctx->opcode, 1, 13) << 1;
21446 switch (extract32(ctx->opcode, 14, 2)) {
21449 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21452 s = sextract32(ctx->opcode, 0, 1) << 14 |
21453 extract32(ctx->opcode, 1, 13) << 1;
21454 check_cp1_enabled(ctx);
21455 switch (extract32(ctx->opcode, 16, 5)) {
21457 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21460 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21465 int32_t imm = extract32(ctx->opcode, 1, 13) |
21466 extract32(ctx->opcode, 0, 1) << 13;
21468 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21473 generate_exception_end(ctx, EXCP_RI);
21479 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21481 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21485 if (rs == rt || rt == 0) {
21486 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21487 } else if (rs == 0) {
21488 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21490 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21498 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21499 extract32(ctx->opcode, 1, 13) << 1;
21500 switch (extract32(ctx->opcode, 14, 2)) {
21503 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21506 if (rs != 0 && rt != 0 && rs == rt) {
21508 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21510 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21514 if (rs == 0 || rs == rt) {
21516 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21518 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21522 generate_exception_end(ctx, EXCP_RI);
21529 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21530 extract32(ctx->opcode, 1, 10) << 1;
21531 uint32_t u = extract32(ctx->opcode, 11, 7);
21533 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21538 generate_exception_end(ctx, EXCP_RI);
21544 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21547 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21548 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21549 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
21553 /* make sure instructions are on a halfword boundary */
21554 if (ctx->base.pc_next & 0x1) {
21555 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21556 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21557 tcg_temp_free(tmp);
21558 generate_exception_end(ctx, EXCP_AdEL);
21562 op = extract32(ctx->opcode, 10, 6);
21565 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21568 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21569 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21572 switch (extract32(ctx->opcode, 3, 2)) {
21573 case NM_P16_SYSCALL:
21574 if (extract32(ctx->opcode, 2, 1) == 0) {
21575 generate_exception_end(ctx, EXCP_SYSCALL);
21577 generate_exception_end(ctx, EXCP_RI);
21581 generate_exception_end(ctx, EXCP_BREAK);
21584 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21585 gen_helper_do_semihosting(cpu_env);
21587 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21588 generate_exception_end(ctx, EXCP_RI);
21590 generate_exception_end(ctx, EXCP_DBp);
21595 generate_exception_end(ctx, EXCP_RI);
21602 int shift = extract32(ctx->opcode, 0, 3);
21604 shift = (shift == 0) ? 8 : shift;
21606 switch (extract32(ctx->opcode, 3, 1)) {
21614 gen_shift_imm(ctx, opc, rt, rs, shift);
21618 switch (ctx->opcode & 1) {
21620 gen_pool16c_nanomips_insn(ctx);
21623 gen_ldxs(ctx, rt, rs, rd);
21628 switch (extract32(ctx->opcode, 6, 1)) {
21630 imm = extract32(ctx->opcode, 0, 6) << 2;
21631 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21634 generate_exception_end(ctx, EXCP_RI);
21639 switch (extract32(ctx->opcode, 3, 1)) {
21641 imm = extract32(ctx->opcode, 0, 3) << 2;
21642 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21644 case NM_P_ADDIURS5:
21645 rt = extract32(ctx->opcode, 5, 5);
21647 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21648 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21649 (extract32(ctx->opcode, 0, 3));
21650 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21656 switch (ctx->opcode & 0x1) {
21658 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21661 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21666 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21667 extract32(ctx->opcode, 5, 3);
21668 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21669 extract32(ctx->opcode, 0, 3);
21670 rt = decode_gpr_gpr4(rt);
21671 rs = decode_gpr_gpr4(rs);
21672 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21673 (extract32(ctx->opcode, 3, 1))) {
21676 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21680 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21683 generate_exception_end(ctx, EXCP_RI);
21689 int imm = extract32(ctx->opcode, 0, 7);
21690 imm = (imm == 0x7f ? -1 : imm);
21692 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21698 uint32_t u = extract32(ctx->opcode, 0, 4);
21699 u = (u == 12) ? 0xff :
21700 (u == 13) ? 0xffff : u;
21701 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21705 offset = extract32(ctx->opcode, 0, 2);
21706 switch (extract32(ctx->opcode, 2, 2)) {
21708 gen_ld(ctx, OPC_LB, rt, rs, offset);
21711 rt = decode_gpr_gpr3_src_store(
21712 NANOMIPS_EXTRACT_RD(ctx->opcode));
21713 gen_st(ctx, OPC_SB, rt, rs, offset);
21716 gen_ld(ctx, OPC_LBU, rt, rs, offset);
21719 generate_exception_end(ctx, EXCP_RI);
21724 offset = extract32(ctx->opcode, 1, 2) << 1;
21725 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21727 gen_ld(ctx, OPC_LH, rt, rs, offset);
21730 rt = decode_gpr_gpr3_src_store(
21731 NANOMIPS_EXTRACT_RD(ctx->opcode));
21732 gen_st(ctx, OPC_SH, rt, rs, offset);
21735 gen_ld(ctx, OPC_LHU, rt, rs, offset);
21738 generate_exception_end(ctx, EXCP_RI);
21743 offset = extract32(ctx->opcode, 0, 4) << 2;
21744 gen_ld(ctx, OPC_LW, rt, rs, offset);
21747 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21748 offset = extract32(ctx->opcode, 0, 5) << 2;
21749 gen_ld(ctx, OPC_LW, rt, 29, offset);
21753 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21754 extract32(ctx->opcode, 5, 3);
21755 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21756 extract32(ctx->opcode, 0, 3);
21757 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21758 (extract32(ctx->opcode, 8, 1) << 2);
21759 rt = decode_gpr_gpr4(rt);
21760 rs = decode_gpr_gpr4(rs);
21761 gen_ld(ctx, OPC_LW, rt, rs, offset);
21765 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21766 extract32(ctx->opcode, 5, 3);
21767 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21768 extract32(ctx->opcode, 0, 3);
21769 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21770 (extract32(ctx->opcode, 8, 1) << 2);
21771 rt = decode_gpr_gpr4_zero(rt);
21772 rs = decode_gpr_gpr4(rs);
21773 gen_st(ctx, OPC_SW, rt, rs, offset);
21776 offset = extract32(ctx->opcode, 0, 7) << 2;
21777 gen_ld(ctx, OPC_LW, rt, 28, offset);
21780 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21781 offset = extract32(ctx->opcode, 0, 5) << 2;
21782 gen_st(ctx, OPC_SW, rt, 29, offset);
21785 rt = decode_gpr_gpr3_src_store(
21786 NANOMIPS_EXTRACT_RD(ctx->opcode));
21787 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21788 offset = extract32(ctx->opcode, 0, 4) << 2;
21789 gen_st(ctx, OPC_SW, rt, rs, offset);
21792 rt = decode_gpr_gpr3_src_store(
21793 NANOMIPS_EXTRACT_RD(ctx->opcode));
21794 offset = extract32(ctx->opcode, 0, 7) << 2;
21795 gen_st(ctx, OPC_SW, rt, 28, offset);
21798 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21799 (sextract32(ctx->opcode, 0, 1) << 10) |
21800 (extract32(ctx->opcode, 1, 9) << 1));
21803 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21804 (sextract32(ctx->opcode, 0, 1) << 10) |
21805 (extract32(ctx->opcode, 1, 9) << 1));
21808 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21809 (sextract32(ctx->opcode, 0, 1) << 7) |
21810 (extract32(ctx->opcode, 1, 6) << 1));
21813 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21814 (sextract32(ctx->opcode, 0, 1) << 7) |
21815 (extract32(ctx->opcode, 1, 6) << 1));
21818 switch (ctx->opcode & 0xf) {
21821 switch (extract32(ctx->opcode, 4, 1)) {
21823 gen_compute_branch_nm(ctx, OPC_JR, 2,
21824 extract32(ctx->opcode, 5, 5), 0, 0);
21827 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21828 extract32(ctx->opcode, 5, 5), 31, 0);
21835 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21836 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21837 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21838 extract32(ctx->opcode, 0, 4) << 1);
21845 int count = extract32(ctx->opcode, 0, 4);
21846 int u = extract32(ctx->opcode, 4, 4) << 4;
21848 rt = 30 + extract32(ctx->opcode, 9, 1);
21849 switch (extract32(ctx->opcode, 8, 1)) {
21851 gen_save(ctx, rt, count, 0, u);
21853 case NM_RESTORE_JRC16:
21854 gen_restore(ctx, rt, count, 0, u);
21855 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21864 static const int gpr2reg1[] = {4, 5, 6, 7};
21865 static const int gpr2reg2[] = {5, 6, 7, 8};
21867 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21868 extract32(ctx->opcode, 8, 1);
21869 int r1 = gpr2reg1[rd2];
21870 int r2 = gpr2reg2[rd2];
21871 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21872 extract32(ctx->opcode, 0, 3);
21873 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21874 extract32(ctx->opcode, 5, 3);
21875 TCGv t0 = tcg_temp_new();
21876 TCGv t1 = tcg_temp_new();
21877 if (op == NM_MOVEP) {
21880 rs = decode_gpr_gpr4_zero(r3);
21881 rt = decode_gpr_gpr4_zero(r4);
21883 rd = decode_gpr_gpr4(r3);
21884 re = decode_gpr_gpr4(r4);
21888 gen_load_gpr(t0, rs);
21889 gen_load_gpr(t1, rt);
21890 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21891 tcg_gen_mov_tl(cpu_gpr[re], t1);
21897 return decode_nanomips_32_48_opc(env, ctx);
21904 /* SmartMIPS extension to MIPS32 */
21906 #if defined(TARGET_MIPS64)
21908 /* MDMX extension to MIPS64 */
21912 /* MIPSDSP functions. */
21913 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
21914 int rd, int base, int offset)
21919 t0 = tcg_temp_new();
21922 gen_load_gpr(t0, offset);
21923 } else if (offset == 0) {
21924 gen_load_gpr(t0, base);
21926 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21931 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
21932 gen_store_gpr(t0, rd);
21935 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
21936 gen_store_gpr(t0, rd);
21939 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
21940 gen_store_gpr(t0, rd);
21942 #if defined(TARGET_MIPS64)
21944 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
21945 gen_store_gpr(t0, rd);
21952 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21953 int ret, int v1, int v2)
21959 /* Treat as NOP. */
21963 v1_t = tcg_temp_new();
21964 v2_t = tcg_temp_new();
21966 gen_load_gpr(v1_t, v1);
21967 gen_load_gpr(v2_t, v2);
21970 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21971 case OPC_MULT_G_2E:
21975 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21977 case OPC_ADDUH_R_QB:
21978 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21981 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21983 case OPC_ADDQH_R_PH:
21984 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21987 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21989 case OPC_ADDQH_R_W:
21990 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21993 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21995 case OPC_SUBUH_R_QB:
21996 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21999 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22001 case OPC_SUBQH_R_PH:
22002 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22005 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22007 case OPC_SUBQH_R_W:
22008 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22012 case OPC_ABSQ_S_PH_DSP:
22014 case OPC_ABSQ_S_QB:
22016 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22018 case OPC_ABSQ_S_PH:
22020 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22024 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22026 case OPC_PRECEQ_W_PHL:
22028 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22029 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22031 case OPC_PRECEQ_W_PHR:
22033 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22034 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22035 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22037 case OPC_PRECEQU_PH_QBL:
22039 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22041 case OPC_PRECEQU_PH_QBR:
22043 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22045 case OPC_PRECEQU_PH_QBLA:
22047 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22049 case OPC_PRECEQU_PH_QBRA:
22051 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22053 case OPC_PRECEU_PH_QBL:
22055 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22057 case OPC_PRECEU_PH_QBR:
22059 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22061 case OPC_PRECEU_PH_QBLA:
22063 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22065 case OPC_PRECEU_PH_QBRA:
22067 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22071 case OPC_ADDU_QB_DSP:
22075 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22077 case OPC_ADDQ_S_PH:
22079 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22083 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22087 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22089 case OPC_ADDU_S_QB:
22091 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22095 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22097 case OPC_ADDU_S_PH:
22099 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22103 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22105 case OPC_SUBQ_S_PH:
22107 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22111 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22115 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22117 case OPC_SUBU_S_QB:
22119 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22123 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22125 case OPC_SUBU_S_PH:
22127 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22131 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22135 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22139 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22141 case OPC_RADDU_W_QB:
22143 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22147 case OPC_CMPU_EQ_QB_DSP:
22149 case OPC_PRECR_QB_PH:
22151 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22153 case OPC_PRECRQ_QB_PH:
22155 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22157 case OPC_PRECR_SRA_PH_W:
22160 TCGv_i32 sa_t = tcg_const_i32(v2);
22161 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22163 tcg_temp_free_i32(sa_t);
22166 case OPC_PRECR_SRA_R_PH_W:
22169 TCGv_i32 sa_t = tcg_const_i32(v2);
22170 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22172 tcg_temp_free_i32(sa_t);
22175 case OPC_PRECRQ_PH_W:
22177 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22179 case OPC_PRECRQ_RS_PH_W:
22181 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22183 case OPC_PRECRQU_S_QB_PH:
22185 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22189 #ifdef TARGET_MIPS64
22190 case OPC_ABSQ_S_QH_DSP:
22192 case OPC_PRECEQ_L_PWL:
22194 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22196 case OPC_PRECEQ_L_PWR:
22198 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22200 case OPC_PRECEQ_PW_QHL:
22202 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22204 case OPC_PRECEQ_PW_QHR:
22206 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22208 case OPC_PRECEQ_PW_QHLA:
22210 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22212 case OPC_PRECEQ_PW_QHRA:
22214 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22216 case OPC_PRECEQU_QH_OBL:
22218 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22220 case OPC_PRECEQU_QH_OBR:
22222 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22224 case OPC_PRECEQU_QH_OBLA:
22226 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22228 case OPC_PRECEQU_QH_OBRA:
22230 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22232 case OPC_PRECEU_QH_OBL:
22234 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22236 case OPC_PRECEU_QH_OBR:
22238 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22240 case OPC_PRECEU_QH_OBLA:
22242 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22244 case OPC_PRECEU_QH_OBRA:
22246 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22248 case OPC_ABSQ_S_OB:
22250 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22252 case OPC_ABSQ_S_PW:
22254 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22256 case OPC_ABSQ_S_QH:
22258 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22262 case OPC_ADDU_OB_DSP:
22264 case OPC_RADDU_L_OB:
22266 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22270 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22272 case OPC_SUBQ_S_PW:
22274 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22278 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22280 case OPC_SUBQ_S_QH:
22282 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22286 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22288 case OPC_SUBU_S_OB:
22290 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22294 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22296 case OPC_SUBU_S_QH:
22298 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22302 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22304 case OPC_SUBUH_R_OB:
22306 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22310 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22312 case OPC_ADDQ_S_PW:
22314 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22318 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22320 case OPC_ADDQ_S_QH:
22322 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22326 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22328 case OPC_ADDU_S_OB:
22330 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22334 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22336 case OPC_ADDU_S_QH:
22338 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22342 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22344 case OPC_ADDUH_R_OB:
22346 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22350 case OPC_CMPU_EQ_OB_DSP:
22352 case OPC_PRECR_OB_QH:
22354 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22356 case OPC_PRECR_SRA_QH_PW:
22359 TCGv_i32 ret_t = tcg_const_i32(ret);
22360 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22361 tcg_temp_free_i32(ret_t);
22364 case OPC_PRECR_SRA_R_QH_PW:
22367 TCGv_i32 sa_v = tcg_const_i32(ret);
22368 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22369 tcg_temp_free_i32(sa_v);
22372 case OPC_PRECRQ_OB_QH:
22374 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22376 case OPC_PRECRQ_PW_L:
22378 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22380 case OPC_PRECRQ_QH_PW:
22382 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22384 case OPC_PRECRQ_RS_QH_PW:
22386 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22388 case OPC_PRECRQU_S_OB_QH:
22390 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22397 tcg_temp_free(v1_t);
22398 tcg_temp_free(v2_t);
22401 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22402 int ret, int v1, int v2)
22410 /* Treat as NOP. */
22414 t0 = tcg_temp_new();
22415 v1_t = tcg_temp_new();
22416 v2_t = tcg_temp_new();
22418 tcg_gen_movi_tl(t0, v1);
22419 gen_load_gpr(v1_t, v1);
22420 gen_load_gpr(v2_t, v2);
22423 case OPC_SHLL_QB_DSP:
22425 op2 = MASK_SHLL_QB(ctx->opcode);
22429 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22433 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22437 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22441 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22443 case OPC_SHLL_S_PH:
22445 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22447 case OPC_SHLLV_S_PH:
22449 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22453 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22455 case OPC_SHLLV_S_W:
22457 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22461 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22465 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22469 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22473 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22477 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22479 case OPC_SHRA_R_QB:
22481 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22485 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22487 case OPC_SHRAV_R_QB:
22489 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22493 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22495 case OPC_SHRA_R_PH:
22497 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22501 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22503 case OPC_SHRAV_R_PH:
22505 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22509 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22511 case OPC_SHRAV_R_W:
22513 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22515 default: /* Invalid */
22516 MIPS_INVAL("MASK SHLL.QB");
22517 generate_exception_end(ctx, EXCP_RI);
22522 #ifdef TARGET_MIPS64
22523 case OPC_SHLL_OB_DSP:
22524 op2 = MASK_SHLL_OB(ctx->opcode);
22528 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22532 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22534 case OPC_SHLL_S_PW:
22536 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22538 case OPC_SHLLV_S_PW:
22540 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22544 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22548 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22552 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22556 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22558 case OPC_SHLL_S_QH:
22560 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22562 case OPC_SHLLV_S_QH:
22564 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22568 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22572 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22574 case OPC_SHRA_R_OB:
22576 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22578 case OPC_SHRAV_R_OB:
22580 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22584 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22588 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22590 case OPC_SHRA_R_PW:
22592 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22594 case OPC_SHRAV_R_PW:
22596 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22600 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22604 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22606 case OPC_SHRA_R_QH:
22608 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22610 case OPC_SHRAV_R_QH:
22612 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22616 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22620 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22624 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22628 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22630 default: /* Invalid */
22631 MIPS_INVAL("MASK SHLL.OB");
22632 generate_exception_end(ctx, EXCP_RI);
22640 tcg_temp_free(v1_t);
22641 tcg_temp_free(v2_t);
22644 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22645 int ret, int v1, int v2, int check_ret)
22651 if ((ret == 0) && (check_ret == 1)) {
22652 /* Treat as NOP. */
22656 t0 = tcg_temp_new_i32();
22657 v1_t = tcg_temp_new();
22658 v2_t = tcg_temp_new();
22660 tcg_gen_movi_i32(t0, ret);
22661 gen_load_gpr(v1_t, v1);
22662 gen_load_gpr(v2_t, v2);
22665 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22666 * the same mask and op1. */
22667 case OPC_MULT_G_2E:
22671 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22674 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22677 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22679 case OPC_MULQ_RS_W:
22680 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22684 case OPC_DPA_W_PH_DSP:
22686 case OPC_DPAU_H_QBL:
22688 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22690 case OPC_DPAU_H_QBR:
22692 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22694 case OPC_DPSU_H_QBL:
22696 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22698 case OPC_DPSU_H_QBR:
22700 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22704 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22706 case OPC_DPAX_W_PH:
22708 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22710 case OPC_DPAQ_S_W_PH:
22712 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22714 case OPC_DPAQX_S_W_PH:
22716 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22718 case OPC_DPAQX_SA_W_PH:
22720 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22724 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22726 case OPC_DPSX_W_PH:
22728 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22730 case OPC_DPSQ_S_W_PH:
22732 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22734 case OPC_DPSQX_S_W_PH:
22736 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22738 case OPC_DPSQX_SA_W_PH:
22740 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22742 case OPC_MULSAQ_S_W_PH:
22744 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22746 case OPC_DPAQ_SA_L_W:
22748 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22750 case OPC_DPSQ_SA_L_W:
22752 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22754 case OPC_MAQ_S_W_PHL:
22756 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22758 case OPC_MAQ_S_W_PHR:
22760 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22762 case OPC_MAQ_SA_W_PHL:
22764 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22766 case OPC_MAQ_SA_W_PHR:
22768 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22770 case OPC_MULSA_W_PH:
22772 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22776 #ifdef TARGET_MIPS64
22777 case OPC_DPAQ_W_QH_DSP:
22779 int ac = ret & 0x03;
22780 tcg_gen_movi_i32(t0, ac);
22785 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22789 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22793 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22797 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22801 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22803 case OPC_DPAQ_S_W_QH:
22805 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22807 case OPC_DPAQ_SA_L_PW:
22809 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22811 case OPC_DPAU_H_OBL:
22813 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22815 case OPC_DPAU_H_OBR:
22817 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22821 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22823 case OPC_DPSQ_S_W_QH:
22825 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22827 case OPC_DPSQ_SA_L_PW:
22829 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22831 case OPC_DPSU_H_OBL:
22833 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22835 case OPC_DPSU_H_OBR:
22837 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22839 case OPC_MAQ_S_L_PWL:
22841 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22843 case OPC_MAQ_S_L_PWR:
22845 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22847 case OPC_MAQ_S_W_QHLL:
22849 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22851 case OPC_MAQ_SA_W_QHLL:
22853 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22855 case OPC_MAQ_S_W_QHLR:
22857 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22859 case OPC_MAQ_SA_W_QHLR:
22861 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22863 case OPC_MAQ_S_W_QHRL:
22865 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22867 case OPC_MAQ_SA_W_QHRL:
22869 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22871 case OPC_MAQ_S_W_QHRR:
22873 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22875 case OPC_MAQ_SA_W_QHRR:
22877 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22879 case OPC_MULSAQ_S_L_PW:
22881 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22883 case OPC_MULSAQ_S_W_QH:
22885 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22891 case OPC_ADDU_QB_DSP:
22893 case OPC_MULEU_S_PH_QBL:
22895 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22897 case OPC_MULEU_S_PH_QBR:
22899 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22901 case OPC_MULQ_RS_PH:
22903 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22905 case OPC_MULEQ_S_W_PHL:
22907 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22909 case OPC_MULEQ_S_W_PHR:
22911 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22913 case OPC_MULQ_S_PH:
22915 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22919 #ifdef TARGET_MIPS64
22920 case OPC_ADDU_OB_DSP:
22922 case OPC_MULEQ_S_PW_QHL:
22924 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22926 case OPC_MULEQ_S_PW_QHR:
22928 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22930 case OPC_MULEU_S_QH_OBL:
22932 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22934 case OPC_MULEU_S_QH_OBR:
22936 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22938 case OPC_MULQ_RS_QH:
22940 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22947 tcg_temp_free_i32(t0);
22948 tcg_temp_free(v1_t);
22949 tcg_temp_free(v2_t);
22952 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22960 /* Treat as NOP. */
22964 t0 = tcg_temp_new();
22965 val_t = tcg_temp_new();
22966 gen_load_gpr(val_t, val);
22969 case OPC_ABSQ_S_PH_DSP:
22973 gen_helper_bitrev(cpu_gpr[ret], val_t);
22978 target_long result;
22979 imm = (ctx->opcode >> 16) & 0xFF;
22980 result = (uint32_t)imm << 24 |
22981 (uint32_t)imm << 16 |
22982 (uint32_t)imm << 8 |
22984 result = (int32_t)result;
22985 tcg_gen_movi_tl(cpu_gpr[ret], result);
22990 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22991 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22992 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22993 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22994 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22995 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23000 imm = (ctx->opcode >> 16) & 0x03FF;
23001 imm = (int16_t)(imm << 6) >> 6;
23002 tcg_gen_movi_tl(cpu_gpr[ret], \
23003 (target_long)((int32_t)imm << 16 | \
23009 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23010 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23011 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23012 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23016 #ifdef TARGET_MIPS64
23017 case OPC_ABSQ_S_QH_DSP:
23024 imm = (ctx->opcode >> 16) & 0xFF;
23025 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23026 temp = (temp << 16) | temp;
23027 temp = (temp << 32) | temp;
23028 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23036 imm = (ctx->opcode >> 16) & 0x03FF;
23037 imm = (int16_t)(imm << 6) >> 6;
23038 temp = ((target_long)imm << 32) \
23039 | ((target_long)imm & 0xFFFFFFFF);
23040 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23048 imm = (ctx->opcode >> 16) & 0x03FF;
23049 imm = (int16_t)(imm << 6) >> 6;
23051 temp = ((uint64_t)(uint16_t)imm << 48) |
23052 ((uint64_t)(uint16_t)imm << 32) |
23053 ((uint64_t)(uint16_t)imm << 16) |
23054 (uint64_t)(uint16_t)imm;
23055 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23060 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23061 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23062 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23063 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23064 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23065 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23066 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23070 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23071 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23072 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23076 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23077 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23078 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23079 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23080 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23087 tcg_temp_free(val_t);
23090 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23091 uint32_t op1, uint32_t op2,
23092 int ret, int v1, int v2, int check_ret)
23098 if ((ret == 0) && (check_ret == 1)) {
23099 /* Treat as NOP. */
23103 t1 = tcg_temp_new();
23104 v1_t = tcg_temp_new();
23105 v2_t = tcg_temp_new();
23107 gen_load_gpr(v1_t, v1);
23108 gen_load_gpr(v2_t, v2);
23111 case OPC_CMPU_EQ_QB_DSP:
23113 case OPC_CMPU_EQ_QB:
23115 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23117 case OPC_CMPU_LT_QB:
23119 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23121 case OPC_CMPU_LE_QB:
23123 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23125 case OPC_CMPGU_EQ_QB:
23127 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23129 case OPC_CMPGU_LT_QB:
23131 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23133 case OPC_CMPGU_LE_QB:
23135 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23137 case OPC_CMPGDU_EQ_QB:
23139 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23140 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23141 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23142 tcg_gen_shli_tl(t1, t1, 24);
23143 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23145 case OPC_CMPGDU_LT_QB:
23147 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23148 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23149 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23150 tcg_gen_shli_tl(t1, t1, 24);
23151 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23153 case OPC_CMPGDU_LE_QB:
23155 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23156 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23157 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23158 tcg_gen_shli_tl(t1, t1, 24);
23159 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23161 case OPC_CMP_EQ_PH:
23163 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23165 case OPC_CMP_LT_PH:
23167 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23169 case OPC_CMP_LE_PH:
23171 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23175 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23179 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23181 case OPC_PACKRL_PH:
23183 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23187 #ifdef TARGET_MIPS64
23188 case OPC_CMPU_EQ_OB_DSP:
23190 case OPC_CMP_EQ_PW:
23192 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23194 case OPC_CMP_LT_PW:
23196 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23198 case OPC_CMP_LE_PW:
23200 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23202 case OPC_CMP_EQ_QH:
23204 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23206 case OPC_CMP_LT_QH:
23208 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23210 case OPC_CMP_LE_QH:
23212 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23214 case OPC_CMPGDU_EQ_OB:
23216 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23218 case OPC_CMPGDU_LT_OB:
23220 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23222 case OPC_CMPGDU_LE_OB:
23224 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23226 case OPC_CMPGU_EQ_OB:
23228 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23230 case OPC_CMPGU_LT_OB:
23232 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23234 case OPC_CMPGU_LE_OB:
23236 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23238 case OPC_CMPU_EQ_OB:
23240 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23242 case OPC_CMPU_LT_OB:
23244 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23246 case OPC_CMPU_LE_OB:
23248 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23250 case OPC_PACKRL_PW:
23252 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23256 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23260 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23264 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23272 tcg_temp_free(v1_t);
23273 tcg_temp_free(v2_t);
23276 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23277 uint32_t op1, int rt, int rs, int sa)
23284 /* Treat as NOP. */
23288 t0 = tcg_temp_new();
23289 gen_load_gpr(t0, rs);
23292 case OPC_APPEND_DSP:
23293 switch (MASK_APPEND(ctx->opcode)) {
23296 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23298 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23302 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23303 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23304 tcg_gen_shli_tl(t0, t0, 32 - sa);
23305 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23307 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23311 if (sa != 0 && sa != 2) {
23312 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23313 tcg_gen_ext32u_tl(t0, t0);
23314 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23315 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23317 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23319 default: /* Invalid */
23320 MIPS_INVAL("MASK APPEND");
23321 generate_exception_end(ctx, EXCP_RI);
23325 #ifdef TARGET_MIPS64
23326 case OPC_DAPPEND_DSP:
23327 switch (MASK_DAPPEND(ctx->opcode)) {
23330 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23334 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23335 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23336 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23340 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23341 tcg_gen_shli_tl(t0, t0, 64 - sa);
23342 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23347 if (sa != 0 && sa != 2 && sa != 4) {
23348 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23349 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23350 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23353 default: /* Invalid */
23354 MIPS_INVAL("MASK DAPPEND");
23355 generate_exception_end(ctx, EXCP_RI);
23364 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23365 int ret, int v1, int v2, int check_ret)
23374 if ((ret == 0) && (check_ret == 1)) {
23375 /* Treat as NOP. */
23379 t0 = tcg_temp_new();
23380 t1 = tcg_temp_new();
23381 v1_t = tcg_temp_new();
23382 v2_t = tcg_temp_new();
23384 gen_load_gpr(v1_t, v1);
23385 gen_load_gpr(v2_t, v2);
23388 case OPC_EXTR_W_DSP:
23392 tcg_gen_movi_tl(t0, v2);
23393 tcg_gen_movi_tl(t1, v1);
23394 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23397 tcg_gen_movi_tl(t0, v2);
23398 tcg_gen_movi_tl(t1, v1);
23399 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23401 case OPC_EXTR_RS_W:
23402 tcg_gen_movi_tl(t0, v2);
23403 tcg_gen_movi_tl(t1, v1);
23404 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23407 tcg_gen_movi_tl(t0, v2);
23408 tcg_gen_movi_tl(t1, v1);
23409 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23411 case OPC_EXTRV_S_H:
23412 tcg_gen_movi_tl(t0, v2);
23413 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23416 tcg_gen_movi_tl(t0, v2);
23417 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23419 case OPC_EXTRV_R_W:
23420 tcg_gen_movi_tl(t0, v2);
23421 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23423 case OPC_EXTRV_RS_W:
23424 tcg_gen_movi_tl(t0, v2);
23425 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23428 tcg_gen_movi_tl(t0, v2);
23429 tcg_gen_movi_tl(t1, v1);
23430 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23433 tcg_gen_movi_tl(t0, v2);
23434 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23437 tcg_gen_movi_tl(t0, v2);
23438 tcg_gen_movi_tl(t1, v1);
23439 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23442 tcg_gen_movi_tl(t0, v2);
23443 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23446 imm = (ctx->opcode >> 20) & 0x3F;
23447 tcg_gen_movi_tl(t0, ret);
23448 tcg_gen_movi_tl(t1, imm);
23449 gen_helper_shilo(t0, t1, cpu_env);
23452 tcg_gen_movi_tl(t0, ret);
23453 gen_helper_shilo(t0, v1_t, cpu_env);
23456 tcg_gen_movi_tl(t0, ret);
23457 gen_helper_mthlip(t0, v1_t, cpu_env);
23460 imm = (ctx->opcode >> 11) & 0x3FF;
23461 tcg_gen_movi_tl(t0, imm);
23462 gen_helper_wrdsp(v1_t, t0, cpu_env);
23465 imm = (ctx->opcode >> 16) & 0x03FF;
23466 tcg_gen_movi_tl(t0, imm);
23467 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23471 #ifdef TARGET_MIPS64
23472 case OPC_DEXTR_W_DSP:
23476 tcg_gen_movi_tl(t0, ret);
23477 gen_helper_dmthlip(v1_t, t0, cpu_env);
23481 int shift = (ctx->opcode >> 19) & 0x7F;
23482 int ac = (ctx->opcode >> 11) & 0x03;
23483 tcg_gen_movi_tl(t0, shift);
23484 tcg_gen_movi_tl(t1, ac);
23485 gen_helper_dshilo(t0, t1, cpu_env);
23490 int ac = (ctx->opcode >> 11) & 0x03;
23491 tcg_gen_movi_tl(t0, ac);
23492 gen_helper_dshilo(v1_t, t0, cpu_env);
23496 tcg_gen_movi_tl(t0, v2);
23497 tcg_gen_movi_tl(t1, v1);
23499 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23502 tcg_gen_movi_tl(t0, v2);
23503 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23506 tcg_gen_movi_tl(t0, v2);
23507 tcg_gen_movi_tl(t1, v1);
23508 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23511 tcg_gen_movi_tl(t0, v2);
23512 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23515 tcg_gen_movi_tl(t0, v2);
23516 tcg_gen_movi_tl(t1, v1);
23517 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23519 case OPC_DEXTR_R_L:
23520 tcg_gen_movi_tl(t0, v2);
23521 tcg_gen_movi_tl(t1, v1);
23522 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23524 case OPC_DEXTR_RS_L:
23525 tcg_gen_movi_tl(t0, v2);
23526 tcg_gen_movi_tl(t1, v1);
23527 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23530 tcg_gen_movi_tl(t0, v2);
23531 tcg_gen_movi_tl(t1, v1);
23532 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23534 case OPC_DEXTR_R_W:
23535 tcg_gen_movi_tl(t0, v2);
23536 tcg_gen_movi_tl(t1, v1);
23537 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23539 case OPC_DEXTR_RS_W:
23540 tcg_gen_movi_tl(t0, v2);
23541 tcg_gen_movi_tl(t1, v1);
23542 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23544 case OPC_DEXTR_S_H:
23545 tcg_gen_movi_tl(t0, v2);
23546 tcg_gen_movi_tl(t1, v1);
23547 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23549 case OPC_DEXTRV_S_H:
23550 tcg_gen_movi_tl(t0, v2);
23551 tcg_gen_movi_tl(t1, v1);
23552 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23555 tcg_gen_movi_tl(t0, v2);
23556 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23558 case OPC_DEXTRV_R_L:
23559 tcg_gen_movi_tl(t0, v2);
23560 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23562 case OPC_DEXTRV_RS_L:
23563 tcg_gen_movi_tl(t0, v2);
23564 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23567 tcg_gen_movi_tl(t0, v2);
23568 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23570 case OPC_DEXTRV_R_W:
23571 tcg_gen_movi_tl(t0, v2);
23572 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23574 case OPC_DEXTRV_RS_W:
23575 tcg_gen_movi_tl(t0, v2);
23576 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23585 tcg_temp_free(v1_t);
23586 tcg_temp_free(v2_t);
23589 /* End MIPSDSP functions. */
23591 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23593 int rs, rt, rd, sa;
23596 rs = (ctx->opcode >> 21) & 0x1f;
23597 rt = (ctx->opcode >> 16) & 0x1f;
23598 rd = (ctx->opcode >> 11) & 0x1f;
23599 sa = (ctx->opcode >> 6) & 0x1f;
23601 op1 = MASK_SPECIAL(ctx->opcode);
23604 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23610 op2 = MASK_R6_MULDIV(ctx->opcode);
23620 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23623 MIPS_INVAL("special_r6 muldiv");
23624 generate_exception_end(ctx, EXCP_RI);
23630 gen_cond_move(ctx, op1, rd, rs, rt);
23634 if (rt == 0 && sa == 1) {
23635 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23636 We need additionally to check other fields */
23637 gen_cl(ctx, op1, rd, rs);
23639 generate_exception_end(ctx, EXCP_RI);
23643 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23644 gen_helper_do_semihosting(cpu_env);
23646 if (ctx->hflags & MIPS_HFLAG_SBRI) {
23647 generate_exception_end(ctx, EXCP_RI);
23649 generate_exception_end(ctx, EXCP_DBp);
23653 #if defined(TARGET_MIPS64)
23655 check_mips_64(ctx);
23656 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23660 if (rt == 0 && sa == 1) {
23661 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23662 We need additionally to check other fields */
23663 check_mips_64(ctx);
23664 gen_cl(ctx, op1, rd, rs);
23666 generate_exception_end(ctx, EXCP_RI);
23674 op2 = MASK_R6_MULDIV(ctx->opcode);
23684 check_mips_64(ctx);
23685 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23688 MIPS_INVAL("special_r6 muldiv");
23689 generate_exception_end(ctx, EXCP_RI);
23694 default: /* Invalid */
23695 MIPS_INVAL("special_r6");
23696 generate_exception_end(ctx, EXCP_RI);
23701 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23703 int rs, rt, rd, sa;
23706 rs = (ctx->opcode >> 21) & 0x1f;
23707 rt = (ctx->opcode >> 16) & 0x1f;
23708 rd = (ctx->opcode >> 11) & 0x1f;
23709 sa = (ctx->opcode >> 6) & 0x1f;
23711 op1 = MASK_SPECIAL(ctx->opcode);
23713 case OPC_MOVN: /* Conditional move */
23715 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
23716 INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900);
23717 gen_cond_move(ctx, op1, rd, rs, rt);
23719 case OPC_MFHI: /* Move from HI/LO */
23721 gen_HILO(ctx, op1, rs & 3, rd);
23724 case OPC_MTLO: /* Move to HI/LO */
23725 gen_HILO(ctx, op1, rd & 3, rs);
23728 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23729 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23730 check_cp1_enabled(ctx);
23731 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23732 (ctx->opcode >> 16) & 1);
23734 generate_exception_err(ctx, EXCP_CpU, 1);
23740 check_insn(ctx, INSN_VR54XX);
23741 op1 = MASK_MUL_VR54XX(ctx->opcode);
23742 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23743 } else if (ctx->insn_flags & INSN_R5900) {
23744 gen_mul_txx9(ctx, op1, rd, rs, rt);
23746 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23751 gen_muldiv(ctx, op1, 0, rs, rt);
23753 #if defined(TARGET_MIPS64)
23758 check_insn(ctx, ISA_MIPS3);
23759 check_insn_opc_user_only(ctx, INSN_R5900);
23760 check_mips_64(ctx);
23761 gen_muldiv(ctx, op1, 0, rs, rt);
23765 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23768 #ifdef MIPS_STRICT_STANDARD
23769 MIPS_INVAL("SPIM");
23770 generate_exception_end(ctx, EXCP_RI);
23772 /* Implemented as RI exception for now. */
23773 MIPS_INVAL("spim (unofficial)");
23774 generate_exception_end(ctx, EXCP_RI);
23777 default: /* Invalid */
23778 MIPS_INVAL("special_legacy");
23779 generate_exception_end(ctx, EXCP_RI);
23784 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
23786 int rs, rt, rd, sa;
23789 rs = (ctx->opcode >> 21) & 0x1f;
23790 rt = (ctx->opcode >> 16) & 0x1f;
23791 rd = (ctx->opcode >> 11) & 0x1f;
23792 sa = (ctx->opcode >> 6) & 0x1f;
23794 op1 = MASK_SPECIAL(ctx->opcode);
23796 case OPC_SLL: /* Shift with immediate */
23797 if (sa == 5 && rd == 0 &&
23798 rs == 0 && rt == 0) { /* PAUSE */
23799 if ((ctx->insn_flags & ISA_MIPS32R6) &&
23800 (ctx->hflags & MIPS_HFLAG_BMASK)) {
23801 generate_exception_end(ctx, EXCP_RI);
23807 gen_shift_imm(ctx, op1, rd, rt, sa);
23810 switch ((ctx->opcode >> 21) & 0x1f) {
23812 /* rotr is decoded as srl on non-R2 CPUs */
23813 if (ctx->insn_flags & ISA_MIPS32R2) {
23818 gen_shift_imm(ctx, op1, rd, rt, sa);
23821 generate_exception_end(ctx, EXCP_RI);
23829 gen_arith(ctx, op1, rd, rs, rt);
23831 case OPC_SLLV: /* Shifts */
23833 gen_shift(ctx, op1, rd, rs, rt);
23836 switch ((ctx->opcode >> 6) & 0x1f) {
23838 /* rotrv is decoded as srlv on non-R2 CPUs */
23839 if (ctx->insn_flags & ISA_MIPS32R2) {
23844 gen_shift(ctx, op1, rd, rs, rt);
23847 generate_exception_end(ctx, EXCP_RI);
23851 case OPC_SLT: /* Set on less than */
23853 gen_slt(ctx, op1, rd, rs, rt);
23855 case OPC_AND: /* Logic*/
23859 gen_logic(ctx, op1, rd, rs, rt);
23862 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23864 case OPC_TGE: /* Traps */
23870 check_insn(ctx, ISA_MIPS2);
23871 gen_trap(ctx, op1, rs, rt, -1);
23873 case OPC_LSA: /* OPC_PMON */
23874 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23875 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23876 decode_opc_special_r6(env, ctx);
23878 /* Pmon entry point, also R4010 selsl */
23879 #ifdef MIPS_STRICT_STANDARD
23880 MIPS_INVAL("PMON / selsl");
23881 generate_exception_end(ctx, EXCP_RI);
23883 gen_helper_0e0i(pmon, sa);
23888 generate_exception_end(ctx, EXCP_SYSCALL);
23891 generate_exception_end(ctx, EXCP_BREAK);
23894 check_insn(ctx, ISA_MIPS2);
23895 gen_sync(extract32(ctx->opcode, 6, 5));
23898 #if defined(TARGET_MIPS64)
23899 /* MIPS64 specific opcodes */
23904 check_insn(ctx, ISA_MIPS3);
23905 check_mips_64(ctx);
23906 gen_shift_imm(ctx, op1, rd, rt, sa);
23909 switch ((ctx->opcode >> 21) & 0x1f) {
23911 /* drotr is decoded as dsrl on non-R2 CPUs */
23912 if (ctx->insn_flags & ISA_MIPS32R2) {
23917 check_insn(ctx, ISA_MIPS3);
23918 check_mips_64(ctx);
23919 gen_shift_imm(ctx, op1, rd, rt, sa);
23922 generate_exception_end(ctx, EXCP_RI);
23927 switch ((ctx->opcode >> 21) & 0x1f) {
23929 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23930 if (ctx->insn_flags & ISA_MIPS32R2) {
23935 check_insn(ctx, ISA_MIPS3);
23936 check_mips_64(ctx);
23937 gen_shift_imm(ctx, op1, rd, rt, sa);
23940 generate_exception_end(ctx, EXCP_RI);
23948 check_insn(ctx, ISA_MIPS3);
23949 check_mips_64(ctx);
23950 gen_arith(ctx, op1, rd, rs, rt);
23954 check_insn(ctx, ISA_MIPS3);
23955 check_mips_64(ctx);
23956 gen_shift(ctx, op1, rd, rs, rt);
23959 switch ((ctx->opcode >> 6) & 0x1f) {
23961 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23962 if (ctx->insn_flags & ISA_MIPS32R2) {
23967 check_insn(ctx, ISA_MIPS3);
23968 check_mips_64(ctx);
23969 gen_shift(ctx, op1, rd, rs, rt);
23972 generate_exception_end(ctx, EXCP_RI);
23977 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23978 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23979 decode_opc_special_r6(env, ctx);
23984 if (ctx->insn_flags & ISA_MIPS32R6) {
23985 decode_opc_special_r6(env, ctx);
23987 decode_opc_special_legacy(env, ctx);
23992 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
23997 check_insn_opc_removed(ctx, ISA_MIPS32R6);
23999 rs = (ctx->opcode >> 21) & 0x1f;
24000 rt = (ctx->opcode >> 16) & 0x1f;
24001 rd = (ctx->opcode >> 11) & 0x1f;
24003 op1 = MASK_SPECIAL2(ctx->opcode);
24005 case OPC_MADD: /* Multiply and add/sub */
24009 check_insn(ctx, ISA_MIPS32);
24010 gen_muldiv(ctx, op1, rd & 3, rs, rt);
24013 gen_arith(ctx, op1, rd, rs, rt);
24016 case OPC_DIVU_G_2F:
24017 case OPC_MULT_G_2F:
24018 case OPC_MULTU_G_2F:
24020 case OPC_MODU_G_2F:
24021 check_insn(ctx, INSN_LOONGSON2F);
24022 gen_loongson_integer(ctx, op1, rd, rs, rt);
24026 check_insn(ctx, ISA_MIPS32);
24027 gen_cl(ctx, op1, rd, rs);
24030 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
24031 gen_helper_do_semihosting(cpu_env);
24033 /* XXX: not clear which exception should be raised
24034 * when in debug mode...
24036 check_insn(ctx, ISA_MIPS32);
24037 generate_exception_end(ctx, EXCP_DBp);
24040 #if defined(TARGET_MIPS64)
24043 check_insn(ctx, ISA_MIPS64);
24044 check_mips_64(ctx);
24045 gen_cl(ctx, op1, rd, rs);
24047 case OPC_DMULT_G_2F:
24048 case OPC_DMULTU_G_2F:
24049 case OPC_DDIV_G_2F:
24050 case OPC_DDIVU_G_2F:
24051 case OPC_DMOD_G_2F:
24052 case OPC_DMODU_G_2F:
24053 check_insn(ctx, INSN_LOONGSON2F);
24054 gen_loongson_integer(ctx, op1, rd, rs, rt);
24057 default: /* Invalid */
24058 MIPS_INVAL("special2_legacy");
24059 generate_exception_end(ctx, EXCP_RI);
24064 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
24066 int rs, rt, rd, sa;
24070 rs = (ctx->opcode >> 21) & 0x1f;
24071 rt = (ctx->opcode >> 16) & 0x1f;
24072 rd = (ctx->opcode >> 11) & 0x1f;
24073 sa = (ctx->opcode >> 6) & 0x1f;
24074 imm = (int16_t)ctx->opcode >> 7;
24076 op1 = MASK_SPECIAL3(ctx->opcode);
24080 /* hint codes 24-31 are reserved and signal RI */
24081 generate_exception_end(ctx, EXCP_RI);
24083 /* Treat as NOP. */
24086 check_cp0_enabled(ctx);
24087 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
24088 gen_cache_operation(ctx, rt, rs, imm);
24092 gen_st_cond(ctx, op1, rt, rs, imm);
24095 gen_ld(ctx, op1, rt, rs, imm);
24100 /* Treat as NOP. */
24103 op2 = MASK_BSHFL(ctx->opcode);
24109 gen_align(ctx, 32, rd, rs, rt, sa & 3);
24112 gen_bitswap(ctx, op2, rd, rt);
24117 #if defined(TARGET_MIPS64)
24119 gen_st_cond(ctx, op1, rt, rs, imm);
24122 gen_ld(ctx, op1, rt, rs, imm);
24125 check_mips_64(ctx);
24128 /* Treat as NOP. */
24131 op2 = MASK_DBSHFL(ctx->opcode);
24141 gen_align(ctx, 64, rd, rs, rt, sa & 7);
24144 gen_bitswap(ctx, op2, rd, rt);
24151 default: /* Invalid */
24152 MIPS_INVAL("special3_r6");
24153 generate_exception_end(ctx, EXCP_RI);
24158 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
24163 rs = (ctx->opcode >> 21) & 0x1f;
24164 rt = (ctx->opcode >> 16) & 0x1f;
24165 rd = (ctx->opcode >> 11) & 0x1f;
24167 op1 = MASK_SPECIAL3(ctx->opcode);
24170 case OPC_DIVU_G_2E:
24172 case OPC_MODU_G_2E:
24173 case OPC_MULT_G_2E:
24174 case OPC_MULTU_G_2E:
24175 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
24176 * the same mask and op1. */
24177 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
24178 op2 = MASK_ADDUH_QB(ctx->opcode);
24181 case OPC_ADDUH_R_QB:
24183 case OPC_ADDQH_R_PH:
24185 case OPC_ADDQH_R_W:
24187 case OPC_SUBUH_R_QB:
24189 case OPC_SUBQH_R_PH:
24191 case OPC_SUBQH_R_W:
24192 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24197 case OPC_MULQ_RS_W:
24198 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
24201 MIPS_INVAL("MASK ADDUH.QB");
24202 generate_exception_end(ctx, EXCP_RI);
24205 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
24206 gen_loongson_integer(ctx, op1, rd, rs, rt);
24208 generate_exception_end(ctx, EXCP_RI);
24212 op2 = MASK_LX(ctx->opcode);
24214 #if defined(TARGET_MIPS64)
24220 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
24222 default: /* Invalid */
24223 MIPS_INVAL("MASK LX");
24224 generate_exception_end(ctx, EXCP_RI);
24228 case OPC_ABSQ_S_PH_DSP:
24229 op2 = MASK_ABSQ_S_PH(ctx->opcode);
24231 case OPC_ABSQ_S_QB:
24232 case OPC_ABSQ_S_PH:
24234 case OPC_PRECEQ_W_PHL:
24235 case OPC_PRECEQ_W_PHR:
24236 case OPC_PRECEQU_PH_QBL:
24237 case OPC_PRECEQU_PH_QBR:
24238 case OPC_PRECEQU_PH_QBLA:
24239 case OPC_PRECEQU_PH_QBRA:
24240 case OPC_PRECEU_PH_QBL:
24241 case OPC_PRECEU_PH_QBR:
24242 case OPC_PRECEU_PH_QBLA:
24243 case OPC_PRECEU_PH_QBRA:
24244 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24251 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
24254 MIPS_INVAL("MASK ABSQ_S.PH");
24255 generate_exception_end(ctx, EXCP_RI);
24259 case OPC_ADDU_QB_DSP:
24260 op2 = MASK_ADDU_QB(ctx->opcode);
24263 case OPC_ADDQ_S_PH:
24266 case OPC_ADDU_S_QB:
24268 case OPC_ADDU_S_PH:
24270 case OPC_SUBQ_S_PH:
24273 case OPC_SUBU_S_QB:
24275 case OPC_SUBU_S_PH:
24279 case OPC_RADDU_W_QB:
24280 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24282 case OPC_MULEU_S_PH_QBL:
24283 case OPC_MULEU_S_PH_QBR:
24284 case OPC_MULQ_RS_PH:
24285 case OPC_MULEQ_S_W_PHL:
24286 case OPC_MULEQ_S_W_PHR:
24287 case OPC_MULQ_S_PH:
24288 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
24290 default: /* Invalid */
24291 MIPS_INVAL("MASK ADDU.QB");
24292 generate_exception_end(ctx, EXCP_RI);
24297 case OPC_CMPU_EQ_QB_DSP:
24298 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
24300 case OPC_PRECR_SRA_PH_W:
24301 case OPC_PRECR_SRA_R_PH_W:
24302 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
24304 case OPC_PRECR_QB_PH:
24305 case OPC_PRECRQ_QB_PH:
24306 case OPC_PRECRQ_PH_W:
24307 case OPC_PRECRQ_RS_PH_W:
24308 case OPC_PRECRQU_S_QB_PH:
24309 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24311 case OPC_CMPU_EQ_QB:
24312 case OPC_CMPU_LT_QB:
24313 case OPC_CMPU_LE_QB:
24314 case OPC_CMP_EQ_PH:
24315 case OPC_CMP_LT_PH:
24316 case OPC_CMP_LE_PH:
24317 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
24319 case OPC_CMPGU_EQ_QB:
24320 case OPC_CMPGU_LT_QB:
24321 case OPC_CMPGU_LE_QB:
24322 case OPC_CMPGDU_EQ_QB:
24323 case OPC_CMPGDU_LT_QB:
24324 case OPC_CMPGDU_LE_QB:
24327 case OPC_PACKRL_PH:
24328 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
24330 default: /* Invalid */
24331 MIPS_INVAL("MASK CMPU.EQ.QB");
24332 generate_exception_end(ctx, EXCP_RI);
24336 case OPC_SHLL_QB_DSP:
24337 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
24339 case OPC_DPA_W_PH_DSP:
24340 op2 = MASK_DPA_W_PH(ctx->opcode);
24342 case OPC_DPAU_H_QBL:
24343 case OPC_DPAU_H_QBR:
24344 case OPC_DPSU_H_QBL:
24345 case OPC_DPSU_H_QBR:
24347 case OPC_DPAX_W_PH:
24348 case OPC_DPAQ_S_W_PH:
24349 case OPC_DPAQX_S_W_PH:
24350 case OPC_DPAQX_SA_W_PH:
24352 case OPC_DPSX_W_PH:
24353 case OPC_DPSQ_S_W_PH:
24354 case OPC_DPSQX_S_W_PH:
24355 case OPC_DPSQX_SA_W_PH:
24356 case OPC_MULSAQ_S_W_PH:
24357 case OPC_DPAQ_SA_L_W:
24358 case OPC_DPSQ_SA_L_W:
24359 case OPC_MAQ_S_W_PHL:
24360 case OPC_MAQ_S_W_PHR:
24361 case OPC_MAQ_SA_W_PHL:
24362 case OPC_MAQ_SA_W_PHR:
24363 case OPC_MULSA_W_PH:
24364 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24366 default: /* Invalid */
24367 MIPS_INVAL("MASK DPAW.PH");
24368 generate_exception_end(ctx, EXCP_RI);
24373 op2 = MASK_INSV(ctx->opcode);
24384 t0 = tcg_temp_new();
24385 t1 = tcg_temp_new();
24387 gen_load_gpr(t0, rt);
24388 gen_load_gpr(t1, rs);
24390 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
24396 default: /* Invalid */
24397 MIPS_INVAL("MASK INSV");
24398 generate_exception_end(ctx, EXCP_RI);
24402 case OPC_APPEND_DSP:
24403 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
24405 case OPC_EXTR_W_DSP:
24406 op2 = MASK_EXTR_W(ctx->opcode);
24410 case OPC_EXTR_RS_W:
24412 case OPC_EXTRV_S_H:
24414 case OPC_EXTRV_R_W:
24415 case OPC_EXTRV_RS_W:
24420 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
24423 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
24429 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
24431 default: /* Invalid */
24432 MIPS_INVAL("MASK EXTR.W");
24433 generate_exception_end(ctx, EXCP_RI);
24437 #if defined(TARGET_MIPS64)
24438 case OPC_DDIV_G_2E:
24439 case OPC_DDIVU_G_2E:
24440 case OPC_DMULT_G_2E:
24441 case OPC_DMULTU_G_2E:
24442 case OPC_DMOD_G_2E:
24443 case OPC_DMODU_G_2E:
24444 check_insn(ctx, INSN_LOONGSON2E);
24445 gen_loongson_integer(ctx, op1, rd, rs, rt);
24447 case OPC_ABSQ_S_QH_DSP:
24448 op2 = MASK_ABSQ_S_QH(ctx->opcode);
24450 case OPC_PRECEQ_L_PWL:
24451 case OPC_PRECEQ_L_PWR:
24452 case OPC_PRECEQ_PW_QHL:
24453 case OPC_PRECEQ_PW_QHR:
24454 case OPC_PRECEQ_PW_QHLA:
24455 case OPC_PRECEQ_PW_QHRA:
24456 case OPC_PRECEQU_QH_OBL:
24457 case OPC_PRECEQU_QH_OBR:
24458 case OPC_PRECEQU_QH_OBLA:
24459 case OPC_PRECEQU_QH_OBRA:
24460 case OPC_PRECEU_QH_OBL:
24461 case OPC_PRECEU_QH_OBR:
24462 case OPC_PRECEU_QH_OBLA:
24463 case OPC_PRECEU_QH_OBRA:
24464 case OPC_ABSQ_S_OB:
24465 case OPC_ABSQ_S_PW:
24466 case OPC_ABSQ_S_QH:
24467 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24475 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
24477 default: /* Invalid */
24478 MIPS_INVAL("MASK ABSQ_S.QH");
24479 generate_exception_end(ctx, EXCP_RI);
24483 case OPC_ADDU_OB_DSP:
24484 op2 = MASK_ADDU_OB(ctx->opcode);
24486 case OPC_RADDU_L_OB:
24488 case OPC_SUBQ_S_PW:
24490 case OPC_SUBQ_S_QH:
24492 case OPC_SUBU_S_OB:
24494 case OPC_SUBU_S_QH:
24496 case OPC_SUBUH_R_OB:
24498 case OPC_ADDQ_S_PW:
24500 case OPC_ADDQ_S_QH:
24502 case OPC_ADDU_S_OB:
24504 case OPC_ADDU_S_QH:
24506 case OPC_ADDUH_R_OB:
24507 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24509 case OPC_MULEQ_S_PW_QHL:
24510 case OPC_MULEQ_S_PW_QHR:
24511 case OPC_MULEU_S_QH_OBL:
24512 case OPC_MULEU_S_QH_OBR:
24513 case OPC_MULQ_RS_QH:
24514 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
24516 default: /* Invalid */
24517 MIPS_INVAL("MASK ADDU.OB");
24518 generate_exception_end(ctx, EXCP_RI);
24522 case OPC_CMPU_EQ_OB_DSP:
24523 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
24525 case OPC_PRECR_SRA_QH_PW:
24526 case OPC_PRECR_SRA_R_QH_PW:
24527 /* Return value is rt. */
24528 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
24530 case OPC_PRECR_OB_QH:
24531 case OPC_PRECRQ_OB_QH:
24532 case OPC_PRECRQ_PW_L:
24533 case OPC_PRECRQ_QH_PW:
24534 case OPC_PRECRQ_RS_QH_PW:
24535 case OPC_PRECRQU_S_OB_QH:
24536 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24538 case OPC_CMPU_EQ_OB:
24539 case OPC_CMPU_LT_OB:
24540 case OPC_CMPU_LE_OB:
24541 case OPC_CMP_EQ_QH:
24542 case OPC_CMP_LT_QH:
24543 case OPC_CMP_LE_QH:
24544 case OPC_CMP_EQ_PW:
24545 case OPC_CMP_LT_PW:
24546 case OPC_CMP_LE_PW:
24547 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
24549 case OPC_CMPGDU_EQ_OB:
24550 case OPC_CMPGDU_LT_OB:
24551 case OPC_CMPGDU_LE_OB:
24552 case OPC_CMPGU_EQ_OB:
24553 case OPC_CMPGU_LT_OB:
24554 case OPC_CMPGU_LE_OB:
24555 case OPC_PACKRL_PW:
24559 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
24561 default: /* Invalid */
24562 MIPS_INVAL("MASK CMPU_EQ.OB");
24563 generate_exception_end(ctx, EXCP_RI);
24567 case OPC_DAPPEND_DSP:
24568 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
24570 case OPC_DEXTR_W_DSP:
24571 op2 = MASK_DEXTR_W(ctx->opcode);
24578 case OPC_DEXTR_R_L:
24579 case OPC_DEXTR_RS_L:
24581 case OPC_DEXTR_R_W:
24582 case OPC_DEXTR_RS_W:
24583 case OPC_DEXTR_S_H:
24585 case OPC_DEXTRV_R_L:
24586 case OPC_DEXTRV_RS_L:
24587 case OPC_DEXTRV_S_H:
24589 case OPC_DEXTRV_R_W:
24590 case OPC_DEXTRV_RS_W:
24591 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
24596 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
24598 default: /* Invalid */
24599 MIPS_INVAL("MASK EXTR.W");
24600 generate_exception_end(ctx, EXCP_RI);
24604 case OPC_DPAQ_W_QH_DSP:
24605 op2 = MASK_DPAQ_W_QH(ctx->opcode);
24607 case OPC_DPAU_H_OBL:
24608 case OPC_DPAU_H_OBR:
24609 case OPC_DPSU_H_OBL:
24610 case OPC_DPSU_H_OBR:
24612 case OPC_DPAQ_S_W_QH:
24614 case OPC_DPSQ_S_W_QH:
24615 case OPC_MULSAQ_S_W_QH:
24616 case OPC_DPAQ_SA_L_PW:
24617 case OPC_DPSQ_SA_L_PW:
24618 case OPC_MULSAQ_S_L_PW:
24619 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24621 case OPC_MAQ_S_W_QHLL:
24622 case OPC_MAQ_S_W_QHLR:
24623 case OPC_MAQ_S_W_QHRL:
24624 case OPC_MAQ_S_W_QHRR:
24625 case OPC_MAQ_SA_W_QHLL:
24626 case OPC_MAQ_SA_W_QHLR:
24627 case OPC_MAQ_SA_W_QHRL:
24628 case OPC_MAQ_SA_W_QHRR:
24629 case OPC_MAQ_S_L_PWL:
24630 case OPC_MAQ_S_L_PWR:
24635 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24637 default: /* Invalid */
24638 MIPS_INVAL("MASK DPAQ.W.QH");
24639 generate_exception_end(ctx, EXCP_RI);
24643 case OPC_DINSV_DSP:
24644 op2 = MASK_INSV(ctx->opcode);
24655 t0 = tcg_temp_new();
24656 t1 = tcg_temp_new();
24658 gen_load_gpr(t0, rt);
24659 gen_load_gpr(t1, rs);
24661 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
24667 default: /* Invalid */
24668 MIPS_INVAL("MASK DINSV");
24669 generate_exception_end(ctx, EXCP_RI);
24673 case OPC_SHLL_OB_DSP:
24674 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
24677 default: /* Invalid */
24678 MIPS_INVAL("special3_legacy");
24679 generate_exception_end(ctx, EXCP_RI);
24684 static void decode_tx79_mmi0(CPUMIPSState *env, DisasContext *ctx)
24686 uint32_t opc = MASK_TX79_MMI0(ctx->opcode);
24689 case TX79_MMI0_PADDW: /* TODO: TX79_MMI0_PADDW */
24690 case TX79_MMI0_PSUBW: /* TODO: TX79_MMI0_PSUBW */
24691 case TX79_MMI0_PCGTW: /* TODO: TX79_MMI0_PCGTW */
24692 case TX79_MMI0_PMAXW: /* TODO: TX79_MMI0_PMAXW */
24693 case TX79_MMI0_PADDH: /* TODO: TX79_MMI0_PADDH */
24694 case TX79_MMI0_PSUBH: /* TODO: TX79_MMI0_PSUBH */
24695 case TX79_MMI0_PCGTH: /* TODO: TX79_MMI0_PCGTH */
24696 case TX79_MMI0_PMAXH: /* TODO: TX79_MMI0_PMAXH */
24697 case TX79_MMI0_PADDB: /* TODO: TX79_MMI0_PADDB */
24698 case TX79_MMI0_PSUBB: /* TODO: TX79_MMI0_PSUBB */
24699 case TX79_MMI0_PCGTB: /* TODO: TX79_MMI0_PCGTB */
24700 case TX79_MMI0_PADDSW: /* TODO: TX79_MMI0_PADDSW */
24701 case TX79_MMI0_PSUBSW: /* TODO: TX79_MMI0_PSUBSW */
24702 case TX79_MMI0_PEXTLW: /* TODO: TX79_MMI0_PEXTLW */
24703 case TX79_MMI0_PPACW: /* TODO: TX79_MMI0_PPACW */
24704 case TX79_MMI0_PADDSH: /* TODO: TX79_MMI0_PADDSH */
24705 case TX79_MMI0_PSUBSH: /* TODO: TX79_MMI0_PSUBSH */
24706 case TX79_MMI0_PEXTLH: /* TODO: TX79_MMI0_PEXTLH */
24707 case TX79_MMI0_PPACH: /* TODO: TX79_MMI0_PPACH */
24708 case TX79_MMI0_PADDSB: /* TODO: TX79_MMI0_PADDSB */
24709 case TX79_MMI0_PSUBSB: /* TODO: TX79_MMI0_PSUBSB */
24710 case TX79_MMI0_PEXTLB: /* TODO: TX79_MMI0_PEXTLB */
24711 case TX79_MMI0_PPACB: /* TODO: TX79_MMI0_PPACB */
24712 case TX79_MMI0_PEXT5: /* TODO: TX79_MMI0_PEXT5 */
24713 case TX79_MMI0_PPAC5: /* TODO: TX79_MMI0_PPAC5 */
24714 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI0 */
24717 MIPS_INVAL("TX79 MMI class MMI0");
24718 generate_exception_end(ctx, EXCP_RI);
24723 static void decode_tx79_mmi1(CPUMIPSState *env, DisasContext *ctx)
24725 uint32_t opc = MASK_TX79_MMI1(ctx->opcode);
24728 case TX79_MMI1_PABSW: /* TODO: TX79_MMI1_PABSW */
24729 case TX79_MMI1_PCEQW: /* TODO: TX79_MMI1_PCEQW */
24730 case TX79_MMI1_PMINW: /* TODO: TX79_MMI1_PMINW */
24731 case TX79_MMI1_PADSBH: /* TODO: TX79_MMI1_PADSBH */
24732 case TX79_MMI1_PABSH: /* TODO: TX79_MMI1_PABSH */
24733 case TX79_MMI1_PCEQH: /* TODO: TX79_MMI1_PCEQH */
24734 case TX79_MMI1_PMINH: /* TODO: TX79_MMI1_PMINH */
24735 case TX79_MMI1_PCEQB: /* TODO: TX79_MMI1_PCEQB */
24736 case TX79_MMI1_PADDUW: /* TODO: TX79_MMI1_PADDUW */
24737 case TX79_MMI1_PSUBUW: /* TODO: TX79_MMI1_PSUBUW */
24738 case TX79_MMI1_PEXTUW: /* TODO: TX79_MMI1_PEXTUW */
24739 case TX79_MMI1_PADDUH: /* TODO: TX79_MMI1_PADDUH */
24740 case TX79_MMI1_PSUBUH: /* TODO: TX79_MMI1_PSUBUH */
24741 case TX79_MMI1_PEXTUH: /* TODO: TX79_MMI1_PEXTUH */
24742 case TX79_MMI1_PADDUB: /* TODO: TX79_MMI1_PADDUB */
24743 case TX79_MMI1_PSUBUB: /* TODO: TX79_MMI1_PSUBUB */
24744 case TX79_MMI1_PEXTUB: /* TODO: TX79_MMI1_PEXTUB */
24745 case TX79_MMI1_QFSRV: /* TODO: TX79_MMI1_QFSRV */
24746 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI1 */
24749 MIPS_INVAL("TX79 MMI class MMI1");
24750 generate_exception_end(ctx, EXCP_RI);
24755 static void decode_tx79_mmi2(CPUMIPSState *env, DisasContext *ctx)
24757 uint32_t opc = MASK_TX79_MMI2(ctx->opcode);
24760 case TX79_MMI2_PMADDW: /* TODO: TX79_MMI2_PMADDW */
24761 case TX79_MMI2_PSLLVW: /* TODO: TX79_MMI2_PSLLVW */
24762 case TX79_MMI2_PSRLVW: /* TODO: TX79_MMI2_PSRLVW */
24763 case TX79_MMI2_PMSUBW: /* TODO: TX79_MMI2_PMSUBW */
24764 case TX79_MMI2_PMFHI: /* TODO: TX79_MMI2_PMFHI */
24765 case TX79_MMI2_PMFLO: /* TODO: TX79_MMI2_PMFLO */
24766 case TX79_MMI2_PINTH: /* TODO: TX79_MMI2_PINTH */
24767 case TX79_MMI2_PMULTW: /* TODO: TX79_MMI2_PMULTW */
24768 case TX79_MMI2_PDIVW: /* TODO: TX79_MMI2_PDIVW */
24769 case TX79_MMI2_PCPYLD: /* TODO: TX79_MMI2_PCPYLD */
24770 case TX79_MMI2_PMADDH: /* TODO: TX79_MMI2_PMADDH */
24771 case TX79_MMI2_PHMADH: /* TODO: TX79_MMI2_PHMADH */
24772 case TX79_MMI2_PAND: /* TODO: TX79_MMI2_PAND */
24773 case TX79_MMI2_PXOR: /* TODO: TX79_MMI2_PXOR */
24774 case TX79_MMI2_PMSUBH: /* TODO: TX79_MMI2_PMSUBH */
24775 case TX79_MMI2_PHMSBH: /* TODO: TX79_MMI2_PHMSBH */
24776 case TX79_MMI2_PEXEH: /* TODO: TX79_MMI2_PEXEH */
24777 case TX79_MMI2_PREVH: /* TODO: TX79_MMI2_PREVH */
24778 case TX79_MMI2_PMULTH: /* TODO: TX79_MMI2_PMULTH */
24779 case TX79_MMI2_PDIVBW: /* TODO: TX79_MMI2_PDIVBW */
24780 case TX79_MMI2_PEXEW: /* TODO: TX79_MMI2_PEXEW */
24781 case TX79_MMI2_PROT3W: /* TODO: TX79_MMI2_PROT3W */
24782 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI2 */
24785 MIPS_INVAL("TX79 MMI class MMI2");
24786 generate_exception_end(ctx, EXCP_RI);
24791 static void decode_tx79_mmi3(CPUMIPSState *env, DisasContext *ctx)
24793 uint32_t opc = MASK_TX79_MMI3(ctx->opcode);
24796 case TX79_MMI3_PMADDUW: /* TODO: TX79_MMI3_PMADDUW */
24797 case TX79_MMI3_PSRAVW: /* TODO: TX79_MMI3_PSRAVW */
24798 case TX79_MMI3_PMTHI: /* TODO: TX79_MMI3_PMTHI */
24799 case TX79_MMI3_PMTLO: /* TODO: TX79_MMI3_PMTLO */
24800 case TX79_MMI3_PINTEH: /* TODO: TX79_MMI3_PINTEH */
24801 case TX79_MMI3_PMULTUW: /* TODO: TX79_MMI3_PMULTUW */
24802 case TX79_MMI3_PDIVUW: /* TODO: TX79_MMI3_PDIVUW */
24803 case TX79_MMI3_PCPYUD: /* TODO: TX79_MMI3_PCPYUD */
24804 case TX79_MMI3_POR: /* TODO: TX79_MMI3_POR */
24805 case TX79_MMI3_PNOR: /* TODO: TX79_MMI3_PNOR */
24806 case TX79_MMI3_PEXCH: /* TODO: TX79_MMI3_PEXCH */
24807 case TX79_MMI3_PCPYH: /* TODO: TX79_MMI3_PCPYH */
24808 case TX79_MMI3_PEXCW: /* TODO: TX79_MMI3_PEXCW */
24809 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI3 */
24812 MIPS_INVAL("TX79 MMI class MMI3");
24813 generate_exception_end(ctx, EXCP_RI);
24818 static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
24820 uint32_t opc = MASK_TX79_MMI(ctx->opcode);
24821 int rs = extract32(ctx->opcode, 21, 5);
24822 int rt = extract32(ctx->opcode, 16, 5);
24823 int rd = extract32(ctx->opcode, 11, 5);
24826 case TX79_MMI_CLASS_MMI0:
24827 decode_tx79_mmi0(env, ctx);
24829 case TX79_MMI_CLASS_MMI1:
24830 decode_tx79_mmi1(env, ctx);
24832 case TX79_MMI_CLASS_MMI2:
24833 decode_tx79_mmi2(env, ctx);
24835 case TX79_MMI_CLASS_MMI3:
24836 decode_tx79_mmi3(env, ctx);
24838 case TX79_MMI_MULT1:
24839 case TX79_MMI_MULTU1:
24840 gen_mul_txx9(ctx, opc, rd, rs, rt);
24842 case TX79_MMI_DIV1:
24843 case TX79_MMI_DIVU1:
24844 gen_muldiv(ctx, opc, 1, rs, rt);
24846 case TX79_MMI_MTLO1:
24847 case TX79_MMI_MTHI1:
24848 gen_HILO(ctx, opc, 1, rs);
24850 case TX79_MMI_MFLO1:
24851 case TX79_MMI_MFHI1:
24852 gen_HILO(ctx, opc, 1, rd);
24854 case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */
24855 case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */
24856 case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */
24857 case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */
24858 case TX79_MMI_MADDU1: /* TODO: TX79_MMI_MADDU1 */
24859 case TX79_MMI_PMFHL: /* TODO: TX79_MMI_PMFHL */
24860 case TX79_MMI_PMTHL: /* TODO: TX79_MMI_PMTHL */
24861 case TX79_MMI_PSLLH: /* TODO: TX79_MMI_PSLLH */
24862 case TX79_MMI_PSRLH: /* TODO: TX79_MMI_PSRLH */
24863 case TX79_MMI_PSRAH: /* TODO: TX79_MMI_PSRAH */
24864 case TX79_MMI_PSLLW: /* TODO: TX79_MMI_PSLLW */
24865 case TX79_MMI_PSRLW: /* TODO: TX79_MMI_PSRLW */
24866 case TX79_MMI_PSRAW: /* TODO: TX79_MMI_PSRAW */
24867 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_CLASS_MMI */
24870 MIPS_INVAL("TX79 MMI class");
24871 generate_exception_end(ctx, EXCP_RI);
24876 static void decode_tx79_lq(CPUMIPSState *env, DisasContext *ctx)
24878 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_LQ */
24881 static void gen_tx79_sq(DisasContext *ctx, int base, int rt, int offset)
24883 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_SQ */
24887 * The TX79-specific instruction Store Quadword
24889 * +--------+-------+-------+------------------------+
24890 * | 011111 | base | rt | offset | SQ
24891 * +--------+-------+-------+------------------------+
24894 * has the same opcode as the Read Hardware Register instruction
24896 * +--------+-------+-------+-------+-------+--------+
24897 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
24898 * +--------+-------+-------+-------+-------+--------+
24901 * that is required, trapped and emulated by the Linux kernel. However, all
24902 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
24903 * offset is odd. Therefore all valid SQ instructions can execute normally.
24904 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
24905 * between SQ and RDHWR, as the Linux kernel does.
24907 static void decode_tx79_sq(CPUMIPSState *env, DisasContext *ctx)
24909 int base = extract32(ctx->opcode, 21, 5);
24910 int rt = extract32(ctx->opcode, 16, 5);
24911 int offset = extract32(ctx->opcode, 0, 16);
24913 #ifdef CONFIG_USER_ONLY
24914 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
24915 uint32_t op2 = extract32(ctx->opcode, 6, 5);
24917 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
24918 int rd = extract32(ctx->opcode, 11, 5);
24920 gen_rdhwr(ctx, rt, rd, 0);
24925 gen_tx79_sq(ctx, base, rt, offset);
24928 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
24930 int rs, rt, rd, sa;
24934 rs = (ctx->opcode >> 21) & 0x1f;
24935 rt = (ctx->opcode >> 16) & 0x1f;
24936 rd = (ctx->opcode >> 11) & 0x1f;
24937 sa = (ctx->opcode >> 6) & 0x1f;
24938 imm = sextract32(ctx->opcode, 7, 9);
24940 op1 = MASK_SPECIAL3(ctx->opcode);
24943 * EVA loads and stores overlap Loongson 2E instructions decoded by
24944 * decode_opc_special3_legacy(), so be careful to allow their decoding when
24951 check_insn_opc_removed(ctx, ISA_MIPS32R6);
24959 check_cp0_enabled(ctx);
24960 gen_ld(ctx, op1, rt, rs, imm);
24964 check_insn_opc_removed(ctx, ISA_MIPS32R6);
24969 check_cp0_enabled(ctx);
24970 gen_st(ctx, op1, rt, rs, imm);
24973 check_cp0_enabled(ctx);
24974 gen_st_cond(ctx, op1, rt, rs, imm);
24977 check_cp0_enabled(ctx);
24978 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
24979 gen_cache_operation(ctx, rt, rs, imm);
24981 /* Treat as NOP. */
24984 check_cp0_enabled(ctx);
24985 /* Treat as NOP. */
24993 check_insn(ctx, ISA_MIPS32R2);
24994 gen_bitops(ctx, op1, rt, rs, sa, rd);
24997 op2 = MASK_BSHFL(ctx->opcode);
25004 check_insn(ctx, ISA_MIPS32R6);
25005 decode_opc_special3_r6(env, ctx);
25008 check_insn(ctx, ISA_MIPS32R2);
25009 gen_bshfl(ctx, op2, rt, rd);
25013 #if defined(TARGET_MIPS64)
25020 check_insn(ctx, ISA_MIPS64R2);
25021 check_mips_64(ctx);
25022 gen_bitops(ctx, op1, rt, rs, sa, rd);
25025 op2 = MASK_DBSHFL(ctx->opcode);
25036 check_insn(ctx, ISA_MIPS32R6);
25037 decode_opc_special3_r6(env, ctx);
25040 check_insn(ctx, ISA_MIPS64R2);
25041 check_mips_64(ctx);
25042 op2 = MASK_DBSHFL(ctx->opcode);
25043 gen_bshfl(ctx, op2, rt, rd);
25049 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
25054 TCGv t0 = tcg_temp_new();
25055 TCGv t1 = tcg_temp_new();
25057 gen_load_gpr(t0, rt);
25058 gen_load_gpr(t1, rs);
25059 gen_helper_fork(t0, t1);
25067 TCGv t0 = tcg_temp_new();
25069 gen_load_gpr(t0, rs);
25070 gen_helper_yield(t0, cpu_env, t0);
25071 gen_store_gpr(t0, rd);
25076 if (ctx->insn_flags & ISA_MIPS32R6) {
25077 decode_opc_special3_r6(env, ctx);
25079 decode_opc_special3_legacy(env, ctx);
25084 /* MIPS SIMD Architecture (MSA) */
25085 static inline int check_msa_access(DisasContext *ctx)
25087 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
25088 !(ctx->hflags & MIPS_HFLAG_F64))) {
25089 generate_exception_end(ctx, EXCP_RI);
25093 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
25094 if (ctx->insn_flags & ASE_MSA) {
25095 generate_exception_end(ctx, EXCP_MSADIS);
25098 generate_exception_end(ctx, EXCP_RI);
25105 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
25107 /* generates tcg ops to check if any element is 0 */
25108 /* Note this function only works with MSA_WRLEN = 128 */
25109 uint64_t eval_zero_or_big = 0;
25110 uint64_t eval_big = 0;
25111 TCGv_i64 t0 = tcg_temp_new_i64();
25112 TCGv_i64 t1 = tcg_temp_new_i64();
25115 eval_zero_or_big = 0x0101010101010101ULL;
25116 eval_big = 0x8080808080808080ULL;
25119 eval_zero_or_big = 0x0001000100010001ULL;
25120 eval_big = 0x8000800080008000ULL;
25123 eval_zero_or_big = 0x0000000100000001ULL;
25124 eval_big = 0x8000000080000000ULL;
25127 eval_zero_or_big = 0x0000000000000001ULL;
25128 eval_big = 0x8000000000000000ULL;
25131 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
25132 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
25133 tcg_gen_andi_i64(t0, t0, eval_big);
25134 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
25135 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
25136 tcg_gen_andi_i64(t1, t1, eval_big);
25137 tcg_gen_or_i64(t0, t0, t1);
25138 /* if all bits are zero then all elements are not zero */
25139 /* if some bit is non-zero then some element is zero */
25140 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
25141 tcg_gen_trunc_i64_tl(tresult, t0);
25142 tcg_temp_free_i64(t0);
25143 tcg_temp_free_i64(t1);
25146 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
25148 uint8_t df = (ctx->opcode >> 21) & 0x3;
25149 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25150 int64_t s16 = (int16_t)ctx->opcode;
25152 check_msa_access(ctx);
25154 if (ctx->hflags & MIPS_HFLAG_BMASK) {
25155 generate_exception_end(ctx, EXCP_RI);
25162 TCGv_i64 t0 = tcg_temp_new_i64();
25163 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
25164 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
25165 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
25166 tcg_gen_trunc_i64_tl(bcond, t0);
25167 tcg_temp_free_i64(t0);
25174 gen_check_zero_element(bcond, df, wt);
25180 gen_check_zero_element(bcond, df, wt);
25181 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
25185 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
25187 ctx->hflags |= MIPS_HFLAG_BC;
25188 ctx->hflags |= MIPS_HFLAG_BDS32;
25191 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
25193 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
25194 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
25195 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25196 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25198 TCGv_i32 twd = tcg_const_i32(wd);
25199 TCGv_i32 tws = tcg_const_i32(ws);
25200 TCGv_i32 ti8 = tcg_const_i32(i8);
25202 switch (MASK_MSA_I8(ctx->opcode)) {
25204 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
25207 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
25210 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
25213 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
25216 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
25219 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
25222 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
25228 uint8_t df = (ctx->opcode >> 24) & 0x3;
25229 if (df == DF_DOUBLE) {
25230 generate_exception_end(ctx, EXCP_RI);
25232 TCGv_i32 tdf = tcg_const_i32(df);
25233 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
25234 tcg_temp_free_i32(tdf);
25239 MIPS_INVAL("MSA instruction");
25240 generate_exception_end(ctx, EXCP_RI);
25244 tcg_temp_free_i32(twd);
25245 tcg_temp_free_i32(tws);
25246 tcg_temp_free_i32(ti8);
25249 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
25251 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
25252 uint8_t df = (ctx->opcode >> 21) & 0x3;
25253 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
25254 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
25255 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25256 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25258 TCGv_i32 tdf = tcg_const_i32(df);
25259 TCGv_i32 twd = tcg_const_i32(wd);
25260 TCGv_i32 tws = tcg_const_i32(ws);
25261 TCGv_i32 timm = tcg_temp_new_i32();
25262 tcg_gen_movi_i32(timm, u5);
25264 switch (MASK_MSA_I5(ctx->opcode)) {
25266 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
25269 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
25271 case OPC_MAXI_S_df:
25272 tcg_gen_movi_i32(timm, s5);
25273 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
25275 case OPC_MAXI_U_df:
25276 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
25278 case OPC_MINI_S_df:
25279 tcg_gen_movi_i32(timm, s5);
25280 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
25282 case OPC_MINI_U_df:
25283 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
25286 tcg_gen_movi_i32(timm, s5);
25287 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
25289 case OPC_CLTI_S_df:
25290 tcg_gen_movi_i32(timm, s5);
25291 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
25293 case OPC_CLTI_U_df:
25294 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
25296 case OPC_CLEI_S_df:
25297 tcg_gen_movi_i32(timm, s5);
25298 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
25300 case OPC_CLEI_U_df:
25301 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
25305 int32_t s10 = sextract32(ctx->opcode, 11, 10);
25306 tcg_gen_movi_i32(timm, s10);
25307 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
25311 MIPS_INVAL("MSA instruction");
25312 generate_exception_end(ctx, EXCP_RI);
25316 tcg_temp_free_i32(tdf);
25317 tcg_temp_free_i32(twd);
25318 tcg_temp_free_i32(tws);
25319 tcg_temp_free_i32(timm);
25322 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
25324 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
25325 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
25326 uint32_t df = 0, m = 0;
25327 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25328 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25335 if ((dfm & 0x40) == 0x00) {
25338 } else if ((dfm & 0x60) == 0x40) {
25341 } else if ((dfm & 0x70) == 0x60) {
25344 } else if ((dfm & 0x78) == 0x70) {
25348 generate_exception_end(ctx, EXCP_RI);
25352 tdf = tcg_const_i32(df);
25353 tm = tcg_const_i32(m);
25354 twd = tcg_const_i32(wd);
25355 tws = tcg_const_i32(ws);
25357 switch (MASK_MSA_BIT(ctx->opcode)) {
25359 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
25362 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
25365 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
25368 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
25371 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
25374 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
25376 case OPC_BINSLI_df:
25377 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
25379 case OPC_BINSRI_df:
25380 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
25383 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
25386 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
25389 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
25392 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
25395 MIPS_INVAL("MSA instruction");
25396 generate_exception_end(ctx, EXCP_RI);
25400 tcg_temp_free_i32(tdf);
25401 tcg_temp_free_i32(tm);
25402 tcg_temp_free_i32(twd);
25403 tcg_temp_free_i32(tws);
25406 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
25408 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
25409 uint8_t df = (ctx->opcode >> 21) & 0x3;
25410 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25411 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25412 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25414 TCGv_i32 tdf = tcg_const_i32(df);
25415 TCGv_i32 twd = tcg_const_i32(wd);
25416 TCGv_i32 tws = tcg_const_i32(ws);
25417 TCGv_i32 twt = tcg_const_i32(wt);
25419 switch (MASK_MSA_3R(ctx->opcode)) {
25421 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
25424 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
25427 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
25430 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
25432 case OPC_SUBS_S_df:
25433 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
25436 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
25439 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
25442 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
25445 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
25448 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
25450 case OPC_ADDS_A_df:
25451 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
25453 case OPC_SUBS_U_df:
25454 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
25457 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
25460 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
25463 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
25466 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
25469 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
25472 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
25474 case OPC_ADDS_S_df:
25475 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
25477 case OPC_SUBSUS_U_df:
25478 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
25481 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
25484 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
25487 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
25490 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
25493 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
25496 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
25498 case OPC_ADDS_U_df:
25499 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
25501 case OPC_SUBSUU_S_df:
25502 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
25505 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
25508 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
25511 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
25514 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
25517 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
25519 case OPC_ASUB_S_df:
25520 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
25523 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
25526 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
25529 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
25532 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
25535 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
25538 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
25540 case OPC_ASUB_U_df:
25541 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
25544 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
25547 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
25550 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
25553 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
25555 case OPC_AVER_S_df:
25556 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
25559 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
25562 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
25565 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
25568 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
25570 case OPC_AVER_U_df:
25571 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
25574 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
25577 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
25580 case OPC_DOTP_S_df:
25581 case OPC_DOTP_U_df:
25582 case OPC_DPADD_S_df:
25583 case OPC_DPADD_U_df:
25584 case OPC_DPSUB_S_df:
25585 case OPC_HADD_S_df:
25586 case OPC_DPSUB_U_df:
25587 case OPC_HADD_U_df:
25588 case OPC_HSUB_S_df:
25589 case OPC_HSUB_U_df:
25590 if (df == DF_BYTE) {
25591 generate_exception_end(ctx, EXCP_RI);
25594 switch (MASK_MSA_3R(ctx->opcode)) {
25595 case OPC_DOTP_S_df:
25596 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
25598 case OPC_DOTP_U_df:
25599 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
25601 case OPC_DPADD_S_df:
25602 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
25604 case OPC_DPADD_U_df:
25605 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
25607 case OPC_DPSUB_S_df:
25608 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
25610 case OPC_HADD_S_df:
25611 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
25613 case OPC_DPSUB_U_df:
25614 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
25616 case OPC_HADD_U_df:
25617 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
25619 case OPC_HSUB_S_df:
25620 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
25622 case OPC_HSUB_U_df:
25623 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
25628 MIPS_INVAL("MSA instruction");
25629 generate_exception_end(ctx, EXCP_RI);
25632 tcg_temp_free_i32(twd);
25633 tcg_temp_free_i32(tws);
25634 tcg_temp_free_i32(twt);
25635 tcg_temp_free_i32(tdf);
25638 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
25640 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
25641 uint8_t source = (ctx->opcode >> 11) & 0x1f;
25642 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
25643 TCGv telm = tcg_temp_new();
25644 TCGv_i32 tsr = tcg_const_i32(source);
25645 TCGv_i32 tdt = tcg_const_i32(dest);
25647 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
25649 gen_load_gpr(telm, source);
25650 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
25653 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
25654 gen_store_gpr(telm, dest);
25657 gen_helper_msa_move_v(cpu_env, tdt, tsr);
25660 MIPS_INVAL("MSA instruction");
25661 generate_exception_end(ctx, EXCP_RI);
25665 tcg_temp_free(telm);
25666 tcg_temp_free_i32(tdt);
25667 tcg_temp_free_i32(tsr);
25670 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
25673 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
25674 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25675 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25677 TCGv_i32 tws = tcg_const_i32(ws);
25678 TCGv_i32 twd = tcg_const_i32(wd);
25679 TCGv_i32 tn = tcg_const_i32(n);
25680 TCGv_i32 tdf = tcg_const_i32(df);
25682 switch (MASK_MSA_ELM(ctx->opcode)) {
25684 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
25686 case OPC_SPLATI_df:
25687 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
25690 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
25692 case OPC_COPY_S_df:
25693 case OPC_COPY_U_df:
25694 case OPC_INSERT_df:
25695 #if !defined(TARGET_MIPS64)
25696 /* Double format valid only for MIPS64 */
25697 if (df == DF_DOUBLE) {
25698 generate_exception_end(ctx, EXCP_RI);
25702 switch (MASK_MSA_ELM(ctx->opcode)) {
25703 case OPC_COPY_S_df:
25704 if (likely(wd != 0)) {
25705 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
25708 case OPC_COPY_U_df:
25709 if (likely(wd != 0)) {
25710 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
25713 case OPC_INSERT_df:
25714 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
25719 MIPS_INVAL("MSA instruction");
25720 generate_exception_end(ctx, EXCP_RI);
25722 tcg_temp_free_i32(twd);
25723 tcg_temp_free_i32(tws);
25724 tcg_temp_free_i32(tn);
25725 tcg_temp_free_i32(tdf);
25728 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
25730 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
25731 uint32_t df = 0, n = 0;
25733 if ((dfn & 0x30) == 0x00) {
25736 } else if ((dfn & 0x38) == 0x20) {
25739 } else if ((dfn & 0x3c) == 0x30) {
25742 } else if ((dfn & 0x3e) == 0x38) {
25745 } else if (dfn == 0x3E) {
25746 /* CTCMSA, CFCMSA, MOVE.V */
25747 gen_msa_elm_3e(env, ctx);
25750 generate_exception_end(ctx, EXCP_RI);
25754 gen_msa_elm_df(env, ctx, df, n);
25757 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
25759 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
25760 uint8_t df = (ctx->opcode >> 21) & 0x1;
25761 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25762 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25763 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25765 TCGv_i32 twd = tcg_const_i32(wd);
25766 TCGv_i32 tws = tcg_const_i32(ws);
25767 TCGv_i32 twt = tcg_const_i32(wt);
25768 TCGv_i32 tdf = tcg_temp_new_i32();
25770 /* adjust df value for floating-point instruction */
25771 tcg_gen_movi_i32(tdf, df + 2);
25773 switch (MASK_MSA_3RF(ctx->opcode)) {
25775 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
25778 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
25781 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
25784 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
25787 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
25790 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
25793 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
25796 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
25799 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
25802 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
25805 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
25808 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
25811 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
25814 tcg_gen_movi_i32(tdf, df + 1);
25815 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
25818 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
25821 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
25823 case OPC_MADD_Q_df:
25824 tcg_gen_movi_i32(tdf, df + 1);
25825 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
25828 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
25830 case OPC_MSUB_Q_df:
25831 tcg_gen_movi_i32(tdf, df + 1);
25832 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
25835 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
25838 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
25841 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
25844 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
25847 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
25850 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
25853 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
25856 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
25859 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
25862 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
25865 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
25868 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
25871 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
25873 case OPC_MULR_Q_df:
25874 tcg_gen_movi_i32(tdf, df + 1);
25875 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
25878 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
25880 case OPC_FMIN_A_df:
25881 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
25883 case OPC_MADDR_Q_df:
25884 tcg_gen_movi_i32(tdf, df + 1);
25885 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
25888 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
25891 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
25893 case OPC_MSUBR_Q_df:
25894 tcg_gen_movi_i32(tdf, df + 1);
25895 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
25898 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
25900 case OPC_FMAX_A_df:
25901 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
25904 MIPS_INVAL("MSA instruction");
25905 generate_exception_end(ctx, EXCP_RI);
25909 tcg_temp_free_i32(twd);
25910 tcg_temp_free_i32(tws);
25911 tcg_temp_free_i32(twt);
25912 tcg_temp_free_i32(tdf);
25915 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
25917 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
25918 (op & (0x7 << 18)))
25919 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25920 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25921 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25922 uint8_t df = (ctx->opcode >> 16) & 0x3;
25923 TCGv_i32 twd = tcg_const_i32(wd);
25924 TCGv_i32 tws = tcg_const_i32(ws);
25925 TCGv_i32 twt = tcg_const_i32(wt);
25926 TCGv_i32 tdf = tcg_const_i32(df);
25928 switch (MASK_MSA_2R(ctx->opcode)) {
25930 #if !defined(TARGET_MIPS64)
25931 /* Double format valid only for MIPS64 */
25932 if (df == DF_DOUBLE) {
25933 generate_exception_end(ctx, EXCP_RI);
25937 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
25940 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
25943 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
25946 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
25949 MIPS_INVAL("MSA instruction");
25950 generate_exception_end(ctx, EXCP_RI);
25954 tcg_temp_free_i32(twd);
25955 tcg_temp_free_i32(tws);
25956 tcg_temp_free_i32(twt);
25957 tcg_temp_free_i32(tdf);
25960 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
25962 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
25963 (op & (0xf << 17)))
25964 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25965 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25966 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25967 uint8_t df = (ctx->opcode >> 16) & 0x1;
25968 TCGv_i32 twd = tcg_const_i32(wd);
25969 TCGv_i32 tws = tcg_const_i32(ws);
25970 TCGv_i32 twt = tcg_const_i32(wt);
25971 /* adjust df value for floating-point instruction */
25972 TCGv_i32 tdf = tcg_const_i32(df + 2);
25974 switch (MASK_MSA_2RF(ctx->opcode)) {
25975 case OPC_FCLASS_df:
25976 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
25978 case OPC_FTRUNC_S_df:
25979 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
25981 case OPC_FTRUNC_U_df:
25982 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
25985 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
25987 case OPC_FRSQRT_df:
25988 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
25991 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
25994 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
25997 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
25999 case OPC_FEXUPL_df:
26000 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
26002 case OPC_FEXUPR_df:
26003 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
26006 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
26009 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
26011 case OPC_FTINT_S_df:
26012 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
26014 case OPC_FTINT_U_df:
26015 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
26017 case OPC_FFINT_S_df:
26018 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
26020 case OPC_FFINT_U_df:
26021 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
26025 tcg_temp_free_i32(twd);
26026 tcg_temp_free_i32(tws);
26027 tcg_temp_free_i32(twt);
26028 tcg_temp_free_i32(tdf);
26031 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
26033 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
26034 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26035 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26036 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26037 TCGv_i32 twd = tcg_const_i32(wd);
26038 TCGv_i32 tws = tcg_const_i32(ws);
26039 TCGv_i32 twt = tcg_const_i32(wt);
26041 switch (MASK_MSA_VEC(ctx->opcode)) {
26043 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
26046 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
26049 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
26052 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
26055 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
26058 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
26061 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
26064 MIPS_INVAL("MSA instruction");
26065 generate_exception_end(ctx, EXCP_RI);
26069 tcg_temp_free_i32(twd);
26070 tcg_temp_free_i32(tws);
26071 tcg_temp_free_i32(twt);
26074 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
26076 switch (MASK_MSA_VEC(ctx->opcode)) {
26084 gen_msa_vec_v(env, ctx);
26087 gen_msa_2r(env, ctx);
26090 gen_msa_2rf(env, ctx);
26093 MIPS_INVAL("MSA instruction");
26094 generate_exception_end(ctx, EXCP_RI);
26099 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
26101 uint32_t opcode = ctx->opcode;
26102 check_insn(ctx, ASE_MSA);
26103 check_msa_access(ctx);
26105 switch (MASK_MSA_MINOR(opcode)) {
26106 case OPC_MSA_I8_00:
26107 case OPC_MSA_I8_01:
26108 case OPC_MSA_I8_02:
26109 gen_msa_i8(env, ctx);
26111 case OPC_MSA_I5_06:
26112 case OPC_MSA_I5_07:
26113 gen_msa_i5(env, ctx);
26115 case OPC_MSA_BIT_09:
26116 case OPC_MSA_BIT_0A:
26117 gen_msa_bit(env, ctx);
26119 case OPC_MSA_3R_0D:
26120 case OPC_MSA_3R_0E:
26121 case OPC_MSA_3R_0F:
26122 case OPC_MSA_3R_10:
26123 case OPC_MSA_3R_11:
26124 case OPC_MSA_3R_12:
26125 case OPC_MSA_3R_13:
26126 case OPC_MSA_3R_14:
26127 case OPC_MSA_3R_15:
26128 gen_msa_3r(env, ctx);
26131 gen_msa_elm(env, ctx);
26133 case OPC_MSA_3RF_1A:
26134 case OPC_MSA_3RF_1B:
26135 case OPC_MSA_3RF_1C:
26136 gen_msa_3rf(env, ctx);
26139 gen_msa_vec(env, ctx);
26150 int32_t s10 = sextract32(ctx->opcode, 16, 10);
26151 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
26152 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26153 uint8_t df = (ctx->opcode >> 0) & 0x3;
26155 TCGv_i32 twd = tcg_const_i32(wd);
26156 TCGv taddr = tcg_temp_new();
26157 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
26159 switch (MASK_MSA_MINOR(opcode)) {
26161 gen_helper_msa_ld_b(cpu_env, twd, taddr);
26164 gen_helper_msa_ld_h(cpu_env, twd, taddr);
26167 gen_helper_msa_ld_w(cpu_env, twd, taddr);
26170 gen_helper_msa_ld_d(cpu_env, twd, taddr);
26173 gen_helper_msa_st_b(cpu_env, twd, taddr);
26176 gen_helper_msa_st_h(cpu_env, twd, taddr);
26179 gen_helper_msa_st_w(cpu_env, twd, taddr);
26182 gen_helper_msa_st_d(cpu_env, twd, taddr);
26186 tcg_temp_free_i32(twd);
26187 tcg_temp_free(taddr);
26191 MIPS_INVAL("MSA instruction");
26192 generate_exception_end(ctx, EXCP_RI);
26198 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
26201 int rs, rt, rd, sa;
26205 /* make sure instructions are on a word boundary */
26206 if (ctx->base.pc_next & 0x3) {
26207 env->CP0_BadVAddr = ctx->base.pc_next;
26208 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
26212 /* Handle blikely not taken case */
26213 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
26214 TCGLabel *l1 = gen_new_label();
26216 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
26217 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
26218 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
26222 op = MASK_OP_MAJOR(ctx->opcode);
26223 rs = (ctx->opcode >> 21) & 0x1f;
26224 rt = (ctx->opcode >> 16) & 0x1f;
26225 rd = (ctx->opcode >> 11) & 0x1f;
26226 sa = (ctx->opcode >> 6) & 0x1f;
26227 imm = (int16_t)ctx->opcode;
26230 decode_opc_special(env, ctx);
26233 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
26234 decode_tx79_mmi(env, ctx);
26236 decode_opc_special2_legacy(env, ctx);
26240 if (ctx->insn_flags & INSN_R5900) {
26241 decode_tx79_sq(env, ctx); /* TX79_SQ */
26243 decode_opc_special3(env, ctx);
26247 op1 = MASK_REGIMM(ctx->opcode);
26249 case OPC_BLTZL: /* REGIMM branches */
26253 check_insn(ctx, ISA_MIPS2);
26254 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26258 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
26262 if (ctx->insn_flags & ISA_MIPS32R6) {
26264 /* OPC_NAL, OPC_BAL */
26265 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
26267 generate_exception_end(ctx, EXCP_RI);
26270 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
26273 case OPC_TGEI: /* REGIMM traps */
26280 check_insn(ctx, ISA_MIPS2);
26281 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26282 gen_trap(ctx, op1, rs, -1, imm);
26285 check_insn(ctx, ISA_MIPS32R6);
26286 generate_exception_end(ctx, EXCP_RI);
26289 check_insn(ctx, ISA_MIPS32R2);
26290 /* Break the TB to be able to sync copied instructions
26292 ctx->base.is_jmp = DISAS_STOP;
26294 case OPC_BPOSGE32: /* MIPS DSP branch */
26295 #if defined(TARGET_MIPS64)
26299 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
26301 #if defined(TARGET_MIPS64)
26303 check_insn(ctx, ISA_MIPS32R6);
26304 check_mips_64(ctx);
26306 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
26310 check_insn(ctx, ISA_MIPS32R6);
26311 check_mips_64(ctx);
26313 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
26317 default: /* Invalid */
26318 MIPS_INVAL("regimm");
26319 generate_exception_end(ctx, EXCP_RI);
26324 check_cp0_enabled(ctx);
26325 op1 = MASK_CP0(ctx->opcode);
26333 #if defined(TARGET_MIPS64)
26337 #ifndef CONFIG_USER_ONLY
26338 gen_cp0(env, ctx, op1, rt, rd);
26339 #endif /* !CONFIG_USER_ONLY */
26357 #ifndef CONFIG_USER_ONLY
26358 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
26359 #endif /* !CONFIG_USER_ONLY */
26362 #ifndef CONFIG_USER_ONLY
26365 TCGv t0 = tcg_temp_new();
26367 op2 = MASK_MFMC0(ctx->opcode);
26371 gen_helper_dmt(t0);
26372 gen_store_gpr(t0, rt);
26376 gen_helper_emt(t0);
26377 gen_store_gpr(t0, rt);
26381 gen_helper_dvpe(t0, cpu_env);
26382 gen_store_gpr(t0, rt);
26386 gen_helper_evpe(t0, cpu_env);
26387 gen_store_gpr(t0, rt);
26390 check_insn(ctx, ISA_MIPS32R6);
26392 gen_helper_dvp(t0, cpu_env);
26393 gen_store_gpr(t0, rt);
26397 check_insn(ctx, ISA_MIPS32R6);
26399 gen_helper_evp(t0, cpu_env);
26400 gen_store_gpr(t0, rt);
26404 check_insn(ctx, ISA_MIPS32R2);
26405 save_cpu_state(ctx, 1);
26406 gen_helper_di(t0, cpu_env);
26407 gen_store_gpr(t0, rt);
26408 /* Stop translation as we may have switched
26409 the execution mode. */
26410 ctx->base.is_jmp = DISAS_STOP;
26413 check_insn(ctx, ISA_MIPS32R2);
26414 save_cpu_state(ctx, 1);
26415 gen_helper_ei(t0, cpu_env);
26416 gen_store_gpr(t0, rt);
26417 /* DISAS_STOP isn't sufficient, we need to ensure we break
26418 out of translated code to check for pending interrupts */
26419 gen_save_pc(ctx->base.pc_next + 4);
26420 ctx->base.is_jmp = DISAS_EXIT;
26422 default: /* Invalid */
26423 MIPS_INVAL("mfmc0");
26424 generate_exception_end(ctx, EXCP_RI);
26429 #endif /* !CONFIG_USER_ONLY */
26432 check_insn(ctx, ISA_MIPS32R2);
26433 gen_load_srsgpr(rt, rd);
26436 check_insn(ctx, ISA_MIPS32R2);
26437 gen_store_srsgpr(rt, rd);
26441 generate_exception_end(ctx, EXCP_RI);
26445 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
26446 if (ctx->insn_flags & ISA_MIPS32R6) {
26447 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
26448 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26451 /* Arithmetic with immediate opcode */
26452 gen_arith_imm(ctx, op, rt, rs, imm);
26456 gen_arith_imm(ctx, op, rt, rs, imm);
26458 case OPC_SLTI: /* Set on less than with immediate opcode */
26460 gen_slt_imm(ctx, op, rt, rs, imm);
26462 case OPC_ANDI: /* Arithmetic with immediate opcode */
26463 case OPC_LUI: /* OPC_AUI */
26466 gen_logic_imm(ctx, op, rt, rs, imm);
26468 case OPC_J: /* Jump */
26470 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
26471 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
26474 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
26475 if (ctx->insn_flags & ISA_MIPS32R6) {
26477 generate_exception_end(ctx, EXCP_RI);
26480 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
26481 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26484 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
26487 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
26488 if (ctx->insn_flags & ISA_MIPS32R6) {
26490 generate_exception_end(ctx, EXCP_RI);
26493 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
26494 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26497 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
26500 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
26503 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
26505 check_insn(ctx, ISA_MIPS32R6);
26506 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
26507 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26510 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
26513 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
26515 check_insn(ctx, ISA_MIPS32R6);
26516 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
26517 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26522 check_insn(ctx, ISA_MIPS2);
26523 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26527 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
26529 case OPC_LL: /* Load and stores */
26530 check_insn(ctx, ISA_MIPS2);
26531 check_insn_opc_user_only(ctx, INSN_R5900);
26535 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26543 gen_ld(ctx, op, rt, rs, imm);
26547 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26552 gen_st(ctx, op, rt, rs, imm);
26555 check_insn(ctx, ISA_MIPS2);
26556 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26557 check_insn_opc_user_only(ctx, INSN_R5900);
26558 gen_st_cond(ctx, op, rt, rs, imm);
26561 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26562 check_cp0_enabled(ctx);
26563 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
26564 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26565 gen_cache_operation(ctx, rt, rs, imm);
26567 /* Treat as NOP. */
26570 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26571 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
26573 /* Treat as NOP. */
26576 /* Floating point (COP1). */
26581 gen_cop1_ldst(ctx, op, rt, rs, imm);
26585 op1 = MASK_CP1(ctx->opcode);
26590 check_cp1_enabled(ctx);
26591 check_insn(ctx, ISA_MIPS32R2);
26597 check_cp1_enabled(ctx);
26598 gen_cp1(ctx, op1, rt, rd);
26600 #if defined(TARGET_MIPS64)
26603 check_cp1_enabled(ctx);
26604 check_insn(ctx, ISA_MIPS3);
26605 check_mips_64(ctx);
26606 gen_cp1(ctx, op1, rt, rd);
26609 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
26610 check_cp1_enabled(ctx);
26611 if (ctx->insn_flags & ISA_MIPS32R6) {
26613 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
26618 check_insn(ctx, ASE_MIPS3D);
26619 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
26620 (rt >> 2) & 0x7, imm << 2);
26624 check_cp1_enabled(ctx);
26625 check_insn(ctx, ISA_MIPS32R6);
26626 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
26630 check_cp1_enabled(ctx);
26631 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26633 check_insn(ctx, ASE_MIPS3D);
26636 check_cp1_enabled(ctx);
26637 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26638 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
26639 (rt >> 2) & 0x7, imm << 2);
26646 check_cp1_enabled(ctx);
26647 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
26653 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
26654 check_cp1_enabled(ctx);
26655 if (ctx->insn_flags & ISA_MIPS32R6) {
26657 case R6_OPC_CMP_AF_S:
26658 case R6_OPC_CMP_UN_S:
26659 case R6_OPC_CMP_EQ_S:
26660 case R6_OPC_CMP_UEQ_S:
26661 case R6_OPC_CMP_LT_S:
26662 case R6_OPC_CMP_ULT_S:
26663 case R6_OPC_CMP_LE_S:
26664 case R6_OPC_CMP_ULE_S:
26665 case R6_OPC_CMP_SAF_S:
26666 case R6_OPC_CMP_SUN_S:
26667 case R6_OPC_CMP_SEQ_S:
26668 case R6_OPC_CMP_SEUQ_S:
26669 case R6_OPC_CMP_SLT_S:
26670 case R6_OPC_CMP_SULT_S:
26671 case R6_OPC_CMP_SLE_S:
26672 case R6_OPC_CMP_SULE_S:
26673 case R6_OPC_CMP_OR_S:
26674 case R6_OPC_CMP_UNE_S:
26675 case R6_OPC_CMP_NE_S:
26676 case R6_OPC_CMP_SOR_S:
26677 case R6_OPC_CMP_SUNE_S:
26678 case R6_OPC_CMP_SNE_S:
26679 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
26681 case R6_OPC_CMP_AF_D:
26682 case R6_OPC_CMP_UN_D:
26683 case R6_OPC_CMP_EQ_D:
26684 case R6_OPC_CMP_UEQ_D:
26685 case R6_OPC_CMP_LT_D:
26686 case R6_OPC_CMP_ULT_D:
26687 case R6_OPC_CMP_LE_D:
26688 case R6_OPC_CMP_ULE_D:
26689 case R6_OPC_CMP_SAF_D:
26690 case R6_OPC_CMP_SUN_D:
26691 case R6_OPC_CMP_SEQ_D:
26692 case R6_OPC_CMP_SEUQ_D:
26693 case R6_OPC_CMP_SLT_D:
26694 case R6_OPC_CMP_SULT_D:
26695 case R6_OPC_CMP_SLE_D:
26696 case R6_OPC_CMP_SULE_D:
26697 case R6_OPC_CMP_OR_D:
26698 case R6_OPC_CMP_UNE_D:
26699 case R6_OPC_CMP_NE_D:
26700 case R6_OPC_CMP_SOR_D:
26701 case R6_OPC_CMP_SUNE_D:
26702 case R6_OPC_CMP_SNE_D:
26703 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
26706 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
26707 rt, rd, sa, (imm >> 8) & 0x7);
26712 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
26727 check_insn(ctx, ASE_MSA);
26728 gen_msa_branch(env, ctx, op1);
26732 generate_exception_end(ctx, EXCP_RI);
26737 /* Compact branches [R6] and COP2 [non-R6] */
26738 case OPC_BC: /* OPC_LWC2 */
26739 case OPC_BALC: /* OPC_SWC2 */
26740 if (ctx->insn_flags & ISA_MIPS32R6) {
26741 /* OPC_BC, OPC_BALC */
26742 gen_compute_compact_branch(ctx, op, 0, 0,
26743 sextract32(ctx->opcode << 2, 0, 28));
26745 /* OPC_LWC2, OPC_SWC2 */
26746 /* COP2: Not implemented. */
26747 generate_exception_err(ctx, EXCP_CpU, 2);
26750 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
26751 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
26752 if (ctx->insn_flags & ISA_MIPS32R6) {
26754 /* OPC_BEQZC, OPC_BNEZC */
26755 gen_compute_compact_branch(ctx, op, rs, 0,
26756 sextract32(ctx->opcode << 2, 0, 23));
26758 /* OPC_JIC, OPC_JIALC */
26759 gen_compute_compact_branch(ctx, op, 0, rt, imm);
26762 /* OPC_LWC2, OPC_SWC2 */
26763 /* COP2: Not implemented. */
26764 generate_exception_err(ctx, EXCP_CpU, 2);
26768 check_insn(ctx, INSN_LOONGSON2F);
26769 /* Note that these instructions use different fields. */
26770 gen_loongson_multimedia(ctx, sa, rd, rt);
26774 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26775 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26776 check_cp1_enabled(ctx);
26777 op1 = MASK_CP3(ctx->opcode);
26781 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
26787 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
26788 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
26791 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
26792 /* Treat as NOP. */
26795 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
26809 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
26810 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
26814 generate_exception_end(ctx, EXCP_RI);
26818 generate_exception_err(ctx, EXCP_CpU, 1);
26822 #if defined(TARGET_MIPS64)
26823 /* MIPS64 opcodes */
26825 check_insn_opc_user_only(ctx, INSN_R5900);
26829 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26833 check_insn(ctx, ISA_MIPS3);
26834 check_mips_64(ctx);
26835 gen_ld(ctx, op, rt, rs, imm);
26839 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26842 check_insn(ctx, ISA_MIPS3);
26843 check_mips_64(ctx);
26844 gen_st(ctx, op, rt, rs, imm);
26847 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26848 check_insn(ctx, ISA_MIPS3);
26849 check_insn_opc_user_only(ctx, INSN_R5900);
26850 check_mips_64(ctx);
26851 gen_st_cond(ctx, op, rt, rs, imm);
26853 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
26854 if (ctx->insn_flags & ISA_MIPS32R6) {
26855 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
26856 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26859 check_insn(ctx, ISA_MIPS3);
26860 check_mips_64(ctx);
26861 gen_arith_imm(ctx, op, rt, rs, imm);
26865 check_insn(ctx, ISA_MIPS3);
26866 check_mips_64(ctx);
26867 gen_arith_imm(ctx, op, rt, rs, imm);
26870 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
26871 if (ctx->insn_flags & ISA_MIPS32R6) {
26872 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
26874 MIPS_INVAL("major opcode");
26875 generate_exception_end(ctx, EXCP_RI);
26879 case OPC_DAUI: /* OPC_JALX */
26880 if (ctx->insn_flags & ISA_MIPS32R6) {
26881 #if defined(TARGET_MIPS64)
26883 check_mips_64(ctx);
26885 generate_exception(ctx, EXCP_RI);
26886 } else if (rt != 0) {
26887 TCGv t0 = tcg_temp_new();
26888 gen_load_gpr(t0, rs);
26889 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
26893 generate_exception_end(ctx, EXCP_RI);
26894 MIPS_INVAL("major opcode");
26898 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
26899 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
26900 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
26903 case OPC_MSA: /* OPC_MDMX */
26904 if (ctx->insn_flags & INSN_R5900) {
26905 decode_tx79_lq(env, ctx); /* TX79_LQ */
26907 /* MDMX: Not implemented. */
26912 check_insn(ctx, ISA_MIPS32R6);
26913 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
26915 default: /* Invalid */
26916 MIPS_INVAL("major opcode");
26917 generate_exception_end(ctx, EXCP_RI);
26922 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
26924 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26925 CPUMIPSState *env = cs->env_ptr;
26927 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
26928 ctx->saved_pc = -1;
26929 ctx->insn_flags = env->insn_flags;
26930 ctx->CP0_Config1 = env->CP0_Config1;
26931 ctx->CP0_Config2 = env->CP0_Config2;
26932 ctx->CP0_Config3 = env->CP0_Config3;
26933 ctx->CP0_Config5 = env->CP0_Config5;
26935 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
26936 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
26937 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
26938 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
26939 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
26940 ctx->PAMask = env->PAMask;
26941 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
26942 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
26943 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
26944 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
26945 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
26946 /* Restore delay slot state from the tb context. */
26947 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
26948 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
26949 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
26950 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
26951 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
26952 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
26953 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
26954 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
26955 restore_cpu_state(env, ctx);
26956 #ifdef CONFIG_USER_ONLY
26957 ctx->mem_idx = MIPS_HFLAG_UM;
26959 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
26961 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
26962 MO_UNALN : MO_ALIGN;
26964 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
26968 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
26972 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
26974 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26976 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
26980 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
26981 const CPUBreakpoint *bp)
26983 DisasContext *ctx = container_of(dcbase, DisasContext, base);
26985 save_cpu_state(ctx, 1);
26986 ctx->base.is_jmp = DISAS_NORETURN;
26987 gen_helper_raise_exception_debug(cpu_env);
26988 /* The address covered by the breakpoint must be included in
26989 [tb->pc, tb->pc + tb->size) in order to for it to be
26990 properly cleared -- thus we increment the PC here so that
26991 the logic setting tb->size below does the right thing. */
26992 ctx->base.pc_next += 4;
26996 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
26998 CPUMIPSState *env = cs->env_ptr;
26999 DisasContext *ctx = container_of(dcbase, DisasContext, base);
27003 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
27004 if (ctx->insn_flags & ISA_NANOMIPS32) {
27005 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
27006 insn_bytes = decode_nanomips_opc(env, ctx);
27007 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
27008 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
27010 decode_opc(env, ctx);
27011 } else if (ctx->insn_flags & ASE_MICROMIPS) {
27012 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
27013 insn_bytes = decode_micromips_opc(env, ctx);
27014 } else if (ctx->insn_flags & ASE_MIPS16) {
27015 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
27016 insn_bytes = decode_mips16_opc(env, ctx);
27018 generate_exception_end(ctx, EXCP_RI);
27019 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
27023 if (ctx->hflags & MIPS_HFLAG_BMASK) {
27024 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
27025 MIPS_HFLAG_FBNSLOT))) {
27026 /* force to generate branch as there is neither delay nor
27030 if ((ctx->hflags & MIPS_HFLAG_M16) &&
27031 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
27032 /* Force to generate branch as microMIPS R6 doesn't restrict
27033 branches in the forbidden slot. */
27038 gen_branch(ctx, insn_bytes);
27040 ctx->base.pc_next += insn_bytes;
27042 if (ctx->base.is_jmp != DISAS_NEXT) {
27045 /* Execute a branch and its delay slot as a single instruction.
27046 This is what GDB expects and is consistent with what the
27047 hardware does (e.g. if a delay slot instruction faults, the
27048 reported PC is the PC of the branch). */
27049 if (ctx->base.singlestep_enabled &&
27050 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
27051 ctx->base.is_jmp = DISAS_TOO_MANY;
27053 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
27054 ctx->base.is_jmp = DISAS_TOO_MANY;
27058 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
27060 DisasContext *ctx = container_of(dcbase, DisasContext, base);
27062 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
27063 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
27064 gen_helper_raise_exception_debug(cpu_env);
27066 switch (ctx->base.is_jmp) {
27068 gen_save_pc(ctx->base.pc_next);
27069 tcg_gen_lookup_and_goto_ptr();
27072 case DISAS_TOO_MANY:
27073 save_cpu_state(ctx, 0);
27074 gen_goto_tb(ctx, 0, ctx->base.pc_next);
27077 tcg_gen_exit_tb(NULL, 0);
27079 case DISAS_NORETURN:
27082 g_assert_not_reached();
27087 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
27089 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
27090 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
27093 static const TranslatorOps mips_tr_ops = {
27094 .init_disas_context = mips_tr_init_disas_context,
27095 .tb_start = mips_tr_tb_start,
27096 .insn_start = mips_tr_insn_start,
27097 .breakpoint_check = mips_tr_breakpoint_check,
27098 .translate_insn = mips_tr_translate_insn,
27099 .tb_stop = mips_tr_tb_stop,
27100 .disas_log = mips_tr_disas_log,
27103 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
27107 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
27110 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
27114 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
27116 #define printfpr(fp) \
27119 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
27120 " fd:%13g fs:%13g psu: %13g\n", \
27121 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
27122 (double)(fp)->fd, \
27123 (double)(fp)->fs[FP_ENDIAN_IDX], \
27124 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
27127 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
27128 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
27129 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
27130 " fd:%13g fs:%13g psu:%13g\n", \
27131 tmp.w[FP_ENDIAN_IDX], tmp.d, \
27133 (double)tmp.fs[FP_ENDIAN_IDX], \
27134 (double)tmp.fs[!FP_ENDIAN_IDX]); \
27139 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
27140 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
27141 get_float_exception_flags(&env->active_fpu.fp_status));
27142 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
27143 fpu_fprintf(f, "%3s: ", fregnames[i]);
27144 printfpr(&env->active_fpu.fpr[i]);
27150 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
27153 MIPSCPU *cpu = MIPS_CPU(cs);
27154 CPUMIPSState *env = &cpu->env;
27157 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
27158 " LO=0x" TARGET_FMT_lx " ds %04x "
27159 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
27160 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
27161 env->hflags, env->btarget, env->bcond);
27162 for (i = 0; i < 32; i++) {
27164 cpu_fprintf(f, "GPR%02d:", i);
27165 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
27167 cpu_fprintf(f, "\n");
27170 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
27171 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
27172 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
27174 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27175 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
27176 env->CP0_Config2, env->CP0_Config3);
27177 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
27178 env->CP0_Config4, env->CP0_Config5);
27179 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
27180 fpu_dump_state(env, f, cpu_fprintf, flags);
27184 void mips_tcg_init(void)
27189 for (i = 1; i < 32; i++)
27190 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
27191 offsetof(CPUMIPSState, active_tc.gpr[i]),
27194 for (i = 0; i < 32; i++) {
27195 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
27197 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
27198 /* The scalar floating-point unit (FPU) registers are mapped on
27199 * the MSA vector registers. */
27200 fpu_f64[i] = msa_wr_d[i * 2];
27201 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
27202 msa_wr_d[i * 2 + 1] =
27203 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
27206 cpu_PC = tcg_global_mem_new(cpu_env,
27207 offsetof(CPUMIPSState, active_tc.PC), "PC");
27208 for (i = 0; i < MIPS_DSP_ACC; i++) {
27209 cpu_HI[i] = tcg_global_mem_new(cpu_env,
27210 offsetof(CPUMIPSState, active_tc.HI[i]),
27212 cpu_LO[i] = tcg_global_mem_new(cpu_env,
27213 offsetof(CPUMIPSState, active_tc.LO[i]),
27216 cpu_dspctrl = tcg_global_mem_new(cpu_env,
27217 offsetof(CPUMIPSState, active_tc.DSPControl),
27219 bcond = tcg_global_mem_new(cpu_env,
27220 offsetof(CPUMIPSState, bcond), "bcond");
27221 btarget = tcg_global_mem_new(cpu_env,
27222 offsetof(CPUMIPSState, btarget), "btarget");
27223 hflags = tcg_global_mem_new_i32(cpu_env,
27224 offsetof(CPUMIPSState, hflags), "hflags");
27226 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
27227 offsetof(CPUMIPSState, active_fpu.fcr0),
27229 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
27230 offsetof(CPUMIPSState, active_fpu.fcr31),
27234 #include "translate_init.inc.c"
27236 void cpu_mips_realize_env(CPUMIPSState *env)
27238 env->exception_base = (int32_t)0xBFC00000;
27240 #ifndef CONFIG_USER_ONLY
27241 mmu_init(env, env->cpu_model);
27243 fpu_init(env, env->cpu_model);
27244 mvp_init(env, env->cpu_model);
27247 bool cpu_supports_cps_smp(const char *cpu_type)
27249 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
27250 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
27253 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
27255 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
27256 return (mcc->cpu_def->insn_flags & isa) != 0;
27259 void cpu_set_exception_base(int vp_index, target_ulong address)
27261 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
27262 vp->env.exception_base = address;
27265 void cpu_state_reset(CPUMIPSState *env)
27267 MIPSCPU *cpu = mips_env_get_cpu(env);
27268 CPUState *cs = CPU(cpu);
27270 /* Reset registers to their default values */
27271 env->CP0_PRid = env->cpu_model->CP0_PRid;
27272 env->CP0_Config0 = env->cpu_model->CP0_Config0;
27273 #ifdef TARGET_WORDS_BIGENDIAN
27274 env->CP0_Config0 |= (1 << CP0C0_BE);
27276 env->CP0_Config1 = env->cpu_model->CP0_Config1;
27277 env->CP0_Config2 = env->cpu_model->CP0_Config2;
27278 env->CP0_Config3 = env->cpu_model->CP0_Config3;
27279 env->CP0_Config4 = env->cpu_model->CP0_Config4;
27280 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
27281 env->CP0_Config5 = env->cpu_model->CP0_Config5;
27282 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
27283 env->CP0_Config6 = env->cpu_model->CP0_Config6;
27284 env->CP0_Config7 = env->cpu_model->CP0_Config7;
27285 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
27286 << env->cpu_model->CP0_LLAddr_shift;
27287 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
27288 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
27289 env->CCRes = env->cpu_model->CCRes;
27290 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
27291 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
27292 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
27293 env->current_tc = 0;
27294 env->SEGBITS = env->cpu_model->SEGBITS;
27295 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
27296 #if defined(TARGET_MIPS64)
27297 if (env->cpu_model->insn_flags & ISA_MIPS3) {
27298 env->SEGMask |= 3ULL << 62;
27301 env->PABITS = env->cpu_model->PABITS;
27302 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
27303 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
27304 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
27305 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
27306 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
27307 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
27308 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
27309 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
27310 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
27311 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
27312 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
27313 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
27314 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
27315 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
27316 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
27317 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
27318 env->msair = env->cpu_model->MSAIR;
27319 env->insn_flags = env->cpu_model->insn_flags;
27321 #if defined(CONFIG_USER_ONLY)
27322 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
27323 # ifdef TARGET_MIPS64
27324 /* Enable 64-bit register mode. */
27325 env->CP0_Status |= (1 << CP0St_PX);
27327 # ifdef TARGET_ABI_MIPSN64
27328 /* Enable 64-bit address mode. */
27329 env->CP0_Status |= (1 << CP0St_UX);
27331 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
27332 hardware registers. */
27333 env->CP0_HWREna |= 0x0000000F;
27334 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
27335 env->CP0_Status |= (1 << CP0St_CU1);
27337 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
27338 env->CP0_Status |= (1 << CP0St_MX);
27340 # if defined(TARGET_MIPS64)
27341 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
27342 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
27343 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
27344 env->CP0_Status |= (1 << CP0St_FR);
27348 if (env->hflags & MIPS_HFLAG_BMASK) {
27349 /* If the exception was raised from a delay slot,
27350 come back to the jump. */
27351 env->CP0_ErrorEPC = (env->active_tc.PC
27352 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
27354 env->CP0_ErrorEPC = env->active_tc.PC;
27356 env->active_tc.PC = env->exception_base;
27357 env->CP0_Random = env->tlb->nb_tlb - 1;
27358 env->tlb->tlb_in_use = env->tlb->nb_tlb;
27359 env->CP0_Wired = 0;
27360 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
27361 env->CP0_EBase = (cs->cpu_index & 0x3FF);
27362 if (mips_um_ksegs_enabled()) {
27363 env->CP0_EBase |= 0x40000000;
27365 env->CP0_EBase |= (int32_t)0x80000000;
27367 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
27368 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
27370 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
27372 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
27373 /* vectored interrupts not implemented, timer on int 7,
27374 no performance counters. */
27375 env->CP0_IntCtl = 0xe0000000;
27379 for (i = 0; i < 7; i++) {
27380 env->CP0_WatchLo[i] = 0;
27381 env->CP0_WatchHi[i] = 0x80000000;
27383 env->CP0_WatchLo[7] = 0;
27384 env->CP0_WatchHi[7] = 0;
27386 /* Count register increments in debug mode, EJTAG version 1 */
27387 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
27389 cpu_mips_store_count(env, 1);
27391 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
27394 /* Only TC0 on VPE 0 starts as active. */
27395 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
27396 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
27397 env->tcs[i].CP0_TCHalt = 1;
27399 env->active_tc.CP0_TCHalt = 1;
27402 if (cs->cpu_index == 0) {
27403 /* VPE0 starts up enabled. */
27404 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
27405 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
27407 /* TC0 starts up unhalted. */
27409 env->active_tc.CP0_TCHalt = 0;
27410 env->tcs[0].CP0_TCHalt = 0;
27411 /* With thread 0 active. */
27412 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
27413 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
27418 * Configure default legacy segmentation control. We use this regardless of
27419 * whether segmentation control is presented to the guest.
27421 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
27422 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
27423 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
27424 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
27425 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
27426 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
27428 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
27429 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
27430 (3 << CP0SC_C)) << 16;
27431 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
27432 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
27433 (1 << CP0SC_EU) | (2 << CP0SC_C);
27434 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
27435 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
27436 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
27437 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
27438 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
27440 if ((env->insn_flags & ISA_MIPS32R6) &&
27441 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
27442 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
27443 env->CP0_Status |= (1 << CP0St_FR);
27446 if (env->insn_flags & ISA_MIPS32R6) {
27448 env->CP0_PWSize = 0x40;
27454 env->CP0_PWField = 0x0C30C302;
27461 env->CP0_PWField = 0x02;
27464 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
27465 /* microMIPS on reset when Config3.ISA is 3 */
27466 env->hflags |= MIPS_HFLAG_M16;
27470 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
27474 compute_hflags(env);
27475 restore_fp_status(env);
27476 restore_pamask(env);
27477 cs->exception_index = EXCP_NONE;
27479 if (semihosting_get_argc()) {
27480 /* UHI interface can be used to obtain argc and argv */
27481 env->active_tc.gpr[4] = -1;
27485 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
27486 target_ulong *data)
27488 env->active_tc.PC = data[0];
27489 env->hflags &= ~MIPS_HFLAG_BMASK;
27490 env->hflags |= data[1];
27491 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
27492 case MIPS_HFLAG_BR:
27494 case MIPS_HFLAG_BC:
27495 case MIPS_HFLAG_BL:
27497 env->btarget = data[2];