2 * MIPS32 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/>.
25 #include "disas/disas.h"
27 #include "exec/cpu_ldst.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 #include "sysemu/kvm.h"
32 #include "exec/semihost.h"
34 #include "trace-tcg.h"
36 #define MIPS_DEBUG_DISAS 0
38 /* MIPS major opcodes */
39 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
42 /* indirect opcode tables */
43 OPC_SPECIAL = (0x00 << 26),
44 OPC_REGIMM = (0x01 << 26),
45 OPC_CP0 = (0x10 << 26),
46 OPC_CP1 = (0x11 << 26),
47 OPC_CP2 = (0x12 << 26),
48 OPC_CP3 = (0x13 << 26),
49 OPC_SPECIAL2 = (0x1C << 26),
50 OPC_SPECIAL3 = (0x1F << 26),
51 /* arithmetic with immediate */
52 OPC_ADDI = (0x08 << 26),
53 OPC_ADDIU = (0x09 << 26),
54 OPC_SLTI = (0x0A << 26),
55 OPC_SLTIU = (0x0B << 26),
56 /* logic with immediate */
57 OPC_ANDI = (0x0C << 26),
58 OPC_ORI = (0x0D << 26),
59 OPC_XORI = (0x0E << 26),
60 OPC_LUI = (0x0F << 26),
61 /* arithmetic with immediate */
62 OPC_DADDI = (0x18 << 26),
63 OPC_DADDIU = (0x19 << 26),
64 /* Jump and branches */
66 OPC_JAL = (0x03 << 26),
67 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
68 OPC_BEQL = (0x14 << 26),
69 OPC_BNE = (0x05 << 26),
70 OPC_BNEL = (0x15 << 26),
71 OPC_BLEZ = (0x06 << 26),
72 OPC_BLEZL = (0x16 << 26),
73 OPC_BGTZ = (0x07 << 26),
74 OPC_BGTZL = (0x17 << 26),
75 OPC_JALX = (0x1D << 26),
76 OPC_DAUI = (0x1D << 26),
78 OPC_LDL = (0x1A << 26),
79 OPC_LDR = (0x1B << 26),
80 OPC_LB = (0x20 << 26),
81 OPC_LH = (0x21 << 26),
82 OPC_LWL = (0x22 << 26),
83 OPC_LW = (0x23 << 26),
84 OPC_LWPC = OPC_LW | 0x5,
85 OPC_LBU = (0x24 << 26),
86 OPC_LHU = (0x25 << 26),
87 OPC_LWR = (0x26 << 26),
88 OPC_LWU = (0x27 << 26),
89 OPC_SB = (0x28 << 26),
90 OPC_SH = (0x29 << 26),
91 OPC_SWL = (0x2A << 26),
92 OPC_SW = (0x2B << 26),
93 OPC_SDL = (0x2C << 26),
94 OPC_SDR = (0x2D << 26),
95 OPC_SWR = (0x2E << 26),
96 OPC_LL = (0x30 << 26),
97 OPC_LLD = (0x34 << 26),
98 OPC_LD = (0x37 << 26),
99 OPC_LDPC = OPC_LD | 0x5,
100 OPC_SC = (0x38 << 26),
101 OPC_SCD = (0x3C << 26),
102 OPC_SD = (0x3F << 26),
103 /* Floating point load/store */
104 OPC_LWC1 = (0x31 << 26),
105 OPC_LWC2 = (0x32 << 26),
106 OPC_LDC1 = (0x35 << 26),
107 OPC_LDC2 = (0x36 << 26),
108 OPC_SWC1 = (0x39 << 26),
109 OPC_SWC2 = (0x3A << 26),
110 OPC_SDC1 = (0x3D << 26),
111 OPC_SDC2 = (0x3E << 26),
112 /* Compact Branches */
113 OPC_BLEZALC = (0x06 << 26),
114 OPC_BGEZALC = (0x06 << 26),
115 OPC_BGEUC = (0x06 << 26),
116 OPC_BGTZALC = (0x07 << 26),
117 OPC_BLTZALC = (0x07 << 26),
118 OPC_BLTUC = (0x07 << 26),
119 OPC_BOVC = (0x08 << 26),
120 OPC_BEQZALC = (0x08 << 26),
121 OPC_BEQC = (0x08 << 26),
122 OPC_BLEZC = (0x16 << 26),
123 OPC_BGEZC = (0x16 << 26),
124 OPC_BGEC = (0x16 << 26),
125 OPC_BGTZC = (0x17 << 26),
126 OPC_BLTZC = (0x17 << 26),
127 OPC_BLTC = (0x17 << 26),
128 OPC_BNVC = (0x18 << 26),
129 OPC_BNEZALC = (0x18 << 26),
130 OPC_BNEC = (0x18 << 26),
131 OPC_BC = (0x32 << 26),
132 OPC_BEQZC = (0x36 << 26),
133 OPC_JIC = (0x36 << 26),
134 OPC_BALC = (0x3A << 26),
135 OPC_BNEZC = (0x3E << 26),
136 OPC_JIALC = (0x3E << 26),
137 /* MDMX ASE specific */
138 OPC_MDMX = (0x1E << 26),
139 /* MSA ASE, same as MDMX */
141 /* Cache and prefetch */
142 OPC_CACHE = (0x2F << 26),
143 OPC_PREF = (0x33 << 26),
144 /* PC-relative address computation / loads */
145 OPC_PCREL = (0x3B << 26),
148 /* PC-relative address computation / loads */
149 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
150 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
152 /* Instructions determined by bits 19 and 20 */
153 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
154 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
155 OPC_LWUPC = OPC_PCREL | (2 << 19),
157 /* Instructions determined by bits 16 ... 20 */
158 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
159 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
162 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
165 /* MIPS special opcodes */
166 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
170 OPC_SLL = 0x00 | OPC_SPECIAL,
171 /* NOP is SLL r0, r0, 0 */
172 /* SSNOP is SLL r0, r0, 1 */
173 /* EHB is SLL r0, r0, 3 */
174 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
175 OPC_ROTR = OPC_SRL | (1 << 21),
176 OPC_SRA = 0x03 | OPC_SPECIAL,
177 OPC_SLLV = 0x04 | OPC_SPECIAL,
178 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
179 OPC_ROTRV = OPC_SRLV | (1 << 6),
180 OPC_SRAV = 0x07 | OPC_SPECIAL,
181 OPC_DSLLV = 0x14 | OPC_SPECIAL,
182 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
183 OPC_DROTRV = OPC_DSRLV | (1 << 6),
184 OPC_DSRAV = 0x17 | OPC_SPECIAL,
185 OPC_DSLL = 0x38 | OPC_SPECIAL,
186 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
187 OPC_DROTR = OPC_DSRL | (1 << 21),
188 OPC_DSRA = 0x3B | OPC_SPECIAL,
189 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
190 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
191 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
192 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
193 /* Multiplication / division */
194 OPC_MULT = 0x18 | OPC_SPECIAL,
195 OPC_MULTU = 0x19 | OPC_SPECIAL,
196 OPC_DIV = 0x1A | OPC_SPECIAL,
197 OPC_DIVU = 0x1B | OPC_SPECIAL,
198 OPC_DMULT = 0x1C | OPC_SPECIAL,
199 OPC_DMULTU = 0x1D | OPC_SPECIAL,
200 OPC_DDIV = 0x1E | OPC_SPECIAL,
201 OPC_DDIVU = 0x1F | OPC_SPECIAL,
203 /* 2 registers arithmetic / logic */
204 OPC_ADD = 0x20 | OPC_SPECIAL,
205 OPC_ADDU = 0x21 | OPC_SPECIAL,
206 OPC_SUB = 0x22 | OPC_SPECIAL,
207 OPC_SUBU = 0x23 | OPC_SPECIAL,
208 OPC_AND = 0x24 | OPC_SPECIAL,
209 OPC_OR = 0x25 | OPC_SPECIAL,
210 OPC_XOR = 0x26 | OPC_SPECIAL,
211 OPC_NOR = 0x27 | OPC_SPECIAL,
212 OPC_SLT = 0x2A | OPC_SPECIAL,
213 OPC_SLTU = 0x2B | OPC_SPECIAL,
214 OPC_DADD = 0x2C | OPC_SPECIAL,
215 OPC_DADDU = 0x2D | OPC_SPECIAL,
216 OPC_DSUB = 0x2E | OPC_SPECIAL,
217 OPC_DSUBU = 0x2F | OPC_SPECIAL,
219 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
220 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
222 OPC_TGE = 0x30 | OPC_SPECIAL,
223 OPC_TGEU = 0x31 | OPC_SPECIAL,
224 OPC_TLT = 0x32 | OPC_SPECIAL,
225 OPC_TLTU = 0x33 | OPC_SPECIAL,
226 OPC_TEQ = 0x34 | OPC_SPECIAL,
227 OPC_TNE = 0x36 | OPC_SPECIAL,
228 /* HI / LO registers load & stores */
229 OPC_MFHI = 0x10 | OPC_SPECIAL,
230 OPC_MTHI = 0x11 | OPC_SPECIAL,
231 OPC_MFLO = 0x12 | OPC_SPECIAL,
232 OPC_MTLO = 0x13 | OPC_SPECIAL,
233 /* Conditional moves */
234 OPC_MOVZ = 0x0A | OPC_SPECIAL,
235 OPC_MOVN = 0x0B | OPC_SPECIAL,
237 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
238 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
240 OPC_MOVCI = 0x01 | OPC_SPECIAL,
243 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
244 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
245 OPC_BREAK = 0x0D | OPC_SPECIAL,
246 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
247 OPC_SYNC = 0x0F | OPC_SPECIAL,
249 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
250 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
251 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
252 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
255 /* R6 Multiply and Divide instructions have the same Opcode
256 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
257 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
260 R6_OPC_MUL = OPC_MULT | (2 << 6),
261 R6_OPC_MUH = OPC_MULT | (3 << 6),
262 R6_OPC_MULU = OPC_MULTU | (2 << 6),
263 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
264 R6_OPC_DIV = OPC_DIV | (2 << 6),
265 R6_OPC_MOD = OPC_DIV | (3 << 6),
266 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
267 R6_OPC_MODU = OPC_DIVU | (3 << 6),
269 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
270 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
271 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
272 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
273 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
274 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
275 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
276 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
278 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
279 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
280 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
281 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
282 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
284 OPC_LSA = 0x05 | OPC_SPECIAL,
285 OPC_DLSA = 0x15 | OPC_SPECIAL,
288 /* Multiplication variants of the vr54xx. */
289 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
292 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
293 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
294 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
295 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
296 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
297 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
298 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
299 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
300 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
301 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
302 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
303 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
304 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
305 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
308 /* REGIMM (rt field) opcodes */
309 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
312 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
313 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
314 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
315 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
316 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
317 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
318 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
319 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
320 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
321 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
322 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
323 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
324 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
325 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
326 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
328 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
329 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
332 /* Special2 opcodes */
333 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
336 /* Multiply & xxx operations */
337 OPC_MADD = 0x00 | OPC_SPECIAL2,
338 OPC_MADDU = 0x01 | OPC_SPECIAL2,
339 OPC_MUL = 0x02 | OPC_SPECIAL2,
340 OPC_MSUB = 0x04 | OPC_SPECIAL2,
341 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
343 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
344 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
345 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
346 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
347 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
348 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
349 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
350 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
351 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
352 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
353 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
354 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
356 OPC_CLZ = 0x20 | OPC_SPECIAL2,
357 OPC_CLO = 0x21 | OPC_SPECIAL2,
358 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
359 OPC_DCLO = 0x25 | OPC_SPECIAL2,
361 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
364 /* Special3 opcodes */
365 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
368 OPC_EXT = 0x00 | OPC_SPECIAL3,
369 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
370 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
371 OPC_DEXT = 0x03 | OPC_SPECIAL3,
372 OPC_INS = 0x04 | OPC_SPECIAL3,
373 OPC_DINSM = 0x05 | OPC_SPECIAL3,
374 OPC_DINSU = 0x06 | OPC_SPECIAL3,
375 OPC_DINS = 0x07 | OPC_SPECIAL3,
376 OPC_FORK = 0x08 | OPC_SPECIAL3,
377 OPC_YIELD = 0x09 | OPC_SPECIAL3,
378 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
379 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
380 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
383 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
384 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
385 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
386 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
387 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
388 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
389 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
390 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
391 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
392 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
393 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
394 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
397 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
398 /* MIPS DSP Arithmetic */
399 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
400 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
401 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
402 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
403 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
404 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
405 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
406 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
407 /* MIPS DSP GPR-Based Shift Sub-class */
408 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
409 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
410 /* MIPS DSP Multiply Sub-class insns */
411 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
412 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
413 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
414 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
415 /* DSP Bit/Manipulation Sub-class */
416 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
417 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
418 /* MIPS DSP Append Sub-class */
419 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
420 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
421 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
422 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
423 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
426 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
427 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
428 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
429 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
430 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
431 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
435 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
438 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
439 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
440 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
441 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
442 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
443 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
447 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
450 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
451 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
452 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
453 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
454 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
457 /* MIPS DSP REGIMM opcodes */
459 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
460 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
463 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
466 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
467 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
468 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
469 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
472 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
474 /* MIPS DSP Arithmetic Sub-class */
475 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
476 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
477 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
478 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
482 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
483 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
484 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
489 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
490 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
491 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
492 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
493 /* MIPS DSP Multiply Sub-class insns */
494 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
495 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
496 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
497 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
502 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
503 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
505 /* MIPS DSP Arithmetic Sub-class */
506 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
507 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
508 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
509 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
518 /* MIPS DSP Multiply Sub-class insns */
519 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
520 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
521 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
522 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
525 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
527 /* MIPS DSP Arithmetic Sub-class */
528 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
529 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
530 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
531 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
541 /* DSP Bit/Manipulation Sub-class */
542 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
549 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
551 /* MIPS DSP Arithmetic Sub-class */
552 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
553 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
554 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
555 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
559 /* DSP Compare-Pick Sub-class */
560 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
577 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
579 /* MIPS DSP GPR-Based Shift Sub-class */
580 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
581 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
582 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
583 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
604 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
606 /* MIPS DSP Multiply Sub-class insns */
607 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
608 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
609 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
610 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
621 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
624 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
631 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
633 /* DSP Bit/Manipulation Sub-class */
634 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
637 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
639 /* MIPS DSP Append Sub-class */
640 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
641 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
642 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
645 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
647 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
648 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
649 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
650 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
651 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
660 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
661 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
662 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
663 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
664 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
667 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669 /* MIPS DSP Arithmetic Sub-class */
670 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
671 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
672 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
673 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
687 /* DSP Bit/Manipulation Sub-class */
688 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
696 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
698 /* MIPS DSP Multiply Sub-class insns */
699 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
700 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
701 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
702 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
704 /* MIPS DSP Arithmetic Sub-class */
705 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
706 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
707 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
708 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
716 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
717 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
718 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
728 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
730 /* DSP Compare-Pick Sub-class */
731 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
732 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
733 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
734 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
750 /* MIPS DSP Arithmetic Sub-class */
751 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
761 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
763 /* DSP Append Sub-class */
764 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
765 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
766 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
767 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
770 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
772 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
773 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
774 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
775 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
776 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
777 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
796 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
798 /* DSP Bit/Manipulation Sub-class */
799 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
802 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
804 /* MIPS DSP Multiply Sub-class insns */
805 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
806 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
807 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
808 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
833 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
835 /* MIPS DSP GPR-Based Shift Sub-class */
836 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
837 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
838 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
839 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
864 /* Coprocessor 0 (rs field) */
865 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
868 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
869 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
870 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
871 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
872 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
873 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
874 OPC_MFTR = (0x08 << 21) | OPC_CP0,
875 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
876 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
877 OPC_MTTR = (0x0C << 21) | OPC_CP0,
878 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
879 OPC_C0 = (0x10 << 21) | OPC_CP0,
880 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
881 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
885 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
888 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
889 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
890 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
891 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
892 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
893 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
896 /* Coprocessor 0 (with rs == C0) */
897 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
900 OPC_TLBR = 0x01 | OPC_C0,
901 OPC_TLBWI = 0x02 | OPC_C0,
902 OPC_TLBINV = 0x03 | OPC_C0,
903 OPC_TLBINVF = 0x04 | OPC_C0,
904 OPC_TLBWR = 0x06 | OPC_C0,
905 OPC_TLBP = 0x08 | OPC_C0,
906 OPC_RFE = 0x10 | OPC_C0,
907 OPC_ERET = 0x18 | OPC_C0,
908 OPC_DERET = 0x1F | OPC_C0,
909 OPC_WAIT = 0x20 | OPC_C0,
912 /* Coprocessor 1 (rs field) */
913 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
915 /* Values for the fmt field in FP instructions */
917 /* 0 - 15 are reserved */
918 FMT_S = 16, /* single fp */
919 FMT_D = 17, /* double fp */
920 FMT_E = 18, /* extended fp */
921 FMT_Q = 19, /* quad fp */
922 FMT_W = 20, /* 32-bit fixed */
923 FMT_L = 21, /* 64-bit fixed */
924 FMT_PS = 22, /* paired single fp */
925 /* 23 - 31 are reserved */
929 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
930 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
931 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
932 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
933 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
934 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
935 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
936 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
937 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
938 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
939 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
940 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
941 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
942 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
943 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
944 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
945 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
946 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
947 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
948 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
949 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
950 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
951 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
952 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
953 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
954 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
955 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
956 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
957 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
958 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
961 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
962 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
965 OPC_BC1F = (0x00 << 16) | OPC_BC1,
966 OPC_BC1T = (0x01 << 16) | OPC_BC1,
967 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
968 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
972 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
973 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
977 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
978 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
981 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
984 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
985 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
986 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
987 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
988 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
989 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
990 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
991 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
992 OPC_BC2 = (0x08 << 21) | OPC_CP2,
993 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
994 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
997 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1000 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1001 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1002 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1003 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1004 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1005 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1009 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1010 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1011 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1012 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1013 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1014 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1019 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1020 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1021 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1022 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1023 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1024 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1025 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1027 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1028 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1029 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1030 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1031 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1032 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1033 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1034 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1036 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1037 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1038 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1039 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1040 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1041 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1043 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1044 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1045 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1046 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1047 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1048 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1050 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1051 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1052 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1053 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1054 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1055 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1058 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1059 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1060 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1061 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1062 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1064 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1065 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1066 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1067 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1068 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1069 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1071 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1072 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1073 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1074 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1075 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1076 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1078 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1079 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1080 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1081 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1082 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1083 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1085 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1086 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1087 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1088 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1089 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1090 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1094 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1097 OPC_LWXC1 = 0x00 | OPC_CP3,
1098 OPC_LDXC1 = 0x01 | OPC_CP3,
1099 OPC_LUXC1 = 0x05 | OPC_CP3,
1100 OPC_SWXC1 = 0x08 | OPC_CP3,
1101 OPC_SDXC1 = 0x09 | OPC_CP3,
1102 OPC_SUXC1 = 0x0D | OPC_CP3,
1103 OPC_PREFX = 0x0F | OPC_CP3,
1104 OPC_ALNV_PS = 0x1E | OPC_CP3,
1105 OPC_MADD_S = 0x20 | OPC_CP3,
1106 OPC_MADD_D = 0x21 | OPC_CP3,
1107 OPC_MADD_PS = 0x26 | OPC_CP3,
1108 OPC_MSUB_S = 0x28 | OPC_CP3,
1109 OPC_MSUB_D = 0x29 | OPC_CP3,
1110 OPC_MSUB_PS = 0x2E | OPC_CP3,
1111 OPC_NMADD_S = 0x30 | OPC_CP3,
1112 OPC_NMADD_D = 0x31 | OPC_CP3,
1113 OPC_NMADD_PS= 0x36 | OPC_CP3,
1114 OPC_NMSUB_S = 0x38 | OPC_CP3,
1115 OPC_NMSUB_D = 0x39 | OPC_CP3,
1116 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1120 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1122 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1123 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1124 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1125 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1126 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1127 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1128 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1129 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1130 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1131 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1132 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1133 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1134 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1135 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1136 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1137 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1138 OPC_MSA_ELM = 0x19 | OPC_MSA,
1139 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1140 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1141 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1142 OPC_MSA_VEC = 0x1E | OPC_MSA,
1144 /* MI10 instruction */
1145 OPC_LD_B = (0x20) | OPC_MSA,
1146 OPC_LD_H = (0x21) | OPC_MSA,
1147 OPC_LD_W = (0x22) | OPC_MSA,
1148 OPC_LD_D = (0x23) | OPC_MSA,
1149 OPC_ST_B = (0x24) | OPC_MSA,
1150 OPC_ST_H = (0x25) | OPC_MSA,
1151 OPC_ST_W = (0x26) | OPC_MSA,
1152 OPC_ST_D = (0x27) | OPC_MSA,
1156 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1157 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1158 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1159 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1160 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1161 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1162 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1163 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1164 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1165 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1166 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1167 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1168 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1170 /* I8 instruction */
1171 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1172 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1173 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1174 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1175 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1176 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1177 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1178 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1179 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1180 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1182 /* VEC/2R/2RF instruction */
1183 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1184 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1185 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1186 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1187 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1188 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1189 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1191 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1192 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1194 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1195 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1196 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1197 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1198 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1200 /* 2RF instruction df(bit 16) = _w, _d */
1201 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1202 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1203 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1204 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1205 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1206 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1207 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1208 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1209 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1210 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1211 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1212 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1213 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1214 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1215 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1216 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1218 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1219 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1220 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1221 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1222 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1223 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1224 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1225 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1226 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1227 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1228 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1229 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1230 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1231 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1232 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1233 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1234 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1235 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1236 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1237 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1238 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1239 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1240 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1241 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1242 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1243 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1244 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1245 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1246 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1247 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1248 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1249 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1250 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1251 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1252 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1253 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1254 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1255 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1256 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1257 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1258 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1259 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1260 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1261 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1262 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1263 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1264 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1265 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1266 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1267 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1268 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1269 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1270 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1271 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1272 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1273 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1274 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1275 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1276 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1277 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1278 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1279 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1280 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1281 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1283 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1284 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1285 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1286 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1287 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1288 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1289 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1290 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1294 /* 3RF instruction _df(bit 21) = _w, _d */
1295 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1296 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1297 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1298 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1299 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1300 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1301 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1302 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1303 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1304 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1305 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1306 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1307 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1308 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1309 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1310 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1311 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1312 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1313 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1314 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1315 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1316 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1317 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1318 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1319 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1320 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1321 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1322 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1323 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1324 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1325 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1326 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1327 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1328 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1329 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1330 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1331 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1332 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1333 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1334 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1335 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1337 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1338 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1339 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1340 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1341 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1342 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1343 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1344 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1345 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1346 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1347 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1348 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1349 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1352 /* global register indices */
1353 static TCGv_ptr cpu_env;
1354 static TCGv cpu_gpr[32], cpu_PC;
1355 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1356 static TCGv cpu_dspctrl, btarget, bcond;
1357 static TCGv_i32 hflags;
1358 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1359 static TCGv_i64 fpu_f64[32];
1360 static TCGv_i64 msa_wr_d[64];
1362 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1363 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1365 #include "exec/gen-icount.h"
1367 #define gen_helper_0e0i(name, arg) do { \
1368 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1369 gen_helper_##name(cpu_env, helper_tmp); \
1370 tcg_temp_free_i32(helper_tmp); \
1373 #define gen_helper_0e1i(name, arg1, arg2) do { \
1374 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1375 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1376 tcg_temp_free_i32(helper_tmp); \
1379 #define gen_helper_1e0i(name, ret, arg1) do { \
1380 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1381 gen_helper_##name(ret, cpu_env, helper_tmp); \
1382 tcg_temp_free_i32(helper_tmp); \
1385 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1386 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1387 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1388 tcg_temp_free_i32(helper_tmp); \
1391 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1392 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1393 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1394 tcg_temp_free_i32(helper_tmp); \
1397 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1398 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1399 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1400 tcg_temp_free_i32(helper_tmp); \
1403 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1404 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1405 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1406 tcg_temp_free_i32(helper_tmp); \
1409 typedef struct DisasContext {
1410 struct TranslationBlock *tb;
1411 target_ulong pc, saved_pc;
1413 int singlestep_enabled;
1415 int32_t CP0_Config1;
1416 /* Routine used to access memory */
1418 TCGMemOp default_tcg_memop_mask;
1419 uint32_t hflags, saved_hflags;
1421 target_ulong btarget;
1430 int CP0_LLAddr_shift;
1435 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1436 * exception condition */
1437 BS_STOP = 1, /* We want to stop translation for any reason */
1438 BS_BRANCH = 2, /* We reached a branch condition */
1439 BS_EXCP = 3, /* We reached an exception condition */
1442 static const char * const regnames[] = {
1443 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1444 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1445 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1446 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1449 static const char * const regnames_HI[] = {
1450 "HI0", "HI1", "HI2", "HI3",
1453 static const char * const regnames_LO[] = {
1454 "LO0", "LO1", "LO2", "LO3",
1457 static const char * const fregnames[] = {
1458 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1459 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1460 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1461 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1464 static const char * const msaregnames[] = {
1465 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1466 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1467 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1468 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1469 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1470 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1471 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1472 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1473 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1474 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1475 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1476 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1477 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1478 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1479 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1480 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1483 #define LOG_DISAS(...) \
1485 if (MIPS_DEBUG_DISAS) { \
1486 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1490 #define MIPS_INVAL(op) \
1492 if (MIPS_DEBUG_DISAS) { \
1493 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1494 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1495 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1496 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
1500 /* General purpose registers moves. */
1501 static inline void gen_load_gpr (TCGv t, int reg)
1504 tcg_gen_movi_tl(t, 0);
1506 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1509 static inline void gen_store_gpr (TCGv t, int reg)
1512 tcg_gen_mov_tl(cpu_gpr[reg], t);
1515 /* Moves to/from shadow registers. */
1516 static inline void gen_load_srsgpr (int from, int to)
1518 TCGv t0 = tcg_temp_new();
1521 tcg_gen_movi_tl(t0, 0);
1523 TCGv_i32 t2 = tcg_temp_new_i32();
1524 TCGv_ptr addr = tcg_temp_new_ptr();
1526 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1527 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1528 tcg_gen_andi_i32(t2, t2, 0xf);
1529 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1530 tcg_gen_ext_i32_ptr(addr, t2);
1531 tcg_gen_add_ptr(addr, cpu_env, addr);
1533 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1534 tcg_temp_free_ptr(addr);
1535 tcg_temp_free_i32(t2);
1537 gen_store_gpr(t0, to);
1541 static inline void gen_store_srsgpr (int from, int to)
1544 TCGv t0 = tcg_temp_new();
1545 TCGv_i32 t2 = tcg_temp_new_i32();
1546 TCGv_ptr addr = tcg_temp_new_ptr();
1548 gen_load_gpr(t0, from);
1549 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1550 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1551 tcg_gen_andi_i32(t2, t2, 0xf);
1552 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1553 tcg_gen_ext_i32_ptr(addr, t2);
1554 tcg_gen_add_ptr(addr, cpu_env, addr);
1556 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1557 tcg_temp_free_ptr(addr);
1558 tcg_temp_free_i32(t2);
1564 static inline void gen_save_pc(target_ulong pc)
1566 tcg_gen_movi_tl(cpu_PC, pc);
1569 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1571 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1572 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1573 gen_save_pc(ctx->pc);
1574 ctx->saved_pc = ctx->pc;
1576 if (ctx->hflags != ctx->saved_hflags) {
1577 tcg_gen_movi_i32(hflags, ctx->hflags);
1578 ctx->saved_hflags = ctx->hflags;
1579 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1585 tcg_gen_movi_tl(btarget, ctx->btarget);
1591 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1593 ctx->saved_hflags = ctx->hflags;
1594 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1600 ctx->btarget = env->btarget;
1605 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1607 TCGv_i32 texcp = tcg_const_i32(excp);
1608 TCGv_i32 terr = tcg_const_i32(err);
1609 save_cpu_state(ctx, 1);
1610 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1611 tcg_temp_free_i32(terr);
1612 tcg_temp_free_i32(texcp);
1613 ctx->bstate = BS_EXCP;
1616 static inline void generate_exception(DisasContext *ctx, int excp)
1618 gen_helper_0e0i(raise_exception, excp);
1621 static inline void generate_exception_end(DisasContext *ctx, int excp)
1623 generate_exception_err(ctx, excp, 0);
1626 /* Floating point register moves. */
1627 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1629 if (ctx->hflags & MIPS_HFLAG_FRE) {
1630 generate_exception(ctx, EXCP_RI);
1632 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1635 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1638 if (ctx->hflags & MIPS_HFLAG_FRE) {
1639 generate_exception(ctx, EXCP_RI);
1641 t64 = tcg_temp_new_i64();
1642 tcg_gen_extu_i32_i64(t64, t);
1643 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1644 tcg_temp_free_i64(t64);
1647 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1649 if (ctx->hflags & MIPS_HFLAG_F64) {
1650 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1652 gen_load_fpr32(ctx, t, reg | 1);
1656 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1658 if (ctx->hflags & MIPS_HFLAG_F64) {
1659 TCGv_i64 t64 = tcg_temp_new_i64();
1660 tcg_gen_extu_i32_i64(t64, t);
1661 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1662 tcg_temp_free_i64(t64);
1664 gen_store_fpr32(ctx, t, reg | 1);
1668 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1670 if (ctx->hflags & MIPS_HFLAG_F64) {
1671 tcg_gen_mov_i64(t, fpu_f64[reg]);
1673 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1677 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1679 if (ctx->hflags & MIPS_HFLAG_F64) {
1680 tcg_gen_mov_i64(fpu_f64[reg], t);
1683 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1684 t0 = tcg_temp_new_i64();
1685 tcg_gen_shri_i64(t0, t, 32);
1686 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1687 tcg_temp_free_i64(t0);
1691 static inline int get_fp_bit (int cc)
1699 /* Addresses computation */
1700 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1702 tcg_gen_add_tl(ret, arg0, arg1);
1704 #if defined(TARGET_MIPS64)
1705 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1706 tcg_gen_ext32s_i64(ret, ret);
1711 /* Addresses computation (translation time) */
1712 static target_long addr_add(DisasContext *ctx, target_long base,
1715 target_long sum = base + offset;
1717 #if defined(TARGET_MIPS64)
1718 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1725 /* Sign-extract the low 32-bits to a target_long. */
1726 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1728 #if defined(TARGET_MIPS64)
1729 tcg_gen_ext32s_i64(ret, arg);
1731 tcg_gen_extrl_i64_i32(ret, arg);
1735 /* Sign-extract the high 32-bits to a target_long. */
1736 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1738 #if defined(TARGET_MIPS64)
1739 tcg_gen_sari_i64(ret, arg, 32);
1741 tcg_gen_extrh_i64_i32(ret, arg);
1745 static inline void check_cp0_enabled(DisasContext *ctx)
1747 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1748 generate_exception_err(ctx, EXCP_CpU, 0);
1751 static inline void check_cp1_enabled(DisasContext *ctx)
1753 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1754 generate_exception_err(ctx, EXCP_CpU, 1);
1757 /* Verify that the processor is running with COP1X instructions enabled.
1758 This is associated with the nabla symbol in the MIPS32 and MIPS64
1761 static inline void check_cop1x(DisasContext *ctx)
1763 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1764 generate_exception_end(ctx, EXCP_RI);
1767 /* Verify that the processor is running with 64-bit floating-point
1768 operations enabled. */
1770 static inline void check_cp1_64bitmode(DisasContext *ctx)
1772 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1773 generate_exception_end(ctx, EXCP_RI);
1777 * Verify if floating point register is valid; an operation is not defined
1778 * if bit 0 of any register specification is set and the FR bit in the
1779 * Status register equals zero, since the register numbers specify an
1780 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1781 * in the Status register equals one, both even and odd register numbers
1782 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1784 * Multiple 64 bit wide registers can be checked by calling
1785 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1787 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1789 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1790 generate_exception_end(ctx, EXCP_RI);
1793 /* Verify that the processor is running with DSP instructions enabled.
1794 This is enabled by CP0 Status register MX(24) bit.
1797 static inline void check_dsp(DisasContext *ctx)
1799 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1800 if (ctx->insn_flags & ASE_DSP) {
1801 generate_exception_end(ctx, EXCP_DSPDIS);
1803 generate_exception_end(ctx, EXCP_RI);
1808 static inline void check_dspr2(DisasContext *ctx)
1810 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1811 if (ctx->insn_flags & ASE_DSP) {
1812 generate_exception_end(ctx, EXCP_DSPDIS);
1814 generate_exception_end(ctx, EXCP_RI);
1819 /* This code generates a "reserved instruction" exception if the
1820 CPU does not support the instruction set corresponding to flags. */
1821 static inline void check_insn(DisasContext *ctx, int flags)
1823 if (unlikely(!(ctx->insn_flags & flags))) {
1824 generate_exception_end(ctx, EXCP_RI);
1828 /* This code generates a "reserved instruction" exception if the
1829 CPU has corresponding flag set which indicates that the instruction
1830 has been removed. */
1831 static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1833 if (unlikely(ctx->insn_flags & flags)) {
1834 generate_exception_end(ctx, EXCP_RI);
1838 /* This code generates a "reserved instruction" exception if the
1839 CPU does not support 64-bit paired-single (PS) floating point data type */
1840 static inline void check_ps(DisasContext *ctx)
1842 if (unlikely(!ctx->ps)) {
1843 generate_exception(ctx, EXCP_RI);
1845 check_cp1_64bitmode(ctx);
1848 #ifdef TARGET_MIPS64
1849 /* This code generates a "reserved instruction" exception if 64-bit
1850 instructions are not enabled. */
1851 static inline void check_mips_64(DisasContext *ctx)
1853 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1854 generate_exception_end(ctx, EXCP_RI);
1858 #ifndef CONFIG_USER_ONLY
1859 static inline void check_mvh(DisasContext *ctx)
1861 if (unlikely(!ctx->mvh)) {
1862 generate_exception(ctx, EXCP_RI);
1867 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1868 calling interface for 32 and 64-bit FPRs. No sense in changing
1869 all callers for gen_load_fpr32 when we need the CTX parameter for
1871 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1872 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1873 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1874 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1875 int ft, int fs, int cc) \
1877 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1878 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1887 check_cp1_registers(ctx, fs | ft); \
1895 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1896 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1898 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1899 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1900 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1901 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1902 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1903 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1904 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1905 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1906 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1907 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1908 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1909 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1910 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1911 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1912 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1913 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1916 tcg_temp_free_i##bits (fp0); \
1917 tcg_temp_free_i##bits (fp1); \
1920 FOP_CONDS(, 0, d, FMT_D, 64)
1921 FOP_CONDS(abs, 1, d, FMT_D, 64)
1922 FOP_CONDS(, 0, s, FMT_S, 32)
1923 FOP_CONDS(abs, 1, s, FMT_S, 32)
1924 FOP_CONDS(, 0, ps, FMT_PS, 64)
1925 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1928 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1929 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1930 int ft, int fs, int fd) \
1932 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1933 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1934 if (ifmt == FMT_D) { \
1935 check_cp1_registers(ctx, fs | ft | fd); \
1937 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1938 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1941 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1944 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1947 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1950 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1953 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1956 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1959 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1962 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1965 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1968 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1971 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1974 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1977 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1980 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1983 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1986 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1989 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1992 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1995 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1998 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2001 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2004 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2010 tcg_temp_free_i ## bits (fp0); \
2011 tcg_temp_free_i ## bits (fp1); \
2014 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2015 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2017 #undef gen_ldcmp_fpr32
2018 #undef gen_ldcmp_fpr64
2020 /* load/store instructions. */
2021 #ifdef CONFIG_USER_ONLY
2022 #define OP_LD_ATOMIC(insn,fname) \
2023 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2025 TCGv t0 = tcg_temp_new(); \
2026 tcg_gen_mov_tl(t0, arg1); \
2027 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2028 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2029 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2030 tcg_temp_free(t0); \
2033 #define OP_LD_ATOMIC(insn,fname) \
2034 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2036 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
2039 OP_LD_ATOMIC(ll,ld32s);
2040 #if defined(TARGET_MIPS64)
2041 OP_LD_ATOMIC(lld,ld64);
2045 #ifdef CONFIG_USER_ONLY
2046 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2047 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2049 TCGv t0 = tcg_temp_new(); \
2050 TCGLabel *l1 = gen_new_label(); \
2051 TCGLabel *l2 = gen_new_label(); \
2053 tcg_gen_andi_tl(t0, arg2, almask); \
2054 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2055 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2056 generate_exception(ctx, EXCP_AdES); \
2057 gen_set_label(l1); \
2058 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2059 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2060 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2061 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2062 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2063 generate_exception_end(ctx, EXCP_SC); \
2064 gen_set_label(l2); \
2065 tcg_gen_movi_tl(t0, 0); \
2066 gen_store_gpr(t0, rt); \
2067 tcg_temp_free(t0); \
2070 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2071 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2073 TCGv t0 = tcg_temp_new(); \
2074 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2075 gen_store_gpr(t0, rt); \
2076 tcg_temp_free(t0); \
2079 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2080 #if defined(TARGET_MIPS64)
2081 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2085 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2086 int base, int16_t offset)
2089 tcg_gen_movi_tl(addr, offset);
2090 } else if (offset == 0) {
2091 gen_load_gpr(addr, base);
2093 tcg_gen_movi_tl(addr, offset);
2094 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2098 static target_ulong pc_relative_pc (DisasContext *ctx)
2100 target_ulong pc = ctx->pc;
2102 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2103 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2108 pc &= ~(target_ulong)3;
2113 static void gen_ld(DisasContext *ctx, uint32_t opc,
2114 int rt, int base, int16_t offset)
2118 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2119 /* Loongson CPU uses a load to zero register for prefetch.
2120 We emulate it as a NOP. On other CPU we must perform the
2121 actual memory access. */
2125 t0 = tcg_temp_new();
2126 gen_base_offset_addr(ctx, t0, base, offset);
2129 #if defined(TARGET_MIPS64)
2131 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2132 ctx->default_tcg_memop_mask);
2133 gen_store_gpr(t0, rt);
2136 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2137 ctx->default_tcg_memop_mask);
2138 gen_store_gpr(t0, rt);
2142 op_ld_lld(t0, t0, ctx);
2143 gen_store_gpr(t0, rt);
2146 t1 = tcg_temp_new();
2147 /* Do a byte access to possibly trigger a page
2148 fault with the unaligned address. */
2149 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2150 tcg_gen_andi_tl(t1, t0, 7);
2151 #ifndef TARGET_WORDS_BIGENDIAN
2152 tcg_gen_xori_tl(t1, t1, 7);
2154 tcg_gen_shli_tl(t1, t1, 3);
2155 tcg_gen_andi_tl(t0, t0, ~7);
2156 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2157 tcg_gen_shl_tl(t0, t0, t1);
2158 t2 = tcg_const_tl(-1);
2159 tcg_gen_shl_tl(t2, t2, t1);
2160 gen_load_gpr(t1, rt);
2161 tcg_gen_andc_tl(t1, t1, t2);
2163 tcg_gen_or_tl(t0, t0, t1);
2165 gen_store_gpr(t0, rt);
2168 t1 = tcg_temp_new();
2169 /* Do a byte access to possibly trigger a page
2170 fault with the unaligned address. */
2171 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2172 tcg_gen_andi_tl(t1, t0, 7);
2173 #ifdef TARGET_WORDS_BIGENDIAN
2174 tcg_gen_xori_tl(t1, t1, 7);
2176 tcg_gen_shli_tl(t1, t1, 3);
2177 tcg_gen_andi_tl(t0, t0, ~7);
2178 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2179 tcg_gen_shr_tl(t0, t0, t1);
2180 tcg_gen_xori_tl(t1, t1, 63);
2181 t2 = tcg_const_tl(0xfffffffffffffffeull);
2182 tcg_gen_shl_tl(t2, t2, t1);
2183 gen_load_gpr(t1, rt);
2184 tcg_gen_and_tl(t1, t1, t2);
2186 tcg_gen_or_tl(t0, t0, t1);
2188 gen_store_gpr(t0, rt);
2191 t1 = tcg_const_tl(pc_relative_pc(ctx));
2192 gen_op_addr_add(ctx, t0, t0, t1);
2194 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2195 gen_store_gpr(t0, rt);
2199 t1 = tcg_const_tl(pc_relative_pc(ctx));
2200 gen_op_addr_add(ctx, t0, t0, t1);
2202 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2203 gen_store_gpr(t0, rt);
2206 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2207 ctx->default_tcg_memop_mask);
2208 gen_store_gpr(t0, rt);
2211 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2212 ctx->default_tcg_memop_mask);
2213 gen_store_gpr(t0, rt);
2216 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2217 ctx->default_tcg_memop_mask);
2218 gen_store_gpr(t0, rt);
2221 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2222 gen_store_gpr(t0, rt);
2225 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2226 gen_store_gpr(t0, rt);
2229 t1 = tcg_temp_new();
2230 /* Do a byte access to possibly trigger a page
2231 fault with the unaligned address. */
2232 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2233 tcg_gen_andi_tl(t1, t0, 3);
2234 #ifndef TARGET_WORDS_BIGENDIAN
2235 tcg_gen_xori_tl(t1, t1, 3);
2237 tcg_gen_shli_tl(t1, t1, 3);
2238 tcg_gen_andi_tl(t0, t0, ~3);
2239 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2240 tcg_gen_shl_tl(t0, t0, t1);
2241 t2 = tcg_const_tl(-1);
2242 tcg_gen_shl_tl(t2, t2, t1);
2243 gen_load_gpr(t1, rt);
2244 tcg_gen_andc_tl(t1, t1, t2);
2246 tcg_gen_or_tl(t0, t0, t1);
2248 tcg_gen_ext32s_tl(t0, t0);
2249 gen_store_gpr(t0, rt);
2252 t1 = tcg_temp_new();
2253 /* Do a byte access to possibly trigger a page
2254 fault with the unaligned address. */
2255 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2256 tcg_gen_andi_tl(t1, t0, 3);
2257 #ifdef TARGET_WORDS_BIGENDIAN
2258 tcg_gen_xori_tl(t1, t1, 3);
2260 tcg_gen_shli_tl(t1, t1, 3);
2261 tcg_gen_andi_tl(t0, t0, ~3);
2262 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2263 tcg_gen_shr_tl(t0, t0, t1);
2264 tcg_gen_xori_tl(t1, t1, 31);
2265 t2 = tcg_const_tl(0xfffffffeull);
2266 tcg_gen_shl_tl(t2, t2, t1);
2267 gen_load_gpr(t1, rt);
2268 tcg_gen_and_tl(t1, t1, t2);
2270 tcg_gen_or_tl(t0, t0, t1);
2272 tcg_gen_ext32s_tl(t0, t0);
2273 gen_store_gpr(t0, rt);
2277 op_ld_ll(t0, t0, ctx);
2278 gen_store_gpr(t0, rt);
2285 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2286 int base, int16_t offset)
2288 TCGv t0 = tcg_temp_new();
2289 TCGv t1 = tcg_temp_new();
2291 gen_base_offset_addr(ctx, t0, base, offset);
2292 gen_load_gpr(t1, rt);
2294 #if defined(TARGET_MIPS64)
2296 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2297 ctx->default_tcg_memop_mask);
2300 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2303 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2307 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2308 ctx->default_tcg_memop_mask);
2311 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2312 ctx->default_tcg_memop_mask);
2315 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2318 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2321 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2329 /* Store conditional */
2330 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2331 int base, int16_t offset)
2335 #ifdef CONFIG_USER_ONLY
2336 t0 = tcg_temp_local_new();
2337 t1 = tcg_temp_local_new();
2339 t0 = tcg_temp_new();
2340 t1 = tcg_temp_new();
2342 gen_base_offset_addr(ctx, t0, base, offset);
2343 gen_load_gpr(t1, rt);
2345 #if defined(TARGET_MIPS64)
2348 op_st_scd(t1, t0, rt, ctx);
2353 op_st_sc(t1, t0, rt, ctx);
2360 /* Load and store */
2361 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2362 int base, int16_t offset)
2364 TCGv t0 = tcg_temp_new();
2366 gen_base_offset_addr(ctx, t0, base, offset);
2367 /* Don't do NOP if destination is zero: we must perform the actual
2372 TCGv_i32 fp0 = tcg_temp_new_i32();
2373 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2374 ctx->default_tcg_memop_mask);
2375 gen_store_fpr32(ctx, fp0, ft);
2376 tcg_temp_free_i32(fp0);
2381 TCGv_i32 fp0 = tcg_temp_new_i32();
2382 gen_load_fpr32(ctx, fp0, ft);
2383 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2384 ctx->default_tcg_memop_mask);
2385 tcg_temp_free_i32(fp0);
2390 TCGv_i64 fp0 = tcg_temp_new_i64();
2391 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2392 ctx->default_tcg_memop_mask);
2393 gen_store_fpr64(ctx, fp0, ft);
2394 tcg_temp_free_i64(fp0);
2399 TCGv_i64 fp0 = tcg_temp_new_i64();
2400 gen_load_fpr64(ctx, fp0, ft);
2401 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2402 ctx->default_tcg_memop_mask);
2403 tcg_temp_free_i64(fp0);
2407 MIPS_INVAL("flt_ldst");
2408 generate_exception_end(ctx, EXCP_RI);
2415 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2416 int rs, int16_t imm)
2418 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2419 check_cp1_enabled(ctx);
2423 check_insn(ctx, ISA_MIPS2);
2426 gen_flt_ldst(ctx, op, rt, rs, imm);
2429 generate_exception_err(ctx, EXCP_CpU, 1);
2433 /* Arithmetic with immediate operand */
2434 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2435 int rt, int rs, int16_t imm)
2437 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2439 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2440 /* If no destination, treat it as a NOP.
2441 For addi, we must generate the overflow exception when needed. */
2447 TCGv t0 = tcg_temp_local_new();
2448 TCGv t1 = tcg_temp_new();
2449 TCGv t2 = tcg_temp_new();
2450 TCGLabel *l1 = gen_new_label();
2452 gen_load_gpr(t1, rs);
2453 tcg_gen_addi_tl(t0, t1, uimm);
2454 tcg_gen_ext32s_tl(t0, t0);
2456 tcg_gen_xori_tl(t1, t1, ~uimm);
2457 tcg_gen_xori_tl(t2, t0, uimm);
2458 tcg_gen_and_tl(t1, t1, t2);
2460 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2462 /* operands of same sign, result different sign */
2463 generate_exception(ctx, EXCP_OVERFLOW);
2465 tcg_gen_ext32s_tl(t0, t0);
2466 gen_store_gpr(t0, rt);
2472 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2473 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2475 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2478 #if defined(TARGET_MIPS64)
2481 TCGv t0 = tcg_temp_local_new();
2482 TCGv t1 = tcg_temp_new();
2483 TCGv t2 = tcg_temp_new();
2484 TCGLabel *l1 = gen_new_label();
2486 gen_load_gpr(t1, rs);
2487 tcg_gen_addi_tl(t0, t1, uimm);
2489 tcg_gen_xori_tl(t1, t1, ~uimm);
2490 tcg_gen_xori_tl(t2, t0, uimm);
2491 tcg_gen_and_tl(t1, t1, t2);
2493 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2495 /* operands of same sign, result different sign */
2496 generate_exception(ctx, EXCP_OVERFLOW);
2498 gen_store_gpr(t0, rt);
2504 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2506 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2513 /* Logic with immediate operand */
2514 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2515 int rt, int rs, int16_t imm)
2520 /* If no destination, treat it as a NOP. */
2523 uimm = (uint16_t)imm;
2526 if (likely(rs != 0))
2527 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2529 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2533 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2535 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2538 if (likely(rs != 0))
2539 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2541 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2544 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2546 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2547 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2549 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2558 /* Set on less than with immediate operand */
2559 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2560 int rt, int rs, int16_t imm)
2562 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2566 /* If no destination, treat it as a NOP. */
2569 t0 = tcg_temp_new();
2570 gen_load_gpr(t0, rs);
2573 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2576 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2582 /* Shifts with immediate operand */
2583 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2584 int rt, int rs, int16_t imm)
2586 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2590 /* If no destination, treat it as a NOP. */
2594 t0 = tcg_temp_new();
2595 gen_load_gpr(t0, rs);
2598 tcg_gen_shli_tl(t0, t0, uimm);
2599 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2602 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2606 tcg_gen_ext32u_tl(t0, t0);
2607 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2609 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2614 TCGv_i32 t1 = tcg_temp_new_i32();
2616 tcg_gen_trunc_tl_i32(t1, t0);
2617 tcg_gen_rotri_i32(t1, t1, uimm);
2618 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2619 tcg_temp_free_i32(t1);
2621 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2624 #if defined(TARGET_MIPS64)
2626 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2629 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2632 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2636 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2638 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2642 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2645 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2648 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2651 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2659 static void gen_arith(DisasContext *ctx, uint32_t opc,
2660 int rd, int rs, int rt)
2662 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2663 && opc != OPC_DADD && opc != OPC_DSUB) {
2664 /* If no destination, treat it as a NOP.
2665 For add & sub, we must generate the overflow exception when needed. */
2672 TCGv t0 = tcg_temp_local_new();
2673 TCGv t1 = tcg_temp_new();
2674 TCGv t2 = tcg_temp_new();
2675 TCGLabel *l1 = gen_new_label();
2677 gen_load_gpr(t1, rs);
2678 gen_load_gpr(t2, rt);
2679 tcg_gen_add_tl(t0, t1, t2);
2680 tcg_gen_ext32s_tl(t0, t0);
2681 tcg_gen_xor_tl(t1, t1, t2);
2682 tcg_gen_xor_tl(t2, t0, t2);
2683 tcg_gen_andc_tl(t1, t2, t1);
2685 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2687 /* operands of same sign, result different sign */
2688 generate_exception(ctx, EXCP_OVERFLOW);
2690 gen_store_gpr(t0, rd);
2695 if (rs != 0 && rt != 0) {
2696 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2697 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2698 } else if (rs == 0 && rt != 0) {
2699 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2700 } else if (rs != 0 && rt == 0) {
2701 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2703 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2708 TCGv t0 = tcg_temp_local_new();
2709 TCGv t1 = tcg_temp_new();
2710 TCGv t2 = tcg_temp_new();
2711 TCGLabel *l1 = gen_new_label();
2713 gen_load_gpr(t1, rs);
2714 gen_load_gpr(t2, rt);
2715 tcg_gen_sub_tl(t0, t1, t2);
2716 tcg_gen_ext32s_tl(t0, t0);
2717 tcg_gen_xor_tl(t2, t1, t2);
2718 tcg_gen_xor_tl(t1, t0, t1);
2719 tcg_gen_and_tl(t1, t1, t2);
2721 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2723 /* operands of different sign, first operand and result different sign */
2724 generate_exception(ctx, EXCP_OVERFLOW);
2726 gen_store_gpr(t0, rd);
2731 if (rs != 0 && rt != 0) {
2732 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2733 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2734 } else if (rs == 0 && rt != 0) {
2735 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2736 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2737 } else if (rs != 0 && rt == 0) {
2738 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2740 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2743 #if defined(TARGET_MIPS64)
2746 TCGv t0 = tcg_temp_local_new();
2747 TCGv t1 = tcg_temp_new();
2748 TCGv t2 = tcg_temp_new();
2749 TCGLabel *l1 = gen_new_label();
2751 gen_load_gpr(t1, rs);
2752 gen_load_gpr(t2, rt);
2753 tcg_gen_add_tl(t0, t1, t2);
2754 tcg_gen_xor_tl(t1, t1, t2);
2755 tcg_gen_xor_tl(t2, t0, t2);
2756 tcg_gen_andc_tl(t1, t2, t1);
2758 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2760 /* operands of same sign, result different sign */
2761 generate_exception(ctx, EXCP_OVERFLOW);
2763 gen_store_gpr(t0, rd);
2768 if (rs != 0 && rt != 0) {
2769 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2770 } else if (rs == 0 && rt != 0) {
2771 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2772 } else if (rs != 0 && rt == 0) {
2773 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2775 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2780 TCGv t0 = tcg_temp_local_new();
2781 TCGv t1 = tcg_temp_new();
2782 TCGv t2 = tcg_temp_new();
2783 TCGLabel *l1 = gen_new_label();
2785 gen_load_gpr(t1, rs);
2786 gen_load_gpr(t2, rt);
2787 tcg_gen_sub_tl(t0, t1, t2);
2788 tcg_gen_xor_tl(t2, t1, t2);
2789 tcg_gen_xor_tl(t1, t0, t1);
2790 tcg_gen_and_tl(t1, t1, t2);
2792 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2794 /* operands of different sign, first operand and result different sign */
2795 generate_exception(ctx, EXCP_OVERFLOW);
2797 gen_store_gpr(t0, rd);
2802 if (rs != 0 && rt != 0) {
2803 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2804 } else if (rs == 0 && rt != 0) {
2805 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2806 } else if (rs != 0 && rt == 0) {
2807 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2809 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2814 if (likely(rs != 0 && rt != 0)) {
2815 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2816 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2824 /* Conditional move */
2825 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2826 int rd, int rs, int rt)
2831 /* If no destination, treat it as a NOP. */
2835 t0 = tcg_temp_new();
2836 gen_load_gpr(t0, rt);
2837 t1 = tcg_const_tl(0);
2838 t2 = tcg_temp_new();
2839 gen_load_gpr(t2, rs);
2842 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2845 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2848 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2851 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2860 static void gen_logic(DisasContext *ctx, uint32_t opc,
2861 int rd, int rs, int rt)
2864 /* If no destination, treat it as a NOP. */
2870 if (likely(rs != 0 && rt != 0)) {
2871 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2873 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2877 if (rs != 0 && rt != 0) {
2878 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2879 } else if (rs == 0 && rt != 0) {
2880 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2881 } else if (rs != 0 && rt == 0) {
2882 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2884 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2888 if (likely(rs != 0 && rt != 0)) {
2889 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2890 } else if (rs == 0 && rt != 0) {
2891 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2892 } else if (rs != 0 && rt == 0) {
2893 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2895 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2899 if (likely(rs != 0 && rt != 0)) {
2900 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2901 } else if (rs == 0 && rt != 0) {
2902 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2903 } else if (rs != 0 && rt == 0) {
2904 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2906 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2912 /* Set on lower than */
2913 static void gen_slt(DisasContext *ctx, uint32_t opc,
2914 int rd, int rs, int rt)
2919 /* If no destination, treat it as a NOP. */
2923 t0 = tcg_temp_new();
2924 t1 = tcg_temp_new();
2925 gen_load_gpr(t0, rs);
2926 gen_load_gpr(t1, rt);
2929 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2932 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2940 static void gen_shift(DisasContext *ctx, uint32_t opc,
2941 int rd, int rs, int rt)
2946 /* If no destination, treat it as a NOP.
2947 For add & sub, we must generate the overflow exception when needed. */
2951 t0 = tcg_temp_new();
2952 t1 = tcg_temp_new();
2953 gen_load_gpr(t0, rs);
2954 gen_load_gpr(t1, rt);
2957 tcg_gen_andi_tl(t0, t0, 0x1f);
2958 tcg_gen_shl_tl(t0, t1, t0);
2959 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2962 tcg_gen_andi_tl(t0, t0, 0x1f);
2963 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2966 tcg_gen_ext32u_tl(t1, t1);
2967 tcg_gen_andi_tl(t0, t0, 0x1f);
2968 tcg_gen_shr_tl(t0, t1, t0);
2969 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2973 TCGv_i32 t2 = tcg_temp_new_i32();
2974 TCGv_i32 t3 = tcg_temp_new_i32();
2976 tcg_gen_trunc_tl_i32(t2, t0);
2977 tcg_gen_trunc_tl_i32(t3, t1);
2978 tcg_gen_andi_i32(t2, t2, 0x1f);
2979 tcg_gen_rotr_i32(t2, t3, t2);
2980 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2981 tcg_temp_free_i32(t2);
2982 tcg_temp_free_i32(t3);
2985 #if defined(TARGET_MIPS64)
2987 tcg_gen_andi_tl(t0, t0, 0x3f);
2988 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2991 tcg_gen_andi_tl(t0, t0, 0x3f);
2992 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2995 tcg_gen_andi_tl(t0, t0, 0x3f);
2996 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2999 tcg_gen_andi_tl(t0, t0, 0x3f);
3000 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3008 /* Arithmetic on HI/LO registers */
3009 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3011 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3022 #if defined(TARGET_MIPS64)
3024 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3028 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3032 #if defined(TARGET_MIPS64)
3034 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3038 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3043 #if defined(TARGET_MIPS64)
3045 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3049 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3052 tcg_gen_movi_tl(cpu_HI[acc], 0);
3057 #if defined(TARGET_MIPS64)
3059 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3063 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3066 tcg_gen_movi_tl(cpu_LO[acc], 0);
3072 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3075 TCGv t0 = tcg_const_tl(addr);
3076 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3077 gen_store_gpr(t0, reg);
3081 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3087 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3090 offset = sextract32(ctx->opcode << 2, 0, 21);
3091 addr = addr_add(ctx, pc, offset);
3092 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3096 offset = sextract32(ctx->opcode << 2, 0, 21);
3097 addr = addr_add(ctx, pc, offset);
3098 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3100 #if defined(TARGET_MIPS64)
3103 offset = sextract32(ctx->opcode << 2, 0, 21);
3104 addr = addr_add(ctx, pc, offset);
3105 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3109 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3112 offset = sextract32(ctx->opcode, 0, 16) << 16;
3113 addr = addr_add(ctx, pc, offset);
3114 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3119 offset = sextract32(ctx->opcode, 0, 16) << 16;
3120 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3121 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3124 #if defined(TARGET_MIPS64)
3125 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3126 case R6_OPC_LDPC + (1 << 16):
3127 case R6_OPC_LDPC + (2 << 16):
3128 case R6_OPC_LDPC + (3 << 16):
3130 offset = sextract32(ctx->opcode << 3, 0, 21);
3131 addr = addr_add(ctx, (pc & ~0x7), offset);
3132 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3136 MIPS_INVAL("OPC_PCREL");
3137 generate_exception_end(ctx, EXCP_RI);
3144 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3153 t0 = tcg_temp_new();
3154 t1 = tcg_temp_new();
3156 gen_load_gpr(t0, rs);
3157 gen_load_gpr(t1, rt);
3162 TCGv t2 = tcg_temp_new();
3163 TCGv t3 = tcg_temp_new();
3164 tcg_gen_ext32s_tl(t0, t0);
3165 tcg_gen_ext32s_tl(t1, t1);
3166 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3167 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3168 tcg_gen_and_tl(t2, t2, t3);
3169 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3170 tcg_gen_or_tl(t2, t2, t3);
3171 tcg_gen_movi_tl(t3, 0);
3172 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3173 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3174 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3181 TCGv t2 = tcg_temp_new();
3182 TCGv t3 = tcg_temp_new();
3183 tcg_gen_ext32s_tl(t0, t0);
3184 tcg_gen_ext32s_tl(t1, t1);
3185 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3186 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3187 tcg_gen_and_tl(t2, t2, t3);
3188 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3189 tcg_gen_or_tl(t2, t2, t3);
3190 tcg_gen_movi_tl(t3, 0);
3191 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3192 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3193 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3200 TCGv t2 = tcg_const_tl(0);
3201 TCGv t3 = tcg_const_tl(1);
3202 tcg_gen_ext32u_tl(t0, t0);
3203 tcg_gen_ext32u_tl(t1, t1);
3204 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3205 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3206 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3213 TCGv t2 = tcg_const_tl(0);
3214 TCGv t3 = tcg_const_tl(1);
3215 tcg_gen_ext32u_tl(t0, t0);
3216 tcg_gen_ext32u_tl(t1, t1);
3217 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3218 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3219 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3226 TCGv_i32 t2 = tcg_temp_new_i32();
3227 TCGv_i32 t3 = tcg_temp_new_i32();
3228 tcg_gen_trunc_tl_i32(t2, t0);
3229 tcg_gen_trunc_tl_i32(t3, t1);
3230 tcg_gen_mul_i32(t2, t2, t3);
3231 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3232 tcg_temp_free_i32(t2);
3233 tcg_temp_free_i32(t3);
3238 TCGv_i32 t2 = tcg_temp_new_i32();
3239 TCGv_i32 t3 = tcg_temp_new_i32();
3240 tcg_gen_trunc_tl_i32(t2, t0);
3241 tcg_gen_trunc_tl_i32(t3, t1);
3242 tcg_gen_muls2_i32(t2, t3, t2, t3);
3243 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3244 tcg_temp_free_i32(t2);
3245 tcg_temp_free_i32(t3);
3250 TCGv_i32 t2 = tcg_temp_new_i32();
3251 TCGv_i32 t3 = tcg_temp_new_i32();
3252 tcg_gen_trunc_tl_i32(t2, t0);
3253 tcg_gen_trunc_tl_i32(t3, t1);
3254 tcg_gen_mul_i32(t2, t2, t3);
3255 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3256 tcg_temp_free_i32(t2);
3257 tcg_temp_free_i32(t3);
3262 TCGv_i32 t2 = tcg_temp_new_i32();
3263 TCGv_i32 t3 = tcg_temp_new_i32();
3264 tcg_gen_trunc_tl_i32(t2, t0);
3265 tcg_gen_trunc_tl_i32(t3, t1);
3266 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3267 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3268 tcg_temp_free_i32(t2);
3269 tcg_temp_free_i32(t3);
3272 #if defined(TARGET_MIPS64)
3275 TCGv t2 = tcg_temp_new();
3276 TCGv t3 = tcg_temp_new();
3277 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3278 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3279 tcg_gen_and_tl(t2, t2, t3);
3280 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3281 tcg_gen_or_tl(t2, t2, t3);
3282 tcg_gen_movi_tl(t3, 0);
3283 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3284 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3291 TCGv t2 = tcg_temp_new();
3292 TCGv t3 = tcg_temp_new();
3293 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3294 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3295 tcg_gen_and_tl(t2, t2, t3);
3296 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3297 tcg_gen_or_tl(t2, t2, t3);
3298 tcg_gen_movi_tl(t3, 0);
3299 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3300 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3307 TCGv t2 = tcg_const_tl(0);
3308 TCGv t3 = tcg_const_tl(1);
3309 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3310 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3317 TCGv t2 = tcg_const_tl(0);
3318 TCGv t3 = tcg_const_tl(1);
3319 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3320 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3326 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3330 TCGv t2 = tcg_temp_new();
3331 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3336 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3340 TCGv t2 = tcg_temp_new();
3341 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3347 MIPS_INVAL("r6 mul/div");
3348 generate_exception_end(ctx, EXCP_RI);
3356 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3357 int acc, int rs, int rt)
3361 t0 = tcg_temp_new();
3362 t1 = tcg_temp_new();
3364 gen_load_gpr(t0, rs);
3365 gen_load_gpr(t1, rt);
3374 TCGv t2 = tcg_temp_new();
3375 TCGv t3 = tcg_temp_new();
3376 tcg_gen_ext32s_tl(t0, t0);
3377 tcg_gen_ext32s_tl(t1, t1);
3378 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3379 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3380 tcg_gen_and_tl(t2, t2, t3);
3381 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3382 tcg_gen_or_tl(t2, t2, t3);
3383 tcg_gen_movi_tl(t3, 0);
3384 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3385 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3386 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3387 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3388 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3395 TCGv t2 = tcg_const_tl(0);
3396 TCGv t3 = tcg_const_tl(1);
3397 tcg_gen_ext32u_tl(t0, t0);
3398 tcg_gen_ext32u_tl(t1, t1);
3399 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3400 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3401 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3402 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3403 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3410 TCGv_i32 t2 = tcg_temp_new_i32();
3411 TCGv_i32 t3 = tcg_temp_new_i32();
3412 tcg_gen_trunc_tl_i32(t2, t0);
3413 tcg_gen_trunc_tl_i32(t3, t1);
3414 tcg_gen_muls2_i32(t2, t3, t2, t3);
3415 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3416 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3417 tcg_temp_free_i32(t2);
3418 tcg_temp_free_i32(t3);
3423 TCGv_i32 t2 = tcg_temp_new_i32();
3424 TCGv_i32 t3 = tcg_temp_new_i32();
3425 tcg_gen_trunc_tl_i32(t2, t0);
3426 tcg_gen_trunc_tl_i32(t3, t1);
3427 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3428 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3429 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3430 tcg_temp_free_i32(t2);
3431 tcg_temp_free_i32(t3);
3434 #if defined(TARGET_MIPS64)
3437 TCGv t2 = tcg_temp_new();
3438 TCGv t3 = tcg_temp_new();
3439 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3440 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3441 tcg_gen_and_tl(t2, t2, t3);
3442 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3443 tcg_gen_or_tl(t2, t2, t3);
3444 tcg_gen_movi_tl(t3, 0);
3445 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3446 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3447 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3454 TCGv t2 = tcg_const_tl(0);
3455 TCGv t3 = tcg_const_tl(1);
3456 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3457 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3458 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3464 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3467 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3472 TCGv_i64 t2 = tcg_temp_new_i64();
3473 TCGv_i64 t3 = tcg_temp_new_i64();
3475 tcg_gen_ext_tl_i64(t2, t0);
3476 tcg_gen_ext_tl_i64(t3, t1);
3477 tcg_gen_mul_i64(t2, t2, t3);
3478 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3479 tcg_gen_add_i64(t2, t2, t3);
3480 tcg_temp_free_i64(t3);
3481 gen_move_low32(cpu_LO[acc], t2);
3482 gen_move_high32(cpu_HI[acc], t2);
3483 tcg_temp_free_i64(t2);
3488 TCGv_i64 t2 = tcg_temp_new_i64();
3489 TCGv_i64 t3 = tcg_temp_new_i64();
3491 tcg_gen_ext32u_tl(t0, t0);
3492 tcg_gen_ext32u_tl(t1, t1);
3493 tcg_gen_extu_tl_i64(t2, t0);
3494 tcg_gen_extu_tl_i64(t3, t1);
3495 tcg_gen_mul_i64(t2, t2, t3);
3496 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3497 tcg_gen_add_i64(t2, t2, t3);
3498 tcg_temp_free_i64(t3);
3499 gen_move_low32(cpu_LO[acc], t2);
3500 gen_move_high32(cpu_HI[acc], t2);
3501 tcg_temp_free_i64(t2);
3506 TCGv_i64 t2 = tcg_temp_new_i64();
3507 TCGv_i64 t3 = tcg_temp_new_i64();
3509 tcg_gen_ext_tl_i64(t2, t0);
3510 tcg_gen_ext_tl_i64(t3, t1);
3511 tcg_gen_mul_i64(t2, t2, t3);
3512 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3513 tcg_gen_sub_i64(t2, t3, t2);
3514 tcg_temp_free_i64(t3);
3515 gen_move_low32(cpu_LO[acc], t2);
3516 gen_move_high32(cpu_HI[acc], t2);
3517 tcg_temp_free_i64(t2);
3522 TCGv_i64 t2 = tcg_temp_new_i64();
3523 TCGv_i64 t3 = tcg_temp_new_i64();
3525 tcg_gen_ext32u_tl(t0, t0);
3526 tcg_gen_ext32u_tl(t1, t1);
3527 tcg_gen_extu_tl_i64(t2, t0);
3528 tcg_gen_extu_tl_i64(t3, t1);
3529 tcg_gen_mul_i64(t2, t2, t3);
3530 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3531 tcg_gen_sub_i64(t2, t3, t2);
3532 tcg_temp_free_i64(t3);
3533 gen_move_low32(cpu_LO[acc], t2);
3534 gen_move_high32(cpu_HI[acc], t2);
3535 tcg_temp_free_i64(t2);
3539 MIPS_INVAL("mul/div");
3540 generate_exception_end(ctx, EXCP_RI);
3548 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3549 int rd, int rs, int rt)
3551 TCGv t0 = tcg_temp_new();
3552 TCGv t1 = tcg_temp_new();
3554 gen_load_gpr(t0, rs);
3555 gen_load_gpr(t1, rt);
3558 case OPC_VR54XX_MULS:
3559 gen_helper_muls(t0, cpu_env, t0, t1);
3561 case OPC_VR54XX_MULSU:
3562 gen_helper_mulsu(t0, cpu_env, t0, t1);
3564 case OPC_VR54XX_MACC:
3565 gen_helper_macc(t0, cpu_env, t0, t1);
3567 case OPC_VR54XX_MACCU:
3568 gen_helper_maccu(t0, cpu_env, t0, t1);
3570 case OPC_VR54XX_MSAC:
3571 gen_helper_msac(t0, cpu_env, t0, t1);
3573 case OPC_VR54XX_MSACU:
3574 gen_helper_msacu(t0, cpu_env, t0, t1);
3576 case OPC_VR54XX_MULHI:
3577 gen_helper_mulhi(t0, cpu_env, t0, t1);
3579 case OPC_VR54XX_MULHIU:
3580 gen_helper_mulhiu(t0, cpu_env, t0, t1);
3582 case OPC_VR54XX_MULSHI:
3583 gen_helper_mulshi(t0, cpu_env, t0, t1);
3585 case OPC_VR54XX_MULSHIU:
3586 gen_helper_mulshiu(t0, cpu_env, t0, t1);
3588 case OPC_VR54XX_MACCHI:
3589 gen_helper_macchi(t0, cpu_env, t0, t1);
3591 case OPC_VR54XX_MACCHIU:
3592 gen_helper_macchiu(t0, cpu_env, t0, t1);
3594 case OPC_VR54XX_MSACHI:
3595 gen_helper_msachi(t0, cpu_env, t0, t1);
3597 case OPC_VR54XX_MSACHIU:
3598 gen_helper_msachiu(t0, cpu_env, t0, t1);
3601 MIPS_INVAL("mul vr54xx");
3602 generate_exception_end(ctx, EXCP_RI);
3605 gen_store_gpr(t0, rd);
3612 static void gen_cl (DisasContext *ctx, uint32_t opc,
3621 t0 = tcg_temp_new();
3622 gen_load_gpr(t0, rs);
3626 gen_helper_clo(cpu_gpr[rd], t0);
3630 gen_helper_clz(cpu_gpr[rd], t0);
3632 #if defined(TARGET_MIPS64)
3635 gen_helper_dclo(cpu_gpr[rd], t0);
3639 gen_helper_dclz(cpu_gpr[rd], t0);
3646 /* Godson integer instructions */
3647 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3648 int rd, int rs, int rt)
3660 case OPC_MULTU_G_2E:
3661 case OPC_MULTU_G_2F:
3662 #if defined(TARGET_MIPS64)
3663 case OPC_DMULT_G_2E:
3664 case OPC_DMULT_G_2F:
3665 case OPC_DMULTU_G_2E:
3666 case OPC_DMULTU_G_2F:
3668 t0 = tcg_temp_new();
3669 t1 = tcg_temp_new();
3672 t0 = tcg_temp_local_new();
3673 t1 = tcg_temp_local_new();
3677 gen_load_gpr(t0, rs);
3678 gen_load_gpr(t1, rt);
3683 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3684 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3686 case OPC_MULTU_G_2E:
3687 case OPC_MULTU_G_2F:
3688 tcg_gen_ext32u_tl(t0, t0);
3689 tcg_gen_ext32u_tl(t1, t1);
3690 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3691 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3696 TCGLabel *l1 = gen_new_label();
3697 TCGLabel *l2 = gen_new_label();
3698 TCGLabel *l3 = gen_new_label();
3699 tcg_gen_ext32s_tl(t0, t0);
3700 tcg_gen_ext32s_tl(t1, t1);
3701 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3702 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3705 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3706 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3707 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3710 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3711 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3718 TCGLabel *l1 = gen_new_label();
3719 TCGLabel *l2 = gen_new_label();
3720 tcg_gen_ext32u_tl(t0, t0);
3721 tcg_gen_ext32u_tl(t1, t1);
3722 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3723 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3726 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3727 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3734 TCGLabel *l1 = gen_new_label();
3735 TCGLabel *l2 = gen_new_label();
3736 TCGLabel *l3 = gen_new_label();
3737 tcg_gen_ext32u_tl(t0, t0);
3738 tcg_gen_ext32u_tl(t1, t1);
3739 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3740 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3741 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3743 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3746 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3747 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3754 TCGLabel *l1 = gen_new_label();
3755 TCGLabel *l2 = gen_new_label();
3756 tcg_gen_ext32u_tl(t0, t0);
3757 tcg_gen_ext32u_tl(t1, t1);
3758 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3759 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3762 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3763 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3767 #if defined(TARGET_MIPS64)
3768 case OPC_DMULT_G_2E:
3769 case OPC_DMULT_G_2F:
3770 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3772 case OPC_DMULTU_G_2E:
3773 case OPC_DMULTU_G_2F:
3774 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3779 TCGLabel *l1 = gen_new_label();
3780 TCGLabel *l2 = gen_new_label();
3781 TCGLabel *l3 = gen_new_label();
3782 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3783 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3786 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3787 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3788 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3791 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3795 case OPC_DDIVU_G_2E:
3796 case OPC_DDIVU_G_2F:
3798 TCGLabel *l1 = gen_new_label();
3799 TCGLabel *l2 = gen_new_label();
3800 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3801 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3804 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3811 TCGLabel *l1 = gen_new_label();
3812 TCGLabel *l2 = gen_new_label();
3813 TCGLabel *l3 = gen_new_label();
3814 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3815 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3816 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3821 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3825 case OPC_DMODU_G_2E:
3826 case OPC_DMODU_G_2F:
3828 TCGLabel *l1 = gen_new_label();
3829 TCGLabel *l2 = gen_new_label();
3830 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3831 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3834 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3845 /* Loongson multimedia instructions */
3846 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3848 uint32_t opc, shift_max;
3851 opc = MASK_LMI(ctx->opcode);
3857 t0 = tcg_temp_local_new_i64();
3858 t1 = tcg_temp_local_new_i64();
3861 t0 = tcg_temp_new_i64();
3862 t1 = tcg_temp_new_i64();
3866 gen_load_fpr64(ctx, t0, rs);
3867 gen_load_fpr64(ctx, t1, rt);
3869 #define LMI_HELPER(UP, LO) \
3870 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3871 #define LMI_HELPER_1(UP, LO) \
3872 case OPC_##UP: gen_helper_##LO(t0, t0); break
3873 #define LMI_DIRECT(UP, LO, OP) \
3874 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3877 LMI_HELPER(PADDSH, paddsh);
3878 LMI_HELPER(PADDUSH, paddush);
3879 LMI_HELPER(PADDH, paddh);
3880 LMI_HELPER(PADDW, paddw);
3881 LMI_HELPER(PADDSB, paddsb);
3882 LMI_HELPER(PADDUSB, paddusb);
3883 LMI_HELPER(PADDB, paddb);
3885 LMI_HELPER(PSUBSH, psubsh);
3886 LMI_HELPER(PSUBUSH, psubush);
3887 LMI_HELPER(PSUBH, psubh);
3888 LMI_HELPER(PSUBW, psubw);
3889 LMI_HELPER(PSUBSB, psubsb);
3890 LMI_HELPER(PSUBUSB, psubusb);
3891 LMI_HELPER(PSUBB, psubb);
3893 LMI_HELPER(PSHUFH, pshufh);
3894 LMI_HELPER(PACKSSWH, packsswh);
3895 LMI_HELPER(PACKSSHB, packsshb);
3896 LMI_HELPER(PACKUSHB, packushb);
3898 LMI_HELPER(PUNPCKLHW, punpcklhw);
3899 LMI_HELPER(PUNPCKHHW, punpckhhw);
3900 LMI_HELPER(PUNPCKLBH, punpcklbh);
3901 LMI_HELPER(PUNPCKHBH, punpckhbh);
3902 LMI_HELPER(PUNPCKLWD, punpcklwd);
3903 LMI_HELPER(PUNPCKHWD, punpckhwd);
3905 LMI_HELPER(PAVGH, pavgh);
3906 LMI_HELPER(PAVGB, pavgb);
3907 LMI_HELPER(PMAXSH, pmaxsh);
3908 LMI_HELPER(PMINSH, pminsh);
3909 LMI_HELPER(PMAXUB, pmaxub);
3910 LMI_HELPER(PMINUB, pminub);
3912 LMI_HELPER(PCMPEQW, pcmpeqw);
3913 LMI_HELPER(PCMPGTW, pcmpgtw);
3914 LMI_HELPER(PCMPEQH, pcmpeqh);
3915 LMI_HELPER(PCMPGTH, pcmpgth);
3916 LMI_HELPER(PCMPEQB, pcmpeqb);
3917 LMI_HELPER(PCMPGTB, pcmpgtb);
3919 LMI_HELPER(PSLLW, psllw);
3920 LMI_HELPER(PSLLH, psllh);
3921 LMI_HELPER(PSRLW, psrlw);
3922 LMI_HELPER(PSRLH, psrlh);
3923 LMI_HELPER(PSRAW, psraw);
3924 LMI_HELPER(PSRAH, psrah);
3926 LMI_HELPER(PMULLH, pmullh);
3927 LMI_HELPER(PMULHH, pmulhh);
3928 LMI_HELPER(PMULHUH, pmulhuh);
3929 LMI_HELPER(PMADDHW, pmaddhw);
3931 LMI_HELPER(PASUBUB, pasubub);
3932 LMI_HELPER_1(BIADD, biadd);
3933 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3935 LMI_DIRECT(PADDD, paddd, add);
3936 LMI_DIRECT(PSUBD, psubd, sub);
3937 LMI_DIRECT(XOR_CP2, xor, xor);
3938 LMI_DIRECT(NOR_CP2, nor, nor);
3939 LMI_DIRECT(AND_CP2, and, and);
3940 LMI_DIRECT(PANDN, pandn, andc);
3941 LMI_DIRECT(OR, or, or);
3944 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3947 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3950 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3953 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3957 tcg_gen_andi_i64(t1, t1, 3);
3958 tcg_gen_shli_i64(t1, t1, 4);
3959 tcg_gen_shr_i64(t0, t0, t1);
3960 tcg_gen_ext16u_i64(t0, t0);
3964 tcg_gen_add_i64(t0, t0, t1);
3965 tcg_gen_ext32s_i64(t0, t0);
3968 tcg_gen_sub_i64(t0, t0, t1);
3969 tcg_gen_ext32s_i64(t0, t0);
3991 /* Make sure shift count isn't TCG undefined behaviour. */
3992 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3997 tcg_gen_shl_i64(t0, t0, t1);
4001 /* Since SRA is UndefinedResult without sign-extended inputs,
4002 we can treat SRA and DSRA the same. */
4003 tcg_gen_sar_i64(t0, t0, t1);
4006 /* We want to shift in zeros for SRL; zero-extend first. */
4007 tcg_gen_ext32u_i64(t0, t0);
4010 tcg_gen_shr_i64(t0, t0, t1);
4014 if (shift_max == 32) {
4015 tcg_gen_ext32s_i64(t0, t0);
4018 /* Shifts larger than MAX produce zero. */
4019 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4020 tcg_gen_neg_i64(t1, t1);
4021 tcg_gen_and_i64(t0, t0, t1);
4027 TCGv_i64 t2 = tcg_temp_new_i64();
4028 TCGLabel *lab = gen_new_label();
4030 tcg_gen_mov_i64(t2, t0);
4031 tcg_gen_add_i64(t0, t1, t2);
4032 if (opc == OPC_ADD_CP2) {
4033 tcg_gen_ext32s_i64(t0, t0);
4035 tcg_gen_xor_i64(t1, t1, t2);
4036 tcg_gen_xor_i64(t2, t2, t0);
4037 tcg_gen_andc_i64(t1, t2, t1);
4038 tcg_temp_free_i64(t2);
4039 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4040 generate_exception(ctx, EXCP_OVERFLOW);
4048 TCGv_i64 t2 = tcg_temp_new_i64();
4049 TCGLabel *lab = gen_new_label();
4051 tcg_gen_mov_i64(t2, t0);
4052 tcg_gen_sub_i64(t0, t1, t2);
4053 if (opc == OPC_SUB_CP2) {
4054 tcg_gen_ext32s_i64(t0, t0);
4056 tcg_gen_xor_i64(t1, t1, t2);
4057 tcg_gen_xor_i64(t2, t2, t0);
4058 tcg_gen_and_i64(t1, t1, t2);
4059 tcg_temp_free_i64(t2);
4060 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4061 generate_exception(ctx, EXCP_OVERFLOW);
4067 tcg_gen_ext32u_i64(t0, t0);
4068 tcg_gen_ext32u_i64(t1, t1);
4069 tcg_gen_mul_i64(t0, t0, t1);
4078 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4079 FD field is the CC field? */
4081 MIPS_INVAL("loongson_cp2");
4082 generate_exception_end(ctx, EXCP_RI);
4089 gen_store_fpr64(ctx, t0, rd);
4091 tcg_temp_free_i64(t0);
4092 tcg_temp_free_i64(t1);
4096 static void gen_trap (DisasContext *ctx, uint32_t opc,
4097 int rs, int rt, int16_t imm)
4100 TCGv t0 = tcg_temp_new();
4101 TCGv t1 = tcg_temp_new();
4104 /* Load needed operands */
4112 /* Compare two registers */
4114 gen_load_gpr(t0, rs);
4115 gen_load_gpr(t1, rt);
4125 /* Compare register to immediate */
4126 if (rs != 0 || imm != 0) {
4127 gen_load_gpr(t0, rs);
4128 tcg_gen_movi_tl(t1, (int32_t)imm);
4135 case OPC_TEQ: /* rs == rs */
4136 case OPC_TEQI: /* r0 == 0 */
4137 case OPC_TGE: /* rs >= rs */
4138 case OPC_TGEI: /* r0 >= 0 */
4139 case OPC_TGEU: /* rs >= rs unsigned */
4140 case OPC_TGEIU: /* r0 >= 0 unsigned */
4142 generate_exception_end(ctx, EXCP_TRAP);
4144 case OPC_TLT: /* rs < rs */
4145 case OPC_TLTI: /* r0 < 0 */
4146 case OPC_TLTU: /* rs < rs unsigned */
4147 case OPC_TLTIU: /* r0 < 0 unsigned */
4148 case OPC_TNE: /* rs != rs */
4149 case OPC_TNEI: /* r0 != 0 */
4150 /* Never trap: treat as NOP. */
4154 TCGLabel *l1 = gen_new_label();
4159 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4163 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4167 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4171 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4175 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4179 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4182 generate_exception(ctx, EXCP_TRAP);
4189 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4191 TranslationBlock *tb;
4193 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4194 likely(!ctx->singlestep_enabled)) {
4197 tcg_gen_exit_tb((uintptr_t)tb + n);
4200 if (ctx->singlestep_enabled) {
4201 save_cpu_state(ctx, 0);
4202 gen_helper_raise_exception_debug(cpu_env);
4208 /* Branches (before delay slot) */
4209 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4211 int rs, int rt, int32_t offset,
4214 target_ulong btgt = -1;
4216 int bcond_compute = 0;
4217 TCGv t0 = tcg_temp_new();
4218 TCGv t1 = tcg_temp_new();
4220 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4221 #ifdef MIPS_DEBUG_DISAS
4222 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4223 TARGET_FMT_lx "\n", ctx->pc);
4225 generate_exception_end(ctx, EXCP_RI);
4229 /* Load needed operands */
4235 /* Compare two registers */
4237 gen_load_gpr(t0, rs);
4238 gen_load_gpr(t1, rt);
4241 btgt = ctx->pc + insn_bytes + offset;
4255 /* Compare to zero */
4257 gen_load_gpr(t0, rs);
4260 btgt = ctx->pc + insn_bytes + offset;
4263 #if defined(TARGET_MIPS64)
4265 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4267 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4270 btgt = ctx->pc + insn_bytes + offset;
4275 /* Jump to immediate */
4276 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4280 /* Jump to register */
4281 if (offset != 0 && offset != 16) {
4282 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4283 others are reserved. */
4284 MIPS_INVAL("jump hint");
4285 generate_exception_end(ctx, EXCP_RI);
4288 gen_load_gpr(btarget, rs);
4291 MIPS_INVAL("branch/jump");
4292 generate_exception_end(ctx, EXCP_RI);
4295 if (bcond_compute == 0) {
4296 /* No condition to be computed */
4298 case OPC_BEQ: /* rx == rx */
4299 case OPC_BEQL: /* rx == rx likely */
4300 case OPC_BGEZ: /* 0 >= 0 */
4301 case OPC_BGEZL: /* 0 >= 0 likely */
4302 case OPC_BLEZ: /* 0 <= 0 */
4303 case OPC_BLEZL: /* 0 <= 0 likely */
4305 ctx->hflags |= MIPS_HFLAG_B;
4307 case OPC_BGEZAL: /* 0 >= 0 */
4308 case OPC_BGEZALL: /* 0 >= 0 likely */
4309 /* Always take and link */
4311 ctx->hflags |= MIPS_HFLAG_B;
4313 case OPC_BNE: /* rx != rx */
4314 case OPC_BGTZ: /* 0 > 0 */
4315 case OPC_BLTZ: /* 0 < 0 */
4318 case OPC_BLTZAL: /* 0 < 0 */
4319 /* Handle as an unconditional branch to get correct delay
4322 btgt = ctx->pc + insn_bytes + delayslot_size;
4323 ctx->hflags |= MIPS_HFLAG_B;
4325 case OPC_BLTZALL: /* 0 < 0 likely */
4326 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4327 /* Skip the instruction in the delay slot */
4330 case OPC_BNEL: /* rx != rx likely */
4331 case OPC_BGTZL: /* 0 > 0 likely */
4332 case OPC_BLTZL: /* 0 < 0 likely */
4333 /* Skip the instruction in the delay slot */
4337 ctx->hflags |= MIPS_HFLAG_B;
4340 ctx->hflags |= MIPS_HFLAG_BX;
4344 ctx->hflags |= MIPS_HFLAG_B;
4347 ctx->hflags |= MIPS_HFLAG_BR;
4351 ctx->hflags |= MIPS_HFLAG_BR;
4354 MIPS_INVAL("branch/jump");
4355 generate_exception_end(ctx, EXCP_RI);
4361 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4364 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4367 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4370 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4373 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4376 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4379 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4383 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4387 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4390 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4393 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4396 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4399 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4402 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4405 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4407 #if defined(TARGET_MIPS64)
4409 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4413 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4416 ctx->hflags |= MIPS_HFLAG_BC;
4419 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4422 ctx->hflags |= MIPS_HFLAG_BL;
4425 MIPS_INVAL("conditional branch/jump");
4426 generate_exception_end(ctx, EXCP_RI);
4431 ctx->btarget = btgt;
4433 switch (delayslot_size) {
4435 ctx->hflags |= MIPS_HFLAG_BDS16;
4438 ctx->hflags |= MIPS_HFLAG_BDS32;
4443 int post_delay = insn_bytes + delayslot_size;
4444 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4446 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4450 if (insn_bytes == 2)
4451 ctx->hflags |= MIPS_HFLAG_B16;
4456 /* special3 bitfield operations */
4457 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4458 int rs, int lsb, int msb)
4460 TCGv t0 = tcg_temp_new();
4461 TCGv t1 = tcg_temp_new();
4463 gen_load_gpr(t1, rs);
4466 if (lsb + msb > 31) {
4469 tcg_gen_shri_tl(t0, t1, lsb);
4471 tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
4473 tcg_gen_ext32s_tl(t0, t0);
4476 #if defined(TARGET_MIPS64)
4485 if (lsb + msb > 63) {
4488 tcg_gen_shri_tl(t0, t1, lsb);
4490 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4498 gen_load_gpr(t0, rt);
4499 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4500 tcg_gen_ext32s_tl(t0, t0);
4502 #if defined(TARGET_MIPS64)
4513 gen_load_gpr(t0, rt);
4514 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4519 MIPS_INVAL("bitops");
4520 generate_exception_end(ctx, EXCP_RI);
4525 gen_store_gpr(t0, rt);
4530 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4535 /* If no destination, treat it as a NOP. */
4539 t0 = tcg_temp_new();
4540 gen_load_gpr(t0, rt);
4544 TCGv t1 = tcg_temp_new();
4546 tcg_gen_shri_tl(t1, t0, 8);
4547 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4548 tcg_gen_shli_tl(t0, t0, 8);
4549 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4550 tcg_gen_or_tl(t0, t0, t1);
4552 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4556 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4559 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4561 #if defined(TARGET_MIPS64)
4564 TCGv t1 = tcg_temp_new();
4566 tcg_gen_shri_tl(t1, t0, 8);
4567 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4568 tcg_gen_shli_tl(t0, t0, 8);
4569 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4570 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4576 TCGv t1 = tcg_temp_new();
4578 tcg_gen_shri_tl(t1, t0, 16);
4579 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4580 tcg_gen_shli_tl(t0, t0, 16);
4581 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4582 tcg_gen_or_tl(t0, t0, t1);
4583 tcg_gen_shri_tl(t1, t0, 32);
4584 tcg_gen_shli_tl(t0, t0, 32);
4585 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4591 MIPS_INVAL("bsfhl");
4592 generate_exception_end(ctx, EXCP_RI);
4599 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4608 t0 = tcg_temp_new();
4609 t1 = tcg_temp_new();
4610 gen_load_gpr(t0, rs);
4611 gen_load_gpr(t1, rt);
4612 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4613 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4614 if (opc == OPC_LSA) {
4615 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4624 static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4632 t0 = tcg_temp_new();
4633 gen_load_gpr(t0, rt);
4635 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4637 TCGv t1 = tcg_temp_new();
4638 gen_load_gpr(t1, rs);
4642 TCGv_i64 t2 = tcg_temp_new_i64();
4643 tcg_gen_concat_tl_i64(t2, t1, t0);
4644 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4645 gen_move_low32(cpu_gpr[rd], t2);
4646 tcg_temp_free_i64(t2);
4649 #if defined(TARGET_MIPS64)
4651 tcg_gen_shli_tl(t0, t0, 8 * bp);
4652 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4653 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4663 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4670 t0 = tcg_temp_new();
4671 gen_load_gpr(t0, rt);
4674 gen_helper_bitswap(cpu_gpr[rd], t0);
4676 #if defined(TARGET_MIPS64)
4678 gen_helper_dbitswap(cpu_gpr[rd], t0);
4685 #ifndef CONFIG_USER_ONLY
4686 /* CP0 (MMU and control) */
4687 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4689 TCGv_i64 t0 = tcg_temp_new_i64();
4690 TCGv_i64 t1 = tcg_temp_new_i64();
4692 tcg_gen_ext_tl_i64(t0, arg);
4693 tcg_gen_ld_i64(t1, cpu_env, off);
4694 #if defined(TARGET_MIPS64)
4695 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4697 tcg_gen_concat32_i64(t1, t1, t0);
4699 tcg_gen_st_i64(t1, cpu_env, off);
4700 tcg_temp_free_i64(t1);
4701 tcg_temp_free_i64(t0);
4704 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4706 TCGv_i64 t0 = tcg_temp_new_i64();
4707 TCGv_i64 t1 = tcg_temp_new_i64();
4709 tcg_gen_ext_tl_i64(t0, arg);
4710 tcg_gen_ld_i64(t1, cpu_env, off);
4711 tcg_gen_concat32_i64(t1, t1, t0);
4712 tcg_gen_st_i64(t1, cpu_env, off);
4713 tcg_temp_free_i64(t1);
4714 tcg_temp_free_i64(t0);
4717 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4719 TCGv_i64 t0 = tcg_temp_new_i64();
4721 tcg_gen_ld_i64(t0, cpu_env, off);
4722 #if defined(TARGET_MIPS64)
4723 tcg_gen_shri_i64(t0, t0, 30);
4725 tcg_gen_shri_i64(t0, t0, 32);
4727 gen_move_low32(arg, t0);
4728 tcg_temp_free_i64(t0);
4731 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4733 TCGv_i64 t0 = tcg_temp_new_i64();
4735 tcg_gen_ld_i64(t0, cpu_env, off);
4736 tcg_gen_shri_i64(t0, t0, 32 + shift);
4737 gen_move_low32(arg, t0);
4738 tcg_temp_free_i64(t0);
4741 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4743 TCGv_i32 t0 = tcg_temp_new_i32();
4745 tcg_gen_ld_i32(t0, cpu_env, off);
4746 tcg_gen_ext_i32_tl(arg, t0);
4747 tcg_temp_free_i32(t0);
4750 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4752 tcg_gen_ld_tl(arg, cpu_env, off);
4753 tcg_gen_ext32s_tl(arg, arg);
4756 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4758 TCGv_i32 t0 = tcg_temp_new_i32();
4760 tcg_gen_trunc_tl_i32(t0, arg);
4761 tcg_gen_st_i32(t0, cpu_env, off);
4762 tcg_temp_free_i32(t0);
4765 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4767 const char *rn = "invalid";
4769 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4770 goto mfhc0_read_zero;
4777 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4781 goto mfhc0_read_zero;
4787 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4791 goto mfhc0_read_zero;
4797 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4798 ctx->CP0_LLAddr_shift);
4802 goto mfhc0_read_zero;
4811 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4815 goto mfhc0_read_zero;
4819 goto mfhc0_read_zero;
4822 (void)rn; /* avoid a compiler warning */
4823 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4827 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4828 tcg_gen_movi_tl(arg, 0);
4831 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4833 const char *rn = "invalid";
4834 uint64_t mask = ctx->PAMask >> 36;
4836 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4844 tcg_gen_andi_tl(arg, arg, mask);
4845 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4855 tcg_gen_andi_tl(arg, arg, mask);
4856 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4866 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4867 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4868 relevant for modern MIPS cores supporting MTHC0, therefore
4869 treating MTHC0 to LLAddr as NOP. */
4882 tcg_gen_andi_tl(arg, arg, mask);
4883 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4894 (void)rn; /* avoid a compiler warning */
4896 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4899 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4901 if (ctx->insn_flags & ISA_MIPS32R6) {
4902 tcg_gen_movi_tl(arg, 0);
4904 tcg_gen_movi_tl(arg, ~0);
4908 #define CP0_CHECK(c) \
4911 goto cp0_unimplemented; \
4915 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4917 const char *rn = "invalid";
4920 check_insn(ctx, ISA_MIPS32);
4926 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4930 CP0_CHECK(ctx->insn_flags & ASE_MT);
4931 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4935 CP0_CHECK(ctx->insn_flags & ASE_MT);
4936 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4940 CP0_CHECK(ctx->insn_flags & ASE_MT);
4941 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4945 goto cp0_unimplemented;
4951 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4952 gen_helper_mfc0_random(arg, cpu_env);
4956 CP0_CHECK(ctx->insn_flags & ASE_MT);
4957 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4961 CP0_CHECK(ctx->insn_flags & ASE_MT);
4962 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4966 CP0_CHECK(ctx->insn_flags & ASE_MT);
4967 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4971 CP0_CHECK(ctx->insn_flags & ASE_MT);
4972 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4976 CP0_CHECK(ctx->insn_flags & ASE_MT);
4977 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4981 CP0_CHECK(ctx->insn_flags & ASE_MT);
4982 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4983 rn = "VPEScheFBack";
4986 CP0_CHECK(ctx->insn_flags & ASE_MT);
4987 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4991 goto cp0_unimplemented;
4998 TCGv_i64 tmp = tcg_temp_new_i64();
4999 tcg_gen_ld_i64(tmp, cpu_env,
5000 offsetof(CPUMIPSState, CP0_EntryLo0));
5001 #if defined(TARGET_MIPS64)
5003 /* Move RI/XI fields to bits 31:30 */
5004 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5005 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5008 gen_move_low32(arg, tmp);
5009 tcg_temp_free_i64(tmp);
5014 CP0_CHECK(ctx->insn_flags & ASE_MT);
5015 gen_helper_mfc0_tcstatus(arg, cpu_env);
5019 CP0_CHECK(ctx->insn_flags & ASE_MT);
5020 gen_helper_mfc0_tcbind(arg, cpu_env);
5024 CP0_CHECK(ctx->insn_flags & ASE_MT);
5025 gen_helper_mfc0_tcrestart(arg, cpu_env);
5029 CP0_CHECK(ctx->insn_flags & ASE_MT);
5030 gen_helper_mfc0_tchalt(arg, cpu_env);
5034 CP0_CHECK(ctx->insn_flags & ASE_MT);
5035 gen_helper_mfc0_tccontext(arg, cpu_env);
5039 CP0_CHECK(ctx->insn_flags & ASE_MT);
5040 gen_helper_mfc0_tcschedule(arg, cpu_env);
5044 CP0_CHECK(ctx->insn_flags & ASE_MT);
5045 gen_helper_mfc0_tcschefback(arg, cpu_env);
5049 goto cp0_unimplemented;
5056 TCGv_i64 tmp = tcg_temp_new_i64();
5057 tcg_gen_ld_i64(tmp, cpu_env,
5058 offsetof(CPUMIPSState, CP0_EntryLo1));
5059 #if defined(TARGET_MIPS64)
5061 /* Move RI/XI fields to bits 31:30 */
5062 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5063 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5066 gen_move_low32(arg, tmp);
5067 tcg_temp_free_i64(tmp);
5072 goto cp0_unimplemented;
5078 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5079 tcg_gen_ext32s_tl(arg, arg);
5083 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5084 rn = "ContextConfig";
5085 goto cp0_unimplemented;
5088 CP0_CHECK(ctx->ulri);
5089 tcg_gen_ld32s_tl(arg, cpu_env,
5090 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5094 goto cp0_unimplemented;
5100 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5104 check_insn(ctx, ISA_MIPS32R2);
5105 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5109 goto cp0_unimplemented;
5115 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5119 check_insn(ctx, ISA_MIPS32R2);
5120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5124 check_insn(ctx, ISA_MIPS32R2);
5125 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5129 check_insn(ctx, ISA_MIPS32R2);
5130 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5134 check_insn(ctx, ISA_MIPS32R2);
5135 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5139 check_insn(ctx, ISA_MIPS32R2);
5140 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5144 goto cp0_unimplemented;
5150 check_insn(ctx, ISA_MIPS32R2);
5151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5155 goto cp0_unimplemented;
5161 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5162 tcg_gen_ext32s_tl(arg, arg);
5167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5176 goto cp0_unimplemented;
5182 /* Mark as an IO operation because we read the time. */
5183 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5186 gen_helper_mfc0_count(arg, cpu_env);
5187 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5190 /* Break the TB to be able to take timer interrupts immediately
5191 after reading count. */
5192 ctx->bstate = BS_STOP;
5195 /* 6,7 are implementation dependent */
5197 goto cp0_unimplemented;
5203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5204 tcg_gen_ext32s_tl(arg, arg);
5208 goto cp0_unimplemented;
5214 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5217 /* 6,7 are implementation dependent */
5219 goto cp0_unimplemented;
5225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5229 check_insn(ctx, ISA_MIPS32R2);
5230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5234 check_insn(ctx, ISA_MIPS32R2);
5235 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5239 check_insn(ctx, ISA_MIPS32R2);
5240 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5244 goto cp0_unimplemented;
5250 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5254 goto cp0_unimplemented;
5260 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5261 tcg_gen_ext32s_tl(arg, arg);
5265 goto cp0_unimplemented;
5271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5275 check_insn(ctx, ISA_MIPS32R2);
5276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5280 goto cp0_unimplemented;
5286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5302 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5309 /* 6,7 are implementation dependent */
5311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5319 goto cp0_unimplemented;
5325 gen_helper_mfc0_lladdr(arg, cpu_env);
5329 goto cp0_unimplemented;
5335 gen_helper_1e0i(mfc0_watchlo, arg, sel);
5339 goto cp0_unimplemented;
5345 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5349 goto cp0_unimplemented;
5355 #if defined(TARGET_MIPS64)
5356 check_insn(ctx, ISA_MIPS3);
5357 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5358 tcg_gen_ext32s_tl(arg, arg);
5363 goto cp0_unimplemented;
5367 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5368 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5371 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5375 goto cp0_unimplemented;
5379 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5380 rn = "'Diagnostic"; /* implementation dependent */
5385 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5389 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5390 rn = "TraceControl";
5393 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5394 rn = "TraceControl2";
5397 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5398 rn = "UserTraceData";
5401 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5405 goto cp0_unimplemented;
5412 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5413 tcg_gen_ext32s_tl(arg, arg);
5417 goto cp0_unimplemented;
5423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5424 rn = "Performance0";
5427 // gen_helper_mfc0_performance1(arg);
5428 rn = "Performance1";
5431 // gen_helper_mfc0_performance2(arg);
5432 rn = "Performance2";
5435 // gen_helper_mfc0_performance3(arg);
5436 rn = "Performance3";
5439 // gen_helper_mfc0_performance4(arg);
5440 rn = "Performance4";
5443 // gen_helper_mfc0_performance5(arg);
5444 rn = "Performance5";
5447 // gen_helper_mfc0_performance6(arg);
5448 rn = "Performance6";
5451 // gen_helper_mfc0_performance7(arg);
5452 rn = "Performance7";
5455 goto cp0_unimplemented;
5459 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5465 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5469 goto cp0_unimplemented;
5479 TCGv_i64 tmp = tcg_temp_new_i64();
5480 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5481 gen_move_low32(arg, tmp);
5482 tcg_temp_free_i64(tmp);
5490 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5494 goto cp0_unimplemented;
5503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5514 goto cp0_unimplemented;
5520 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5521 tcg_gen_ext32s_tl(arg, arg);
5525 goto cp0_unimplemented;
5532 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5536 CP0_CHECK(ctx->kscrexist & (1 << sel));
5537 tcg_gen_ld_tl(arg, cpu_env,
5538 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5539 tcg_gen_ext32s_tl(arg, arg);
5543 goto cp0_unimplemented;
5547 goto cp0_unimplemented;
5549 (void)rn; /* avoid a compiler warning */
5550 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5554 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5555 gen_mfc0_unimplemented(ctx, arg);
5558 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5560 const char *rn = "invalid";
5563 check_insn(ctx, ISA_MIPS32);
5565 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5573 gen_helper_mtc0_index(cpu_env, arg);
5577 CP0_CHECK(ctx->insn_flags & ASE_MT);
5578 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5582 CP0_CHECK(ctx->insn_flags & ASE_MT);
5587 CP0_CHECK(ctx->insn_flags & ASE_MT);
5592 goto cp0_unimplemented;
5602 CP0_CHECK(ctx->insn_flags & ASE_MT);
5603 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5607 CP0_CHECK(ctx->insn_flags & ASE_MT);
5608 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5612 CP0_CHECK(ctx->insn_flags & ASE_MT);
5613 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5617 CP0_CHECK(ctx->insn_flags & ASE_MT);
5618 gen_helper_mtc0_yqmask(cpu_env, arg);
5622 CP0_CHECK(ctx->insn_flags & ASE_MT);
5623 tcg_gen_st_tl(arg, cpu_env,
5624 offsetof(CPUMIPSState, CP0_VPESchedule));
5628 CP0_CHECK(ctx->insn_flags & ASE_MT);
5629 tcg_gen_st_tl(arg, cpu_env,
5630 offsetof(CPUMIPSState, CP0_VPEScheFBack));
5631 rn = "VPEScheFBack";
5634 CP0_CHECK(ctx->insn_flags & ASE_MT);
5635 gen_helper_mtc0_vpeopt(cpu_env, arg);
5639 goto cp0_unimplemented;
5645 gen_helper_mtc0_entrylo0(cpu_env, arg);
5649 CP0_CHECK(ctx->insn_flags & ASE_MT);
5650 gen_helper_mtc0_tcstatus(cpu_env, arg);
5654 CP0_CHECK(ctx->insn_flags & ASE_MT);
5655 gen_helper_mtc0_tcbind(cpu_env, arg);
5659 CP0_CHECK(ctx->insn_flags & ASE_MT);
5660 gen_helper_mtc0_tcrestart(cpu_env, arg);
5664 CP0_CHECK(ctx->insn_flags & ASE_MT);
5665 gen_helper_mtc0_tchalt(cpu_env, arg);
5669 CP0_CHECK(ctx->insn_flags & ASE_MT);
5670 gen_helper_mtc0_tccontext(cpu_env, arg);
5674 CP0_CHECK(ctx->insn_flags & ASE_MT);
5675 gen_helper_mtc0_tcschedule(cpu_env, arg);
5679 CP0_CHECK(ctx->insn_flags & ASE_MT);
5680 gen_helper_mtc0_tcschefback(cpu_env, arg);
5684 goto cp0_unimplemented;
5690 gen_helper_mtc0_entrylo1(cpu_env, arg);
5694 goto cp0_unimplemented;
5700 gen_helper_mtc0_context(cpu_env, arg);
5704 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5705 rn = "ContextConfig";
5706 goto cp0_unimplemented;
5709 CP0_CHECK(ctx->ulri);
5710 tcg_gen_st_tl(arg, cpu_env,
5711 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5715 goto cp0_unimplemented;
5721 gen_helper_mtc0_pagemask(cpu_env, arg);
5725 check_insn(ctx, ISA_MIPS32R2);
5726 gen_helper_mtc0_pagegrain(cpu_env, arg);
5728 ctx->bstate = BS_STOP;
5731 goto cp0_unimplemented;
5737 gen_helper_mtc0_wired(cpu_env, arg);
5741 check_insn(ctx, ISA_MIPS32R2);
5742 gen_helper_mtc0_srsconf0(cpu_env, arg);
5746 check_insn(ctx, ISA_MIPS32R2);
5747 gen_helper_mtc0_srsconf1(cpu_env, arg);
5751 check_insn(ctx, ISA_MIPS32R2);
5752 gen_helper_mtc0_srsconf2(cpu_env, arg);
5756 check_insn(ctx, ISA_MIPS32R2);
5757 gen_helper_mtc0_srsconf3(cpu_env, arg);
5761 check_insn(ctx, ISA_MIPS32R2);
5762 gen_helper_mtc0_srsconf4(cpu_env, arg);
5766 goto cp0_unimplemented;
5772 check_insn(ctx, ISA_MIPS32R2);
5773 gen_helper_mtc0_hwrena(cpu_env, arg);
5774 ctx->bstate = BS_STOP;
5778 goto cp0_unimplemented;
5796 goto cp0_unimplemented;
5802 gen_helper_mtc0_count(cpu_env, arg);
5805 /* 6,7 are implementation dependent */
5807 goto cp0_unimplemented;
5813 gen_helper_mtc0_entryhi(cpu_env, arg);
5817 goto cp0_unimplemented;
5823 gen_helper_mtc0_compare(cpu_env, arg);
5826 /* 6,7 are implementation dependent */
5828 goto cp0_unimplemented;
5834 save_cpu_state(ctx, 1);
5835 gen_helper_mtc0_status(cpu_env, arg);
5836 /* BS_STOP isn't good enough here, hflags may have changed. */
5837 gen_save_pc(ctx->pc + 4);
5838 ctx->bstate = BS_EXCP;
5842 check_insn(ctx, ISA_MIPS32R2);
5843 gen_helper_mtc0_intctl(cpu_env, arg);
5844 /* Stop translation as we may have switched the execution mode */
5845 ctx->bstate = BS_STOP;
5849 check_insn(ctx, ISA_MIPS32R2);
5850 gen_helper_mtc0_srsctl(cpu_env, arg);
5851 /* Stop translation as we may have switched the execution mode */
5852 ctx->bstate = BS_STOP;
5856 check_insn(ctx, ISA_MIPS32R2);
5857 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5858 /* Stop translation as we may have switched the execution mode */
5859 ctx->bstate = BS_STOP;
5863 goto cp0_unimplemented;
5869 save_cpu_state(ctx, 1);
5870 gen_helper_mtc0_cause(cpu_env, arg);
5874 goto cp0_unimplemented;
5880 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5884 goto cp0_unimplemented;
5894 check_insn(ctx, ISA_MIPS32R2);
5895 gen_helper_mtc0_ebase(cpu_env, arg);
5899 goto cp0_unimplemented;
5905 gen_helper_mtc0_config0(cpu_env, arg);
5907 /* Stop translation as we may have switched the execution mode */
5908 ctx->bstate = BS_STOP;
5911 /* ignored, read only */
5915 gen_helper_mtc0_config2(cpu_env, arg);
5917 /* Stop translation as we may have switched the execution mode */
5918 ctx->bstate = BS_STOP;
5921 gen_helper_mtc0_config3(cpu_env, arg);
5923 /* Stop translation as we may have switched the execution mode */
5924 ctx->bstate = BS_STOP;
5927 gen_helper_mtc0_config4(cpu_env, arg);
5929 ctx->bstate = BS_STOP;
5932 gen_helper_mtc0_config5(cpu_env, arg);
5934 /* Stop translation as we may have switched the execution mode */
5935 ctx->bstate = BS_STOP;
5937 /* 6,7 are implementation dependent */
5947 rn = "Invalid config selector";
5948 goto cp0_unimplemented;
5954 gen_helper_mtc0_lladdr(cpu_env, arg);
5958 goto cp0_unimplemented;
5964 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5968 goto cp0_unimplemented;
5974 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5978 goto cp0_unimplemented;
5984 #if defined(TARGET_MIPS64)
5985 check_insn(ctx, ISA_MIPS3);
5986 gen_helper_mtc0_xcontext(cpu_env, arg);
5991 goto cp0_unimplemented;
5995 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5996 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5999 gen_helper_mtc0_framemask(cpu_env, arg);
6003 goto cp0_unimplemented;
6008 rn = "Diagnostic"; /* implementation dependent */
6013 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6014 /* BS_STOP isn't good enough here, hflags may have changed. */
6015 gen_save_pc(ctx->pc + 4);
6016 ctx->bstate = BS_EXCP;
6020 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6021 rn = "TraceControl";
6022 /* Stop translation as we may have switched the execution mode */
6023 ctx->bstate = BS_STOP;
6026 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6027 rn = "TraceControl2";
6028 /* Stop translation as we may have switched the execution mode */
6029 ctx->bstate = BS_STOP;
6032 /* Stop translation as we may have switched the execution mode */
6033 ctx->bstate = BS_STOP;
6034 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6035 rn = "UserTraceData";
6036 /* Stop translation as we may have switched the execution mode */
6037 ctx->bstate = BS_STOP;
6040 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6041 /* Stop translation as we may have switched the execution mode */
6042 ctx->bstate = BS_STOP;
6046 goto cp0_unimplemented;
6053 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6057 goto cp0_unimplemented;
6063 gen_helper_mtc0_performance0(cpu_env, arg);
6064 rn = "Performance0";
6067 // gen_helper_mtc0_performance1(arg);
6068 rn = "Performance1";
6071 // gen_helper_mtc0_performance2(arg);
6072 rn = "Performance2";
6075 // gen_helper_mtc0_performance3(arg);
6076 rn = "Performance3";
6079 // gen_helper_mtc0_performance4(arg);
6080 rn = "Performance4";
6083 // gen_helper_mtc0_performance5(arg);
6084 rn = "Performance5";
6087 // gen_helper_mtc0_performance6(arg);
6088 rn = "Performance6";
6091 // gen_helper_mtc0_performance7(arg);
6092 rn = "Performance7";
6095 goto cp0_unimplemented;
6109 goto cp0_unimplemented;
6118 gen_helper_mtc0_taglo(cpu_env, arg);
6125 gen_helper_mtc0_datalo(cpu_env, arg);
6129 goto cp0_unimplemented;
6138 gen_helper_mtc0_taghi(cpu_env, arg);
6145 gen_helper_mtc0_datahi(cpu_env, arg);
6150 goto cp0_unimplemented;
6156 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6160 goto cp0_unimplemented;
6167 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6171 CP0_CHECK(ctx->kscrexist & (1 << sel));
6172 tcg_gen_st_tl(arg, cpu_env,
6173 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6177 goto cp0_unimplemented;
6179 /* Stop translation as we may have switched the execution mode */
6180 ctx->bstate = BS_STOP;
6183 goto cp0_unimplemented;
6185 (void)rn; /* avoid a compiler warning */
6186 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6187 /* For simplicity assume that all writes can cause interrupts. */
6188 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6190 ctx->bstate = BS_STOP;
6195 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6198 #if defined(TARGET_MIPS64)
6199 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6201 const char *rn = "invalid";
6204 check_insn(ctx, ISA_MIPS64);
6210 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6214 CP0_CHECK(ctx->insn_flags & ASE_MT);
6215 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6219 CP0_CHECK(ctx->insn_flags & ASE_MT);
6220 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6224 CP0_CHECK(ctx->insn_flags & ASE_MT);
6225 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6229 goto cp0_unimplemented;
6235 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6236 gen_helper_mfc0_random(arg, cpu_env);
6240 CP0_CHECK(ctx->insn_flags & ASE_MT);
6241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6245 CP0_CHECK(ctx->insn_flags & ASE_MT);
6246 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6250 CP0_CHECK(ctx->insn_flags & ASE_MT);
6251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6255 CP0_CHECK(ctx->insn_flags & ASE_MT);
6256 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6260 CP0_CHECK(ctx->insn_flags & ASE_MT);
6261 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6265 CP0_CHECK(ctx->insn_flags & ASE_MT);
6266 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6267 rn = "VPEScheFBack";
6270 CP0_CHECK(ctx->insn_flags & ASE_MT);
6271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6275 goto cp0_unimplemented;
6281 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6285 CP0_CHECK(ctx->insn_flags & ASE_MT);
6286 gen_helper_mfc0_tcstatus(arg, cpu_env);
6290 CP0_CHECK(ctx->insn_flags & ASE_MT);
6291 gen_helper_mfc0_tcbind(arg, cpu_env);
6295 CP0_CHECK(ctx->insn_flags & ASE_MT);
6296 gen_helper_dmfc0_tcrestart(arg, cpu_env);
6300 CP0_CHECK(ctx->insn_flags & ASE_MT);
6301 gen_helper_dmfc0_tchalt(arg, cpu_env);
6305 CP0_CHECK(ctx->insn_flags & ASE_MT);
6306 gen_helper_dmfc0_tccontext(arg, cpu_env);
6310 CP0_CHECK(ctx->insn_flags & ASE_MT);
6311 gen_helper_dmfc0_tcschedule(arg, cpu_env);
6315 CP0_CHECK(ctx->insn_flags & ASE_MT);
6316 gen_helper_dmfc0_tcschefback(arg, cpu_env);
6320 goto cp0_unimplemented;
6326 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6330 goto cp0_unimplemented;
6336 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6340 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6341 rn = "ContextConfig";
6342 goto cp0_unimplemented;
6345 CP0_CHECK(ctx->ulri);
6346 tcg_gen_ld_tl(arg, cpu_env,
6347 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6351 goto cp0_unimplemented;
6357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6361 check_insn(ctx, ISA_MIPS32R2);
6362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6366 goto cp0_unimplemented;
6372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6376 check_insn(ctx, ISA_MIPS32R2);
6377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6381 check_insn(ctx, ISA_MIPS32R2);
6382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6386 check_insn(ctx, ISA_MIPS32R2);
6387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6391 check_insn(ctx, ISA_MIPS32R2);
6392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6396 check_insn(ctx, ISA_MIPS32R2);
6397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6401 goto cp0_unimplemented;
6407 check_insn(ctx, ISA_MIPS32R2);
6408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6412 goto cp0_unimplemented;
6418 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6432 goto cp0_unimplemented;
6438 /* Mark as an IO operation because we read the time. */
6439 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6442 gen_helper_mfc0_count(arg, cpu_env);
6443 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6446 /* Break the TB to be able to take timer interrupts immediately
6447 after reading count. */
6448 ctx->bstate = BS_STOP;
6451 /* 6,7 are implementation dependent */
6453 goto cp0_unimplemented;
6459 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6463 goto cp0_unimplemented;
6469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6472 /* 6,7 are implementation dependent */
6474 goto cp0_unimplemented;
6480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6484 check_insn(ctx, ISA_MIPS32R2);
6485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6489 check_insn(ctx, ISA_MIPS32R2);
6490 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6494 check_insn(ctx, ISA_MIPS32R2);
6495 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6499 goto cp0_unimplemented;
6505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6509 goto cp0_unimplemented;
6515 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6519 goto cp0_unimplemented;
6525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6529 check_insn(ctx, ISA_MIPS32R2);
6530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6534 goto cp0_unimplemented;
6540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6548 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6552 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6556 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6563 /* 6,7 are implementation dependent */
6565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6573 goto cp0_unimplemented;
6579 gen_helper_dmfc0_lladdr(arg, cpu_env);
6583 goto cp0_unimplemented;
6589 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6593 goto cp0_unimplemented;
6599 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6603 goto cp0_unimplemented;
6609 check_insn(ctx, ISA_MIPS3);
6610 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6614 goto cp0_unimplemented;
6618 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6619 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6622 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6626 goto cp0_unimplemented;
6630 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6631 rn = "'Diagnostic"; /* implementation dependent */
6636 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6640 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6641 rn = "TraceControl";
6644 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6645 rn = "TraceControl2";
6648 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6649 rn = "UserTraceData";
6652 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6656 goto cp0_unimplemented;
6663 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6667 goto cp0_unimplemented;
6673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6674 rn = "Performance0";
6677 // gen_helper_dmfc0_performance1(arg);
6678 rn = "Performance1";
6681 // gen_helper_dmfc0_performance2(arg);
6682 rn = "Performance2";
6685 // gen_helper_dmfc0_performance3(arg);
6686 rn = "Performance3";
6689 // gen_helper_dmfc0_performance4(arg);
6690 rn = "Performance4";
6693 // gen_helper_dmfc0_performance5(arg);
6694 rn = "Performance5";
6697 // gen_helper_dmfc0_performance6(arg);
6698 rn = "Performance6";
6701 // gen_helper_dmfc0_performance7(arg);
6702 rn = "Performance7";
6705 goto cp0_unimplemented;
6709 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6716 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6720 goto cp0_unimplemented;
6729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6736 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6740 goto cp0_unimplemented;
6749 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6756 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6760 goto cp0_unimplemented;
6766 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6770 goto cp0_unimplemented;
6777 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6781 CP0_CHECK(ctx->kscrexist & (1 << sel));
6782 tcg_gen_ld_tl(arg, cpu_env,
6783 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6787 goto cp0_unimplemented;
6791 goto cp0_unimplemented;
6793 (void)rn; /* avoid a compiler warning */
6794 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6798 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6799 gen_mfc0_unimplemented(ctx, arg);
6802 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6804 const char *rn = "invalid";
6807 check_insn(ctx, ISA_MIPS64);
6809 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6817 gen_helper_mtc0_index(cpu_env, arg);
6821 CP0_CHECK(ctx->insn_flags & ASE_MT);
6822 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6826 CP0_CHECK(ctx->insn_flags & ASE_MT);
6831 CP0_CHECK(ctx->insn_flags & ASE_MT);
6836 goto cp0_unimplemented;
6846 CP0_CHECK(ctx->insn_flags & ASE_MT);
6847 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6851 CP0_CHECK(ctx->insn_flags & ASE_MT);
6852 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6856 CP0_CHECK(ctx->insn_flags & ASE_MT);
6857 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6861 CP0_CHECK(ctx->insn_flags & ASE_MT);
6862 gen_helper_mtc0_yqmask(cpu_env, arg);
6866 CP0_CHECK(ctx->insn_flags & ASE_MT);
6867 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6871 CP0_CHECK(ctx->insn_flags & ASE_MT);
6872 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6873 rn = "VPEScheFBack";
6876 CP0_CHECK(ctx->insn_flags & ASE_MT);
6877 gen_helper_mtc0_vpeopt(cpu_env, arg);
6881 goto cp0_unimplemented;
6887 gen_helper_dmtc0_entrylo0(cpu_env, arg);
6891 CP0_CHECK(ctx->insn_flags & ASE_MT);
6892 gen_helper_mtc0_tcstatus(cpu_env, arg);
6896 CP0_CHECK(ctx->insn_flags & ASE_MT);
6897 gen_helper_mtc0_tcbind(cpu_env, arg);
6901 CP0_CHECK(ctx->insn_flags & ASE_MT);
6902 gen_helper_mtc0_tcrestart(cpu_env, arg);
6906 CP0_CHECK(ctx->insn_flags & ASE_MT);
6907 gen_helper_mtc0_tchalt(cpu_env, arg);
6911 CP0_CHECK(ctx->insn_flags & ASE_MT);
6912 gen_helper_mtc0_tccontext(cpu_env, arg);
6916 CP0_CHECK(ctx->insn_flags & ASE_MT);
6917 gen_helper_mtc0_tcschedule(cpu_env, arg);
6921 CP0_CHECK(ctx->insn_flags & ASE_MT);
6922 gen_helper_mtc0_tcschefback(cpu_env, arg);
6926 goto cp0_unimplemented;
6932 gen_helper_dmtc0_entrylo1(cpu_env, arg);
6936 goto cp0_unimplemented;
6942 gen_helper_mtc0_context(cpu_env, arg);
6946 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6947 rn = "ContextConfig";
6948 goto cp0_unimplemented;
6951 CP0_CHECK(ctx->ulri);
6952 tcg_gen_st_tl(arg, cpu_env,
6953 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6957 goto cp0_unimplemented;
6963 gen_helper_mtc0_pagemask(cpu_env, arg);
6967 check_insn(ctx, ISA_MIPS32R2);
6968 gen_helper_mtc0_pagegrain(cpu_env, arg);
6972 goto cp0_unimplemented;
6978 gen_helper_mtc0_wired(cpu_env, arg);
6982 check_insn(ctx, ISA_MIPS32R2);
6983 gen_helper_mtc0_srsconf0(cpu_env, arg);
6987 check_insn(ctx, ISA_MIPS32R2);
6988 gen_helper_mtc0_srsconf1(cpu_env, arg);
6992 check_insn(ctx, ISA_MIPS32R2);
6993 gen_helper_mtc0_srsconf2(cpu_env, arg);
6997 check_insn(ctx, ISA_MIPS32R2);
6998 gen_helper_mtc0_srsconf3(cpu_env, arg);
7002 check_insn(ctx, ISA_MIPS32R2);
7003 gen_helper_mtc0_srsconf4(cpu_env, arg);
7007 goto cp0_unimplemented;
7013 check_insn(ctx, ISA_MIPS32R2);
7014 gen_helper_mtc0_hwrena(cpu_env, arg);
7015 ctx->bstate = BS_STOP;
7019 goto cp0_unimplemented;
7037 goto cp0_unimplemented;
7043 gen_helper_mtc0_count(cpu_env, arg);
7046 /* 6,7 are implementation dependent */
7048 goto cp0_unimplemented;
7050 /* Stop translation as we may have switched the execution mode */
7051 ctx->bstate = BS_STOP;
7056 gen_helper_mtc0_entryhi(cpu_env, arg);
7060 goto cp0_unimplemented;
7066 gen_helper_mtc0_compare(cpu_env, arg);
7069 /* 6,7 are implementation dependent */
7071 goto cp0_unimplemented;
7073 /* Stop translation as we may have switched the execution mode */
7074 ctx->bstate = BS_STOP;
7079 save_cpu_state(ctx, 1);
7080 gen_helper_mtc0_status(cpu_env, arg);
7081 /* BS_STOP isn't good enough here, hflags may have changed. */
7082 gen_save_pc(ctx->pc + 4);
7083 ctx->bstate = BS_EXCP;
7087 check_insn(ctx, ISA_MIPS32R2);
7088 gen_helper_mtc0_intctl(cpu_env, arg);
7089 /* Stop translation as we may have switched the execution mode */
7090 ctx->bstate = BS_STOP;
7094 check_insn(ctx, ISA_MIPS32R2);
7095 gen_helper_mtc0_srsctl(cpu_env, arg);
7096 /* Stop translation as we may have switched the execution mode */
7097 ctx->bstate = BS_STOP;
7101 check_insn(ctx, ISA_MIPS32R2);
7102 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7103 /* Stop translation as we may have switched the execution mode */
7104 ctx->bstate = BS_STOP;
7108 goto cp0_unimplemented;
7114 save_cpu_state(ctx, 1);
7115 /* Mark as an IO operation because we may trigger a software
7117 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7120 gen_helper_mtc0_cause(cpu_env, arg);
7121 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7124 /* Stop translation as we may have triggered an intetrupt */
7125 ctx->bstate = BS_STOP;
7129 goto cp0_unimplemented;
7135 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7139 goto cp0_unimplemented;
7149 check_insn(ctx, ISA_MIPS32R2);
7150 gen_helper_mtc0_ebase(cpu_env, arg);
7154 goto cp0_unimplemented;
7160 gen_helper_mtc0_config0(cpu_env, arg);
7162 /* Stop translation as we may have switched the execution mode */
7163 ctx->bstate = BS_STOP;
7166 /* ignored, read only */
7170 gen_helper_mtc0_config2(cpu_env, arg);
7172 /* Stop translation as we may have switched the execution mode */
7173 ctx->bstate = BS_STOP;
7176 gen_helper_mtc0_config3(cpu_env, arg);
7178 /* Stop translation as we may have switched the execution mode */
7179 ctx->bstate = BS_STOP;
7182 /* currently ignored */
7186 gen_helper_mtc0_config5(cpu_env, arg);
7188 /* Stop translation as we may have switched the execution mode */
7189 ctx->bstate = BS_STOP;
7191 /* 6,7 are implementation dependent */
7193 rn = "Invalid config selector";
7194 goto cp0_unimplemented;
7200 gen_helper_mtc0_lladdr(cpu_env, arg);
7204 goto cp0_unimplemented;
7210 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7214 goto cp0_unimplemented;
7220 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7224 goto cp0_unimplemented;
7230 check_insn(ctx, ISA_MIPS3);
7231 gen_helper_mtc0_xcontext(cpu_env, arg);
7235 goto cp0_unimplemented;
7239 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7240 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7243 gen_helper_mtc0_framemask(cpu_env, arg);
7247 goto cp0_unimplemented;
7252 rn = "Diagnostic"; /* implementation dependent */
7257 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7258 /* BS_STOP isn't good enough here, hflags may have changed. */
7259 gen_save_pc(ctx->pc + 4);
7260 ctx->bstate = BS_EXCP;
7264 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7265 /* Stop translation as we may have switched the execution mode */
7266 ctx->bstate = BS_STOP;
7267 rn = "TraceControl";
7270 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7271 /* Stop translation as we may have switched the execution mode */
7272 ctx->bstate = BS_STOP;
7273 rn = "TraceControl2";
7276 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7277 /* Stop translation as we may have switched the execution mode */
7278 ctx->bstate = BS_STOP;
7279 rn = "UserTraceData";
7282 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7283 /* Stop translation as we may have switched the execution mode */
7284 ctx->bstate = BS_STOP;
7288 goto cp0_unimplemented;
7295 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7299 goto cp0_unimplemented;
7305 gen_helper_mtc0_performance0(cpu_env, arg);
7306 rn = "Performance0";
7309 // gen_helper_mtc0_performance1(cpu_env, arg);
7310 rn = "Performance1";
7313 // gen_helper_mtc0_performance2(cpu_env, arg);
7314 rn = "Performance2";
7317 // gen_helper_mtc0_performance3(cpu_env, arg);
7318 rn = "Performance3";
7321 // gen_helper_mtc0_performance4(cpu_env, arg);
7322 rn = "Performance4";
7325 // gen_helper_mtc0_performance5(cpu_env, arg);
7326 rn = "Performance5";
7329 // gen_helper_mtc0_performance6(cpu_env, arg);
7330 rn = "Performance6";
7333 // gen_helper_mtc0_performance7(cpu_env, arg);
7334 rn = "Performance7";
7337 goto cp0_unimplemented;
7351 goto cp0_unimplemented;
7360 gen_helper_mtc0_taglo(cpu_env, arg);
7367 gen_helper_mtc0_datalo(cpu_env, arg);
7371 goto cp0_unimplemented;
7380 gen_helper_mtc0_taghi(cpu_env, arg);
7387 gen_helper_mtc0_datahi(cpu_env, arg);
7392 goto cp0_unimplemented;
7398 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7402 goto cp0_unimplemented;
7409 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7413 CP0_CHECK(ctx->kscrexist & (1 << sel));
7414 tcg_gen_st_tl(arg, cpu_env,
7415 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7419 goto cp0_unimplemented;
7421 /* Stop translation as we may have switched the execution mode */
7422 ctx->bstate = BS_STOP;
7425 goto cp0_unimplemented;
7427 (void)rn; /* avoid a compiler warning */
7428 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7429 /* For simplicity assume that all writes can cause interrupts. */
7430 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7432 ctx->bstate = BS_STOP;
7437 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7439 #endif /* TARGET_MIPS64 */
7441 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7442 int u, int sel, int h)
7444 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7445 TCGv t0 = tcg_temp_local_new();
7447 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7448 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7449 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7450 tcg_gen_movi_tl(t0, -1);
7451 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7452 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7453 tcg_gen_movi_tl(t0, -1);
7459 gen_helper_mftc0_vpecontrol(t0, cpu_env);
7462 gen_helper_mftc0_vpeconf0(t0, cpu_env);
7472 gen_helper_mftc0_tcstatus(t0, cpu_env);
7475 gen_helper_mftc0_tcbind(t0, cpu_env);
7478 gen_helper_mftc0_tcrestart(t0, cpu_env);
7481 gen_helper_mftc0_tchalt(t0, cpu_env);
7484 gen_helper_mftc0_tccontext(t0, cpu_env);
7487 gen_helper_mftc0_tcschedule(t0, cpu_env);
7490 gen_helper_mftc0_tcschefback(t0, cpu_env);
7493 gen_mfc0(ctx, t0, rt, sel);
7500 gen_helper_mftc0_entryhi(t0, cpu_env);
7503 gen_mfc0(ctx, t0, rt, sel);
7509 gen_helper_mftc0_status(t0, cpu_env);
7512 gen_mfc0(ctx, t0, rt, sel);
7518 gen_helper_mftc0_cause(t0, cpu_env);
7528 gen_helper_mftc0_epc(t0, cpu_env);
7538 gen_helper_mftc0_ebase(t0, cpu_env);
7548 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7558 gen_helper_mftc0_debug(t0, cpu_env);
7561 gen_mfc0(ctx, t0, rt, sel);
7566 gen_mfc0(ctx, t0, rt, sel);
7568 } else switch (sel) {
7569 /* GPR registers. */
7571 gen_helper_1e0i(mftgpr, t0, rt);
7573 /* Auxiliary CPU registers */
7577 gen_helper_1e0i(mftlo, t0, 0);
7580 gen_helper_1e0i(mfthi, t0, 0);
7583 gen_helper_1e0i(mftacx, t0, 0);
7586 gen_helper_1e0i(mftlo, t0, 1);
7589 gen_helper_1e0i(mfthi, t0, 1);
7592 gen_helper_1e0i(mftacx, t0, 1);
7595 gen_helper_1e0i(mftlo, t0, 2);
7598 gen_helper_1e0i(mfthi, t0, 2);
7601 gen_helper_1e0i(mftacx, t0, 2);
7604 gen_helper_1e0i(mftlo, t0, 3);
7607 gen_helper_1e0i(mfthi, t0, 3);
7610 gen_helper_1e0i(mftacx, t0, 3);
7613 gen_helper_mftdsp(t0, cpu_env);
7619 /* Floating point (COP1). */
7621 /* XXX: For now we support only a single FPU context. */
7623 TCGv_i32 fp0 = tcg_temp_new_i32();
7625 gen_load_fpr32(ctx, fp0, rt);
7626 tcg_gen_ext_i32_tl(t0, fp0);
7627 tcg_temp_free_i32(fp0);
7629 TCGv_i32 fp0 = tcg_temp_new_i32();
7631 gen_load_fpr32h(ctx, fp0, rt);
7632 tcg_gen_ext_i32_tl(t0, fp0);
7633 tcg_temp_free_i32(fp0);
7637 /* XXX: For now we support only a single FPU context. */
7638 gen_helper_1e0i(cfc1, t0, rt);
7640 /* COP2: Not implemented. */
7647 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7648 gen_store_gpr(t0, rd);
7654 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7655 generate_exception_end(ctx, EXCP_RI);
7658 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7659 int u, int sel, int h)
7661 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7662 TCGv t0 = tcg_temp_local_new();
7664 gen_load_gpr(t0, rt);
7665 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7666 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7667 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7669 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7670 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7677 gen_helper_mttc0_vpecontrol(cpu_env, t0);
7680 gen_helper_mttc0_vpeconf0(cpu_env, t0);
7690 gen_helper_mttc0_tcstatus(cpu_env, t0);
7693 gen_helper_mttc0_tcbind(cpu_env, t0);
7696 gen_helper_mttc0_tcrestart(cpu_env, t0);
7699 gen_helper_mttc0_tchalt(cpu_env, t0);
7702 gen_helper_mttc0_tccontext(cpu_env, t0);
7705 gen_helper_mttc0_tcschedule(cpu_env, t0);
7708 gen_helper_mttc0_tcschefback(cpu_env, t0);
7711 gen_mtc0(ctx, t0, rd, sel);
7718 gen_helper_mttc0_entryhi(cpu_env, t0);
7721 gen_mtc0(ctx, t0, rd, sel);
7727 gen_helper_mttc0_status(cpu_env, t0);
7730 gen_mtc0(ctx, t0, rd, sel);
7736 gen_helper_mttc0_cause(cpu_env, t0);
7746 gen_helper_mttc0_ebase(cpu_env, t0);
7756 gen_helper_mttc0_debug(cpu_env, t0);
7759 gen_mtc0(ctx, t0, rd, sel);
7764 gen_mtc0(ctx, t0, rd, sel);
7766 } else switch (sel) {
7767 /* GPR registers. */
7769 gen_helper_0e1i(mttgpr, t0, rd);
7771 /* Auxiliary CPU registers */
7775 gen_helper_0e1i(mttlo, t0, 0);
7778 gen_helper_0e1i(mtthi, t0, 0);
7781 gen_helper_0e1i(mttacx, t0, 0);
7784 gen_helper_0e1i(mttlo, t0, 1);
7787 gen_helper_0e1i(mtthi, t0, 1);
7790 gen_helper_0e1i(mttacx, t0, 1);
7793 gen_helper_0e1i(mttlo, t0, 2);
7796 gen_helper_0e1i(mtthi, t0, 2);
7799 gen_helper_0e1i(mttacx, t0, 2);
7802 gen_helper_0e1i(mttlo, t0, 3);
7805 gen_helper_0e1i(mtthi, t0, 3);
7808 gen_helper_0e1i(mttacx, t0, 3);
7811 gen_helper_mttdsp(cpu_env, t0);
7817 /* Floating point (COP1). */
7819 /* XXX: For now we support only a single FPU context. */
7821 TCGv_i32 fp0 = tcg_temp_new_i32();
7823 tcg_gen_trunc_tl_i32(fp0, t0);
7824 gen_store_fpr32(ctx, fp0, rd);
7825 tcg_temp_free_i32(fp0);
7827 TCGv_i32 fp0 = tcg_temp_new_i32();
7829 tcg_gen_trunc_tl_i32(fp0, t0);
7830 gen_store_fpr32h(ctx, fp0, rd);
7831 tcg_temp_free_i32(fp0);
7835 /* XXX: For now we support only a single FPU context. */
7837 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7839 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7840 tcg_temp_free_i32(fs_tmp);
7842 /* Stop translation as we may have changed hflags */
7843 ctx->bstate = BS_STOP;
7845 /* COP2: Not implemented. */
7852 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7858 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7859 generate_exception_end(ctx, EXCP_RI);
7862 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
7864 const char *opn = "ldst";
7866 check_cp0_enabled(ctx);
7873 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7878 TCGv t0 = tcg_temp_new();
7880 gen_load_gpr(t0, rt);
7881 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
7886 #if defined(TARGET_MIPS64)
7888 check_insn(ctx, ISA_MIPS3);
7893 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7897 check_insn(ctx, ISA_MIPS3);
7899 TCGv t0 = tcg_temp_new();
7901 gen_load_gpr(t0, rt);
7902 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
7914 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7920 TCGv t0 = tcg_temp_new();
7921 gen_load_gpr(t0, rt);
7922 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
7928 check_insn(ctx, ASE_MT);
7933 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
7934 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7938 check_insn(ctx, ASE_MT);
7939 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
7940 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7945 if (!env->tlb->helper_tlbwi)
7947 gen_helper_tlbwi(cpu_env);
7952 if (!env->tlb->helper_tlbinv) {
7955 gen_helper_tlbinv(cpu_env);
7956 } /* treat as nop if TLBINV not supported */
7961 if (!env->tlb->helper_tlbinvf) {
7964 gen_helper_tlbinvf(cpu_env);
7965 } /* treat as nop if TLBINV not supported */
7969 if (!env->tlb->helper_tlbwr)
7971 gen_helper_tlbwr(cpu_env);
7975 if (!env->tlb->helper_tlbp)
7977 gen_helper_tlbp(cpu_env);
7981 if (!env->tlb->helper_tlbr)
7983 gen_helper_tlbr(cpu_env);
7985 case OPC_ERET: /* OPC_ERETNC */
7986 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7987 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7990 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
7991 if (ctx->opcode & (1 << bit_shift)) {
7994 check_insn(ctx, ISA_MIPS32R5);
7995 gen_helper_eretnc(cpu_env);
7999 check_insn(ctx, ISA_MIPS2);
8000 gen_helper_eret(cpu_env);
8002 ctx->bstate = BS_EXCP;
8007 check_insn(ctx, ISA_MIPS32);
8008 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8009 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8012 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8014 generate_exception_end(ctx, EXCP_RI);
8016 gen_helper_deret(cpu_env);
8017 ctx->bstate = BS_EXCP;
8022 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8023 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8024 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8027 /* If we get an exception, we want to restart at next instruction */
8029 save_cpu_state(ctx, 1);
8031 gen_helper_wait(cpu_env);
8032 ctx->bstate = BS_EXCP;
8037 generate_exception_end(ctx, EXCP_RI);
8040 (void)opn; /* avoid a compiler warning */
8042 #endif /* !CONFIG_USER_ONLY */
8044 /* CP1 Branches (before delay slot) */
8045 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8046 int32_t cc, int32_t offset)
8048 target_ulong btarget;
8049 TCGv_i32 t0 = tcg_temp_new_i32();
8051 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8052 generate_exception_end(ctx, EXCP_RI);
8057 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8059 btarget = ctx->pc + 4 + offset;
8063 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8064 tcg_gen_not_i32(t0, t0);
8065 tcg_gen_andi_i32(t0, t0, 1);
8066 tcg_gen_extu_i32_tl(bcond, t0);
8069 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8070 tcg_gen_not_i32(t0, t0);
8071 tcg_gen_andi_i32(t0, t0, 1);
8072 tcg_gen_extu_i32_tl(bcond, t0);
8075 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8076 tcg_gen_andi_i32(t0, t0, 1);
8077 tcg_gen_extu_i32_tl(bcond, t0);
8080 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8081 tcg_gen_andi_i32(t0, t0, 1);
8082 tcg_gen_extu_i32_tl(bcond, t0);
8084 ctx->hflags |= MIPS_HFLAG_BL;
8088 TCGv_i32 t1 = tcg_temp_new_i32();
8089 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8090 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8091 tcg_gen_nand_i32(t0, t0, t1);
8092 tcg_temp_free_i32(t1);
8093 tcg_gen_andi_i32(t0, t0, 1);
8094 tcg_gen_extu_i32_tl(bcond, t0);
8099 TCGv_i32 t1 = tcg_temp_new_i32();
8100 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8101 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8102 tcg_gen_or_i32(t0, t0, t1);
8103 tcg_temp_free_i32(t1);
8104 tcg_gen_andi_i32(t0, t0, 1);
8105 tcg_gen_extu_i32_tl(bcond, t0);
8110 TCGv_i32 t1 = tcg_temp_new_i32();
8111 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8112 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8113 tcg_gen_and_i32(t0, t0, t1);
8114 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8115 tcg_gen_and_i32(t0, t0, t1);
8116 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8117 tcg_gen_nand_i32(t0, t0, t1);
8118 tcg_temp_free_i32(t1);
8119 tcg_gen_andi_i32(t0, t0, 1);
8120 tcg_gen_extu_i32_tl(bcond, t0);
8125 TCGv_i32 t1 = tcg_temp_new_i32();
8126 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8127 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8128 tcg_gen_or_i32(t0, t0, t1);
8129 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8130 tcg_gen_or_i32(t0, t0, t1);
8131 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8132 tcg_gen_or_i32(t0, t0, t1);
8133 tcg_temp_free_i32(t1);
8134 tcg_gen_andi_i32(t0, t0, 1);
8135 tcg_gen_extu_i32_tl(bcond, t0);
8138 ctx->hflags |= MIPS_HFLAG_BC;
8141 MIPS_INVAL("cp1 cond branch");
8142 generate_exception_end(ctx, EXCP_RI);
8145 ctx->btarget = btarget;
8146 ctx->hflags |= MIPS_HFLAG_BDS32;
8148 tcg_temp_free_i32(t0);
8151 /* R6 CP1 Branches */
8152 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8153 int32_t ft, int32_t offset,
8156 target_ulong btarget;
8157 TCGv_i64 t0 = tcg_temp_new_i64();
8159 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8160 #ifdef MIPS_DEBUG_DISAS
8161 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8164 generate_exception_end(ctx, EXCP_RI);
8168 gen_load_fpr64(ctx, t0, ft);
8169 tcg_gen_andi_i64(t0, t0, 1);
8171 btarget = addr_add(ctx, ctx->pc + 4, offset);
8175 tcg_gen_xori_i64(t0, t0, 1);
8176 ctx->hflags |= MIPS_HFLAG_BC;
8179 /* t0 already set */
8180 ctx->hflags |= MIPS_HFLAG_BC;
8183 MIPS_INVAL("cp1 cond branch");
8184 generate_exception_end(ctx, EXCP_RI);
8188 tcg_gen_trunc_i64_tl(bcond, t0);
8190 ctx->btarget = btarget;
8192 switch (delayslot_size) {
8194 ctx->hflags |= MIPS_HFLAG_BDS16;
8197 ctx->hflags |= MIPS_HFLAG_BDS32;
8202 tcg_temp_free_i64(t0);
8205 /* Coprocessor 1 (FPU) */
8207 #define FOP(func, fmt) (((fmt) << 21) | (func))
8210 OPC_ADD_S = FOP(0, FMT_S),
8211 OPC_SUB_S = FOP(1, FMT_S),
8212 OPC_MUL_S = FOP(2, FMT_S),
8213 OPC_DIV_S = FOP(3, FMT_S),
8214 OPC_SQRT_S = FOP(4, FMT_S),
8215 OPC_ABS_S = FOP(5, FMT_S),
8216 OPC_MOV_S = FOP(6, FMT_S),
8217 OPC_NEG_S = FOP(7, FMT_S),
8218 OPC_ROUND_L_S = FOP(8, FMT_S),
8219 OPC_TRUNC_L_S = FOP(9, FMT_S),
8220 OPC_CEIL_L_S = FOP(10, FMT_S),
8221 OPC_FLOOR_L_S = FOP(11, FMT_S),
8222 OPC_ROUND_W_S = FOP(12, FMT_S),
8223 OPC_TRUNC_W_S = FOP(13, FMT_S),
8224 OPC_CEIL_W_S = FOP(14, FMT_S),
8225 OPC_FLOOR_W_S = FOP(15, FMT_S),
8226 OPC_SEL_S = FOP(16, FMT_S),
8227 OPC_MOVCF_S = FOP(17, FMT_S),
8228 OPC_MOVZ_S = FOP(18, FMT_S),
8229 OPC_MOVN_S = FOP(19, FMT_S),
8230 OPC_SELEQZ_S = FOP(20, FMT_S),
8231 OPC_RECIP_S = FOP(21, FMT_S),
8232 OPC_RSQRT_S = FOP(22, FMT_S),
8233 OPC_SELNEZ_S = FOP(23, FMT_S),
8234 OPC_MADDF_S = FOP(24, FMT_S),
8235 OPC_MSUBF_S = FOP(25, FMT_S),
8236 OPC_RINT_S = FOP(26, FMT_S),
8237 OPC_CLASS_S = FOP(27, FMT_S),
8238 OPC_MIN_S = FOP(28, FMT_S),
8239 OPC_RECIP2_S = FOP(28, FMT_S),
8240 OPC_MINA_S = FOP(29, FMT_S),
8241 OPC_RECIP1_S = FOP(29, FMT_S),
8242 OPC_MAX_S = FOP(30, FMT_S),
8243 OPC_RSQRT1_S = FOP(30, FMT_S),
8244 OPC_MAXA_S = FOP(31, FMT_S),
8245 OPC_RSQRT2_S = FOP(31, FMT_S),
8246 OPC_CVT_D_S = FOP(33, FMT_S),
8247 OPC_CVT_W_S = FOP(36, FMT_S),
8248 OPC_CVT_L_S = FOP(37, FMT_S),
8249 OPC_CVT_PS_S = FOP(38, FMT_S),
8250 OPC_CMP_F_S = FOP (48, FMT_S),
8251 OPC_CMP_UN_S = FOP (49, FMT_S),
8252 OPC_CMP_EQ_S = FOP (50, FMT_S),
8253 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8254 OPC_CMP_OLT_S = FOP (52, FMT_S),
8255 OPC_CMP_ULT_S = FOP (53, FMT_S),
8256 OPC_CMP_OLE_S = FOP (54, FMT_S),
8257 OPC_CMP_ULE_S = FOP (55, FMT_S),
8258 OPC_CMP_SF_S = FOP (56, FMT_S),
8259 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8260 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8261 OPC_CMP_NGL_S = FOP (59, FMT_S),
8262 OPC_CMP_LT_S = FOP (60, FMT_S),
8263 OPC_CMP_NGE_S = FOP (61, FMT_S),
8264 OPC_CMP_LE_S = FOP (62, FMT_S),
8265 OPC_CMP_NGT_S = FOP (63, FMT_S),
8267 OPC_ADD_D = FOP(0, FMT_D),
8268 OPC_SUB_D = FOP(1, FMT_D),
8269 OPC_MUL_D = FOP(2, FMT_D),
8270 OPC_DIV_D = FOP(3, FMT_D),
8271 OPC_SQRT_D = FOP(4, FMT_D),
8272 OPC_ABS_D = FOP(5, FMT_D),
8273 OPC_MOV_D = FOP(6, FMT_D),
8274 OPC_NEG_D = FOP(7, FMT_D),
8275 OPC_ROUND_L_D = FOP(8, FMT_D),
8276 OPC_TRUNC_L_D = FOP(9, FMT_D),
8277 OPC_CEIL_L_D = FOP(10, FMT_D),
8278 OPC_FLOOR_L_D = FOP(11, FMT_D),
8279 OPC_ROUND_W_D = FOP(12, FMT_D),
8280 OPC_TRUNC_W_D = FOP(13, FMT_D),
8281 OPC_CEIL_W_D = FOP(14, FMT_D),
8282 OPC_FLOOR_W_D = FOP(15, FMT_D),
8283 OPC_SEL_D = FOP(16, FMT_D),
8284 OPC_MOVCF_D = FOP(17, FMT_D),
8285 OPC_MOVZ_D = FOP(18, FMT_D),
8286 OPC_MOVN_D = FOP(19, FMT_D),
8287 OPC_SELEQZ_D = FOP(20, FMT_D),
8288 OPC_RECIP_D = FOP(21, FMT_D),
8289 OPC_RSQRT_D = FOP(22, FMT_D),
8290 OPC_SELNEZ_D = FOP(23, FMT_D),
8291 OPC_MADDF_D = FOP(24, FMT_D),
8292 OPC_MSUBF_D = FOP(25, FMT_D),
8293 OPC_RINT_D = FOP(26, FMT_D),
8294 OPC_CLASS_D = FOP(27, FMT_D),
8295 OPC_MIN_D = FOP(28, FMT_D),
8296 OPC_RECIP2_D = FOP(28, FMT_D),
8297 OPC_MINA_D = FOP(29, FMT_D),
8298 OPC_RECIP1_D = FOP(29, FMT_D),
8299 OPC_MAX_D = FOP(30, FMT_D),
8300 OPC_RSQRT1_D = FOP(30, FMT_D),
8301 OPC_MAXA_D = FOP(31, FMT_D),
8302 OPC_RSQRT2_D = FOP(31, FMT_D),
8303 OPC_CVT_S_D = FOP(32, FMT_D),
8304 OPC_CVT_W_D = FOP(36, FMT_D),
8305 OPC_CVT_L_D = FOP(37, FMT_D),
8306 OPC_CMP_F_D = FOP (48, FMT_D),
8307 OPC_CMP_UN_D = FOP (49, FMT_D),
8308 OPC_CMP_EQ_D = FOP (50, FMT_D),
8309 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8310 OPC_CMP_OLT_D = FOP (52, FMT_D),
8311 OPC_CMP_ULT_D = FOP (53, FMT_D),
8312 OPC_CMP_OLE_D = FOP (54, FMT_D),
8313 OPC_CMP_ULE_D = FOP (55, FMT_D),
8314 OPC_CMP_SF_D = FOP (56, FMT_D),
8315 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8316 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8317 OPC_CMP_NGL_D = FOP (59, FMT_D),
8318 OPC_CMP_LT_D = FOP (60, FMT_D),
8319 OPC_CMP_NGE_D = FOP (61, FMT_D),
8320 OPC_CMP_LE_D = FOP (62, FMT_D),
8321 OPC_CMP_NGT_D = FOP (63, FMT_D),
8323 OPC_CVT_S_W = FOP(32, FMT_W),
8324 OPC_CVT_D_W = FOP(33, FMT_W),
8325 OPC_CVT_S_L = FOP(32, FMT_L),
8326 OPC_CVT_D_L = FOP(33, FMT_L),
8327 OPC_CVT_PS_PW = FOP(38, FMT_W),
8329 OPC_ADD_PS = FOP(0, FMT_PS),
8330 OPC_SUB_PS = FOP(1, FMT_PS),
8331 OPC_MUL_PS = FOP(2, FMT_PS),
8332 OPC_DIV_PS = FOP(3, FMT_PS),
8333 OPC_ABS_PS = FOP(5, FMT_PS),
8334 OPC_MOV_PS = FOP(6, FMT_PS),
8335 OPC_NEG_PS = FOP(7, FMT_PS),
8336 OPC_MOVCF_PS = FOP(17, FMT_PS),
8337 OPC_MOVZ_PS = FOP(18, FMT_PS),
8338 OPC_MOVN_PS = FOP(19, FMT_PS),
8339 OPC_ADDR_PS = FOP(24, FMT_PS),
8340 OPC_MULR_PS = FOP(26, FMT_PS),
8341 OPC_RECIP2_PS = FOP(28, FMT_PS),
8342 OPC_RECIP1_PS = FOP(29, FMT_PS),
8343 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8344 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8346 OPC_CVT_S_PU = FOP(32, FMT_PS),
8347 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8348 OPC_CVT_S_PL = FOP(40, FMT_PS),
8349 OPC_PLL_PS = FOP(44, FMT_PS),
8350 OPC_PLU_PS = FOP(45, FMT_PS),
8351 OPC_PUL_PS = FOP(46, FMT_PS),
8352 OPC_PUU_PS = FOP(47, FMT_PS),
8353 OPC_CMP_F_PS = FOP (48, FMT_PS),
8354 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8355 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8356 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8357 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8358 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8359 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8360 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8361 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8362 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8363 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8364 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8365 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8366 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8367 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8368 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8372 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8373 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8374 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8375 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8376 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8377 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8378 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8379 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8380 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8381 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8382 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8383 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8384 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8385 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8386 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8387 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8388 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8389 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8390 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8391 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8392 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8393 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8395 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8396 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8397 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8398 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8399 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8400 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8401 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8402 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8403 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8404 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8405 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8406 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8407 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8408 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8409 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8410 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8411 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8412 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8413 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8414 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8415 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8416 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8418 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8420 TCGv t0 = tcg_temp_new();
8425 TCGv_i32 fp0 = tcg_temp_new_i32();
8427 gen_load_fpr32(ctx, fp0, fs);
8428 tcg_gen_ext_i32_tl(t0, fp0);
8429 tcg_temp_free_i32(fp0);
8431 gen_store_gpr(t0, rt);
8434 gen_load_gpr(t0, rt);
8436 TCGv_i32 fp0 = tcg_temp_new_i32();
8438 tcg_gen_trunc_tl_i32(fp0, t0);
8439 gen_store_fpr32(ctx, fp0, fs);
8440 tcg_temp_free_i32(fp0);
8444 gen_helper_1e0i(cfc1, t0, fs);
8445 gen_store_gpr(t0, rt);
8448 gen_load_gpr(t0, rt);
8449 save_cpu_state(ctx, 0);
8451 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8453 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8454 tcg_temp_free_i32(fs_tmp);
8456 /* Stop translation as we may have changed hflags */
8457 ctx->bstate = BS_STOP;
8459 #if defined(TARGET_MIPS64)
8461 gen_load_fpr64(ctx, t0, fs);
8462 gen_store_gpr(t0, rt);
8465 gen_load_gpr(t0, rt);
8466 gen_store_fpr64(ctx, t0, fs);
8471 TCGv_i32 fp0 = tcg_temp_new_i32();
8473 gen_load_fpr32h(ctx, fp0, fs);
8474 tcg_gen_ext_i32_tl(t0, fp0);
8475 tcg_temp_free_i32(fp0);
8477 gen_store_gpr(t0, rt);
8480 gen_load_gpr(t0, rt);
8482 TCGv_i32 fp0 = tcg_temp_new_i32();
8484 tcg_gen_trunc_tl_i32(fp0, t0);
8485 gen_store_fpr32h(ctx, fp0, fs);
8486 tcg_temp_free_i32(fp0);
8490 MIPS_INVAL("cp1 move");
8491 generate_exception_end(ctx, EXCP_RI);
8499 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8515 l1 = gen_new_label();
8516 t0 = tcg_temp_new_i32();
8517 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8518 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8519 tcg_temp_free_i32(t0);
8521 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8523 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8528 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8532 TCGv_i32 t0 = tcg_temp_new_i32();
8533 TCGLabel *l1 = gen_new_label();
8540 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8541 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8542 gen_load_fpr32(ctx, t0, fs);
8543 gen_store_fpr32(ctx, t0, fd);
8545 tcg_temp_free_i32(t0);
8548 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8551 TCGv_i32 t0 = tcg_temp_new_i32();
8553 TCGLabel *l1 = gen_new_label();
8560 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8561 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8562 tcg_temp_free_i32(t0);
8563 fp0 = tcg_temp_new_i64();
8564 gen_load_fpr64(ctx, fp0, fs);
8565 gen_store_fpr64(ctx, fp0, fd);
8566 tcg_temp_free_i64(fp0);
8570 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8574 TCGv_i32 t0 = tcg_temp_new_i32();
8575 TCGLabel *l1 = gen_new_label();
8576 TCGLabel *l2 = gen_new_label();
8583 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8584 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8585 gen_load_fpr32(ctx, t0, fs);
8586 gen_store_fpr32(ctx, t0, fd);
8589 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8590 tcg_gen_brcondi_i32(cond, t0, 0, l2);
8591 gen_load_fpr32h(ctx, t0, fs);
8592 gen_store_fpr32h(ctx, t0, fd);
8593 tcg_temp_free_i32(t0);
8597 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8600 TCGv_i32 t1 = tcg_const_i32(0);
8601 TCGv_i32 fp0 = tcg_temp_new_i32();
8602 TCGv_i32 fp1 = tcg_temp_new_i32();
8603 TCGv_i32 fp2 = tcg_temp_new_i32();
8604 gen_load_fpr32(ctx, fp0, fd);
8605 gen_load_fpr32(ctx, fp1, ft);
8606 gen_load_fpr32(ctx, fp2, fs);
8610 tcg_gen_andi_i32(fp0, fp0, 1);
8611 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8614 tcg_gen_andi_i32(fp1, fp1, 1);
8615 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8618 tcg_gen_andi_i32(fp1, fp1, 1);
8619 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8622 MIPS_INVAL("gen_sel_s");
8623 generate_exception_end(ctx, EXCP_RI);
8627 gen_store_fpr32(ctx, fp0, fd);
8628 tcg_temp_free_i32(fp2);
8629 tcg_temp_free_i32(fp1);
8630 tcg_temp_free_i32(fp0);
8631 tcg_temp_free_i32(t1);
8634 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8637 TCGv_i64 t1 = tcg_const_i64(0);
8638 TCGv_i64 fp0 = tcg_temp_new_i64();
8639 TCGv_i64 fp1 = tcg_temp_new_i64();
8640 TCGv_i64 fp2 = tcg_temp_new_i64();
8641 gen_load_fpr64(ctx, fp0, fd);
8642 gen_load_fpr64(ctx, fp1, ft);
8643 gen_load_fpr64(ctx, fp2, fs);
8647 tcg_gen_andi_i64(fp0, fp0, 1);
8648 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8651 tcg_gen_andi_i64(fp1, fp1, 1);
8652 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8655 tcg_gen_andi_i64(fp1, fp1, 1);
8656 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8659 MIPS_INVAL("gen_sel_d");
8660 generate_exception_end(ctx, EXCP_RI);
8664 gen_store_fpr64(ctx, fp0, fd);
8665 tcg_temp_free_i64(fp2);
8666 tcg_temp_free_i64(fp1);
8667 tcg_temp_free_i64(fp0);
8668 tcg_temp_free_i64(t1);
8671 static void gen_farith (DisasContext *ctx, enum fopcode op1,
8672 int ft, int fs, int fd, int cc)
8674 uint32_t func = ctx->opcode & 0x3f;
8678 TCGv_i32 fp0 = tcg_temp_new_i32();
8679 TCGv_i32 fp1 = tcg_temp_new_i32();
8681 gen_load_fpr32(ctx, fp0, fs);
8682 gen_load_fpr32(ctx, fp1, ft);
8683 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8684 tcg_temp_free_i32(fp1);
8685 gen_store_fpr32(ctx, fp0, fd);
8686 tcg_temp_free_i32(fp0);
8691 TCGv_i32 fp0 = tcg_temp_new_i32();
8692 TCGv_i32 fp1 = tcg_temp_new_i32();
8694 gen_load_fpr32(ctx, fp0, fs);
8695 gen_load_fpr32(ctx, fp1, ft);
8696 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8697 tcg_temp_free_i32(fp1);
8698 gen_store_fpr32(ctx, fp0, fd);
8699 tcg_temp_free_i32(fp0);
8704 TCGv_i32 fp0 = tcg_temp_new_i32();
8705 TCGv_i32 fp1 = tcg_temp_new_i32();
8707 gen_load_fpr32(ctx, fp0, fs);
8708 gen_load_fpr32(ctx, fp1, ft);
8709 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8710 tcg_temp_free_i32(fp1);
8711 gen_store_fpr32(ctx, fp0, fd);
8712 tcg_temp_free_i32(fp0);
8717 TCGv_i32 fp0 = tcg_temp_new_i32();
8718 TCGv_i32 fp1 = tcg_temp_new_i32();
8720 gen_load_fpr32(ctx, fp0, fs);
8721 gen_load_fpr32(ctx, fp1, ft);
8722 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8723 tcg_temp_free_i32(fp1);
8724 gen_store_fpr32(ctx, fp0, fd);
8725 tcg_temp_free_i32(fp0);
8730 TCGv_i32 fp0 = tcg_temp_new_i32();
8732 gen_load_fpr32(ctx, fp0, fs);
8733 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8734 gen_store_fpr32(ctx, fp0, fd);
8735 tcg_temp_free_i32(fp0);
8740 TCGv_i32 fp0 = tcg_temp_new_i32();
8742 gen_load_fpr32(ctx, fp0, fs);
8743 gen_helper_float_abs_s(fp0, fp0);
8744 gen_store_fpr32(ctx, fp0, fd);
8745 tcg_temp_free_i32(fp0);
8750 TCGv_i32 fp0 = tcg_temp_new_i32();
8752 gen_load_fpr32(ctx, fp0, fs);
8753 gen_store_fpr32(ctx, fp0, fd);
8754 tcg_temp_free_i32(fp0);
8759 TCGv_i32 fp0 = tcg_temp_new_i32();
8761 gen_load_fpr32(ctx, fp0, fs);
8762 gen_helper_float_chs_s(fp0, fp0);
8763 gen_store_fpr32(ctx, fp0, fd);
8764 tcg_temp_free_i32(fp0);
8768 check_cp1_64bitmode(ctx);
8770 TCGv_i32 fp32 = tcg_temp_new_i32();
8771 TCGv_i64 fp64 = tcg_temp_new_i64();
8773 gen_load_fpr32(ctx, fp32, fs);
8774 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
8775 tcg_temp_free_i32(fp32);
8776 gen_store_fpr64(ctx, fp64, fd);
8777 tcg_temp_free_i64(fp64);
8781 check_cp1_64bitmode(ctx);
8783 TCGv_i32 fp32 = tcg_temp_new_i32();
8784 TCGv_i64 fp64 = tcg_temp_new_i64();
8786 gen_load_fpr32(ctx, fp32, fs);
8787 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
8788 tcg_temp_free_i32(fp32);
8789 gen_store_fpr64(ctx, fp64, fd);
8790 tcg_temp_free_i64(fp64);
8794 check_cp1_64bitmode(ctx);
8796 TCGv_i32 fp32 = tcg_temp_new_i32();
8797 TCGv_i64 fp64 = tcg_temp_new_i64();
8799 gen_load_fpr32(ctx, fp32, fs);
8800 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
8801 tcg_temp_free_i32(fp32);
8802 gen_store_fpr64(ctx, fp64, fd);
8803 tcg_temp_free_i64(fp64);
8807 check_cp1_64bitmode(ctx);
8809 TCGv_i32 fp32 = tcg_temp_new_i32();
8810 TCGv_i64 fp64 = tcg_temp_new_i64();
8812 gen_load_fpr32(ctx, fp32, fs);
8813 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
8814 tcg_temp_free_i32(fp32);
8815 gen_store_fpr64(ctx, fp64, fd);
8816 tcg_temp_free_i64(fp64);
8821 TCGv_i32 fp0 = tcg_temp_new_i32();
8823 gen_load_fpr32(ctx, fp0, fs);
8824 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
8825 gen_store_fpr32(ctx, fp0, fd);
8826 tcg_temp_free_i32(fp0);
8831 TCGv_i32 fp0 = tcg_temp_new_i32();
8833 gen_load_fpr32(ctx, fp0, fs);
8834 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
8835 gen_store_fpr32(ctx, fp0, fd);
8836 tcg_temp_free_i32(fp0);
8841 TCGv_i32 fp0 = tcg_temp_new_i32();
8843 gen_load_fpr32(ctx, fp0, fs);
8844 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
8845 gen_store_fpr32(ctx, fp0, fd);
8846 tcg_temp_free_i32(fp0);
8851 TCGv_i32 fp0 = tcg_temp_new_i32();
8853 gen_load_fpr32(ctx, fp0, fs);
8854 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
8855 gen_store_fpr32(ctx, fp0, fd);
8856 tcg_temp_free_i32(fp0);
8860 check_insn(ctx, ISA_MIPS32R6);
8861 gen_sel_s(ctx, op1, fd, ft, fs);
8864 check_insn(ctx, ISA_MIPS32R6);
8865 gen_sel_s(ctx, op1, fd, ft, fs);
8868 check_insn(ctx, ISA_MIPS32R6);
8869 gen_sel_s(ctx, op1, fd, ft, fs);
8872 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8873 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8876 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8878 TCGLabel *l1 = gen_new_label();
8882 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8884 fp0 = tcg_temp_new_i32();
8885 gen_load_fpr32(ctx, fp0, fs);
8886 gen_store_fpr32(ctx, fp0, fd);
8887 tcg_temp_free_i32(fp0);
8892 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8894 TCGLabel *l1 = gen_new_label();
8898 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8899 fp0 = tcg_temp_new_i32();
8900 gen_load_fpr32(ctx, fp0, fs);
8901 gen_store_fpr32(ctx, fp0, fd);
8902 tcg_temp_free_i32(fp0);
8909 TCGv_i32 fp0 = tcg_temp_new_i32();
8911 gen_load_fpr32(ctx, fp0, fs);
8912 gen_helper_float_recip_s(fp0, cpu_env, fp0);
8913 gen_store_fpr32(ctx, fp0, fd);
8914 tcg_temp_free_i32(fp0);
8919 TCGv_i32 fp0 = tcg_temp_new_i32();
8921 gen_load_fpr32(ctx, fp0, fs);
8922 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
8923 gen_store_fpr32(ctx, fp0, fd);
8924 tcg_temp_free_i32(fp0);
8928 check_insn(ctx, ISA_MIPS32R6);
8930 TCGv_i32 fp0 = tcg_temp_new_i32();
8931 TCGv_i32 fp1 = tcg_temp_new_i32();
8932 TCGv_i32 fp2 = tcg_temp_new_i32();
8933 gen_load_fpr32(ctx, fp0, fs);
8934 gen_load_fpr32(ctx, fp1, ft);
8935 gen_load_fpr32(ctx, fp2, fd);
8936 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
8937 gen_store_fpr32(ctx, fp2, fd);
8938 tcg_temp_free_i32(fp2);
8939 tcg_temp_free_i32(fp1);
8940 tcg_temp_free_i32(fp0);
8944 check_insn(ctx, ISA_MIPS32R6);
8946 TCGv_i32 fp0 = tcg_temp_new_i32();
8947 TCGv_i32 fp1 = tcg_temp_new_i32();
8948 TCGv_i32 fp2 = tcg_temp_new_i32();
8949 gen_load_fpr32(ctx, fp0, fs);
8950 gen_load_fpr32(ctx, fp1, ft);
8951 gen_load_fpr32(ctx, fp2, fd);
8952 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
8953 gen_store_fpr32(ctx, fp2, fd);
8954 tcg_temp_free_i32(fp2);
8955 tcg_temp_free_i32(fp1);
8956 tcg_temp_free_i32(fp0);
8960 check_insn(ctx, ISA_MIPS32R6);
8962 TCGv_i32 fp0 = tcg_temp_new_i32();
8963 gen_load_fpr32(ctx, fp0, fs);
8964 gen_helper_float_rint_s(fp0, cpu_env, fp0);
8965 gen_store_fpr32(ctx, fp0, fd);
8966 tcg_temp_free_i32(fp0);
8970 check_insn(ctx, ISA_MIPS32R6);
8972 TCGv_i32 fp0 = tcg_temp_new_i32();
8973 gen_load_fpr32(ctx, fp0, fs);
8974 gen_helper_float_class_s(fp0, fp0);
8975 gen_store_fpr32(ctx, fp0, fd);
8976 tcg_temp_free_i32(fp0);
8979 case OPC_MIN_S: /* OPC_RECIP2_S */
8980 if (ctx->insn_flags & ISA_MIPS32R6) {
8982 TCGv_i32 fp0 = tcg_temp_new_i32();
8983 TCGv_i32 fp1 = tcg_temp_new_i32();
8984 TCGv_i32 fp2 = tcg_temp_new_i32();
8985 gen_load_fpr32(ctx, fp0, fs);
8986 gen_load_fpr32(ctx, fp1, ft);
8987 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
8988 gen_store_fpr32(ctx, fp2, fd);
8989 tcg_temp_free_i32(fp2);
8990 tcg_temp_free_i32(fp1);
8991 tcg_temp_free_i32(fp0);
8994 check_cp1_64bitmode(ctx);
8996 TCGv_i32 fp0 = tcg_temp_new_i32();
8997 TCGv_i32 fp1 = tcg_temp_new_i32();
8999 gen_load_fpr32(ctx, fp0, fs);
9000 gen_load_fpr32(ctx, fp1, ft);
9001 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9002 tcg_temp_free_i32(fp1);
9003 gen_store_fpr32(ctx, fp0, fd);
9004 tcg_temp_free_i32(fp0);
9008 case OPC_MINA_S: /* OPC_RECIP1_S */
9009 if (ctx->insn_flags & ISA_MIPS32R6) {
9011 TCGv_i32 fp0 = tcg_temp_new_i32();
9012 TCGv_i32 fp1 = tcg_temp_new_i32();
9013 TCGv_i32 fp2 = tcg_temp_new_i32();
9014 gen_load_fpr32(ctx, fp0, fs);
9015 gen_load_fpr32(ctx, fp1, ft);
9016 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9017 gen_store_fpr32(ctx, fp2, fd);
9018 tcg_temp_free_i32(fp2);
9019 tcg_temp_free_i32(fp1);
9020 tcg_temp_free_i32(fp0);
9023 check_cp1_64bitmode(ctx);
9025 TCGv_i32 fp0 = tcg_temp_new_i32();
9027 gen_load_fpr32(ctx, fp0, fs);
9028 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9029 gen_store_fpr32(ctx, fp0, fd);
9030 tcg_temp_free_i32(fp0);
9034 case OPC_MAX_S: /* OPC_RSQRT1_S */
9035 if (ctx->insn_flags & ISA_MIPS32R6) {
9037 TCGv_i32 fp0 = tcg_temp_new_i32();
9038 TCGv_i32 fp1 = tcg_temp_new_i32();
9039 gen_load_fpr32(ctx, fp0, fs);
9040 gen_load_fpr32(ctx, fp1, ft);
9041 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9042 gen_store_fpr32(ctx, fp1, fd);
9043 tcg_temp_free_i32(fp1);
9044 tcg_temp_free_i32(fp0);
9047 check_cp1_64bitmode(ctx);
9049 TCGv_i32 fp0 = tcg_temp_new_i32();
9051 gen_load_fpr32(ctx, fp0, fs);
9052 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9053 gen_store_fpr32(ctx, fp0, fd);
9054 tcg_temp_free_i32(fp0);
9058 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9059 if (ctx->insn_flags & ISA_MIPS32R6) {
9061 TCGv_i32 fp0 = tcg_temp_new_i32();
9062 TCGv_i32 fp1 = tcg_temp_new_i32();
9063 gen_load_fpr32(ctx, fp0, fs);
9064 gen_load_fpr32(ctx, fp1, ft);
9065 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9066 gen_store_fpr32(ctx, fp1, fd);
9067 tcg_temp_free_i32(fp1);
9068 tcg_temp_free_i32(fp0);
9071 check_cp1_64bitmode(ctx);
9073 TCGv_i32 fp0 = tcg_temp_new_i32();
9074 TCGv_i32 fp1 = tcg_temp_new_i32();
9076 gen_load_fpr32(ctx, fp0, fs);
9077 gen_load_fpr32(ctx, fp1, ft);
9078 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9079 tcg_temp_free_i32(fp1);
9080 gen_store_fpr32(ctx, fp0, fd);
9081 tcg_temp_free_i32(fp0);
9086 check_cp1_registers(ctx, fd);
9088 TCGv_i32 fp32 = tcg_temp_new_i32();
9089 TCGv_i64 fp64 = tcg_temp_new_i64();
9091 gen_load_fpr32(ctx, fp32, fs);
9092 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9093 tcg_temp_free_i32(fp32);
9094 gen_store_fpr64(ctx, fp64, fd);
9095 tcg_temp_free_i64(fp64);
9100 TCGv_i32 fp0 = tcg_temp_new_i32();
9102 gen_load_fpr32(ctx, fp0, fs);
9103 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
9104 gen_store_fpr32(ctx, fp0, fd);
9105 tcg_temp_free_i32(fp0);
9109 check_cp1_64bitmode(ctx);
9111 TCGv_i32 fp32 = tcg_temp_new_i32();
9112 TCGv_i64 fp64 = tcg_temp_new_i64();
9114 gen_load_fpr32(ctx, fp32, fs);
9115 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
9116 tcg_temp_free_i32(fp32);
9117 gen_store_fpr64(ctx, fp64, fd);
9118 tcg_temp_free_i64(fp64);
9124 TCGv_i64 fp64 = tcg_temp_new_i64();
9125 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9126 TCGv_i32 fp32_1 = tcg_temp_new_i32();
9128 gen_load_fpr32(ctx, fp32_0, fs);
9129 gen_load_fpr32(ctx, fp32_1, ft);
9130 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9131 tcg_temp_free_i32(fp32_1);
9132 tcg_temp_free_i32(fp32_0);
9133 gen_store_fpr64(ctx, fp64, fd);
9134 tcg_temp_free_i64(fp64);
9146 case OPC_CMP_NGLE_S:
9153 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9154 if (ctx->opcode & (1 << 6)) {
9155 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9157 gen_cmp_s(ctx, func-48, ft, fs, cc);
9161 check_cp1_registers(ctx, fs | ft | fd);
9163 TCGv_i64 fp0 = tcg_temp_new_i64();
9164 TCGv_i64 fp1 = tcg_temp_new_i64();
9166 gen_load_fpr64(ctx, fp0, fs);
9167 gen_load_fpr64(ctx, fp1, ft);
9168 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9169 tcg_temp_free_i64(fp1);
9170 gen_store_fpr64(ctx, fp0, fd);
9171 tcg_temp_free_i64(fp0);
9175 check_cp1_registers(ctx, fs | ft | fd);
9177 TCGv_i64 fp0 = tcg_temp_new_i64();
9178 TCGv_i64 fp1 = tcg_temp_new_i64();
9180 gen_load_fpr64(ctx, fp0, fs);
9181 gen_load_fpr64(ctx, fp1, ft);
9182 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9183 tcg_temp_free_i64(fp1);
9184 gen_store_fpr64(ctx, fp0, fd);
9185 tcg_temp_free_i64(fp0);
9189 check_cp1_registers(ctx, fs | ft | fd);
9191 TCGv_i64 fp0 = tcg_temp_new_i64();
9192 TCGv_i64 fp1 = tcg_temp_new_i64();
9194 gen_load_fpr64(ctx, fp0, fs);
9195 gen_load_fpr64(ctx, fp1, ft);
9196 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9197 tcg_temp_free_i64(fp1);
9198 gen_store_fpr64(ctx, fp0, fd);
9199 tcg_temp_free_i64(fp0);
9203 check_cp1_registers(ctx, fs | ft | fd);
9205 TCGv_i64 fp0 = tcg_temp_new_i64();
9206 TCGv_i64 fp1 = tcg_temp_new_i64();
9208 gen_load_fpr64(ctx, fp0, fs);
9209 gen_load_fpr64(ctx, fp1, ft);
9210 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9211 tcg_temp_free_i64(fp1);
9212 gen_store_fpr64(ctx, fp0, fd);
9213 tcg_temp_free_i64(fp0);
9217 check_cp1_registers(ctx, fs | fd);
9219 TCGv_i64 fp0 = tcg_temp_new_i64();
9221 gen_load_fpr64(ctx, fp0, fs);
9222 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9223 gen_store_fpr64(ctx, fp0, fd);
9224 tcg_temp_free_i64(fp0);
9228 check_cp1_registers(ctx, fs | fd);
9230 TCGv_i64 fp0 = tcg_temp_new_i64();
9232 gen_load_fpr64(ctx, fp0, fs);
9233 gen_helper_float_abs_d(fp0, fp0);
9234 gen_store_fpr64(ctx, fp0, fd);
9235 tcg_temp_free_i64(fp0);
9239 check_cp1_registers(ctx, fs | fd);
9241 TCGv_i64 fp0 = tcg_temp_new_i64();
9243 gen_load_fpr64(ctx, fp0, fs);
9244 gen_store_fpr64(ctx, fp0, fd);
9245 tcg_temp_free_i64(fp0);
9249 check_cp1_registers(ctx, fs | fd);
9251 TCGv_i64 fp0 = tcg_temp_new_i64();
9253 gen_load_fpr64(ctx, fp0, fs);
9254 gen_helper_float_chs_d(fp0, fp0);
9255 gen_store_fpr64(ctx, fp0, fd);
9256 tcg_temp_free_i64(fp0);
9260 check_cp1_64bitmode(ctx);
9262 TCGv_i64 fp0 = tcg_temp_new_i64();
9264 gen_load_fpr64(ctx, fp0, fs);
9265 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
9266 gen_store_fpr64(ctx, fp0, fd);
9267 tcg_temp_free_i64(fp0);
9271 check_cp1_64bitmode(ctx);
9273 TCGv_i64 fp0 = tcg_temp_new_i64();
9275 gen_load_fpr64(ctx, fp0, fs);
9276 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
9277 gen_store_fpr64(ctx, fp0, fd);
9278 tcg_temp_free_i64(fp0);
9282 check_cp1_64bitmode(ctx);
9284 TCGv_i64 fp0 = tcg_temp_new_i64();
9286 gen_load_fpr64(ctx, fp0, fs);
9287 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
9288 gen_store_fpr64(ctx, fp0, fd);
9289 tcg_temp_free_i64(fp0);
9293 check_cp1_64bitmode(ctx);
9295 TCGv_i64 fp0 = tcg_temp_new_i64();
9297 gen_load_fpr64(ctx, fp0, fs);
9298 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
9299 gen_store_fpr64(ctx, fp0, fd);
9300 tcg_temp_free_i64(fp0);
9304 check_cp1_registers(ctx, fs);
9306 TCGv_i32 fp32 = tcg_temp_new_i32();
9307 TCGv_i64 fp64 = tcg_temp_new_i64();
9309 gen_load_fpr64(ctx, fp64, fs);
9310 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
9311 tcg_temp_free_i64(fp64);
9312 gen_store_fpr32(ctx, fp32, fd);
9313 tcg_temp_free_i32(fp32);
9317 check_cp1_registers(ctx, fs);
9319 TCGv_i32 fp32 = tcg_temp_new_i32();
9320 TCGv_i64 fp64 = tcg_temp_new_i64();
9322 gen_load_fpr64(ctx, fp64, fs);
9323 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
9324 tcg_temp_free_i64(fp64);
9325 gen_store_fpr32(ctx, fp32, fd);
9326 tcg_temp_free_i32(fp32);
9330 check_cp1_registers(ctx, fs);
9332 TCGv_i32 fp32 = tcg_temp_new_i32();
9333 TCGv_i64 fp64 = tcg_temp_new_i64();
9335 gen_load_fpr64(ctx, fp64, fs);
9336 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
9337 tcg_temp_free_i64(fp64);
9338 gen_store_fpr32(ctx, fp32, fd);
9339 tcg_temp_free_i32(fp32);
9343 check_cp1_registers(ctx, fs);
9345 TCGv_i32 fp32 = tcg_temp_new_i32();
9346 TCGv_i64 fp64 = tcg_temp_new_i64();
9348 gen_load_fpr64(ctx, fp64, fs);
9349 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
9350 tcg_temp_free_i64(fp64);
9351 gen_store_fpr32(ctx, fp32, fd);
9352 tcg_temp_free_i32(fp32);
9356 check_insn(ctx, ISA_MIPS32R6);
9357 gen_sel_d(ctx, op1, fd, ft, fs);
9360 check_insn(ctx, ISA_MIPS32R6);
9361 gen_sel_d(ctx, op1, fd, ft, fs);
9364 check_insn(ctx, ISA_MIPS32R6);
9365 gen_sel_d(ctx, op1, fd, ft, fs);
9368 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9369 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9372 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9374 TCGLabel *l1 = gen_new_label();
9378 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9380 fp0 = tcg_temp_new_i64();
9381 gen_load_fpr64(ctx, fp0, fs);
9382 gen_store_fpr64(ctx, fp0, fd);
9383 tcg_temp_free_i64(fp0);
9388 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9390 TCGLabel *l1 = gen_new_label();
9394 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9395 fp0 = tcg_temp_new_i64();
9396 gen_load_fpr64(ctx, fp0, fs);
9397 gen_store_fpr64(ctx, fp0, fd);
9398 tcg_temp_free_i64(fp0);
9404 check_cp1_registers(ctx, fs | fd);
9406 TCGv_i64 fp0 = tcg_temp_new_i64();
9408 gen_load_fpr64(ctx, fp0, fs);
9409 gen_helper_float_recip_d(fp0, cpu_env, fp0);
9410 gen_store_fpr64(ctx, fp0, fd);
9411 tcg_temp_free_i64(fp0);
9415 check_cp1_registers(ctx, fs | fd);
9417 TCGv_i64 fp0 = tcg_temp_new_i64();
9419 gen_load_fpr64(ctx, fp0, fs);
9420 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9421 gen_store_fpr64(ctx, fp0, fd);
9422 tcg_temp_free_i64(fp0);
9426 check_insn(ctx, ISA_MIPS32R6);
9428 TCGv_i64 fp0 = tcg_temp_new_i64();
9429 TCGv_i64 fp1 = tcg_temp_new_i64();
9430 TCGv_i64 fp2 = tcg_temp_new_i64();
9431 gen_load_fpr64(ctx, fp0, fs);
9432 gen_load_fpr64(ctx, fp1, ft);
9433 gen_load_fpr64(ctx, fp2, fd);
9434 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9435 gen_store_fpr64(ctx, fp2, fd);
9436 tcg_temp_free_i64(fp2);
9437 tcg_temp_free_i64(fp1);
9438 tcg_temp_free_i64(fp0);
9442 check_insn(ctx, ISA_MIPS32R6);
9444 TCGv_i64 fp0 = tcg_temp_new_i64();
9445 TCGv_i64 fp1 = tcg_temp_new_i64();
9446 TCGv_i64 fp2 = tcg_temp_new_i64();
9447 gen_load_fpr64(ctx, fp0, fs);
9448 gen_load_fpr64(ctx, fp1, ft);
9449 gen_load_fpr64(ctx, fp2, fd);
9450 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9451 gen_store_fpr64(ctx, fp2, fd);
9452 tcg_temp_free_i64(fp2);
9453 tcg_temp_free_i64(fp1);
9454 tcg_temp_free_i64(fp0);
9458 check_insn(ctx, ISA_MIPS32R6);
9460 TCGv_i64 fp0 = tcg_temp_new_i64();
9461 gen_load_fpr64(ctx, fp0, fs);
9462 gen_helper_float_rint_d(fp0, cpu_env, fp0);
9463 gen_store_fpr64(ctx, fp0, fd);
9464 tcg_temp_free_i64(fp0);
9468 check_insn(ctx, ISA_MIPS32R6);
9470 TCGv_i64 fp0 = tcg_temp_new_i64();
9471 gen_load_fpr64(ctx, fp0, fs);
9472 gen_helper_float_class_d(fp0, fp0);
9473 gen_store_fpr64(ctx, fp0, fd);
9474 tcg_temp_free_i64(fp0);
9477 case OPC_MIN_D: /* OPC_RECIP2_D */
9478 if (ctx->insn_flags & ISA_MIPS32R6) {
9480 TCGv_i64 fp0 = tcg_temp_new_i64();
9481 TCGv_i64 fp1 = tcg_temp_new_i64();
9482 gen_load_fpr64(ctx, fp0, fs);
9483 gen_load_fpr64(ctx, fp1, ft);
9484 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9485 gen_store_fpr64(ctx, fp1, fd);
9486 tcg_temp_free_i64(fp1);
9487 tcg_temp_free_i64(fp0);
9490 check_cp1_64bitmode(ctx);
9492 TCGv_i64 fp0 = tcg_temp_new_i64();
9493 TCGv_i64 fp1 = tcg_temp_new_i64();
9495 gen_load_fpr64(ctx, fp0, fs);
9496 gen_load_fpr64(ctx, fp1, ft);
9497 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9498 tcg_temp_free_i64(fp1);
9499 gen_store_fpr64(ctx, fp0, fd);
9500 tcg_temp_free_i64(fp0);
9504 case OPC_MINA_D: /* OPC_RECIP1_D */
9505 if (ctx->insn_flags & ISA_MIPS32R6) {
9507 TCGv_i64 fp0 = tcg_temp_new_i64();
9508 TCGv_i64 fp1 = tcg_temp_new_i64();
9509 gen_load_fpr64(ctx, fp0, fs);
9510 gen_load_fpr64(ctx, fp1, ft);
9511 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9512 gen_store_fpr64(ctx, fp1, fd);
9513 tcg_temp_free_i64(fp1);
9514 tcg_temp_free_i64(fp0);
9517 check_cp1_64bitmode(ctx);
9519 TCGv_i64 fp0 = tcg_temp_new_i64();
9521 gen_load_fpr64(ctx, fp0, fs);
9522 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9523 gen_store_fpr64(ctx, fp0, fd);
9524 tcg_temp_free_i64(fp0);
9528 case OPC_MAX_D: /* OPC_RSQRT1_D */
9529 if (ctx->insn_flags & ISA_MIPS32R6) {
9531 TCGv_i64 fp0 = tcg_temp_new_i64();
9532 TCGv_i64 fp1 = tcg_temp_new_i64();
9533 gen_load_fpr64(ctx, fp0, fs);
9534 gen_load_fpr64(ctx, fp1, ft);
9535 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9536 gen_store_fpr64(ctx, fp1, fd);
9537 tcg_temp_free_i64(fp1);
9538 tcg_temp_free_i64(fp0);
9541 check_cp1_64bitmode(ctx);
9543 TCGv_i64 fp0 = tcg_temp_new_i64();
9545 gen_load_fpr64(ctx, fp0, fs);
9546 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9547 gen_store_fpr64(ctx, fp0, fd);
9548 tcg_temp_free_i64(fp0);
9552 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9553 if (ctx->insn_flags & ISA_MIPS32R6) {
9555 TCGv_i64 fp0 = tcg_temp_new_i64();
9556 TCGv_i64 fp1 = tcg_temp_new_i64();
9557 gen_load_fpr64(ctx, fp0, fs);
9558 gen_load_fpr64(ctx, fp1, ft);
9559 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9560 gen_store_fpr64(ctx, fp1, fd);
9561 tcg_temp_free_i64(fp1);
9562 tcg_temp_free_i64(fp0);
9565 check_cp1_64bitmode(ctx);
9567 TCGv_i64 fp0 = tcg_temp_new_i64();
9568 TCGv_i64 fp1 = tcg_temp_new_i64();
9570 gen_load_fpr64(ctx, fp0, fs);
9571 gen_load_fpr64(ctx, fp1, ft);
9572 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9573 tcg_temp_free_i64(fp1);
9574 gen_store_fpr64(ctx, fp0, fd);
9575 tcg_temp_free_i64(fp0);
9588 case OPC_CMP_NGLE_D:
9595 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9596 if (ctx->opcode & (1 << 6)) {
9597 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9599 gen_cmp_d(ctx, func-48, ft, fs, cc);
9603 check_cp1_registers(ctx, fs);
9605 TCGv_i32 fp32 = tcg_temp_new_i32();
9606 TCGv_i64 fp64 = tcg_temp_new_i64();
9608 gen_load_fpr64(ctx, fp64, fs);
9609 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9610 tcg_temp_free_i64(fp64);
9611 gen_store_fpr32(ctx, fp32, fd);
9612 tcg_temp_free_i32(fp32);
9616 check_cp1_registers(ctx, fs);
9618 TCGv_i32 fp32 = tcg_temp_new_i32();
9619 TCGv_i64 fp64 = tcg_temp_new_i64();
9621 gen_load_fpr64(ctx, fp64, fs);
9622 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
9623 tcg_temp_free_i64(fp64);
9624 gen_store_fpr32(ctx, fp32, fd);
9625 tcg_temp_free_i32(fp32);
9629 check_cp1_64bitmode(ctx);
9631 TCGv_i64 fp0 = tcg_temp_new_i64();
9633 gen_load_fpr64(ctx, fp0, fs);
9634 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
9635 gen_store_fpr64(ctx, fp0, fd);
9636 tcg_temp_free_i64(fp0);
9641 TCGv_i32 fp0 = tcg_temp_new_i32();
9643 gen_load_fpr32(ctx, fp0, fs);
9644 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9645 gen_store_fpr32(ctx, fp0, fd);
9646 tcg_temp_free_i32(fp0);
9650 check_cp1_registers(ctx, fd);
9652 TCGv_i32 fp32 = tcg_temp_new_i32();
9653 TCGv_i64 fp64 = tcg_temp_new_i64();
9655 gen_load_fpr32(ctx, fp32, fs);
9656 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9657 tcg_temp_free_i32(fp32);
9658 gen_store_fpr64(ctx, fp64, fd);
9659 tcg_temp_free_i64(fp64);
9663 check_cp1_64bitmode(ctx);
9665 TCGv_i32 fp32 = tcg_temp_new_i32();
9666 TCGv_i64 fp64 = tcg_temp_new_i64();
9668 gen_load_fpr64(ctx, fp64, fs);
9669 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9670 tcg_temp_free_i64(fp64);
9671 gen_store_fpr32(ctx, fp32, fd);
9672 tcg_temp_free_i32(fp32);
9676 check_cp1_64bitmode(ctx);
9678 TCGv_i64 fp0 = tcg_temp_new_i64();
9680 gen_load_fpr64(ctx, fp0, fs);
9681 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9682 gen_store_fpr64(ctx, fp0, fd);
9683 tcg_temp_free_i64(fp0);
9689 TCGv_i64 fp0 = tcg_temp_new_i64();
9691 gen_load_fpr64(ctx, fp0, fs);
9692 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9693 gen_store_fpr64(ctx, fp0, fd);
9694 tcg_temp_free_i64(fp0);
9700 TCGv_i64 fp0 = tcg_temp_new_i64();
9701 TCGv_i64 fp1 = tcg_temp_new_i64();
9703 gen_load_fpr64(ctx, fp0, fs);
9704 gen_load_fpr64(ctx, fp1, ft);
9705 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
9706 tcg_temp_free_i64(fp1);
9707 gen_store_fpr64(ctx, fp0, fd);
9708 tcg_temp_free_i64(fp0);
9714 TCGv_i64 fp0 = tcg_temp_new_i64();
9715 TCGv_i64 fp1 = tcg_temp_new_i64();
9717 gen_load_fpr64(ctx, fp0, fs);
9718 gen_load_fpr64(ctx, fp1, ft);
9719 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9720 tcg_temp_free_i64(fp1);
9721 gen_store_fpr64(ctx, fp0, fd);
9722 tcg_temp_free_i64(fp0);
9728 TCGv_i64 fp0 = tcg_temp_new_i64();
9729 TCGv_i64 fp1 = tcg_temp_new_i64();
9731 gen_load_fpr64(ctx, fp0, fs);
9732 gen_load_fpr64(ctx, fp1, ft);
9733 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9734 tcg_temp_free_i64(fp1);
9735 gen_store_fpr64(ctx, fp0, fd);
9736 tcg_temp_free_i64(fp0);
9742 TCGv_i64 fp0 = tcg_temp_new_i64();
9744 gen_load_fpr64(ctx, fp0, fs);
9745 gen_helper_float_abs_ps(fp0, fp0);
9746 gen_store_fpr64(ctx, fp0, fd);
9747 tcg_temp_free_i64(fp0);
9753 TCGv_i64 fp0 = tcg_temp_new_i64();
9755 gen_load_fpr64(ctx, fp0, fs);
9756 gen_store_fpr64(ctx, fp0, fd);
9757 tcg_temp_free_i64(fp0);
9763 TCGv_i64 fp0 = tcg_temp_new_i64();
9765 gen_load_fpr64(ctx, fp0, fs);
9766 gen_helper_float_chs_ps(fp0, fp0);
9767 gen_store_fpr64(ctx, fp0, fd);
9768 tcg_temp_free_i64(fp0);
9773 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9778 TCGLabel *l1 = gen_new_label();
9782 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9783 fp0 = tcg_temp_new_i64();
9784 gen_load_fpr64(ctx, fp0, fs);
9785 gen_store_fpr64(ctx, fp0, fd);
9786 tcg_temp_free_i64(fp0);
9793 TCGLabel *l1 = gen_new_label();
9797 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9798 fp0 = tcg_temp_new_i64();
9799 gen_load_fpr64(ctx, fp0, fs);
9800 gen_store_fpr64(ctx, fp0, fd);
9801 tcg_temp_free_i64(fp0);
9809 TCGv_i64 fp0 = tcg_temp_new_i64();
9810 TCGv_i64 fp1 = tcg_temp_new_i64();
9812 gen_load_fpr64(ctx, fp0, ft);
9813 gen_load_fpr64(ctx, fp1, fs);
9814 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
9815 tcg_temp_free_i64(fp1);
9816 gen_store_fpr64(ctx, fp0, fd);
9817 tcg_temp_free_i64(fp0);
9823 TCGv_i64 fp0 = tcg_temp_new_i64();
9824 TCGv_i64 fp1 = tcg_temp_new_i64();
9826 gen_load_fpr64(ctx, fp0, ft);
9827 gen_load_fpr64(ctx, fp1, fs);
9828 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
9829 tcg_temp_free_i64(fp1);
9830 gen_store_fpr64(ctx, fp0, fd);
9831 tcg_temp_free_i64(fp0);
9837 TCGv_i64 fp0 = tcg_temp_new_i64();
9838 TCGv_i64 fp1 = tcg_temp_new_i64();
9840 gen_load_fpr64(ctx, fp0, fs);
9841 gen_load_fpr64(ctx, fp1, ft);
9842 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
9843 tcg_temp_free_i64(fp1);
9844 gen_store_fpr64(ctx, fp0, fd);
9845 tcg_temp_free_i64(fp0);
9851 TCGv_i64 fp0 = tcg_temp_new_i64();
9853 gen_load_fpr64(ctx, fp0, fs);
9854 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
9855 gen_store_fpr64(ctx, fp0, fd);
9856 tcg_temp_free_i64(fp0);
9862 TCGv_i64 fp0 = tcg_temp_new_i64();
9864 gen_load_fpr64(ctx, fp0, fs);
9865 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
9866 gen_store_fpr64(ctx, fp0, fd);
9867 tcg_temp_free_i64(fp0);
9873 TCGv_i64 fp0 = tcg_temp_new_i64();
9874 TCGv_i64 fp1 = tcg_temp_new_i64();
9876 gen_load_fpr64(ctx, fp0, fs);
9877 gen_load_fpr64(ctx, fp1, ft);
9878 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
9879 tcg_temp_free_i64(fp1);
9880 gen_store_fpr64(ctx, fp0, fd);
9881 tcg_temp_free_i64(fp0);
9885 check_cp1_64bitmode(ctx);
9887 TCGv_i32 fp0 = tcg_temp_new_i32();
9889 gen_load_fpr32h(ctx, fp0, fs);
9890 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
9891 gen_store_fpr32(ctx, fp0, fd);
9892 tcg_temp_free_i32(fp0);
9898 TCGv_i64 fp0 = tcg_temp_new_i64();
9900 gen_load_fpr64(ctx, fp0, fs);
9901 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
9902 gen_store_fpr64(ctx, fp0, fd);
9903 tcg_temp_free_i64(fp0);
9907 check_cp1_64bitmode(ctx);
9909 TCGv_i32 fp0 = tcg_temp_new_i32();
9911 gen_load_fpr32(ctx, fp0, fs);
9912 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
9913 gen_store_fpr32(ctx, fp0, fd);
9914 tcg_temp_free_i32(fp0);
9920 TCGv_i32 fp0 = tcg_temp_new_i32();
9921 TCGv_i32 fp1 = tcg_temp_new_i32();
9923 gen_load_fpr32(ctx, fp0, fs);
9924 gen_load_fpr32(ctx, fp1, ft);
9925 gen_store_fpr32h(ctx, fp0, fd);
9926 gen_store_fpr32(ctx, fp1, fd);
9927 tcg_temp_free_i32(fp0);
9928 tcg_temp_free_i32(fp1);
9934 TCGv_i32 fp0 = tcg_temp_new_i32();
9935 TCGv_i32 fp1 = tcg_temp_new_i32();
9937 gen_load_fpr32(ctx, fp0, fs);
9938 gen_load_fpr32h(ctx, fp1, ft);
9939 gen_store_fpr32(ctx, fp1, fd);
9940 gen_store_fpr32h(ctx, fp0, fd);
9941 tcg_temp_free_i32(fp0);
9942 tcg_temp_free_i32(fp1);
9948 TCGv_i32 fp0 = tcg_temp_new_i32();
9949 TCGv_i32 fp1 = tcg_temp_new_i32();
9951 gen_load_fpr32h(ctx, fp0, fs);
9952 gen_load_fpr32(ctx, fp1, ft);
9953 gen_store_fpr32(ctx, fp1, fd);
9954 gen_store_fpr32h(ctx, fp0, fd);
9955 tcg_temp_free_i32(fp0);
9956 tcg_temp_free_i32(fp1);
9962 TCGv_i32 fp0 = tcg_temp_new_i32();
9963 TCGv_i32 fp1 = tcg_temp_new_i32();
9965 gen_load_fpr32h(ctx, fp0, fs);
9966 gen_load_fpr32h(ctx, fp1, ft);
9967 gen_store_fpr32(ctx, fp1, fd);
9968 gen_store_fpr32h(ctx, fp0, fd);
9969 tcg_temp_free_i32(fp0);
9970 tcg_temp_free_i32(fp1);
9976 case OPC_CMP_UEQ_PS:
9977 case OPC_CMP_OLT_PS:
9978 case OPC_CMP_ULT_PS:
9979 case OPC_CMP_OLE_PS:
9980 case OPC_CMP_ULE_PS:
9982 case OPC_CMP_NGLE_PS:
9983 case OPC_CMP_SEQ_PS:
9984 case OPC_CMP_NGL_PS:
9986 case OPC_CMP_NGE_PS:
9988 case OPC_CMP_NGT_PS:
9989 if (ctx->opcode & (1 << 6)) {
9990 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
9992 gen_cmp_ps(ctx, func-48, ft, fs, cc);
9996 MIPS_INVAL("farith");
9997 generate_exception_end(ctx, EXCP_RI);
10002 /* Coprocessor 3 (FPU) */
10003 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10004 int fd, int fs, int base, int index)
10006 TCGv t0 = tcg_temp_new();
10009 gen_load_gpr(t0, index);
10010 } else if (index == 0) {
10011 gen_load_gpr(t0, base);
10013 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10015 /* Don't do NOP if destination is zero: we must perform the actual
10021 TCGv_i32 fp0 = tcg_temp_new_i32();
10023 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10024 tcg_gen_trunc_tl_i32(fp0, t0);
10025 gen_store_fpr32(ctx, fp0, fd);
10026 tcg_temp_free_i32(fp0);
10031 check_cp1_registers(ctx, fd);
10033 TCGv_i64 fp0 = tcg_temp_new_i64();
10034 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10035 gen_store_fpr64(ctx, fp0, fd);
10036 tcg_temp_free_i64(fp0);
10040 check_cp1_64bitmode(ctx);
10041 tcg_gen_andi_tl(t0, t0, ~0x7);
10043 TCGv_i64 fp0 = tcg_temp_new_i64();
10045 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10046 gen_store_fpr64(ctx, fp0, fd);
10047 tcg_temp_free_i64(fp0);
10053 TCGv_i32 fp0 = tcg_temp_new_i32();
10054 gen_load_fpr32(ctx, fp0, fs);
10055 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10056 tcg_temp_free_i32(fp0);
10061 check_cp1_registers(ctx, fs);
10063 TCGv_i64 fp0 = tcg_temp_new_i64();
10064 gen_load_fpr64(ctx, fp0, fs);
10065 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10066 tcg_temp_free_i64(fp0);
10070 check_cp1_64bitmode(ctx);
10071 tcg_gen_andi_tl(t0, t0, ~0x7);
10073 TCGv_i64 fp0 = tcg_temp_new_i64();
10074 gen_load_fpr64(ctx, fp0, fs);
10075 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10076 tcg_temp_free_i64(fp0);
10083 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10084 int fd, int fr, int fs, int ft)
10090 TCGv t0 = tcg_temp_local_new();
10091 TCGv_i32 fp = tcg_temp_new_i32();
10092 TCGv_i32 fph = tcg_temp_new_i32();
10093 TCGLabel *l1 = gen_new_label();
10094 TCGLabel *l2 = gen_new_label();
10096 gen_load_gpr(t0, fr);
10097 tcg_gen_andi_tl(t0, t0, 0x7);
10099 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10100 gen_load_fpr32(ctx, fp, fs);
10101 gen_load_fpr32h(ctx, fph, fs);
10102 gen_store_fpr32(ctx, fp, fd);
10103 gen_store_fpr32h(ctx, fph, fd);
10106 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10108 #ifdef TARGET_WORDS_BIGENDIAN
10109 gen_load_fpr32(ctx, fp, fs);
10110 gen_load_fpr32h(ctx, fph, ft);
10111 gen_store_fpr32h(ctx, fp, fd);
10112 gen_store_fpr32(ctx, fph, fd);
10114 gen_load_fpr32h(ctx, fph, fs);
10115 gen_load_fpr32(ctx, fp, ft);
10116 gen_store_fpr32(ctx, fph, fd);
10117 gen_store_fpr32h(ctx, fp, fd);
10120 tcg_temp_free_i32(fp);
10121 tcg_temp_free_i32(fph);
10127 TCGv_i32 fp0 = tcg_temp_new_i32();
10128 TCGv_i32 fp1 = tcg_temp_new_i32();
10129 TCGv_i32 fp2 = tcg_temp_new_i32();
10131 gen_load_fpr32(ctx, fp0, fs);
10132 gen_load_fpr32(ctx, fp1, ft);
10133 gen_load_fpr32(ctx, fp2, fr);
10134 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10135 tcg_temp_free_i32(fp0);
10136 tcg_temp_free_i32(fp1);
10137 gen_store_fpr32(ctx, fp2, fd);
10138 tcg_temp_free_i32(fp2);
10143 check_cp1_registers(ctx, fd | fs | ft | fr);
10145 TCGv_i64 fp0 = tcg_temp_new_i64();
10146 TCGv_i64 fp1 = tcg_temp_new_i64();
10147 TCGv_i64 fp2 = tcg_temp_new_i64();
10149 gen_load_fpr64(ctx, fp0, fs);
10150 gen_load_fpr64(ctx, fp1, ft);
10151 gen_load_fpr64(ctx, fp2, fr);
10152 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10153 tcg_temp_free_i64(fp0);
10154 tcg_temp_free_i64(fp1);
10155 gen_store_fpr64(ctx, fp2, fd);
10156 tcg_temp_free_i64(fp2);
10162 TCGv_i64 fp0 = tcg_temp_new_i64();
10163 TCGv_i64 fp1 = tcg_temp_new_i64();
10164 TCGv_i64 fp2 = tcg_temp_new_i64();
10166 gen_load_fpr64(ctx, fp0, fs);
10167 gen_load_fpr64(ctx, fp1, ft);
10168 gen_load_fpr64(ctx, fp2, fr);
10169 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10170 tcg_temp_free_i64(fp0);
10171 tcg_temp_free_i64(fp1);
10172 gen_store_fpr64(ctx, fp2, fd);
10173 tcg_temp_free_i64(fp2);
10179 TCGv_i32 fp0 = tcg_temp_new_i32();
10180 TCGv_i32 fp1 = tcg_temp_new_i32();
10181 TCGv_i32 fp2 = tcg_temp_new_i32();
10183 gen_load_fpr32(ctx, fp0, fs);
10184 gen_load_fpr32(ctx, fp1, ft);
10185 gen_load_fpr32(ctx, fp2, fr);
10186 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10187 tcg_temp_free_i32(fp0);
10188 tcg_temp_free_i32(fp1);
10189 gen_store_fpr32(ctx, fp2, fd);
10190 tcg_temp_free_i32(fp2);
10195 check_cp1_registers(ctx, fd | fs | ft | fr);
10197 TCGv_i64 fp0 = tcg_temp_new_i64();
10198 TCGv_i64 fp1 = tcg_temp_new_i64();
10199 TCGv_i64 fp2 = tcg_temp_new_i64();
10201 gen_load_fpr64(ctx, fp0, fs);
10202 gen_load_fpr64(ctx, fp1, ft);
10203 gen_load_fpr64(ctx, fp2, fr);
10204 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10205 tcg_temp_free_i64(fp0);
10206 tcg_temp_free_i64(fp1);
10207 gen_store_fpr64(ctx, fp2, fd);
10208 tcg_temp_free_i64(fp2);
10214 TCGv_i64 fp0 = tcg_temp_new_i64();
10215 TCGv_i64 fp1 = tcg_temp_new_i64();
10216 TCGv_i64 fp2 = tcg_temp_new_i64();
10218 gen_load_fpr64(ctx, fp0, fs);
10219 gen_load_fpr64(ctx, fp1, ft);
10220 gen_load_fpr64(ctx, fp2, fr);
10221 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10222 tcg_temp_free_i64(fp0);
10223 tcg_temp_free_i64(fp1);
10224 gen_store_fpr64(ctx, fp2, fd);
10225 tcg_temp_free_i64(fp2);
10231 TCGv_i32 fp0 = tcg_temp_new_i32();
10232 TCGv_i32 fp1 = tcg_temp_new_i32();
10233 TCGv_i32 fp2 = tcg_temp_new_i32();
10235 gen_load_fpr32(ctx, fp0, fs);
10236 gen_load_fpr32(ctx, fp1, ft);
10237 gen_load_fpr32(ctx, fp2, fr);
10238 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10239 tcg_temp_free_i32(fp0);
10240 tcg_temp_free_i32(fp1);
10241 gen_store_fpr32(ctx, fp2, fd);
10242 tcg_temp_free_i32(fp2);
10247 check_cp1_registers(ctx, fd | fs | ft | fr);
10249 TCGv_i64 fp0 = tcg_temp_new_i64();
10250 TCGv_i64 fp1 = tcg_temp_new_i64();
10251 TCGv_i64 fp2 = tcg_temp_new_i64();
10253 gen_load_fpr64(ctx, fp0, fs);
10254 gen_load_fpr64(ctx, fp1, ft);
10255 gen_load_fpr64(ctx, fp2, fr);
10256 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10257 tcg_temp_free_i64(fp0);
10258 tcg_temp_free_i64(fp1);
10259 gen_store_fpr64(ctx, fp2, fd);
10260 tcg_temp_free_i64(fp2);
10266 TCGv_i64 fp0 = tcg_temp_new_i64();
10267 TCGv_i64 fp1 = tcg_temp_new_i64();
10268 TCGv_i64 fp2 = tcg_temp_new_i64();
10270 gen_load_fpr64(ctx, fp0, fs);
10271 gen_load_fpr64(ctx, fp1, ft);
10272 gen_load_fpr64(ctx, fp2, fr);
10273 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10274 tcg_temp_free_i64(fp0);
10275 tcg_temp_free_i64(fp1);
10276 gen_store_fpr64(ctx, fp2, fd);
10277 tcg_temp_free_i64(fp2);
10283 TCGv_i32 fp0 = tcg_temp_new_i32();
10284 TCGv_i32 fp1 = tcg_temp_new_i32();
10285 TCGv_i32 fp2 = tcg_temp_new_i32();
10287 gen_load_fpr32(ctx, fp0, fs);
10288 gen_load_fpr32(ctx, fp1, ft);
10289 gen_load_fpr32(ctx, fp2, fr);
10290 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10291 tcg_temp_free_i32(fp0);
10292 tcg_temp_free_i32(fp1);
10293 gen_store_fpr32(ctx, fp2, fd);
10294 tcg_temp_free_i32(fp2);
10299 check_cp1_registers(ctx, fd | fs | ft | fr);
10301 TCGv_i64 fp0 = tcg_temp_new_i64();
10302 TCGv_i64 fp1 = tcg_temp_new_i64();
10303 TCGv_i64 fp2 = tcg_temp_new_i64();
10305 gen_load_fpr64(ctx, fp0, fs);
10306 gen_load_fpr64(ctx, fp1, ft);
10307 gen_load_fpr64(ctx, fp2, fr);
10308 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10309 tcg_temp_free_i64(fp0);
10310 tcg_temp_free_i64(fp1);
10311 gen_store_fpr64(ctx, fp2, fd);
10312 tcg_temp_free_i64(fp2);
10318 TCGv_i64 fp0 = tcg_temp_new_i64();
10319 TCGv_i64 fp1 = tcg_temp_new_i64();
10320 TCGv_i64 fp2 = tcg_temp_new_i64();
10322 gen_load_fpr64(ctx, fp0, fs);
10323 gen_load_fpr64(ctx, fp1, ft);
10324 gen_load_fpr64(ctx, fp2, fr);
10325 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10326 tcg_temp_free_i64(fp0);
10327 tcg_temp_free_i64(fp1);
10328 gen_store_fpr64(ctx, fp2, fd);
10329 tcg_temp_free_i64(fp2);
10333 MIPS_INVAL("flt3_arith");
10334 generate_exception_end(ctx, EXCP_RI);
10339 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
10343 #if !defined(CONFIG_USER_ONLY)
10344 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10345 Therefore only check the ISA in system mode. */
10346 check_insn(ctx, ISA_MIPS32R2);
10348 t0 = tcg_temp_new();
10352 gen_helper_rdhwr_cpunum(t0, cpu_env);
10353 gen_store_gpr(t0, rt);
10356 gen_helper_rdhwr_synci_step(t0, cpu_env);
10357 gen_store_gpr(t0, rt);
10360 gen_helper_rdhwr_cc(t0, cpu_env);
10361 gen_store_gpr(t0, rt);
10364 gen_helper_rdhwr_ccres(t0, cpu_env);
10365 gen_store_gpr(t0, rt);
10368 #if defined(CONFIG_USER_ONLY)
10369 tcg_gen_ld_tl(t0, cpu_env,
10370 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10371 gen_store_gpr(t0, rt);
10374 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10375 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10376 tcg_gen_ld_tl(t0, cpu_env,
10377 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10378 gen_store_gpr(t0, rt);
10380 generate_exception_end(ctx, EXCP_RI);
10384 default: /* Invalid */
10385 MIPS_INVAL("rdhwr");
10386 generate_exception_end(ctx, EXCP_RI);
10392 static inline void clear_branch_hflags(DisasContext *ctx)
10394 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10395 if (ctx->bstate == BS_NONE) {
10396 save_cpu_state(ctx, 0);
10398 /* it is not safe to save ctx->hflags as hflags may be changed
10399 in execution time by the instruction in delay / forbidden slot. */
10400 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10404 static void gen_branch(DisasContext *ctx, int insn_bytes)
10406 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10407 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10408 /* Branches completion */
10409 clear_branch_hflags(ctx);
10410 ctx->bstate = BS_BRANCH;
10411 /* FIXME: Need to clear can_do_io. */
10412 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10413 case MIPS_HFLAG_FBNSLOT:
10414 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10417 /* unconditional branch */
10418 if (proc_hflags & MIPS_HFLAG_BX) {
10419 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10421 gen_goto_tb(ctx, 0, ctx->btarget);
10423 case MIPS_HFLAG_BL:
10424 /* blikely taken case */
10425 gen_goto_tb(ctx, 0, ctx->btarget);
10427 case MIPS_HFLAG_BC:
10428 /* Conditional branch */
10430 TCGLabel *l1 = gen_new_label();
10432 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10433 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10435 gen_goto_tb(ctx, 0, ctx->btarget);
10438 case MIPS_HFLAG_BR:
10439 /* unconditional branch to register */
10440 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10441 TCGv t0 = tcg_temp_new();
10442 TCGv_i32 t1 = tcg_temp_new_i32();
10444 tcg_gen_andi_tl(t0, btarget, 0x1);
10445 tcg_gen_trunc_tl_i32(t1, t0);
10447 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10448 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10449 tcg_gen_or_i32(hflags, hflags, t1);
10450 tcg_temp_free_i32(t1);
10452 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10454 tcg_gen_mov_tl(cpu_PC, btarget);
10456 if (ctx->singlestep_enabled) {
10457 save_cpu_state(ctx, 0);
10458 gen_helper_raise_exception_debug(cpu_env);
10460 tcg_gen_exit_tb(0);
10463 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10469 /* Compact Branches */
10470 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10471 int rs, int rt, int32_t offset)
10473 int bcond_compute = 0;
10474 TCGv t0 = tcg_temp_new();
10475 TCGv t1 = tcg_temp_new();
10476 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10478 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10479 #ifdef MIPS_DEBUG_DISAS
10480 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10483 generate_exception_end(ctx, EXCP_RI);
10487 /* Load needed operands and calculate btarget */
10489 /* compact branch */
10490 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10491 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10492 gen_load_gpr(t0, rs);
10493 gen_load_gpr(t1, rt);
10495 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10496 if (rs <= rt && rs == 0) {
10497 /* OPC_BEQZALC, OPC_BNEZALC */
10498 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10501 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10502 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10503 gen_load_gpr(t0, rs);
10504 gen_load_gpr(t1, rt);
10506 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10508 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10509 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10510 if (rs == 0 || rs == rt) {
10511 /* OPC_BLEZALC, OPC_BGEZALC */
10512 /* OPC_BGTZALC, OPC_BLTZALC */
10513 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10515 gen_load_gpr(t0, rs);
10516 gen_load_gpr(t1, rt);
10518 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10522 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10527 /* OPC_BEQZC, OPC_BNEZC */
10528 gen_load_gpr(t0, rs);
10530 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10532 /* OPC_JIC, OPC_JIALC */
10533 TCGv tbase = tcg_temp_new();
10534 TCGv toffset = tcg_temp_new();
10536 gen_load_gpr(tbase, rt);
10537 tcg_gen_movi_tl(toffset, offset);
10538 gen_op_addr_add(ctx, btarget, tbase, toffset);
10539 tcg_temp_free(tbase);
10540 tcg_temp_free(toffset);
10544 MIPS_INVAL("Compact branch/jump");
10545 generate_exception_end(ctx, EXCP_RI);
10549 if (bcond_compute == 0) {
10550 /* Uncoditional compact branch */
10553 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10556 ctx->hflags |= MIPS_HFLAG_BR;
10559 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10562 ctx->hflags |= MIPS_HFLAG_B;
10565 MIPS_INVAL("Compact branch/jump");
10566 generate_exception_end(ctx, EXCP_RI);
10570 /* Generating branch here as compact branches don't have delay slot */
10571 gen_branch(ctx, 4);
10573 /* Conditional compact branch */
10574 TCGLabel *fs = gen_new_label();
10575 save_cpu_state(ctx, 0);
10578 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10579 if (rs == 0 && rt != 0) {
10581 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10582 } else if (rs != 0 && rt != 0 && rs == rt) {
10584 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10587 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10590 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10591 if (rs == 0 && rt != 0) {
10593 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10594 } else if (rs != 0 && rt != 0 && rs == rt) {
10596 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10599 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10602 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10603 if (rs == 0 && rt != 0) {
10605 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10606 } else if (rs != 0 && rt != 0 && rs == rt) {
10608 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10611 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10614 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10615 if (rs == 0 && rt != 0) {
10617 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10618 } else if (rs != 0 && rt != 0 && rs == rt) {
10620 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10623 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10626 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10627 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10629 /* OPC_BOVC, OPC_BNVC */
10630 TCGv t2 = tcg_temp_new();
10631 TCGv t3 = tcg_temp_new();
10632 TCGv t4 = tcg_temp_new();
10633 TCGv input_overflow = tcg_temp_new();
10635 gen_load_gpr(t0, rs);
10636 gen_load_gpr(t1, rt);
10637 tcg_gen_ext32s_tl(t2, t0);
10638 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10639 tcg_gen_ext32s_tl(t3, t1);
10640 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10641 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10643 tcg_gen_add_tl(t4, t2, t3);
10644 tcg_gen_ext32s_tl(t4, t4);
10645 tcg_gen_xor_tl(t2, t2, t3);
10646 tcg_gen_xor_tl(t3, t4, t3);
10647 tcg_gen_andc_tl(t2, t3, t2);
10648 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10649 tcg_gen_or_tl(t4, t4, input_overflow);
10650 if (opc == OPC_BOVC) {
10652 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10655 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10657 tcg_temp_free(input_overflow);
10661 } else if (rs < rt && rs == 0) {
10662 /* OPC_BEQZALC, OPC_BNEZALC */
10663 if (opc == OPC_BEQZALC) {
10665 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10668 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10671 /* OPC_BEQC, OPC_BNEC */
10672 if (opc == OPC_BEQC) {
10674 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10677 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10682 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10685 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10688 MIPS_INVAL("Compact conditional branch/jump");
10689 generate_exception_end(ctx, EXCP_RI);
10693 /* Generating branch here as compact branches don't have delay slot */
10694 gen_goto_tb(ctx, 1, ctx->btarget);
10697 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
10705 /* ISA extensions (ASEs) */
10706 /* MIPS16 extension to MIPS32 */
10708 /* MIPS16 major opcodes */
10710 M16_OPC_ADDIUSP = 0x00,
10711 M16_OPC_ADDIUPC = 0x01,
10713 M16_OPC_JAL = 0x03,
10714 M16_OPC_BEQZ = 0x04,
10715 M16_OPC_BNEQZ = 0x05,
10716 M16_OPC_SHIFT = 0x06,
10718 M16_OPC_RRIA = 0x08,
10719 M16_OPC_ADDIU8 = 0x09,
10720 M16_OPC_SLTI = 0x0a,
10721 M16_OPC_SLTIU = 0x0b,
10724 M16_OPC_CMPI = 0x0e,
10728 M16_OPC_LWSP = 0x12,
10730 M16_OPC_LBU = 0x14,
10731 M16_OPC_LHU = 0x15,
10732 M16_OPC_LWPC = 0x16,
10733 M16_OPC_LWU = 0x17,
10736 M16_OPC_SWSP = 0x1a,
10738 M16_OPC_RRR = 0x1c,
10740 M16_OPC_EXTEND = 0x1e,
10744 /* I8 funct field */
10763 /* RR funct field */
10797 /* I64 funct field */
10805 I64_DADDIUPC = 0x6,
10809 /* RR ry field for CNVT */
10811 RR_RY_CNVT_ZEB = 0x0,
10812 RR_RY_CNVT_ZEH = 0x1,
10813 RR_RY_CNVT_ZEW = 0x2,
10814 RR_RY_CNVT_SEB = 0x4,
10815 RR_RY_CNVT_SEH = 0x5,
10816 RR_RY_CNVT_SEW = 0x6,
10819 static int xlat (int r)
10821 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10826 static void gen_mips16_save (DisasContext *ctx,
10827 int xsregs, int aregs,
10828 int do_ra, int do_s0, int do_s1,
10831 TCGv t0 = tcg_temp_new();
10832 TCGv t1 = tcg_temp_new();
10833 TCGv t2 = tcg_temp_new();
10863 generate_exception_end(ctx, EXCP_RI);
10869 gen_base_offset_addr(ctx, t0, 29, 12);
10870 gen_load_gpr(t1, 7);
10871 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10874 gen_base_offset_addr(ctx, t0, 29, 8);
10875 gen_load_gpr(t1, 6);
10876 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10879 gen_base_offset_addr(ctx, t0, 29, 4);
10880 gen_load_gpr(t1, 5);
10881 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10884 gen_base_offset_addr(ctx, t0, 29, 0);
10885 gen_load_gpr(t1, 4);
10886 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10889 gen_load_gpr(t0, 29);
10891 #define DECR_AND_STORE(reg) do { \
10892 tcg_gen_movi_tl(t2, -4); \
10893 gen_op_addr_add(ctx, t0, t0, t2); \
10894 gen_load_gpr(t1, reg); \
10895 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
10899 DECR_AND_STORE(31);
10904 DECR_AND_STORE(30);
10907 DECR_AND_STORE(23);
10910 DECR_AND_STORE(22);
10913 DECR_AND_STORE(21);
10916 DECR_AND_STORE(20);
10919 DECR_AND_STORE(19);
10922 DECR_AND_STORE(18);
10926 DECR_AND_STORE(17);
10929 DECR_AND_STORE(16);
10959 generate_exception_end(ctx, EXCP_RI);
10975 #undef DECR_AND_STORE
10977 tcg_gen_movi_tl(t2, -framesize);
10978 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
10984 static void gen_mips16_restore (DisasContext *ctx,
10985 int xsregs, int aregs,
10986 int do_ra, int do_s0, int do_s1,
10990 TCGv t0 = tcg_temp_new();
10991 TCGv t1 = tcg_temp_new();
10992 TCGv t2 = tcg_temp_new();
10994 tcg_gen_movi_tl(t2, framesize);
10995 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
10997 #define DECR_AND_LOAD(reg) do { \
10998 tcg_gen_movi_tl(t2, -4); \
10999 gen_op_addr_add(ctx, t0, t0, t2); \
11000 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11001 gen_store_gpr(t1, reg); \
11065 generate_exception_end(ctx, EXCP_RI);
11081 #undef DECR_AND_LOAD
11083 tcg_gen_movi_tl(t2, framesize);
11084 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11090 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11091 int is_64_bit, int extended)
11095 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11096 generate_exception_end(ctx, EXCP_RI);
11100 t0 = tcg_temp_new();
11102 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11103 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11105 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11111 #if defined(TARGET_MIPS64)
11112 static void decode_i64_mips16 (DisasContext *ctx,
11113 int ry, int funct, int16_t offset,
11118 check_insn(ctx, ISA_MIPS3);
11119 check_mips_64(ctx);
11120 offset = extended ? offset : offset << 3;
11121 gen_ld(ctx, OPC_LD, ry, 29, offset);
11124 check_insn(ctx, ISA_MIPS3);
11125 check_mips_64(ctx);
11126 offset = extended ? offset : offset << 3;
11127 gen_st(ctx, OPC_SD, ry, 29, offset);
11130 check_insn(ctx, ISA_MIPS3);
11131 check_mips_64(ctx);
11132 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11133 gen_st(ctx, OPC_SD, 31, 29, offset);
11136 check_insn(ctx, ISA_MIPS3);
11137 check_mips_64(ctx);
11138 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11139 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11142 check_insn(ctx, ISA_MIPS3);
11143 check_mips_64(ctx);
11144 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11145 generate_exception_end(ctx, EXCP_RI);
11147 offset = extended ? offset : offset << 3;
11148 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11152 check_insn(ctx, ISA_MIPS3);
11153 check_mips_64(ctx);
11154 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11155 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11158 check_insn(ctx, ISA_MIPS3);
11159 check_mips_64(ctx);
11160 offset = extended ? offset : offset << 2;
11161 gen_addiupc(ctx, ry, offset, 1, extended);
11164 check_insn(ctx, ISA_MIPS3);
11165 check_mips_64(ctx);
11166 offset = extended ? offset : offset << 2;
11167 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11173 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11175 int extend = cpu_lduw_code(env, ctx->pc + 2);
11176 int op, rx, ry, funct, sa;
11177 int16_t imm, offset;
11179 ctx->opcode = (ctx->opcode << 16) | extend;
11180 op = (ctx->opcode >> 11) & 0x1f;
11181 sa = (ctx->opcode >> 22) & 0x1f;
11182 funct = (ctx->opcode >> 8) & 0x7;
11183 rx = xlat((ctx->opcode >> 8) & 0x7);
11184 ry = xlat((ctx->opcode >> 5) & 0x7);
11185 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11186 | ((ctx->opcode >> 21) & 0x3f) << 5
11187 | (ctx->opcode & 0x1f));
11189 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11192 case M16_OPC_ADDIUSP:
11193 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11195 case M16_OPC_ADDIUPC:
11196 gen_addiupc(ctx, rx, imm, 0, 1);
11199 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11200 /* No delay slot, so just process as a normal instruction */
11203 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11204 /* No delay slot, so just process as a normal instruction */
11206 case M16_OPC_BNEQZ:
11207 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11208 /* No delay slot, so just process as a normal instruction */
11210 case M16_OPC_SHIFT:
11211 switch (ctx->opcode & 0x3) {
11213 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11216 #if defined(TARGET_MIPS64)
11217 check_mips_64(ctx);
11218 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11220 generate_exception_end(ctx, EXCP_RI);
11224 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11227 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11231 #if defined(TARGET_MIPS64)
11233 check_insn(ctx, ISA_MIPS3);
11234 check_mips_64(ctx);
11235 gen_ld(ctx, OPC_LD, ry, rx, offset);
11239 imm = ctx->opcode & 0xf;
11240 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11241 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11242 imm = (int16_t) (imm << 1) >> 1;
11243 if ((ctx->opcode >> 4) & 0x1) {
11244 #if defined(TARGET_MIPS64)
11245 check_mips_64(ctx);
11246 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11248 generate_exception_end(ctx, EXCP_RI);
11251 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11254 case M16_OPC_ADDIU8:
11255 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11258 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11260 case M16_OPC_SLTIU:
11261 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11266 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11269 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11272 gen_st(ctx, OPC_SW, 31, 29, imm);
11275 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11278 check_insn(ctx, ISA_MIPS32);
11280 int xsregs = (ctx->opcode >> 24) & 0x7;
11281 int aregs = (ctx->opcode >> 16) & 0xf;
11282 int do_ra = (ctx->opcode >> 6) & 0x1;
11283 int do_s0 = (ctx->opcode >> 5) & 0x1;
11284 int do_s1 = (ctx->opcode >> 4) & 0x1;
11285 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11286 | (ctx->opcode & 0xf)) << 3;
11288 if (ctx->opcode & (1 << 7)) {
11289 gen_mips16_save(ctx, xsregs, aregs,
11290 do_ra, do_s0, do_s1,
11293 gen_mips16_restore(ctx, xsregs, aregs,
11294 do_ra, do_s0, do_s1,
11300 generate_exception_end(ctx, EXCP_RI);
11305 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11308 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11310 #if defined(TARGET_MIPS64)
11312 check_insn(ctx, ISA_MIPS3);
11313 check_mips_64(ctx);
11314 gen_st(ctx, OPC_SD, ry, rx, offset);
11318 gen_ld(ctx, OPC_LB, ry, rx, offset);
11321 gen_ld(ctx, OPC_LH, ry, rx, offset);
11324 gen_ld(ctx, OPC_LW, rx, 29, offset);
11327 gen_ld(ctx, OPC_LW, ry, rx, offset);
11330 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11333 gen_ld(ctx, OPC_LHU, ry, rx, offset);
11336 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11338 #if defined(TARGET_MIPS64)
11340 check_insn(ctx, ISA_MIPS3);
11341 check_mips_64(ctx);
11342 gen_ld(ctx, OPC_LWU, ry, rx, offset);
11346 gen_st(ctx, OPC_SB, ry, rx, offset);
11349 gen_st(ctx, OPC_SH, ry, rx, offset);
11352 gen_st(ctx, OPC_SW, rx, 29, offset);
11355 gen_st(ctx, OPC_SW, ry, rx, offset);
11357 #if defined(TARGET_MIPS64)
11359 decode_i64_mips16(ctx, ry, funct, offset, 1);
11363 generate_exception_end(ctx, EXCP_RI);
11370 static inline bool is_uhi(int sdbbp_code)
11372 #ifdef CONFIG_USER_ONLY
11375 return semihosting_enabled() && sdbbp_code == 1;
11379 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11383 int op, cnvt_op, op1, offset;
11387 op = (ctx->opcode >> 11) & 0x1f;
11388 sa = (ctx->opcode >> 2) & 0x7;
11389 sa = sa == 0 ? 8 : sa;
11390 rx = xlat((ctx->opcode >> 8) & 0x7);
11391 cnvt_op = (ctx->opcode >> 5) & 0x7;
11392 ry = xlat((ctx->opcode >> 5) & 0x7);
11393 op1 = offset = ctx->opcode & 0x1f;
11398 case M16_OPC_ADDIUSP:
11400 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11402 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11405 case M16_OPC_ADDIUPC:
11406 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11409 offset = (ctx->opcode & 0x7ff) << 1;
11410 offset = (int16_t)(offset << 4) >> 4;
11411 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11412 /* No delay slot, so just process as a normal instruction */
11415 offset = cpu_lduw_code(env, ctx->pc + 2);
11416 offset = (((ctx->opcode & 0x1f) << 21)
11417 | ((ctx->opcode >> 5) & 0x1f) << 16
11419 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11420 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11424 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11425 ((int8_t)ctx->opcode) << 1, 0);
11426 /* No delay slot, so just process as a normal instruction */
11428 case M16_OPC_BNEQZ:
11429 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11430 ((int8_t)ctx->opcode) << 1, 0);
11431 /* No delay slot, so just process as a normal instruction */
11433 case M16_OPC_SHIFT:
11434 switch (ctx->opcode & 0x3) {
11436 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11439 #if defined(TARGET_MIPS64)
11440 check_insn(ctx, ISA_MIPS3);
11441 check_mips_64(ctx);
11442 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11444 generate_exception_end(ctx, EXCP_RI);
11448 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11451 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11455 #if defined(TARGET_MIPS64)
11457 check_insn(ctx, ISA_MIPS3);
11458 check_mips_64(ctx);
11459 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11464 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11466 if ((ctx->opcode >> 4) & 1) {
11467 #if defined(TARGET_MIPS64)
11468 check_insn(ctx, ISA_MIPS3);
11469 check_mips_64(ctx);
11470 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11472 generate_exception_end(ctx, EXCP_RI);
11475 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11479 case M16_OPC_ADDIU8:
11481 int16_t imm = (int8_t) ctx->opcode;
11483 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11488 int16_t imm = (uint8_t) ctx->opcode;
11489 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11492 case M16_OPC_SLTIU:
11494 int16_t imm = (uint8_t) ctx->opcode;
11495 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11502 funct = (ctx->opcode >> 8) & 0x7;
11505 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11506 ((int8_t)ctx->opcode) << 1, 0);
11509 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11510 ((int8_t)ctx->opcode) << 1, 0);
11513 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11516 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11517 ((int8_t)ctx->opcode) << 3);
11520 check_insn(ctx, ISA_MIPS32);
11522 int do_ra = ctx->opcode & (1 << 6);
11523 int do_s0 = ctx->opcode & (1 << 5);
11524 int do_s1 = ctx->opcode & (1 << 4);
11525 int framesize = ctx->opcode & 0xf;
11527 if (framesize == 0) {
11530 framesize = framesize << 3;
11533 if (ctx->opcode & (1 << 7)) {
11534 gen_mips16_save(ctx, 0, 0,
11535 do_ra, do_s0, do_s1, framesize);
11537 gen_mips16_restore(ctx, 0, 0,
11538 do_ra, do_s0, do_s1, framesize);
11544 int rz = xlat(ctx->opcode & 0x7);
11546 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11547 ((ctx->opcode >> 5) & 0x7);
11548 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11552 reg32 = ctx->opcode & 0x1f;
11553 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11556 generate_exception_end(ctx, EXCP_RI);
11563 int16_t imm = (uint8_t) ctx->opcode;
11565 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11570 int16_t imm = (uint8_t) ctx->opcode;
11571 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11574 #if defined(TARGET_MIPS64)
11576 check_insn(ctx, ISA_MIPS3);
11577 check_mips_64(ctx);
11578 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11582 gen_ld(ctx, OPC_LB, ry, rx, offset);
11585 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11588 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11591 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11594 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11597 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11600 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11602 #if defined (TARGET_MIPS64)
11604 check_insn(ctx, ISA_MIPS3);
11605 check_mips_64(ctx);
11606 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11610 gen_st(ctx, OPC_SB, ry, rx, offset);
11613 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11616 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11619 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11623 int rz = xlat((ctx->opcode >> 2) & 0x7);
11626 switch (ctx->opcode & 0x3) {
11628 mips32_op = OPC_ADDU;
11631 mips32_op = OPC_SUBU;
11633 #if defined(TARGET_MIPS64)
11635 mips32_op = OPC_DADDU;
11636 check_insn(ctx, ISA_MIPS3);
11637 check_mips_64(ctx);
11640 mips32_op = OPC_DSUBU;
11641 check_insn(ctx, ISA_MIPS3);
11642 check_mips_64(ctx);
11646 generate_exception_end(ctx, EXCP_RI);
11650 gen_arith(ctx, mips32_op, rz, rx, ry);
11659 int nd = (ctx->opcode >> 7) & 0x1;
11660 int link = (ctx->opcode >> 6) & 0x1;
11661 int ra = (ctx->opcode >> 5) & 0x1;
11664 check_insn(ctx, ISA_MIPS32);
11673 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11678 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11679 gen_helper_do_semihosting(cpu_env);
11681 /* XXX: not clear which exception should be raised
11682 * when in debug mode...
11684 check_insn(ctx, ISA_MIPS32);
11685 generate_exception_end(ctx, EXCP_DBp);
11689 gen_slt(ctx, OPC_SLT, 24, rx, ry);
11692 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11695 generate_exception_end(ctx, EXCP_BREAK);
11698 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11701 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11704 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11706 #if defined (TARGET_MIPS64)
11708 check_insn(ctx, ISA_MIPS3);
11709 check_mips_64(ctx);
11710 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11714 gen_logic(ctx, OPC_XOR, 24, rx, ry);
11717 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11720 gen_logic(ctx, OPC_AND, rx, rx, ry);
11723 gen_logic(ctx, OPC_OR, rx, rx, ry);
11726 gen_logic(ctx, OPC_XOR, rx, rx, ry);
11729 gen_logic(ctx, OPC_NOR, rx, ry, 0);
11732 gen_HILO(ctx, OPC_MFHI, 0, rx);
11735 check_insn(ctx, ISA_MIPS32);
11737 case RR_RY_CNVT_ZEB:
11738 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11740 case RR_RY_CNVT_ZEH:
11741 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11743 case RR_RY_CNVT_SEB:
11744 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11746 case RR_RY_CNVT_SEH:
11747 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11749 #if defined (TARGET_MIPS64)
11750 case RR_RY_CNVT_ZEW:
11751 check_insn(ctx, ISA_MIPS64);
11752 check_mips_64(ctx);
11753 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11755 case RR_RY_CNVT_SEW:
11756 check_insn(ctx, ISA_MIPS64);
11757 check_mips_64(ctx);
11758 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11762 generate_exception_end(ctx, EXCP_RI);
11767 gen_HILO(ctx, OPC_MFLO, 0, rx);
11769 #if defined (TARGET_MIPS64)
11771 check_insn(ctx, ISA_MIPS3);
11772 check_mips_64(ctx);
11773 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
11776 check_insn(ctx, ISA_MIPS3);
11777 check_mips_64(ctx);
11778 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
11781 check_insn(ctx, ISA_MIPS3);
11782 check_mips_64(ctx);
11783 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
11786 check_insn(ctx, ISA_MIPS3);
11787 check_mips_64(ctx);
11788 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
11792 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
11795 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
11798 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
11801 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
11803 #if defined (TARGET_MIPS64)
11805 check_insn(ctx, ISA_MIPS3);
11806 check_mips_64(ctx);
11807 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
11810 check_insn(ctx, ISA_MIPS3);
11811 check_mips_64(ctx);
11812 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
11815 check_insn(ctx, ISA_MIPS3);
11816 check_mips_64(ctx);
11817 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
11820 check_insn(ctx, ISA_MIPS3);
11821 check_mips_64(ctx);
11822 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
11826 generate_exception_end(ctx, EXCP_RI);
11830 case M16_OPC_EXTEND:
11831 decode_extended_mips16_opc(env, ctx);
11834 #if defined(TARGET_MIPS64)
11836 funct = (ctx->opcode >> 8) & 0x7;
11837 decode_i64_mips16(ctx, ry, funct, offset, 0);
11841 generate_exception_end(ctx, EXCP_RI);
11848 /* microMIPS extension to MIPS32/MIPS64 */
11851 * microMIPS32/microMIPS64 major opcodes
11853 * 1. MIPS Architecture for Programmers Volume II-B:
11854 * The microMIPS32 Instruction Set (Revision 3.05)
11856 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11858 * 2. MIPS Architecture For Programmers Volume II-A:
11859 * The MIPS64 Instruction Set (Revision 3.51)
11889 POOL32S = 0x16, /* MIPS64 */
11890 DADDIU32 = 0x17, /* MIPS64 */
11919 /* 0x29 is reserved */
11932 /* 0x31 is reserved */
11945 SD32 = 0x36, /* MIPS64 */
11946 LD32 = 0x37, /* MIPS64 */
11948 /* 0x39 is reserved */
11964 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
11974 /* POOL32A encoding of minor opcode field */
11977 /* These opcodes are distinguished only by bits 9..6; those bits are
11978 * what are recorded below. */
12014 /* The following can be distinguished by their lower 6 bits. */
12022 /* POOL32AXF encoding of minor opcode field extension */
12025 * 1. MIPS Architecture for Programmers Volume II-B:
12026 * The microMIPS32 Instruction Set (Revision 3.05)
12028 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12030 * 2. MIPS Architecture for Programmers VolumeIV-e:
12031 * The MIPS DSP Application-Specific Extension
12032 * to the microMIPS32 Architecture (Revision 2.34)
12034 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12049 /* begin of microMIPS32 DSP */
12051 /* bits 13..12 for 0x01 */
12057 /* bits 13..12 for 0x2a */
12063 /* bits 13..12 for 0x32 */
12067 /* end of microMIPS32 DSP */
12069 /* bits 15..12 for 0x2c */
12086 /* bits 15..12 for 0x34 */
12094 /* bits 15..12 for 0x3c */
12096 JR = 0x0, /* alias */
12104 /* bits 15..12 for 0x05 */
12108 /* bits 15..12 for 0x0d */
12120 /* bits 15..12 for 0x15 */
12126 /* bits 15..12 for 0x1d */
12130 /* bits 15..12 for 0x2d */
12135 /* bits 15..12 for 0x35 */
12142 /* POOL32B encoding of minor opcode field (bits 15..12) */
12158 /* POOL32C encoding of minor opcode field (bits 15..12) */
12166 /* 0xa is reserved */
12173 /* 0x6 is reserved */
12179 /* POOL32F encoding of minor opcode field (bits 5..0) */
12182 /* These are the bit 7..6 values */
12191 /* These are the bit 8..6 values */
12216 MOVZ_FMT_05 = 0x05,
12250 CABS_COND_FMT = 0x1c, /* MIPS3D */
12257 /* POOL32Fxf encoding of minor opcode extension field */
12295 /* POOL32I encoding of minor opcode field (bits 25..21) */
12325 /* These overlap and are distinguished by bit16 of the instruction */
12334 /* POOL16A encoding of minor opcode field */
12341 /* POOL16B encoding of minor opcode field */
12348 /* POOL16C encoding of minor opcode field */
12368 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12388 /* POOL16D encoding of minor opcode field */
12395 /* POOL16E encoding of minor opcode field */
12402 static int mmreg (int r)
12404 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12409 /* Used for 16-bit store instructions. */
12410 static int mmreg2 (int r)
12412 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12417 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12418 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12419 #define uMIPS_RS2(op) uMIPS_RS(op)
12420 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12421 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12422 #define uMIPS_RS5(op) (op & 0x1f)
12424 /* Signed immediate */
12425 #define SIMM(op, start, width) \
12426 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12429 /* Zero-extended immediate */
12430 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12432 static void gen_addiur1sp(DisasContext *ctx)
12434 int rd = mmreg(uMIPS_RD(ctx->opcode));
12436 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12439 static void gen_addiur2(DisasContext *ctx)
12441 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12442 int rd = mmreg(uMIPS_RD(ctx->opcode));
12443 int rs = mmreg(uMIPS_RS(ctx->opcode));
12445 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12448 static void gen_addiusp(DisasContext *ctx)
12450 int encoded = ZIMM(ctx->opcode, 1, 9);
12453 if (encoded <= 1) {
12454 decoded = 256 + encoded;
12455 } else if (encoded <= 255) {
12457 } else if (encoded <= 509) {
12458 decoded = encoded - 512;
12460 decoded = encoded - 768;
12463 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12466 static void gen_addius5(DisasContext *ctx)
12468 int imm = SIMM(ctx->opcode, 1, 4);
12469 int rd = (ctx->opcode >> 5) & 0x1f;
12471 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12474 static void gen_andi16(DisasContext *ctx)
12476 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12477 31, 32, 63, 64, 255, 32768, 65535 };
12478 int rd = mmreg(uMIPS_RD(ctx->opcode));
12479 int rs = mmreg(uMIPS_RS(ctx->opcode));
12480 int encoded = ZIMM(ctx->opcode, 0, 4);
12482 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12485 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12486 int base, int16_t offset)
12491 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12492 generate_exception_end(ctx, EXCP_RI);
12496 t0 = tcg_temp_new();
12498 gen_base_offset_addr(ctx, t0, base, offset);
12500 t1 = tcg_const_tl(reglist);
12501 t2 = tcg_const_i32(ctx->mem_idx);
12503 save_cpu_state(ctx, 1);
12506 gen_helper_lwm(cpu_env, t0, t1, t2);
12509 gen_helper_swm(cpu_env, t0, t1, t2);
12511 #ifdef TARGET_MIPS64
12513 gen_helper_ldm(cpu_env, t0, t1, t2);
12516 gen_helper_sdm(cpu_env, t0, t1, t2);
12522 tcg_temp_free_i32(t2);
12526 static void gen_pool16c_insn(DisasContext *ctx)
12528 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12529 int rs = mmreg(ctx->opcode & 0x7);
12531 switch (((ctx->opcode) >> 4) & 0x3f) {
12536 gen_logic(ctx, OPC_NOR, rd, rs, 0);
12542 gen_logic(ctx, OPC_XOR, rd, rd, rs);
12548 gen_logic(ctx, OPC_AND, rd, rd, rs);
12554 gen_logic(ctx, OPC_OR, rd, rd, rs);
12561 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12562 int offset = ZIMM(ctx->opcode, 0, 4);
12564 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12573 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12574 int offset = ZIMM(ctx->opcode, 0, 4);
12576 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12583 int reg = ctx->opcode & 0x1f;
12585 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12591 int reg = ctx->opcode & 0x1f;
12592 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12593 /* Let normal delay slot handling in our caller take us
12594 to the branch target. */
12599 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12600 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12604 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12605 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12609 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12613 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12616 generate_exception_end(ctx, EXCP_BREAK);
12619 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12620 gen_helper_do_semihosting(cpu_env);
12622 /* XXX: not clear which exception should be raised
12623 * when in debug mode...
12625 check_insn(ctx, ISA_MIPS32);
12626 generate_exception_end(ctx, EXCP_DBp);
12629 case JRADDIUSP + 0:
12630 case JRADDIUSP + 1:
12632 int imm = ZIMM(ctx->opcode, 0, 5);
12633 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12634 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12635 /* Let normal delay slot handling in our caller take us
12636 to the branch target. */
12640 generate_exception_end(ctx, EXCP_RI);
12645 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12648 int rd, rs, re, rt;
12649 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12650 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12651 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12652 rd = rd_enc[enc_dest];
12653 re = re_enc[enc_dest];
12654 rs = rs_rt_enc[enc_rs];
12655 rt = rs_rt_enc[enc_rt];
12657 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12659 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12662 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12664 tcg_gen_movi_tl(cpu_gpr[re], 0);
12668 static void gen_pool16c_r6_insn(DisasContext *ctx)
12670 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12671 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12673 switch (ctx->opcode & 0xf) {
12675 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12678 gen_logic(ctx, OPC_AND, rt, rt, rs);
12682 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12683 int offset = extract32(ctx->opcode, 4, 4);
12684 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12687 case R6_JRC16: /* JRCADDIUSP */
12688 if ((ctx->opcode >> 4) & 1) {
12690 int imm = extract32(ctx->opcode, 5, 5);
12691 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12692 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12695 int rs = extract32(ctx->opcode, 5, 5);
12696 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12699 case MOVEP ... MOVEP_07:
12700 case MOVEP_0C ... MOVEP_0F:
12702 int enc_dest = uMIPS_RD(ctx->opcode);
12703 int enc_rt = uMIPS_RS2(ctx->opcode);
12704 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12705 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12709 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12712 gen_logic(ctx, OPC_OR, rt, rt, rs);
12716 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12717 int offset = extract32(ctx->opcode, 4, 4);
12718 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12721 case JALRC16: /* BREAK16, SDBBP16 */
12722 switch (ctx->opcode & 0x3f) {
12724 case JALRC16 + 0x20:
12726 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
12731 generate_exception(ctx, EXCP_BREAK);
12735 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
12736 gen_helper_do_semihosting(cpu_env);
12738 if (ctx->hflags & MIPS_HFLAG_SBRI) {
12739 generate_exception(ctx, EXCP_RI);
12741 generate_exception(ctx, EXCP_DBp);
12748 generate_exception(ctx, EXCP_RI);
12753 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12755 TCGv t0 = tcg_temp_new();
12756 TCGv t1 = tcg_temp_new();
12758 gen_load_gpr(t0, base);
12761 gen_load_gpr(t1, index);
12762 tcg_gen_shli_tl(t1, t1, 2);
12763 gen_op_addr_add(ctx, t0, t1, t0);
12766 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12767 gen_store_gpr(t1, rd);
12773 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12774 int base, int16_t offset)
12778 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
12779 generate_exception_end(ctx, EXCP_RI);
12783 t0 = tcg_temp_new();
12784 t1 = tcg_temp_new();
12786 gen_base_offset_addr(ctx, t0, base, offset);
12791 generate_exception_end(ctx, EXCP_RI);
12794 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12795 gen_store_gpr(t1, rd);
12796 tcg_gen_movi_tl(t1, 4);
12797 gen_op_addr_add(ctx, t0, t0, t1);
12798 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12799 gen_store_gpr(t1, rd+1);
12802 gen_load_gpr(t1, rd);
12803 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12804 tcg_gen_movi_tl(t1, 4);
12805 gen_op_addr_add(ctx, t0, t0, t1);
12806 gen_load_gpr(t1, rd+1);
12807 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12809 #ifdef TARGET_MIPS64
12812 generate_exception_end(ctx, EXCP_RI);
12815 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12816 gen_store_gpr(t1, rd);
12817 tcg_gen_movi_tl(t1, 8);
12818 gen_op_addr_add(ctx, t0, t0, t1);
12819 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12820 gen_store_gpr(t1, rd+1);
12823 gen_load_gpr(t1, rd);
12824 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12825 tcg_gen_movi_tl(t1, 8);
12826 gen_op_addr_add(ctx, t0, t0, t1);
12827 gen_load_gpr(t1, rd+1);
12828 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12836 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
12838 int extension = (ctx->opcode >> 6) & 0x3f;
12839 int minor = (ctx->opcode >> 12) & 0xf;
12840 uint32_t mips32_op;
12842 switch (extension) {
12844 mips32_op = OPC_TEQ;
12847 mips32_op = OPC_TGE;
12850 mips32_op = OPC_TGEU;
12853 mips32_op = OPC_TLT;
12856 mips32_op = OPC_TLTU;
12859 mips32_op = OPC_TNE;
12861 gen_trap(ctx, mips32_op, rs, rt, -1);
12863 #ifndef CONFIG_USER_ONLY
12866 check_cp0_enabled(ctx);
12868 /* Treat as NOP. */
12871 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
12875 check_cp0_enabled(ctx);
12877 TCGv t0 = tcg_temp_new();
12879 gen_load_gpr(t0, rt);
12880 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
12886 switch (minor & 3) {
12888 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12891 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12894 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12897 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12900 goto pool32axf_invalid;
12904 switch (minor & 3) {
12906 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12909 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12912 goto pool32axf_invalid;
12918 check_insn(ctx, ISA_MIPS32R6);
12919 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
12922 gen_bshfl(ctx, OPC_SEB, rs, rt);
12925 gen_bshfl(ctx, OPC_SEH, rs, rt);
12928 mips32_op = OPC_CLO;
12931 mips32_op = OPC_CLZ;
12933 check_insn(ctx, ISA_MIPS32);
12934 gen_cl(ctx, mips32_op, rt, rs);
12937 gen_rdhwr(ctx, rt, rs);
12940 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12943 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12944 mips32_op = OPC_MULT;
12947 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12948 mips32_op = OPC_MULTU;
12951 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12952 mips32_op = OPC_DIV;
12955 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12956 mips32_op = OPC_DIVU;
12959 check_insn(ctx, ISA_MIPS32);
12960 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12963 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12964 mips32_op = OPC_MADD;
12967 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12968 mips32_op = OPC_MADDU;
12971 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12972 mips32_op = OPC_MSUB;
12975 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12976 mips32_op = OPC_MSUBU;
12978 check_insn(ctx, ISA_MIPS32);
12979 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12982 goto pool32axf_invalid;
12993 generate_exception_err(ctx, EXCP_CpU, 2);
12996 goto pool32axf_invalid;
13001 case JALR: /* JALRC */
13002 case JALR_HB: /* JALRC_HB */
13003 if (ctx->insn_flags & ISA_MIPS32R6) {
13004 /* JALRC, JALRC_HB */
13005 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13007 /* JALR, JALR_HB */
13008 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13009 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13014 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13015 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13016 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13019 goto pool32axf_invalid;
13025 check_cp0_enabled(ctx);
13026 check_insn(ctx, ISA_MIPS32R2);
13027 gen_load_srsgpr(rs, rt);
13030 check_cp0_enabled(ctx);
13031 check_insn(ctx, ISA_MIPS32R2);
13032 gen_store_srsgpr(rs, rt);
13035 goto pool32axf_invalid;
13038 #ifndef CONFIG_USER_ONLY
13042 mips32_op = OPC_TLBP;
13045 mips32_op = OPC_TLBR;
13048 mips32_op = OPC_TLBWI;
13051 mips32_op = OPC_TLBWR;
13054 mips32_op = OPC_TLBINV;
13057 mips32_op = OPC_TLBINVF;
13060 mips32_op = OPC_WAIT;
13063 mips32_op = OPC_DERET;
13066 mips32_op = OPC_ERET;
13068 gen_cp0(env, ctx, mips32_op, rt, rs);
13071 goto pool32axf_invalid;
13077 check_cp0_enabled(ctx);
13079 TCGv t0 = tcg_temp_new();
13081 save_cpu_state(ctx, 1);
13082 gen_helper_di(t0, cpu_env);
13083 gen_store_gpr(t0, rs);
13084 /* Stop translation as we may have switched the execution mode */
13085 ctx->bstate = BS_STOP;
13090 check_cp0_enabled(ctx);
13092 TCGv t0 = tcg_temp_new();
13094 save_cpu_state(ctx, 1);
13095 gen_helper_ei(t0, cpu_env);
13096 gen_store_gpr(t0, rs);
13097 /* Stop translation as we may have switched the execution mode */
13098 ctx->bstate = BS_STOP;
13103 goto pool32axf_invalid;
13113 generate_exception_end(ctx, EXCP_SYSCALL);
13116 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13117 gen_helper_do_semihosting(cpu_env);
13119 check_insn(ctx, ISA_MIPS32);
13120 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13121 generate_exception_end(ctx, EXCP_RI);
13123 generate_exception_end(ctx, EXCP_DBp);
13128 goto pool32axf_invalid;
13132 switch (minor & 3) {
13134 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13137 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13140 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13143 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13146 goto pool32axf_invalid;
13150 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13153 gen_HILO(ctx, OPC_MFHI, 0, rs);
13156 gen_HILO(ctx, OPC_MFLO, 0, rs);
13159 gen_HILO(ctx, OPC_MTHI, 0, rs);
13162 gen_HILO(ctx, OPC_MTLO, 0, rs);
13165 goto pool32axf_invalid;
13170 MIPS_INVAL("pool32axf");
13171 generate_exception_end(ctx, EXCP_RI);
13176 /* Values for microMIPS fmt field. Variable-width, depending on which
13177 formats the instruction supports. */
13196 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13198 int extension = (ctx->opcode >> 6) & 0x3ff;
13199 uint32_t mips32_op;
13201 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13202 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13203 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13205 switch (extension) {
13206 case FLOAT_1BIT_FMT(CFC1, 0):
13207 mips32_op = OPC_CFC1;
13209 case FLOAT_1BIT_FMT(CTC1, 0):
13210 mips32_op = OPC_CTC1;
13212 case FLOAT_1BIT_FMT(MFC1, 0):
13213 mips32_op = OPC_MFC1;
13215 case FLOAT_1BIT_FMT(MTC1, 0):
13216 mips32_op = OPC_MTC1;
13218 case FLOAT_1BIT_FMT(MFHC1, 0):
13219 mips32_op = OPC_MFHC1;
13221 case FLOAT_1BIT_FMT(MTHC1, 0):
13222 mips32_op = OPC_MTHC1;
13224 gen_cp1(ctx, mips32_op, rt, rs);
13227 /* Reciprocal square root */
13228 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13229 mips32_op = OPC_RSQRT_S;
13231 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13232 mips32_op = OPC_RSQRT_D;
13236 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13237 mips32_op = OPC_SQRT_S;
13239 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13240 mips32_op = OPC_SQRT_D;
13244 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13245 mips32_op = OPC_RECIP_S;
13247 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13248 mips32_op = OPC_RECIP_D;
13252 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13253 mips32_op = OPC_FLOOR_L_S;
13255 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13256 mips32_op = OPC_FLOOR_L_D;
13258 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13259 mips32_op = OPC_FLOOR_W_S;
13261 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13262 mips32_op = OPC_FLOOR_W_D;
13266 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13267 mips32_op = OPC_CEIL_L_S;
13269 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13270 mips32_op = OPC_CEIL_L_D;
13272 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13273 mips32_op = OPC_CEIL_W_S;
13275 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13276 mips32_op = OPC_CEIL_W_D;
13280 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13281 mips32_op = OPC_TRUNC_L_S;
13283 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13284 mips32_op = OPC_TRUNC_L_D;
13286 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13287 mips32_op = OPC_TRUNC_W_S;
13289 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13290 mips32_op = OPC_TRUNC_W_D;
13294 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13295 mips32_op = OPC_ROUND_L_S;
13297 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13298 mips32_op = OPC_ROUND_L_D;
13300 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13301 mips32_op = OPC_ROUND_W_S;
13303 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13304 mips32_op = OPC_ROUND_W_D;
13307 /* Integer to floating-point conversion */
13308 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13309 mips32_op = OPC_CVT_L_S;
13311 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13312 mips32_op = OPC_CVT_L_D;
13314 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13315 mips32_op = OPC_CVT_W_S;
13317 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13318 mips32_op = OPC_CVT_W_D;
13321 /* Paired-foo conversions */
13322 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13323 mips32_op = OPC_CVT_S_PL;
13325 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13326 mips32_op = OPC_CVT_S_PU;
13328 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13329 mips32_op = OPC_CVT_PW_PS;
13331 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13332 mips32_op = OPC_CVT_PS_PW;
13335 /* Floating-point moves */
13336 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13337 mips32_op = OPC_MOV_S;
13339 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13340 mips32_op = OPC_MOV_D;
13342 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13343 mips32_op = OPC_MOV_PS;
13346 /* Absolute value */
13347 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13348 mips32_op = OPC_ABS_S;
13350 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13351 mips32_op = OPC_ABS_D;
13353 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13354 mips32_op = OPC_ABS_PS;
13358 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13359 mips32_op = OPC_NEG_S;
13361 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13362 mips32_op = OPC_NEG_D;
13364 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13365 mips32_op = OPC_NEG_PS;
13368 /* Reciprocal square root step */
13369 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13370 mips32_op = OPC_RSQRT1_S;
13372 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13373 mips32_op = OPC_RSQRT1_D;
13375 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13376 mips32_op = OPC_RSQRT1_PS;
13379 /* Reciprocal step */
13380 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13381 mips32_op = OPC_RECIP1_S;
13383 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13384 mips32_op = OPC_RECIP1_S;
13386 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13387 mips32_op = OPC_RECIP1_PS;
13390 /* Conversions from double */
13391 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13392 mips32_op = OPC_CVT_D_S;
13394 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13395 mips32_op = OPC_CVT_D_W;
13397 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13398 mips32_op = OPC_CVT_D_L;
13401 /* Conversions from single */
13402 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13403 mips32_op = OPC_CVT_S_D;
13405 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13406 mips32_op = OPC_CVT_S_W;
13408 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13409 mips32_op = OPC_CVT_S_L;
13411 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13414 /* Conditional moves on floating-point codes */
13415 case COND_FLOAT_MOV(MOVT, 0):
13416 case COND_FLOAT_MOV(MOVT, 1):
13417 case COND_FLOAT_MOV(MOVT, 2):
13418 case COND_FLOAT_MOV(MOVT, 3):
13419 case COND_FLOAT_MOV(MOVT, 4):
13420 case COND_FLOAT_MOV(MOVT, 5):
13421 case COND_FLOAT_MOV(MOVT, 6):
13422 case COND_FLOAT_MOV(MOVT, 7):
13423 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13424 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13426 case COND_FLOAT_MOV(MOVF, 0):
13427 case COND_FLOAT_MOV(MOVF, 1):
13428 case COND_FLOAT_MOV(MOVF, 2):
13429 case COND_FLOAT_MOV(MOVF, 3):
13430 case COND_FLOAT_MOV(MOVF, 4):
13431 case COND_FLOAT_MOV(MOVF, 5):
13432 case COND_FLOAT_MOV(MOVF, 6):
13433 case COND_FLOAT_MOV(MOVF, 7):
13434 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13435 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13438 MIPS_INVAL("pool32fxf");
13439 generate_exception_end(ctx, EXCP_RI);
13444 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13448 int rt, rs, rd, rr;
13450 uint32_t op, minor, mips32_op;
13451 uint32_t cond, fmt, cc;
13453 insn = cpu_lduw_code(env, ctx->pc + 2);
13454 ctx->opcode = (ctx->opcode << 16) | insn;
13456 rt = (ctx->opcode >> 21) & 0x1f;
13457 rs = (ctx->opcode >> 16) & 0x1f;
13458 rd = (ctx->opcode >> 11) & 0x1f;
13459 rr = (ctx->opcode >> 6) & 0x1f;
13460 imm = (int16_t) ctx->opcode;
13462 op = (ctx->opcode >> 26) & 0x3f;
13465 minor = ctx->opcode & 0x3f;
13468 minor = (ctx->opcode >> 6) & 0xf;
13471 mips32_op = OPC_SLL;
13474 mips32_op = OPC_SRA;
13477 mips32_op = OPC_SRL;
13480 mips32_op = OPC_ROTR;
13482 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13485 check_insn(ctx, ISA_MIPS32R6);
13486 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13489 check_insn(ctx, ISA_MIPS32R6);
13490 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13493 goto pool32a_invalid;
13497 minor = (ctx->opcode >> 6) & 0xf;
13501 mips32_op = OPC_ADD;
13504 mips32_op = OPC_ADDU;
13507 mips32_op = OPC_SUB;
13510 mips32_op = OPC_SUBU;
13513 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13514 mips32_op = OPC_MUL;
13516 gen_arith(ctx, mips32_op, rd, rs, rt);
13520 mips32_op = OPC_SLLV;
13523 mips32_op = OPC_SRLV;
13526 mips32_op = OPC_SRAV;
13529 mips32_op = OPC_ROTRV;
13531 gen_shift(ctx, mips32_op, rd, rs, rt);
13533 /* Logical operations */
13535 mips32_op = OPC_AND;
13538 mips32_op = OPC_OR;
13541 mips32_op = OPC_NOR;
13544 mips32_op = OPC_XOR;
13546 gen_logic(ctx, mips32_op, rd, rs, rt);
13548 /* Set less than */
13550 mips32_op = OPC_SLT;
13553 mips32_op = OPC_SLTU;
13555 gen_slt(ctx, mips32_op, rd, rs, rt);
13558 goto pool32a_invalid;
13562 minor = (ctx->opcode >> 6) & 0xf;
13564 /* Conditional moves */
13565 case MOVN: /* MUL */
13566 if (ctx->insn_flags & ISA_MIPS32R6) {
13568 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13571 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13574 case MOVZ: /* MUH */
13575 if (ctx->insn_flags & ISA_MIPS32R6) {
13577 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13580 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13584 check_insn(ctx, ISA_MIPS32R6);
13585 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13588 check_insn(ctx, ISA_MIPS32R6);
13589 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13591 case LWXS: /* DIV */
13592 if (ctx->insn_flags & ISA_MIPS32R6) {
13594 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13597 gen_ldxs(ctx, rs, rt, rd);
13601 check_insn(ctx, ISA_MIPS32R6);
13602 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13605 check_insn(ctx, ISA_MIPS32R6);
13606 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
13609 check_insn(ctx, ISA_MIPS32R6);
13610 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
13613 goto pool32a_invalid;
13617 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13620 check_insn(ctx, ISA_MIPS32R6);
13621 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13622 extract32(ctx->opcode, 9, 2));
13625 check_insn(ctx, ISA_MIPS32R6);
13626 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13627 extract32(ctx->opcode, 9, 2));
13630 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13633 gen_pool32axf(env, ctx, rt, rs);
13636 generate_exception_end(ctx, EXCP_BREAK);
13640 MIPS_INVAL("pool32a");
13641 generate_exception_end(ctx, EXCP_RI);
13646 minor = (ctx->opcode >> 12) & 0xf;
13649 check_cp0_enabled(ctx);
13650 /* Treat as no-op. */
13654 /* COP2: Not implemented. */
13655 generate_exception_err(ctx, EXCP_CpU, 2);
13657 #ifdef TARGET_MIPS64
13660 check_insn(ctx, ISA_MIPS3);
13661 check_mips_64(ctx);
13666 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13668 #ifdef TARGET_MIPS64
13671 check_insn(ctx, ISA_MIPS3);
13672 check_mips_64(ctx);
13677 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13680 MIPS_INVAL("pool32b");
13681 generate_exception_end(ctx, EXCP_RI);
13686 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
13687 minor = ctx->opcode & 0x3f;
13688 check_cp1_enabled(ctx);
13691 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13692 mips32_op = OPC_ALNV_PS;
13695 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13696 mips32_op = OPC_MADD_S;
13699 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13700 mips32_op = OPC_MADD_D;
13703 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13704 mips32_op = OPC_MADD_PS;
13707 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13708 mips32_op = OPC_MSUB_S;
13711 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13712 mips32_op = OPC_MSUB_D;
13715 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13716 mips32_op = OPC_MSUB_PS;
13719 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13720 mips32_op = OPC_NMADD_S;
13723 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13724 mips32_op = OPC_NMADD_D;
13727 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13728 mips32_op = OPC_NMADD_PS;
13731 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13732 mips32_op = OPC_NMSUB_S;
13735 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13736 mips32_op = OPC_NMSUB_D;
13739 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13740 mips32_op = OPC_NMSUB_PS;
13742 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13744 case CABS_COND_FMT:
13745 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13746 cond = (ctx->opcode >> 6) & 0xf;
13747 cc = (ctx->opcode >> 13) & 0x7;
13748 fmt = (ctx->opcode >> 10) & 0x3;
13751 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13754 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13757 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13760 goto pool32f_invalid;
13764 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13765 cond = (ctx->opcode >> 6) & 0xf;
13766 cc = (ctx->opcode >> 13) & 0x7;
13767 fmt = (ctx->opcode >> 10) & 0x3;
13770 gen_cmp_s(ctx, cond, rt, rs, cc);
13773 gen_cmp_d(ctx, cond, rt, rs, cc);
13776 gen_cmp_ps(ctx, cond, rt, rs, cc);
13779 goto pool32f_invalid;
13783 check_insn(ctx, ISA_MIPS32R6);
13784 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13787 check_insn(ctx, ISA_MIPS32R6);
13788 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13791 gen_pool32fxf(ctx, rt, rs);
13795 switch ((ctx->opcode >> 6) & 0x7) {
13797 mips32_op = OPC_PLL_PS;
13800 mips32_op = OPC_PLU_PS;
13803 mips32_op = OPC_PUL_PS;
13806 mips32_op = OPC_PUU_PS;
13809 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13810 mips32_op = OPC_CVT_PS_S;
13812 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13815 goto pool32f_invalid;
13819 check_insn(ctx, ISA_MIPS32R6);
13820 switch ((ctx->opcode >> 9) & 0x3) {
13822 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
13825 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
13828 goto pool32f_invalid;
13833 switch ((ctx->opcode >> 6) & 0x7) {
13835 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13836 mips32_op = OPC_LWXC1;
13839 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13840 mips32_op = OPC_SWXC1;
13843 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13844 mips32_op = OPC_LDXC1;
13847 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13848 mips32_op = OPC_SDXC1;
13851 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13852 mips32_op = OPC_LUXC1;
13855 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13856 mips32_op = OPC_SUXC1;
13858 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13861 goto pool32f_invalid;
13865 check_insn(ctx, ISA_MIPS32R6);
13866 switch ((ctx->opcode >> 9) & 0x3) {
13868 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
13871 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
13874 goto pool32f_invalid;
13879 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13880 fmt = (ctx->opcode >> 9) & 0x3;
13881 switch ((ctx->opcode >> 6) & 0x7) {
13885 mips32_op = OPC_RSQRT2_S;
13888 mips32_op = OPC_RSQRT2_D;
13891 mips32_op = OPC_RSQRT2_PS;
13894 goto pool32f_invalid;
13900 mips32_op = OPC_RECIP2_S;
13903 mips32_op = OPC_RECIP2_D;
13906 mips32_op = OPC_RECIP2_PS;
13909 goto pool32f_invalid;
13913 mips32_op = OPC_ADDR_PS;
13916 mips32_op = OPC_MULR_PS;
13918 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13921 goto pool32f_invalid;
13925 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
13926 cc = (ctx->opcode >> 13) & 0x7;
13927 fmt = (ctx->opcode >> 9) & 0x3;
13928 switch ((ctx->opcode >> 6) & 0x7) {
13929 case MOVF_FMT: /* RINT_FMT */
13930 if (ctx->insn_flags & ISA_MIPS32R6) {
13934 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
13937 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
13940 goto pool32f_invalid;
13946 gen_movcf_s(ctx, rs, rt, cc, 0);
13949 gen_movcf_d(ctx, rs, rt, cc, 0);
13953 gen_movcf_ps(ctx, rs, rt, cc, 0);
13956 goto pool32f_invalid;
13960 case MOVT_FMT: /* CLASS_FMT */
13961 if (ctx->insn_flags & ISA_MIPS32R6) {
13965 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
13968 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
13971 goto pool32f_invalid;
13977 gen_movcf_s(ctx, rs, rt, cc, 1);
13980 gen_movcf_d(ctx, rs, rt, cc, 1);
13984 gen_movcf_ps(ctx, rs, rt, cc, 1);
13987 goto pool32f_invalid;
13992 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13995 goto pool32f_invalid;
13998 #define FINSN_3ARG_SDPS(prfx) \
13999 switch ((ctx->opcode >> 8) & 0x3) { \
14001 mips32_op = OPC_##prfx##_S; \
14004 mips32_op = OPC_##prfx##_D; \
14006 case FMT_SDPS_PS: \
14008 mips32_op = OPC_##prfx##_PS; \
14011 goto pool32f_invalid; \
14014 check_insn(ctx, ISA_MIPS32R6);
14015 switch ((ctx->opcode >> 9) & 0x3) {
14017 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14020 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14023 goto pool32f_invalid;
14027 check_insn(ctx, ISA_MIPS32R6);
14028 switch ((ctx->opcode >> 9) & 0x3) {
14030 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14033 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14036 goto pool32f_invalid;
14040 /* regular FP ops */
14041 switch ((ctx->opcode >> 6) & 0x3) {
14043 FINSN_3ARG_SDPS(ADD);
14046 FINSN_3ARG_SDPS(SUB);
14049 FINSN_3ARG_SDPS(MUL);
14052 fmt = (ctx->opcode >> 8) & 0x3;
14054 mips32_op = OPC_DIV_D;
14055 } else if (fmt == 0) {
14056 mips32_op = OPC_DIV_S;
14058 goto pool32f_invalid;
14062 goto pool32f_invalid;
14067 switch ((ctx->opcode >> 6) & 0x7) {
14068 case MOVN_FMT: /* SELNEZ_FMT */
14069 if (ctx->insn_flags & ISA_MIPS32R6) {
14071 switch ((ctx->opcode >> 9) & 0x3) {
14073 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14076 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14079 goto pool32f_invalid;
14083 FINSN_3ARG_SDPS(MOVN);
14087 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14088 FINSN_3ARG_SDPS(MOVN);
14090 case MOVZ_FMT: /* SELEQZ_FMT */
14091 if (ctx->insn_flags & ISA_MIPS32R6) {
14093 switch ((ctx->opcode >> 9) & 0x3) {
14095 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14098 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14101 goto pool32f_invalid;
14105 FINSN_3ARG_SDPS(MOVZ);
14109 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14110 FINSN_3ARG_SDPS(MOVZ);
14113 check_insn(ctx, ISA_MIPS32R6);
14114 switch ((ctx->opcode >> 9) & 0x3) {
14116 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14119 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14122 goto pool32f_invalid;
14126 check_insn(ctx, ISA_MIPS32R6);
14127 switch ((ctx->opcode >> 9) & 0x3) {
14129 mips32_op = OPC_MADDF_S;
14132 mips32_op = OPC_MADDF_D;
14135 goto pool32f_invalid;
14139 check_insn(ctx, ISA_MIPS32R6);
14140 switch ((ctx->opcode >> 9) & 0x3) {
14142 mips32_op = OPC_MSUBF_S;
14145 mips32_op = OPC_MSUBF_D;
14148 goto pool32f_invalid;
14152 goto pool32f_invalid;
14156 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14160 MIPS_INVAL("pool32f");
14161 generate_exception_end(ctx, EXCP_RI);
14165 generate_exception_err(ctx, EXCP_CpU, 1);
14169 minor = (ctx->opcode >> 21) & 0x1f;
14172 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14173 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14176 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14177 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14178 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14181 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14182 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14183 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14186 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14187 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14190 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14191 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14192 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14195 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14196 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14197 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14200 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14201 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14204 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14205 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14209 case TLTI: /* BC1EQZC */
14210 if (ctx->insn_flags & ISA_MIPS32R6) {
14212 check_cp1_enabled(ctx);
14213 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14216 mips32_op = OPC_TLTI;
14220 case TGEI: /* BC1NEZC */
14221 if (ctx->insn_flags & ISA_MIPS32R6) {
14223 check_cp1_enabled(ctx);
14224 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14227 mips32_op = OPC_TGEI;
14232 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14233 mips32_op = OPC_TLTIU;
14236 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14237 mips32_op = OPC_TGEIU;
14239 case TNEI: /* SYNCI */
14240 if (ctx->insn_flags & ISA_MIPS32R6) {
14242 /* Break the TB to be able to sync copied instructions
14244 ctx->bstate = BS_STOP;
14247 mips32_op = OPC_TNEI;
14252 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14253 mips32_op = OPC_TEQI;
14255 gen_trap(ctx, mips32_op, rs, -1, imm);
14260 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14261 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14262 4, rs, 0, imm << 1, 0);
14263 /* Compact branches don't have a delay slot, so just let
14264 the normal delay slot handling take us to the branch
14268 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14269 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14272 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14273 /* Break the TB to be able to sync copied instructions
14275 ctx->bstate = BS_STOP;
14279 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14280 /* COP2: Not implemented. */
14281 generate_exception_err(ctx, EXCP_CpU, 2);
14284 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14285 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14288 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14289 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14292 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14293 mips32_op = OPC_BC1FANY4;
14296 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14297 mips32_op = OPC_BC1TANY4;
14300 check_insn(ctx, ASE_MIPS3D);
14303 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14304 check_cp1_enabled(ctx);
14305 gen_compute_branch1(ctx, mips32_op,
14306 (ctx->opcode >> 18) & 0x7, imm << 1);
14308 generate_exception_err(ctx, EXCP_CpU, 1);
14313 /* MIPS DSP: not implemented */
14316 MIPS_INVAL("pool32i");
14317 generate_exception_end(ctx, EXCP_RI);
14322 minor = (ctx->opcode >> 12) & 0xf;
14323 offset = sextract32(ctx->opcode, 0,
14324 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14327 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14328 mips32_op = OPC_LWL;
14331 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14332 mips32_op = OPC_SWL;
14335 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14336 mips32_op = OPC_LWR;
14339 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14340 mips32_op = OPC_SWR;
14342 #if defined(TARGET_MIPS64)
14344 check_insn(ctx, ISA_MIPS3);
14345 check_mips_64(ctx);
14346 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14347 mips32_op = OPC_LDL;
14350 check_insn(ctx, ISA_MIPS3);
14351 check_mips_64(ctx);
14352 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14353 mips32_op = OPC_SDL;
14356 check_insn(ctx, ISA_MIPS3);
14357 check_mips_64(ctx);
14358 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14359 mips32_op = OPC_LDR;
14362 check_insn(ctx, ISA_MIPS3);
14363 check_mips_64(ctx);
14364 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14365 mips32_op = OPC_SDR;
14368 check_insn(ctx, ISA_MIPS3);
14369 check_mips_64(ctx);
14370 mips32_op = OPC_LWU;
14373 check_insn(ctx, ISA_MIPS3);
14374 check_mips_64(ctx);
14375 mips32_op = OPC_LLD;
14379 mips32_op = OPC_LL;
14382 gen_ld(ctx, mips32_op, rt, rs, offset);
14385 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
14388 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14390 #if defined(TARGET_MIPS64)
14392 check_insn(ctx, ISA_MIPS3);
14393 check_mips_64(ctx);
14394 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14398 /* Treat as no-op */
14399 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14400 /* hint codes 24-31 are reserved and signal RI */
14401 generate_exception(ctx, EXCP_RI);
14405 MIPS_INVAL("pool32c");
14406 generate_exception_end(ctx, EXCP_RI);
14410 case ADDI32: /* AUI, LUI */
14411 if (ctx->insn_flags & ISA_MIPS32R6) {
14413 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14416 mips32_op = OPC_ADDI;
14421 mips32_op = OPC_ADDIU;
14423 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
14426 /* Logical operations */
14428 mips32_op = OPC_ORI;
14431 mips32_op = OPC_XORI;
14434 mips32_op = OPC_ANDI;
14436 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
14439 /* Set less than immediate */
14441 mips32_op = OPC_SLTI;
14444 mips32_op = OPC_SLTIU;
14446 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
14449 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14450 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14451 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14452 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14454 case JALS32: /* BOVC, BEQC, BEQZALC */
14455 if (ctx->insn_flags & ISA_MIPS32R6) {
14458 mips32_op = OPC_BOVC;
14459 } else if (rs < rt && rs == 0) {
14461 mips32_op = OPC_BEQZALC;
14464 mips32_op = OPC_BEQC;
14466 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14469 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14470 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14471 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14474 case BEQ32: /* BC */
14475 if (ctx->insn_flags & ISA_MIPS32R6) {
14477 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14478 sextract32(ctx->opcode << 1, 0, 27));
14481 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14484 case BNE32: /* BALC */
14485 if (ctx->insn_flags & ISA_MIPS32R6) {
14487 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14488 sextract32(ctx->opcode << 1, 0, 27));
14491 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14494 case J32: /* BGTZC, BLTZC, BLTC */
14495 if (ctx->insn_flags & ISA_MIPS32R6) {
14496 if (rs == 0 && rt != 0) {
14498 mips32_op = OPC_BGTZC;
14499 } else if (rs != 0 && rt != 0 && rs == rt) {
14501 mips32_op = OPC_BLTZC;
14504 mips32_op = OPC_BLTC;
14506 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14509 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14510 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14513 case JAL32: /* BLEZC, BGEZC, BGEC */
14514 if (ctx->insn_flags & ISA_MIPS32R6) {
14515 if (rs == 0 && rt != 0) {
14517 mips32_op = OPC_BLEZC;
14518 } else if (rs != 0 && rt != 0 && rs == rt) {
14520 mips32_op = OPC_BGEZC;
14523 mips32_op = OPC_BGEC;
14525 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14528 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14529 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14530 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14533 /* Floating point (COP1) */
14535 mips32_op = OPC_LWC1;
14538 mips32_op = OPC_LDC1;
14541 mips32_op = OPC_SWC1;
14544 mips32_op = OPC_SDC1;
14546 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
14548 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14549 if (ctx->insn_flags & ISA_MIPS32R6) {
14550 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14551 switch ((ctx->opcode >> 16) & 0x1f) {
14552 case ADDIUPC_00 ... ADDIUPC_07:
14553 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14556 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14559 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14561 case LWPC_08 ... LWPC_0F:
14562 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14565 generate_exception(ctx, EXCP_RI);
14570 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14571 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14573 gen_addiupc(ctx, reg, offset, 0, 0);
14576 case BNVC: /* BNEC, BNEZALC */
14577 check_insn(ctx, ISA_MIPS32R6);
14580 mips32_op = OPC_BNVC;
14581 } else if (rs < rt && rs == 0) {
14583 mips32_op = OPC_BNEZALC;
14586 mips32_op = OPC_BNEC;
14588 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14590 case R6_BNEZC: /* JIALC */
14591 check_insn(ctx, ISA_MIPS32R6);
14594 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14595 sextract32(ctx->opcode << 1, 0, 22));
14598 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14601 case R6_BEQZC: /* JIC */
14602 check_insn(ctx, ISA_MIPS32R6);
14605 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14606 sextract32(ctx->opcode << 1, 0, 22));
14609 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14612 case BLEZALC: /* BGEZALC, BGEUC */
14613 check_insn(ctx, ISA_MIPS32R6);
14614 if (rs == 0 && rt != 0) {
14616 mips32_op = OPC_BLEZALC;
14617 } else if (rs != 0 && rt != 0 && rs == rt) {
14619 mips32_op = OPC_BGEZALC;
14622 mips32_op = OPC_BGEUC;
14624 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14626 case BGTZALC: /* BLTZALC, BLTUC */
14627 check_insn(ctx, ISA_MIPS32R6);
14628 if (rs == 0 && rt != 0) {
14630 mips32_op = OPC_BGTZALC;
14631 } else if (rs != 0 && rt != 0 && rs == rt) {
14633 mips32_op = OPC_BLTZALC;
14636 mips32_op = OPC_BLTUC;
14638 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14640 /* Loads and stores */
14642 mips32_op = OPC_LB;
14645 mips32_op = OPC_LBU;
14648 mips32_op = OPC_LH;
14651 mips32_op = OPC_LHU;
14654 mips32_op = OPC_LW;
14656 #ifdef TARGET_MIPS64
14658 check_insn(ctx, ISA_MIPS3);
14659 check_mips_64(ctx);
14660 mips32_op = OPC_LD;
14663 check_insn(ctx, ISA_MIPS3);
14664 check_mips_64(ctx);
14665 mips32_op = OPC_SD;
14669 mips32_op = OPC_SB;
14672 mips32_op = OPC_SH;
14675 mips32_op = OPC_SW;
14678 gen_ld(ctx, mips32_op, rt, rs, imm);
14681 gen_st(ctx, mips32_op, rt, rs, imm);
14684 generate_exception_end(ctx, EXCP_RI);
14689 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
14693 /* make sure instructions are on a halfword boundary */
14694 if (ctx->pc & 0x1) {
14695 env->CP0_BadVAddr = ctx->pc;
14696 generate_exception_end(ctx, EXCP_AdEL);
14700 op = (ctx->opcode >> 10) & 0x3f;
14701 /* Enforce properly-sized instructions in a delay slot */
14702 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14703 switch (op & 0x7) { /* MSB-3..MSB-5 */
14705 /* POOL32A, POOL32B, POOL32I, POOL32C */
14707 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14709 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14711 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14713 /* LB32, LH32, LWC132, LDC132, LW32 */
14714 if (ctx->hflags & MIPS_HFLAG_BDS16) {
14715 generate_exception_end(ctx, EXCP_RI);
14720 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
14722 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
14724 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
14725 if (ctx->hflags & MIPS_HFLAG_BDS32) {
14726 generate_exception_end(ctx, EXCP_RI);
14736 int rd = mmreg(uMIPS_RD(ctx->opcode));
14737 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
14738 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14741 switch (ctx->opcode & 0x1) {
14749 if (ctx->insn_flags & ISA_MIPS32R6) {
14750 /* In the Release 6 the register number location in
14751 * the instruction encoding has changed.
14753 gen_arith(ctx, opc, rs1, rd, rs2);
14755 gen_arith(ctx, opc, rd, rs1, rs2);
14761 int rd = mmreg(uMIPS_RD(ctx->opcode));
14762 int rs = mmreg(uMIPS_RS(ctx->opcode));
14763 int amount = (ctx->opcode >> 1) & 0x7;
14765 amount = amount == 0 ? 8 : amount;
14767 switch (ctx->opcode & 0x1) {
14776 gen_shift_imm(ctx, opc, rd, rs, amount);
14780 if (ctx->insn_flags & ISA_MIPS32R6) {
14781 gen_pool16c_r6_insn(ctx);
14783 gen_pool16c_insn(ctx);
14788 int rd = mmreg(uMIPS_RD(ctx->opcode));
14789 int rb = 28; /* GP */
14790 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14792 gen_ld(ctx, OPC_LW, rd, rb, offset);
14796 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14797 if (ctx->opcode & 1) {
14798 generate_exception_end(ctx, EXCP_RI);
14801 int enc_dest = uMIPS_RD(ctx->opcode);
14802 int enc_rt = uMIPS_RS2(ctx->opcode);
14803 int enc_rs = uMIPS_RS1(ctx->opcode);
14804 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14809 int rd = mmreg(uMIPS_RD(ctx->opcode));
14810 int rb = mmreg(uMIPS_RS(ctx->opcode));
14811 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14812 offset = (offset == 0xf ? -1 : offset);
14814 gen_ld(ctx, OPC_LBU, rd, rb, offset);
14819 int rd = mmreg(uMIPS_RD(ctx->opcode));
14820 int rb = mmreg(uMIPS_RS(ctx->opcode));
14821 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14823 gen_ld(ctx, OPC_LHU, rd, rb, offset);
14828 int rd = (ctx->opcode >> 5) & 0x1f;
14829 int rb = 29; /* SP */
14830 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14832 gen_ld(ctx, OPC_LW, rd, rb, offset);
14837 int rd = mmreg(uMIPS_RD(ctx->opcode));
14838 int rb = mmreg(uMIPS_RS(ctx->opcode));
14839 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14841 gen_ld(ctx, OPC_LW, rd, rb, offset);
14846 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14847 int rb = mmreg(uMIPS_RS(ctx->opcode));
14848 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14850 gen_st(ctx, OPC_SB, rd, rb, offset);
14855 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14856 int rb = mmreg(uMIPS_RS(ctx->opcode));
14857 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14859 gen_st(ctx, OPC_SH, rd, rb, offset);
14864 int rd = (ctx->opcode >> 5) & 0x1f;
14865 int rb = 29; /* SP */
14866 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14868 gen_st(ctx, OPC_SW, rd, rb, offset);
14873 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14874 int rb = mmreg(uMIPS_RS(ctx->opcode));
14875 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14877 gen_st(ctx, OPC_SW, rd, rb, offset);
14882 int rd = uMIPS_RD5(ctx->opcode);
14883 int rs = uMIPS_RS5(ctx->opcode);
14885 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
14892 switch (ctx->opcode & 0x1) {
14902 switch (ctx->opcode & 0x1) {
14907 gen_addiur1sp(ctx);
14911 case B16: /* BC16 */
14912 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
14913 sextract32(ctx->opcode, 0, 10) << 1,
14914 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
14916 case BNEZ16: /* BNEZC16 */
14917 case BEQZ16: /* BEQZC16 */
14918 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14919 mmreg(uMIPS_RD(ctx->opcode)),
14920 0, sextract32(ctx->opcode, 0, 7) << 1,
14921 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
14926 int reg = mmreg(uMIPS_RD(ctx->opcode));
14927 int imm = ZIMM(ctx->opcode, 0, 7);
14929 imm = (imm == 0x7f ? -1 : imm);
14930 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14936 generate_exception_end(ctx, EXCP_RI);
14939 decode_micromips32_opc(env, ctx);
14946 /* SmartMIPS extension to MIPS32 */
14948 #if defined(TARGET_MIPS64)
14950 /* MDMX extension to MIPS64 */
14954 /* MIPSDSP functions. */
14955 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
14956 int rd, int base, int offset)
14961 t0 = tcg_temp_new();
14964 gen_load_gpr(t0, offset);
14965 } else if (offset == 0) {
14966 gen_load_gpr(t0, base);
14968 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14973 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
14974 gen_store_gpr(t0, rd);
14977 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
14978 gen_store_gpr(t0, rd);
14981 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
14982 gen_store_gpr(t0, rd);
14984 #if defined(TARGET_MIPS64)
14986 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
14987 gen_store_gpr(t0, rd);
14994 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
14995 int ret, int v1, int v2)
15001 /* Treat as NOP. */
15005 v1_t = tcg_temp_new();
15006 v2_t = tcg_temp_new();
15008 gen_load_gpr(v1_t, v1);
15009 gen_load_gpr(v2_t, v2);
15012 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15013 case OPC_MULT_G_2E:
15017 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15019 case OPC_ADDUH_R_QB:
15020 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15023 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15025 case OPC_ADDQH_R_PH:
15026 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15029 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15031 case OPC_ADDQH_R_W:
15032 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15035 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15037 case OPC_SUBUH_R_QB:
15038 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15041 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15043 case OPC_SUBQH_R_PH:
15044 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15047 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15049 case OPC_SUBQH_R_W:
15050 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15054 case OPC_ABSQ_S_PH_DSP:
15056 case OPC_ABSQ_S_QB:
15058 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15060 case OPC_ABSQ_S_PH:
15062 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15066 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15068 case OPC_PRECEQ_W_PHL:
15070 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15071 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15073 case OPC_PRECEQ_W_PHR:
15075 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15076 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15077 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15079 case OPC_PRECEQU_PH_QBL:
15081 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15083 case OPC_PRECEQU_PH_QBR:
15085 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15087 case OPC_PRECEQU_PH_QBLA:
15089 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15091 case OPC_PRECEQU_PH_QBRA:
15093 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15095 case OPC_PRECEU_PH_QBL:
15097 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15099 case OPC_PRECEU_PH_QBR:
15101 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15103 case OPC_PRECEU_PH_QBLA:
15105 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15107 case OPC_PRECEU_PH_QBRA:
15109 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15113 case OPC_ADDU_QB_DSP:
15117 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15119 case OPC_ADDQ_S_PH:
15121 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15125 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15129 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15131 case OPC_ADDU_S_QB:
15133 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15137 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15139 case OPC_ADDU_S_PH:
15141 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15145 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15147 case OPC_SUBQ_S_PH:
15149 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15153 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15157 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15159 case OPC_SUBU_S_QB:
15161 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15165 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15167 case OPC_SUBU_S_PH:
15169 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15173 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15177 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15181 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15183 case OPC_RADDU_W_QB:
15185 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15189 case OPC_CMPU_EQ_QB_DSP:
15191 case OPC_PRECR_QB_PH:
15193 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15195 case OPC_PRECRQ_QB_PH:
15197 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15199 case OPC_PRECR_SRA_PH_W:
15202 TCGv_i32 sa_t = tcg_const_i32(v2);
15203 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15205 tcg_temp_free_i32(sa_t);
15208 case OPC_PRECR_SRA_R_PH_W:
15211 TCGv_i32 sa_t = tcg_const_i32(v2);
15212 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15214 tcg_temp_free_i32(sa_t);
15217 case OPC_PRECRQ_PH_W:
15219 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15221 case OPC_PRECRQ_RS_PH_W:
15223 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15225 case OPC_PRECRQU_S_QB_PH:
15227 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15231 #ifdef TARGET_MIPS64
15232 case OPC_ABSQ_S_QH_DSP:
15234 case OPC_PRECEQ_L_PWL:
15236 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15238 case OPC_PRECEQ_L_PWR:
15240 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15242 case OPC_PRECEQ_PW_QHL:
15244 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15246 case OPC_PRECEQ_PW_QHR:
15248 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15250 case OPC_PRECEQ_PW_QHLA:
15252 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15254 case OPC_PRECEQ_PW_QHRA:
15256 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15258 case OPC_PRECEQU_QH_OBL:
15260 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15262 case OPC_PRECEQU_QH_OBR:
15264 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15266 case OPC_PRECEQU_QH_OBLA:
15268 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15270 case OPC_PRECEQU_QH_OBRA:
15272 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15274 case OPC_PRECEU_QH_OBL:
15276 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15278 case OPC_PRECEU_QH_OBR:
15280 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15282 case OPC_PRECEU_QH_OBLA:
15284 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15286 case OPC_PRECEU_QH_OBRA:
15288 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15290 case OPC_ABSQ_S_OB:
15292 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15294 case OPC_ABSQ_S_PW:
15296 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15298 case OPC_ABSQ_S_QH:
15300 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15304 case OPC_ADDU_OB_DSP:
15306 case OPC_RADDU_L_OB:
15308 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15312 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15314 case OPC_SUBQ_S_PW:
15316 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15320 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15322 case OPC_SUBQ_S_QH:
15324 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15328 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15330 case OPC_SUBU_S_OB:
15332 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15336 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15338 case OPC_SUBU_S_QH:
15340 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15344 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15346 case OPC_SUBUH_R_OB:
15348 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15352 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15354 case OPC_ADDQ_S_PW:
15356 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15360 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15362 case OPC_ADDQ_S_QH:
15364 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15368 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15370 case OPC_ADDU_S_OB:
15372 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15376 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15378 case OPC_ADDU_S_QH:
15380 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15384 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15386 case OPC_ADDUH_R_OB:
15388 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15392 case OPC_CMPU_EQ_OB_DSP:
15394 case OPC_PRECR_OB_QH:
15396 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15398 case OPC_PRECR_SRA_QH_PW:
15401 TCGv_i32 ret_t = tcg_const_i32(ret);
15402 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15403 tcg_temp_free_i32(ret_t);
15406 case OPC_PRECR_SRA_R_QH_PW:
15409 TCGv_i32 sa_v = tcg_const_i32(ret);
15410 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15411 tcg_temp_free_i32(sa_v);
15414 case OPC_PRECRQ_OB_QH:
15416 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15418 case OPC_PRECRQ_PW_L:
15420 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15422 case OPC_PRECRQ_QH_PW:
15424 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15426 case OPC_PRECRQ_RS_QH_PW:
15428 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15430 case OPC_PRECRQU_S_OB_QH:
15432 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15439 tcg_temp_free(v1_t);
15440 tcg_temp_free(v2_t);
15443 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15444 int ret, int v1, int v2)
15452 /* Treat as NOP. */
15456 t0 = tcg_temp_new();
15457 v1_t = tcg_temp_new();
15458 v2_t = tcg_temp_new();
15460 tcg_gen_movi_tl(t0, v1);
15461 gen_load_gpr(v1_t, v1);
15462 gen_load_gpr(v2_t, v2);
15465 case OPC_SHLL_QB_DSP:
15467 op2 = MASK_SHLL_QB(ctx->opcode);
15471 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15475 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15479 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15483 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15485 case OPC_SHLL_S_PH:
15487 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15489 case OPC_SHLLV_S_PH:
15491 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15495 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15497 case OPC_SHLLV_S_W:
15499 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15503 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15507 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15511 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15515 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15519 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15521 case OPC_SHRA_R_QB:
15523 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15527 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15529 case OPC_SHRAV_R_QB:
15531 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15535 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15537 case OPC_SHRA_R_PH:
15539 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15543 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15545 case OPC_SHRAV_R_PH:
15547 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15551 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15553 case OPC_SHRAV_R_W:
15555 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15557 default: /* Invalid */
15558 MIPS_INVAL("MASK SHLL.QB");
15559 generate_exception_end(ctx, EXCP_RI);
15564 #ifdef TARGET_MIPS64
15565 case OPC_SHLL_OB_DSP:
15566 op2 = MASK_SHLL_OB(ctx->opcode);
15570 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15574 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15576 case OPC_SHLL_S_PW:
15578 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15580 case OPC_SHLLV_S_PW:
15582 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15586 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15590 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15594 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15598 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15600 case OPC_SHLL_S_QH:
15602 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15604 case OPC_SHLLV_S_QH:
15606 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15610 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15614 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15616 case OPC_SHRA_R_OB:
15618 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15620 case OPC_SHRAV_R_OB:
15622 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15626 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15630 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15632 case OPC_SHRA_R_PW:
15634 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15636 case OPC_SHRAV_R_PW:
15638 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15642 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15646 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15648 case OPC_SHRA_R_QH:
15650 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15652 case OPC_SHRAV_R_QH:
15654 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15658 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15662 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15666 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15670 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15672 default: /* Invalid */
15673 MIPS_INVAL("MASK SHLL.OB");
15674 generate_exception_end(ctx, EXCP_RI);
15682 tcg_temp_free(v1_t);
15683 tcg_temp_free(v2_t);
15686 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15687 int ret, int v1, int v2, int check_ret)
15693 if ((ret == 0) && (check_ret == 1)) {
15694 /* Treat as NOP. */
15698 t0 = tcg_temp_new_i32();
15699 v1_t = tcg_temp_new();
15700 v2_t = tcg_temp_new();
15702 tcg_gen_movi_i32(t0, ret);
15703 gen_load_gpr(v1_t, v1);
15704 gen_load_gpr(v2_t, v2);
15707 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15708 * the same mask and op1. */
15709 case OPC_MULT_G_2E:
15713 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15716 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15719 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15721 case OPC_MULQ_RS_W:
15722 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15726 case OPC_DPA_W_PH_DSP:
15728 case OPC_DPAU_H_QBL:
15730 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15732 case OPC_DPAU_H_QBR:
15734 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15736 case OPC_DPSU_H_QBL:
15738 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15740 case OPC_DPSU_H_QBR:
15742 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15746 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15748 case OPC_DPAX_W_PH:
15750 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15752 case OPC_DPAQ_S_W_PH:
15754 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15756 case OPC_DPAQX_S_W_PH:
15758 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15760 case OPC_DPAQX_SA_W_PH:
15762 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15766 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15768 case OPC_DPSX_W_PH:
15770 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15772 case OPC_DPSQ_S_W_PH:
15774 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15776 case OPC_DPSQX_S_W_PH:
15778 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15780 case OPC_DPSQX_SA_W_PH:
15782 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15784 case OPC_MULSAQ_S_W_PH:
15786 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15788 case OPC_DPAQ_SA_L_W:
15790 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15792 case OPC_DPSQ_SA_L_W:
15794 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15796 case OPC_MAQ_S_W_PHL:
15798 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15800 case OPC_MAQ_S_W_PHR:
15802 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15804 case OPC_MAQ_SA_W_PHL:
15806 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15808 case OPC_MAQ_SA_W_PHR:
15810 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15812 case OPC_MULSA_W_PH:
15814 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15818 #ifdef TARGET_MIPS64
15819 case OPC_DPAQ_W_QH_DSP:
15821 int ac = ret & 0x03;
15822 tcg_gen_movi_i32(t0, ac);
15827 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15831 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15835 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15839 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15843 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15845 case OPC_DPAQ_S_W_QH:
15847 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15849 case OPC_DPAQ_SA_L_PW:
15851 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15853 case OPC_DPAU_H_OBL:
15855 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15857 case OPC_DPAU_H_OBR:
15859 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15863 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15865 case OPC_DPSQ_S_W_QH:
15867 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15869 case OPC_DPSQ_SA_L_PW:
15871 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15873 case OPC_DPSU_H_OBL:
15875 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15877 case OPC_DPSU_H_OBR:
15879 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15881 case OPC_MAQ_S_L_PWL:
15883 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15885 case OPC_MAQ_S_L_PWR:
15887 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15889 case OPC_MAQ_S_W_QHLL:
15891 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15893 case OPC_MAQ_SA_W_QHLL:
15895 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15897 case OPC_MAQ_S_W_QHLR:
15899 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15901 case OPC_MAQ_SA_W_QHLR:
15903 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15905 case OPC_MAQ_S_W_QHRL:
15907 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15909 case OPC_MAQ_SA_W_QHRL:
15911 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15913 case OPC_MAQ_S_W_QHRR:
15915 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15917 case OPC_MAQ_SA_W_QHRR:
15919 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15921 case OPC_MULSAQ_S_L_PW:
15923 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15925 case OPC_MULSAQ_S_W_QH:
15927 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15933 case OPC_ADDU_QB_DSP:
15935 case OPC_MULEU_S_PH_QBL:
15937 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15939 case OPC_MULEU_S_PH_QBR:
15941 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15943 case OPC_MULQ_RS_PH:
15945 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15947 case OPC_MULEQ_S_W_PHL:
15949 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15951 case OPC_MULEQ_S_W_PHR:
15953 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15955 case OPC_MULQ_S_PH:
15957 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15961 #ifdef TARGET_MIPS64
15962 case OPC_ADDU_OB_DSP:
15964 case OPC_MULEQ_S_PW_QHL:
15966 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15968 case OPC_MULEQ_S_PW_QHR:
15970 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15972 case OPC_MULEU_S_QH_OBL:
15974 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15976 case OPC_MULEU_S_QH_OBR:
15978 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15980 case OPC_MULQ_RS_QH:
15982 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15989 tcg_temp_free_i32(t0);
15990 tcg_temp_free(v1_t);
15991 tcg_temp_free(v2_t);
15994 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16002 /* Treat as NOP. */
16006 t0 = tcg_temp_new();
16007 val_t = tcg_temp_new();
16008 gen_load_gpr(val_t, val);
16011 case OPC_ABSQ_S_PH_DSP:
16015 gen_helper_bitrev(cpu_gpr[ret], val_t);
16020 target_long result;
16021 imm = (ctx->opcode >> 16) & 0xFF;
16022 result = (uint32_t)imm << 24 |
16023 (uint32_t)imm << 16 |
16024 (uint32_t)imm << 8 |
16026 result = (int32_t)result;
16027 tcg_gen_movi_tl(cpu_gpr[ret], result);
16032 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16033 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16034 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16035 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16036 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16037 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16042 imm = (ctx->opcode >> 16) & 0x03FF;
16043 imm = (int16_t)(imm << 6) >> 6;
16044 tcg_gen_movi_tl(cpu_gpr[ret], \
16045 (target_long)((int32_t)imm << 16 | \
16051 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16052 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16053 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16054 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16058 #ifdef TARGET_MIPS64
16059 case OPC_ABSQ_S_QH_DSP:
16066 imm = (ctx->opcode >> 16) & 0xFF;
16067 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16068 temp = (temp << 16) | temp;
16069 temp = (temp << 32) | temp;
16070 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16078 imm = (ctx->opcode >> 16) & 0x03FF;
16079 imm = (int16_t)(imm << 6) >> 6;
16080 temp = ((target_long)imm << 32) \
16081 | ((target_long)imm & 0xFFFFFFFF);
16082 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16090 imm = (ctx->opcode >> 16) & 0x03FF;
16091 imm = (int16_t)(imm << 6) >> 6;
16093 temp = ((uint64_t)(uint16_t)imm << 48) |
16094 ((uint64_t)(uint16_t)imm << 32) |
16095 ((uint64_t)(uint16_t)imm << 16) |
16096 (uint64_t)(uint16_t)imm;
16097 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16102 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16103 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16104 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16105 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16106 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16107 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16108 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16112 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16113 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16114 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16118 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16119 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16120 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16121 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16122 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16129 tcg_temp_free(val_t);
16132 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16133 uint32_t op1, uint32_t op2,
16134 int ret, int v1, int v2, int check_ret)
16140 if ((ret == 0) && (check_ret == 1)) {
16141 /* Treat as NOP. */
16145 t1 = tcg_temp_new();
16146 v1_t = tcg_temp_new();
16147 v2_t = tcg_temp_new();
16149 gen_load_gpr(v1_t, v1);
16150 gen_load_gpr(v2_t, v2);
16153 case OPC_CMPU_EQ_QB_DSP:
16155 case OPC_CMPU_EQ_QB:
16157 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16159 case OPC_CMPU_LT_QB:
16161 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16163 case OPC_CMPU_LE_QB:
16165 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16167 case OPC_CMPGU_EQ_QB:
16169 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16171 case OPC_CMPGU_LT_QB:
16173 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16175 case OPC_CMPGU_LE_QB:
16177 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16179 case OPC_CMPGDU_EQ_QB:
16181 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16182 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16183 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16184 tcg_gen_shli_tl(t1, t1, 24);
16185 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16187 case OPC_CMPGDU_LT_QB:
16189 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16190 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16191 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16192 tcg_gen_shli_tl(t1, t1, 24);
16193 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16195 case OPC_CMPGDU_LE_QB:
16197 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16198 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16199 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16200 tcg_gen_shli_tl(t1, t1, 24);
16201 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16203 case OPC_CMP_EQ_PH:
16205 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16207 case OPC_CMP_LT_PH:
16209 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16211 case OPC_CMP_LE_PH:
16213 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16217 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16221 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16223 case OPC_PACKRL_PH:
16225 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16229 #ifdef TARGET_MIPS64
16230 case OPC_CMPU_EQ_OB_DSP:
16232 case OPC_CMP_EQ_PW:
16234 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16236 case OPC_CMP_LT_PW:
16238 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16240 case OPC_CMP_LE_PW:
16242 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16244 case OPC_CMP_EQ_QH:
16246 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16248 case OPC_CMP_LT_QH:
16250 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16252 case OPC_CMP_LE_QH:
16254 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16256 case OPC_CMPGDU_EQ_OB:
16258 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16260 case OPC_CMPGDU_LT_OB:
16262 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16264 case OPC_CMPGDU_LE_OB:
16266 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16268 case OPC_CMPGU_EQ_OB:
16270 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16272 case OPC_CMPGU_LT_OB:
16274 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16276 case OPC_CMPGU_LE_OB:
16278 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16280 case OPC_CMPU_EQ_OB:
16282 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16284 case OPC_CMPU_LT_OB:
16286 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16288 case OPC_CMPU_LE_OB:
16290 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16292 case OPC_PACKRL_PW:
16294 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16298 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16302 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16306 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16314 tcg_temp_free(v1_t);
16315 tcg_temp_free(v2_t);
16318 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16319 uint32_t op1, int rt, int rs, int sa)
16326 /* Treat as NOP. */
16330 t0 = tcg_temp_new();
16331 gen_load_gpr(t0, rs);
16334 case OPC_APPEND_DSP:
16335 switch (MASK_APPEND(ctx->opcode)) {
16338 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16340 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16344 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16345 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16346 tcg_gen_shli_tl(t0, t0, 32 - sa);
16347 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16349 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16353 if (sa != 0 && sa != 2) {
16354 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16355 tcg_gen_ext32u_tl(t0, t0);
16356 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16357 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16359 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16361 default: /* Invalid */
16362 MIPS_INVAL("MASK APPEND");
16363 generate_exception_end(ctx, EXCP_RI);
16367 #ifdef TARGET_MIPS64
16368 case OPC_DAPPEND_DSP:
16369 switch (MASK_DAPPEND(ctx->opcode)) {
16372 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16376 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16377 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16378 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16382 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16383 tcg_gen_shli_tl(t0, t0, 64 - sa);
16384 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16389 if (sa != 0 && sa != 2 && sa != 4) {
16390 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16391 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16392 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16395 default: /* Invalid */
16396 MIPS_INVAL("MASK DAPPEND");
16397 generate_exception_end(ctx, EXCP_RI);
16406 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16407 int ret, int v1, int v2, int check_ret)
16416 if ((ret == 0) && (check_ret == 1)) {
16417 /* Treat as NOP. */
16421 t0 = tcg_temp_new();
16422 t1 = tcg_temp_new();
16423 v1_t = tcg_temp_new();
16424 v2_t = tcg_temp_new();
16426 gen_load_gpr(v1_t, v1);
16427 gen_load_gpr(v2_t, v2);
16430 case OPC_EXTR_W_DSP:
16434 tcg_gen_movi_tl(t0, v2);
16435 tcg_gen_movi_tl(t1, v1);
16436 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16439 tcg_gen_movi_tl(t0, v2);
16440 tcg_gen_movi_tl(t1, v1);
16441 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16443 case OPC_EXTR_RS_W:
16444 tcg_gen_movi_tl(t0, v2);
16445 tcg_gen_movi_tl(t1, v1);
16446 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16449 tcg_gen_movi_tl(t0, v2);
16450 tcg_gen_movi_tl(t1, v1);
16451 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16453 case OPC_EXTRV_S_H:
16454 tcg_gen_movi_tl(t0, v2);
16455 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16458 tcg_gen_movi_tl(t0, v2);
16459 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16461 case OPC_EXTRV_R_W:
16462 tcg_gen_movi_tl(t0, v2);
16463 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16465 case OPC_EXTRV_RS_W:
16466 tcg_gen_movi_tl(t0, v2);
16467 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16470 tcg_gen_movi_tl(t0, v2);
16471 tcg_gen_movi_tl(t1, v1);
16472 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16475 tcg_gen_movi_tl(t0, v2);
16476 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16479 tcg_gen_movi_tl(t0, v2);
16480 tcg_gen_movi_tl(t1, v1);
16481 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16484 tcg_gen_movi_tl(t0, v2);
16485 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16488 imm = (ctx->opcode >> 20) & 0x3F;
16489 tcg_gen_movi_tl(t0, ret);
16490 tcg_gen_movi_tl(t1, imm);
16491 gen_helper_shilo(t0, t1, cpu_env);
16494 tcg_gen_movi_tl(t0, ret);
16495 gen_helper_shilo(t0, v1_t, cpu_env);
16498 tcg_gen_movi_tl(t0, ret);
16499 gen_helper_mthlip(t0, v1_t, cpu_env);
16502 imm = (ctx->opcode >> 11) & 0x3FF;
16503 tcg_gen_movi_tl(t0, imm);
16504 gen_helper_wrdsp(v1_t, t0, cpu_env);
16507 imm = (ctx->opcode >> 16) & 0x03FF;
16508 tcg_gen_movi_tl(t0, imm);
16509 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16513 #ifdef TARGET_MIPS64
16514 case OPC_DEXTR_W_DSP:
16518 tcg_gen_movi_tl(t0, ret);
16519 gen_helper_dmthlip(v1_t, t0, cpu_env);
16523 int shift = (ctx->opcode >> 19) & 0x7F;
16524 int ac = (ctx->opcode >> 11) & 0x03;
16525 tcg_gen_movi_tl(t0, shift);
16526 tcg_gen_movi_tl(t1, ac);
16527 gen_helper_dshilo(t0, t1, cpu_env);
16532 int ac = (ctx->opcode >> 11) & 0x03;
16533 tcg_gen_movi_tl(t0, ac);
16534 gen_helper_dshilo(v1_t, t0, cpu_env);
16538 tcg_gen_movi_tl(t0, v2);
16539 tcg_gen_movi_tl(t1, v1);
16541 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16544 tcg_gen_movi_tl(t0, v2);
16545 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16548 tcg_gen_movi_tl(t0, v2);
16549 tcg_gen_movi_tl(t1, v1);
16550 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16553 tcg_gen_movi_tl(t0, v2);
16554 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16557 tcg_gen_movi_tl(t0, v2);
16558 tcg_gen_movi_tl(t1, v1);
16559 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16561 case OPC_DEXTR_R_L:
16562 tcg_gen_movi_tl(t0, v2);
16563 tcg_gen_movi_tl(t1, v1);
16564 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16566 case OPC_DEXTR_RS_L:
16567 tcg_gen_movi_tl(t0, v2);
16568 tcg_gen_movi_tl(t1, v1);
16569 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16572 tcg_gen_movi_tl(t0, v2);
16573 tcg_gen_movi_tl(t1, v1);
16574 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16576 case OPC_DEXTR_R_W:
16577 tcg_gen_movi_tl(t0, v2);
16578 tcg_gen_movi_tl(t1, v1);
16579 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16581 case OPC_DEXTR_RS_W:
16582 tcg_gen_movi_tl(t0, v2);
16583 tcg_gen_movi_tl(t1, v1);
16584 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16586 case OPC_DEXTR_S_H:
16587 tcg_gen_movi_tl(t0, v2);
16588 tcg_gen_movi_tl(t1, v1);
16589 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16591 case OPC_DEXTRV_S_H:
16592 tcg_gen_movi_tl(t0, v2);
16593 tcg_gen_movi_tl(t1, v1);
16594 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16597 tcg_gen_movi_tl(t0, v2);
16598 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16600 case OPC_DEXTRV_R_L:
16601 tcg_gen_movi_tl(t0, v2);
16602 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16604 case OPC_DEXTRV_RS_L:
16605 tcg_gen_movi_tl(t0, v2);
16606 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16609 tcg_gen_movi_tl(t0, v2);
16610 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16612 case OPC_DEXTRV_R_W:
16613 tcg_gen_movi_tl(t0, v2);
16614 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16616 case OPC_DEXTRV_RS_W:
16617 tcg_gen_movi_tl(t0, v2);
16618 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16627 tcg_temp_free(v1_t);
16628 tcg_temp_free(v2_t);
16631 /* End MIPSDSP functions. */
16633 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16635 int rs, rt, rd, sa;
16638 rs = (ctx->opcode >> 21) & 0x1f;
16639 rt = (ctx->opcode >> 16) & 0x1f;
16640 rd = (ctx->opcode >> 11) & 0x1f;
16641 sa = (ctx->opcode >> 6) & 0x1f;
16643 op1 = MASK_SPECIAL(ctx->opcode);
16646 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16648 case OPC_MULT ... OPC_DIVU:
16649 op2 = MASK_R6_MULDIV(ctx->opcode);
16659 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16662 MIPS_INVAL("special_r6 muldiv");
16663 generate_exception_end(ctx, EXCP_RI);
16669 gen_cond_move(ctx, op1, rd, rs, rt);
16673 if (rt == 0 && sa == 1) {
16674 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16675 We need additionally to check other fields */
16676 gen_cl(ctx, op1, rd, rs);
16678 generate_exception_end(ctx, EXCP_RI);
16682 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16683 gen_helper_do_semihosting(cpu_env);
16685 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16686 generate_exception_end(ctx, EXCP_RI);
16688 generate_exception_end(ctx, EXCP_DBp);
16692 #if defined(TARGET_MIPS64)
16694 check_mips_64(ctx);
16695 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16699 if (rt == 0 && sa == 1) {
16700 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16701 We need additionally to check other fields */
16702 check_mips_64(ctx);
16703 gen_cl(ctx, op1, rd, rs);
16705 generate_exception_end(ctx, EXCP_RI);
16708 case OPC_DMULT ... OPC_DDIVU:
16709 op2 = MASK_R6_MULDIV(ctx->opcode);
16719 check_mips_64(ctx);
16720 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16723 MIPS_INVAL("special_r6 muldiv");
16724 generate_exception_end(ctx, EXCP_RI);
16729 default: /* Invalid */
16730 MIPS_INVAL("special_r6");
16731 generate_exception_end(ctx, EXCP_RI);
16736 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16738 int rs, rt, rd, sa;
16741 rs = (ctx->opcode >> 21) & 0x1f;
16742 rt = (ctx->opcode >> 16) & 0x1f;
16743 rd = (ctx->opcode >> 11) & 0x1f;
16744 sa = (ctx->opcode >> 6) & 0x1f;
16746 op1 = MASK_SPECIAL(ctx->opcode);
16748 case OPC_MOVN: /* Conditional move */
16750 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16751 INSN_LOONGSON2E | INSN_LOONGSON2F);
16752 gen_cond_move(ctx, op1, rd, rs, rt);
16754 case OPC_MFHI: /* Move from HI/LO */
16756 gen_HILO(ctx, op1, rs & 3, rd);
16759 case OPC_MTLO: /* Move to HI/LO */
16760 gen_HILO(ctx, op1, rd & 3, rs);
16763 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16764 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16765 check_cp1_enabled(ctx);
16766 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16767 (ctx->opcode >> 16) & 1);
16769 generate_exception_err(ctx, EXCP_CpU, 1);
16775 check_insn(ctx, INSN_VR54XX);
16776 op1 = MASK_MUL_VR54XX(ctx->opcode);
16777 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16779 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16784 gen_muldiv(ctx, op1, 0, rs, rt);
16786 #if defined(TARGET_MIPS64)
16787 case OPC_DMULT ... OPC_DDIVU:
16788 check_insn(ctx, ISA_MIPS3);
16789 check_mips_64(ctx);
16790 gen_muldiv(ctx, op1, 0, rs, rt);
16794 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16797 #ifdef MIPS_STRICT_STANDARD
16798 MIPS_INVAL("SPIM");
16799 generate_exception_end(ctx, EXCP_RI);
16801 /* Implemented as RI exception for now. */
16802 MIPS_INVAL("spim (unofficial)");
16803 generate_exception_end(ctx, EXCP_RI);
16806 default: /* Invalid */
16807 MIPS_INVAL("special_legacy");
16808 generate_exception_end(ctx, EXCP_RI);
16813 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
16815 int rs, rt, rd, sa;
16818 rs = (ctx->opcode >> 21) & 0x1f;
16819 rt = (ctx->opcode >> 16) & 0x1f;
16820 rd = (ctx->opcode >> 11) & 0x1f;
16821 sa = (ctx->opcode >> 6) & 0x1f;
16823 op1 = MASK_SPECIAL(ctx->opcode);
16825 case OPC_SLL: /* Shift with immediate */
16826 if (sa == 5 && rd == 0 &&
16827 rs == 0 && rt == 0) { /* PAUSE */
16828 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16829 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16830 generate_exception_end(ctx, EXCP_RI);
16836 gen_shift_imm(ctx, op1, rd, rt, sa);
16839 switch ((ctx->opcode >> 21) & 0x1f) {
16841 /* rotr is decoded as srl on non-R2 CPUs */
16842 if (ctx->insn_flags & ISA_MIPS32R2) {
16847 gen_shift_imm(ctx, op1, rd, rt, sa);
16850 generate_exception_end(ctx, EXCP_RI);
16854 case OPC_ADD ... OPC_SUBU:
16855 gen_arith(ctx, op1, rd, rs, rt);
16857 case OPC_SLLV: /* Shifts */
16859 gen_shift(ctx, op1, rd, rs, rt);
16862 switch ((ctx->opcode >> 6) & 0x1f) {
16864 /* rotrv is decoded as srlv on non-R2 CPUs */
16865 if (ctx->insn_flags & ISA_MIPS32R2) {
16870 gen_shift(ctx, op1, rd, rs, rt);
16873 generate_exception_end(ctx, EXCP_RI);
16877 case OPC_SLT: /* Set on less than */
16879 gen_slt(ctx, op1, rd, rs, rt);
16881 case OPC_AND: /* Logic*/
16885 gen_logic(ctx, op1, rd, rs, rt);
16888 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16890 case OPC_TGE ... OPC_TEQ: /* Traps */
16892 check_insn(ctx, ISA_MIPS2);
16893 gen_trap(ctx, op1, rs, rt, -1);
16895 case OPC_LSA: /* OPC_PMON */
16896 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16897 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16898 decode_opc_special_r6(env, ctx);
16900 /* Pmon entry point, also R4010 selsl */
16901 #ifdef MIPS_STRICT_STANDARD
16902 MIPS_INVAL("PMON / selsl");
16903 generate_exception_end(ctx, EXCP_RI);
16905 gen_helper_0e0i(pmon, sa);
16910 generate_exception_end(ctx, EXCP_SYSCALL);
16913 generate_exception_end(ctx, EXCP_BREAK);
16916 check_insn(ctx, ISA_MIPS2);
16917 /* Treat as NOP. */
16920 #if defined(TARGET_MIPS64)
16921 /* MIPS64 specific opcodes */
16926 check_insn(ctx, ISA_MIPS3);
16927 check_mips_64(ctx);
16928 gen_shift_imm(ctx, op1, rd, rt, sa);
16931 switch ((ctx->opcode >> 21) & 0x1f) {
16933 /* drotr is decoded as dsrl on non-R2 CPUs */
16934 if (ctx->insn_flags & ISA_MIPS32R2) {
16939 check_insn(ctx, ISA_MIPS3);
16940 check_mips_64(ctx);
16941 gen_shift_imm(ctx, op1, rd, rt, sa);
16944 generate_exception_end(ctx, EXCP_RI);
16949 switch ((ctx->opcode >> 21) & 0x1f) {
16951 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16952 if (ctx->insn_flags & ISA_MIPS32R2) {
16957 check_insn(ctx, ISA_MIPS3);
16958 check_mips_64(ctx);
16959 gen_shift_imm(ctx, op1, rd, rt, sa);
16962 generate_exception_end(ctx, EXCP_RI);
16966 case OPC_DADD ... OPC_DSUBU:
16967 check_insn(ctx, ISA_MIPS3);
16968 check_mips_64(ctx);
16969 gen_arith(ctx, op1, rd, rs, rt);
16973 check_insn(ctx, ISA_MIPS3);
16974 check_mips_64(ctx);
16975 gen_shift(ctx, op1, rd, rs, rt);
16978 switch ((ctx->opcode >> 6) & 0x1f) {
16980 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16981 if (ctx->insn_flags & ISA_MIPS32R2) {
16986 check_insn(ctx, ISA_MIPS3);
16987 check_mips_64(ctx);
16988 gen_shift(ctx, op1, rd, rs, rt);
16991 generate_exception_end(ctx, EXCP_RI);
16996 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16997 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16998 decode_opc_special_r6(env, ctx);
17003 if (ctx->insn_flags & ISA_MIPS32R6) {
17004 decode_opc_special_r6(env, ctx);
17006 decode_opc_special_legacy(env, ctx);
17011 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17016 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17018 rs = (ctx->opcode >> 21) & 0x1f;
17019 rt = (ctx->opcode >> 16) & 0x1f;
17020 rd = (ctx->opcode >> 11) & 0x1f;
17022 op1 = MASK_SPECIAL2(ctx->opcode);
17024 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17025 case OPC_MSUB ... OPC_MSUBU:
17026 check_insn(ctx, ISA_MIPS32);
17027 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17030 gen_arith(ctx, op1, rd, rs, rt);
17033 case OPC_DIVU_G_2F:
17034 case OPC_MULT_G_2F:
17035 case OPC_MULTU_G_2F:
17037 case OPC_MODU_G_2F:
17038 check_insn(ctx, INSN_LOONGSON2F);
17039 gen_loongson_integer(ctx, op1, rd, rs, rt);
17043 check_insn(ctx, ISA_MIPS32);
17044 gen_cl(ctx, op1, rd, rs);
17047 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17048 gen_helper_do_semihosting(cpu_env);
17050 /* XXX: not clear which exception should be raised
17051 * when in debug mode...
17053 check_insn(ctx, ISA_MIPS32);
17054 generate_exception_end(ctx, EXCP_DBp);
17057 #if defined(TARGET_MIPS64)
17060 check_insn(ctx, ISA_MIPS64);
17061 check_mips_64(ctx);
17062 gen_cl(ctx, op1, rd, rs);
17064 case OPC_DMULT_G_2F:
17065 case OPC_DMULTU_G_2F:
17066 case OPC_DDIV_G_2F:
17067 case OPC_DDIVU_G_2F:
17068 case OPC_DMOD_G_2F:
17069 case OPC_DMODU_G_2F:
17070 check_insn(ctx, INSN_LOONGSON2F);
17071 gen_loongson_integer(ctx, op1, rd, rs, rt);
17074 default: /* Invalid */
17075 MIPS_INVAL("special2_legacy");
17076 generate_exception_end(ctx, EXCP_RI);
17081 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17083 int rs, rt, rd, sa;
17087 rs = (ctx->opcode >> 21) & 0x1f;
17088 rt = (ctx->opcode >> 16) & 0x1f;
17089 rd = (ctx->opcode >> 11) & 0x1f;
17090 sa = (ctx->opcode >> 6) & 0x1f;
17091 imm = (int16_t)ctx->opcode >> 7;
17093 op1 = MASK_SPECIAL3(ctx->opcode);
17097 /* hint codes 24-31 are reserved and signal RI */
17098 generate_exception_end(ctx, EXCP_RI);
17100 /* Treat as NOP. */
17103 /* Treat as NOP. */
17106 gen_st_cond(ctx, op1, rt, rs, imm);
17109 gen_ld(ctx, op1, rt, rs, imm);
17114 /* Treat as NOP. */
17117 op2 = MASK_BSHFL(ctx->opcode);
17119 case OPC_ALIGN ... OPC_ALIGN_END:
17120 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17123 gen_bitswap(ctx, op2, rd, rt);
17128 #if defined(TARGET_MIPS64)
17130 gen_st_cond(ctx, op1, rt, rs, imm);
17133 gen_ld(ctx, op1, rt, rs, imm);
17136 check_mips_64(ctx);
17139 /* Treat as NOP. */
17142 op2 = MASK_DBSHFL(ctx->opcode);
17144 case OPC_DALIGN ... OPC_DALIGN_END:
17145 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17148 gen_bitswap(ctx, op2, rd, rt);
17155 default: /* Invalid */
17156 MIPS_INVAL("special3_r6");
17157 generate_exception_end(ctx, EXCP_RI);
17162 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17167 rs = (ctx->opcode >> 21) & 0x1f;
17168 rt = (ctx->opcode >> 16) & 0x1f;
17169 rd = (ctx->opcode >> 11) & 0x1f;
17171 op1 = MASK_SPECIAL3(ctx->opcode);
17173 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17174 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17175 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17176 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17177 * the same mask and op1. */
17178 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17179 op2 = MASK_ADDUH_QB(ctx->opcode);
17182 case OPC_ADDUH_R_QB:
17184 case OPC_ADDQH_R_PH:
17186 case OPC_ADDQH_R_W:
17188 case OPC_SUBUH_R_QB:
17190 case OPC_SUBQH_R_PH:
17192 case OPC_SUBQH_R_W:
17193 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17198 case OPC_MULQ_RS_W:
17199 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17202 MIPS_INVAL("MASK ADDUH.QB");
17203 generate_exception_end(ctx, EXCP_RI);
17206 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17207 gen_loongson_integer(ctx, op1, rd, rs, rt);
17209 generate_exception_end(ctx, EXCP_RI);
17213 op2 = MASK_LX(ctx->opcode);
17215 #if defined(TARGET_MIPS64)
17221 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17223 default: /* Invalid */
17224 MIPS_INVAL("MASK LX");
17225 generate_exception_end(ctx, EXCP_RI);
17229 case OPC_ABSQ_S_PH_DSP:
17230 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17232 case OPC_ABSQ_S_QB:
17233 case OPC_ABSQ_S_PH:
17235 case OPC_PRECEQ_W_PHL:
17236 case OPC_PRECEQ_W_PHR:
17237 case OPC_PRECEQU_PH_QBL:
17238 case OPC_PRECEQU_PH_QBR:
17239 case OPC_PRECEQU_PH_QBLA:
17240 case OPC_PRECEQU_PH_QBRA:
17241 case OPC_PRECEU_PH_QBL:
17242 case OPC_PRECEU_PH_QBR:
17243 case OPC_PRECEU_PH_QBLA:
17244 case OPC_PRECEU_PH_QBRA:
17245 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17252 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17255 MIPS_INVAL("MASK ABSQ_S.PH");
17256 generate_exception_end(ctx, EXCP_RI);
17260 case OPC_ADDU_QB_DSP:
17261 op2 = MASK_ADDU_QB(ctx->opcode);
17264 case OPC_ADDQ_S_PH:
17267 case OPC_ADDU_S_QB:
17269 case OPC_ADDU_S_PH:
17271 case OPC_SUBQ_S_PH:
17274 case OPC_SUBU_S_QB:
17276 case OPC_SUBU_S_PH:
17280 case OPC_RADDU_W_QB:
17281 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17283 case OPC_MULEU_S_PH_QBL:
17284 case OPC_MULEU_S_PH_QBR:
17285 case OPC_MULQ_RS_PH:
17286 case OPC_MULEQ_S_W_PHL:
17287 case OPC_MULEQ_S_W_PHR:
17288 case OPC_MULQ_S_PH:
17289 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17291 default: /* Invalid */
17292 MIPS_INVAL("MASK ADDU.QB");
17293 generate_exception_end(ctx, EXCP_RI);
17298 case OPC_CMPU_EQ_QB_DSP:
17299 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17301 case OPC_PRECR_SRA_PH_W:
17302 case OPC_PRECR_SRA_R_PH_W:
17303 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17305 case OPC_PRECR_QB_PH:
17306 case OPC_PRECRQ_QB_PH:
17307 case OPC_PRECRQ_PH_W:
17308 case OPC_PRECRQ_RS_PH_W:
17309 case OPC_PRECRQU_S_QB_PH:
17310 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17312 case OPC_CMPU_EQ_QB:
17313 case OPC_CMPU_LT_QB:
17314 case OPC_CMPU_LE_QB:
17315 case OPC_CMP_EQ_PH:
17316 case OPC_CMP_LT_PH:
17317 case OPC_CMP_LE_PH:
17318 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17320 case OPC_CMPGU_EQ_QB:
17321 case OPC_CMPGU_LT_QB:
17322 case OPC_CMPGU_LE_QB:
17323 case OPC_CMPGDU_EQ_QB:
17324 case OPC_CMPGDU_LT_QB:
17325 case OPC_CMPGDU_LE_QB:
17328 case OPC_PACKRL_PH:
17329 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17331 default: /* Invalid */
17332 MIPS_INVAL("MASK CMPU.EQ.QB");
17333 generate_exception_end(ctx, EXCP_RI);
17337 case OPC_SHLL_QB_DSP:
17338 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17340 case OPC_DPA_W_PH_DSP:
17341 op2 = MASK_DPA_W_PH(ctx->opcode);
17343 case OPC_DPAU_H_QBL:
17344 case OPC_DPAU_H_QBR:
17345 case OPC_DPSU_H_QBL:
17346 case OPC_DPSU_H_QBR:
17348 case OPC_DPAX_W_PH:
17349 case OPC_DPAQ_S_W_PH:
17350 case OPC_DPAQX_S_W_PH:
17351 case OPC_DPAQX_SA_W_PH:
17353 case OPC_DPSX_W_PH:
17354 case OPC_DPSQ_S_W_PH:
17355 case OPC_DPSQX_S_W_PH:
17356 case OPC_DPSQX_SA_W_PH:
17357 case OPC_MULSAQ_S_W_PH:
17358 case OPC_DPAQ_SA_L_W:
17359 case OPC_DPSQ_SA_L_W:
17360 case OPC_MAQ_S_W_PHL:
17361 case OPC_MAQ_S_W_PHR:
17362 case OPC_MAQ_SA_W_PHL:
17363 case OPC_MAQ_SA_W_PHR:
17364 case OPC_MULSA_W_PH:
17365 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17367 default: /* Invalid */
17368 MIPS_INVAL("MASK DPAW.PH");
17369 generate_exception_end(ctx, EXCP_RI);
17374 op2 = MASK_INSV(ctx->opcode);
17385 t0 = tcg_temp_new();
17386 t1 = tcg_temp_new();
17388 gen_load_gpr(t0, rt);
17389 gen_load_gpr(t1, rs);
17391 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17397 default: /* Invalid */
17398 MIPS_INVAL("MASK INSV");
17399 generate_exception_end(ctx, EXCP_RI);
17403 case OPC_APPEND_DSP:
17404 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17406 case OPC_EXTR_W_DSP:
17407 op2 = MASK_EXTR_W(ctx->opcode);
17411 case OPC_EXTR_RS_W:
17413 case OPC_EXTRV_S_H:
17415 case OPC_EXTRV_R_W:
17416 case OPC_EXTRV_RS_W:
17421 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17424 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17430 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17432 default: /* Invalid */
17433 MIPS_INVAL("MASK EXTR.W");
17434 generate_exception_end(ctx, EXCP_RI);
17438 #if defined(TARGET_MIPS64)
17439 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17440 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17441 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17442 check_insn(ctx, INSN_LOONGSON2E);
17443 gen_loongson_integer(ctx, op1, rd, rs, rt);
17445 case OPC_ABSQ_S_QH_DSP:
17446 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17448 case OPC_PRECEQ_L_PWL:
17449 case OPC_PRECEQ_L_PWR:
17450 case OPC_PRECEQ_PW_QHL:
17451 case OPC_PRECEQ_PW_QHR:
17452 case OPC_PRECEQ_PW_QHLA:
17453 case OPC_PRECEQ_PW_QHRA:
17454 case OPC_PRECEQU_QH_OBL:
17455 case OPC_PRECEQU_QH_OBR:
17456 case OPC_PRECEQU_QH_OBLA:
17457 case OPC_PRECEQU_QH_OBRA:
17458 case OPC_PRECEU_QH_OBL:
17459 case OPC_PRECEU_QH_OBR:
17460 case OPC_PRECEU_QH_OBLA:
17461 case OPC_PRECEU_QH_OBRA:
17462 case OPC_ABSQ_S_OB:
17463 case OPC_ABSQ_S_PW:
17464 case OPC_ABSQ_S_QH:
17465 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17473 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17475 default: /* Invalid */
17476 MIPS_INVAL("MASK ABSQ_S.QH");
17477 generate_exception_end(ctx, EXCP_RI);
17481 case OPC_ADDU_OB_DSP:
17482 op2 = MASK_ADDU_OB(ctx->opcode);
17484 case OPC_RADDU_L_OB:
17486 case OPC_SUBQ_S_PW:
17488 case OPC_SUBQ_S_QH:
17490 case OPC_SUBU_S_OB:
17492 case OPC_SUBU_S_QH:
17494 case OPC_SUBUH_R_OB:
17496 case OPC_ADDQ_S_PW:
17498 case OPC_ADDQ_S_QH:
17500 case OPC_ADDU_S_OB:
17502 case OPC_ADDU_S_QH:
17504 case OPC_ADDUH_R_OB:
17505 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17507 case OPC_MULEQ_S_PW_QHL:
17508 case OPC_MULEQ_S_PW_QHR:
17509 case OPC_MULEU_S_QH_OBL:
17510 case OPC_MULEU_S_QH_OBR:
17511 case OPC_MULQ_RS_QH:
17512 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17514 default: /* Invalid */
17515 MIPS_INVAL("MASK ADDU.OB");
17516 generate_exception_end(ctx, EXCP_RI);
17520 case OPC_CMPU_EQ_OB_DSP:
17521 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17523 case OPC_PRECR_SRA_QH_PW:
17524 case OPC_PRECR_SRA_R_QH_PW:
17525 /* Return value is rt. */
17526 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17528 case OPC_PRECR_OB_QH:
17529 case OPC_PRECRQ_OB_QH:
17530 case OPC_PRECRQ_PW_L:
17531 case OPC_PRECRQ_QH_PW:
17532 case OPC_PRECRQ_RS_QH_PW:
17533 case OPC_PRECRQU_S_OB_QH:
17534 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17536 case OPC_CMPU_EQ_OB:
17537 case OPC_CMPU_LT_OB:
17538 case OPC_CMPU_LE_OB:
17539 case OPC_CMP_EQ_QH:
17540 case OPC_CMP_LT_QH:
17541 case OPC_CMP_LE_QH:
17542 case OPC_CMP_EQ_PW:
17543 case OPC_CMP_LT_PW:
17544 case OPC_CMP_LE_PW:
17545 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17547 case OPC_CMPGDU_EQ_OB:
17548 case OPC_CMPGDU_LT_OB:
17549 case OPC_CMPGDU_LE_OB:
17550 case OPC_CMPGU_EQ_OB:
17551 case OPC_CMPGU_LT_OB:
17552 case OPC_CMPGU_LE_OB:
17553 case OPC_PACKRL_PW:
17557 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17559 default: /* Invalid */
17560 MIPS_INVAL("MASK CMPU_EQ.OB");
17561 generate_exception_end(ctx, EXCP_RI);
17565 case OPC_DAPPEND_DSP:
17566 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17568 case OPC_DEXTR_W_DSP:
17569 op2 = MASK_DEXTR_W(ctx->opcode);
17576 case OPC_DEXTR_R_L:
17577 case OPC_DEXTR_RS_L:
17579 case OPC_DEXTR_R_W:
17580 case OPC_DEXTR_RS_W:
17581 case OPC_DEXTR_S_H:
17583 case OPC_DEXTRV_R_L:
17584 case OPC_DEXTRV_RS_L:
17585 case OPC_DEXTRV_S_H:
17587 case OPC_DEXTRV_R_W:
17588 case OPC_DEXTRV_RS_W:
17589 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17594 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17596 default: /* Invalid */
17597 MIPS_INVAL("MASK EXTR.W");
17598 generate_exception_end(ctx, EXCP_RI);
17602 case OPC_DPAQ_W_QH_DSP:
17603 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17605 case OPC_DPAU_H_OBL:
17606 case OPC_DPAU_H_OBR:
17607 case OPC_DPSU_H_OBL:
17608 case OPC_DPSU_H_OBR:
17610 case OPC_DPAQ_S_W_QH:
17612 case OPC_DPSQ_S_W_QH:
17613 case OPC_MULSAQ_S_W_QH:
17614 case OPC_DPAQ_SA_L_PW:
17615 case OPC_DPSQ_SA_L_PW:
17616 case OPC_MULSAQ_S_L_PW:
17617 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17619 case OPC_MAQ_S_W_QHLL:
17620 case OPC_MAQ_S_W_QHLR:
17621 case OPC_MAQ_S_W_QHRL:
17622 case OPC_MAQ_S_W_QHRR:
17623 case OPC_MAQ_SA_W_QHLL:
17624 case OPC_MAQ_SA_W_QHLR:
17625 case OPC_MAQ_SA_W_QHRL:
17626 case OPC_MAQ_SA_W_QHRR:
17627 case OPC_MAQ_S_L_PWL:
17628 case OPC_MAQ_S_L_PWR:
17633 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17635 default: /* Invalid */
17636 MIPS_INVAL("MASK DPAQ.W.QH");
17637 generate_exception_end(ctx, EXCP_RI);
17641 case OPC_DINSV_DSP:
17642 op2 = MASK_INSV(ctx->opcode);
17653 t0 = tcg_temp_new();
17654 t1 = tcg_temp_new();
17656 gen_load_gpr(t0, rt);
17657 gen_load_gpr(t1, rs);
17659 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
17665 default: /* Invalid */
17666 MIPS_INVAL("MASK DINSV");
17667 generate_exception_end(ctx, EXCP_RI);
17671 case OPC_SHLL_OB_DSP:
17672 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17675 default: /* Invalid */
17676 MIPS_INVAL("special3_legacy");
17677 generate_exception_end(ctx, EXCP_RI);
17682 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17684 int rs, rt, rd, sa;
17687 rs = (ctx->opcode >> 21) & 0x1f;
17688 rt = (ctx->opcode >> 16) & 0x1f;
17689 rd = (ctx->opcode >> 11) & 0x1f;
17690 sa = (ctx->opcode >> 6) & 0x1f;
17692 op1 = MASK_SPECIAL3(ctx->opcode);
17696 check_insn(ctx, ISA_MIPS32R2);
17697 gen_bitops(ctx, op1, rt, rs, sa, rd);
17700 op2 = MASK_BSHFL(ctx->opcode);
17702 case OPC_ALIGN ... OPC_ALIGN_END:
17704 check_insn(ctx, ISA_MIPS32R6);
17705 decode_opc_special3_r6(env, ctx);
17708 check_insn(ctx, ISA_MIPS32R2);
17709 gen_bshfl(ctx, op2, rt, rd);
17713 #if defined(TARGET_MIPS64)
17714 case OPC_DEXTM ... OPC_DEXT:
17715 case OPC_DINSM ... OPC_DINS:
17716 check_insn(ctx, ISA_MIPS64R2);
17717 check_mips_64(ctx);
17718 gen_bitops(ctx, op1, rt, rs, sa, rd);
17721 op2 = MASK_DBSHFL(ctx->opcode);
17723 case OPC_DALIGN ... OPC_DALIGN_END:
17725 check_insn(ctx, ISA_MIPS32R6);
17726 decode_opc_special3_r6(env, ctx);
17729 check_insn(ctx, ISA_MIPS64R2);
17730 check_mips_64(ctx);
17731 op2 = MASK_DBSHFL(ctx->opcode);
17732 gen_bshfl(ctx, op2, rt, rd);
17738 gen_rdhwr(ctx, rt, rd);
17741 check_insn(ctx, ASE_MT);
17743 TCGv t0 = tcg_temp_new();
17744 TCGv t1 = tcg_temp_new();
17746 gen_load_gpr(t0, rt);
17747 gen_load_gpr(t1, rs);
17748 gen_helper_fork(t0, t1);
17754 check_insn(ctx, ASE_MT);
17756 TCGv t0 = tcg_temp_new();
17758 gen_load_gpr(t0, rs);
17759 gen_helper_yield(t0, cpu_env, t0);
17760 gen_store_gpr(t0, rd);
17765 if (ctx->insn_flags & ISA_MIPS32R6) {
17766 decode_opc_special3_r6(env, ctx);
17768 decode_opc_special3_legacy(env, ctx);
17773 /* MIPS SIMD Architecture (MSA) */
17774 static inline int check_msa_access(DisasContext *ctx)
17776 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17777 !(ctx->hflags & MIPS_HFLAG_F64))) {
17778 generate_exception_end(ctx, EXCP_RI);
17782 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17783 if (ctx->insn_flags & ASE_MSA) {
17784 generate_exception_end(ctx, EXCP_MSADIS);
17787 generate_exception_end(ctx, EXCP_RI);
17794 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17796 /* generates tcg ops to check if any element is 0 */
17797 /* Note this function only works with MSA_WRLEN = 128 */
17798 uint64_t eval_zero_or_big = 0;
17799 uint64_t eval_big = 0;
17800 TCGv_i64 t0 = tcg_temp_new_i64();
17801 TCGv_i64 t1 = tcg_temp_new_i64();
17804 eval_zero_or_big = 0x0101010101010101ULL;
17805 eval_big = 0x8080808080808080ULL;
17808 eval_zero_or_big = 0x0001000100010001ULL;
17809 eval_big = 0x8000800080008000ULL;
17812 eval_zero_or_big = 0x0000000100000001ULL;
17813 eval_big = 0x8000000080000000ULL;
17816 eval_zero_or_big = 0x0000000000000001ULL;
17817 eval_big = 0x8000000000000000ULL;
17820 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17821 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17822 tcg_gen_andi_i64(t0, t0, eval_big);
17823 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17824 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17825 tcg_gen_andi_i64(t1, t1, eval_big);
17826 tcg_gen_or_i64(t0, t0, t1);
17827 /* if all bits are zero then all elements are not zero */
17828 /* if some bit is non-zero then some element is zero */
17829 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17830 tcg_gen_trunc_i64_tl(tresult, t0);
17831 tcg_temp_free_i64(t0);
17832 tcg_temp_free_i64(t1);
17835 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17837 uint8_t df = (ctx->opcode >> 21) & 0x3;
17838 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17839 int64_t s16 = (int16_t)ctx->opcode;
17841 check_msa_access(ctx);
17843 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
17844 generate_exception_end(ctx, EXCP_RI);
17851 TCGv_i64 t0 = tcg_temp_new_i64();
17852 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17853 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17854 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17855 tcg_gen_trunc_i64_tl(bcond, t0);
17856 tcg_temp_free_i64(t0);
17863 gen_check_zero_element(bcond, df, wt);
17869 gen_check_zero_element(bcond, df, wt);
17870 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17874 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17876 ctx->hflags |= MIPS_HFLAG_BC;
17877 ctx->hflags |= MIPS_HFLAG_BDS32;
17880 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17882 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17883 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17884 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17885 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17887 TCGv_i32 twd = tcg_const_i32(wd);
17888 TCGv_i32 tws = tcg_const_i32(ws);
17889 TCGv_i32 ti8 = tcg_const_i32(i8);
17891 switch (MASK_MSA_I8(ctx->opcode)) {
17893 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17896 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17899 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17902 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17905 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17908 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17911 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17917 uint8_t df = (ctx->opcode >> 24) & 0x3;
17918 if (df == DF_DOUBLE) {
17919 generate_exception_end(ctx, EXCP_RI);
17921 TCGv_i32 tdf = tcg_const_i32(df);
17922 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
17923 tcg_temp_free_i32(tdf);
17928 MIPS_INVAL("MSA instruction");
17929 generate_exception_end(ctx, EXCP_RI);
17933 tcg_temp_free_i32(twd);
17934 tcg_temp_free_i32(tws);
17935 tcg_temp_free_i32(ti8);
17938 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17940 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17941 uint8_t df = (ctx->opcode >> 21) & 0x3;
17942 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17943 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17944 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17945 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17947 TCGv_i32 tdf = tcg_const_i32(df);
17948 TCGv_i32 twd = tcg_const_i32(wd);
17949 TCGv_i32 tws = tcg_const_i32(ws);
17950 TCGv_i32 timm = tcg_temp_new_i32();
17951 tcg_gen_movi_i32(timm, u5);
17953 switch (MASK_MSA_I5(ctx->opcode)) {
17955 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
17958 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
17960 case OPC_MAXI_S_df:
17961 tcg_gen_movi_i32(timm, s5);
17962 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
17964 case OPC_MAXI_U_df:
17965 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
17967 case OPC_MINI_S_df:
17968 tcg_gen_movi_i32(timm, s5);
17969 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
17971 case OPC_MINI_U_df:
17972 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
17975 tcg_gen_movi_i32(timm, s5);
17976 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
17978 case OPC_CLTI_S_df:
17979 tcg_gen_movi_i32(timm, s5);
17980 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
17982 case OPC_CLTI_U_df:
17983 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
17985 case OPC_CLEI_S_df:
17986 tcg_gen_movi_i32(timm, s5);
17987 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
17989 case OPC_CLEI_U_df:
17990 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
17994 int32_t s10 = sextract32(ctx->opcode, 11, 10);
17995 tcg_gen_movi_i32(timm, s10);
17996 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18000 MIPS_INVAL("MSA instruction");
18001 generate_exception_end(ctx, EXCP_RI);
18005 tcg_temp_free_i32(tdf);
18006 tcg_temp_free_i32(twd);
18007 tcg_temp_free_i32(tws);
18008 tcg_temp_free_i32(timm);
18011 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18013 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18014 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18015 uint32_t df = 0, m = 0;
18016 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18017 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18024 if ((dfm & 0x40) == 0x00) {
18027 } else if ((dfm & 0x60) == 0x40) {
18030 } else if ((dfm & 0x70) == 0x60) {
18033 } else if ((dfm & 0x78) == 0x70) {
18037 generate_exception_end(ctx, EXCP_RI);
18041 tdf = tcg_const_i32(df);
18042 tm = tcg_const_i32(m);
18043 twd = tcg_const_i32(wd);
18044 tws = tcg_const_i32(ws);
18046 switch (MASK_MSA_BIT(ctx->opcode)) {
18048 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18051 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18054 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18057 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18060 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18063 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18065 case OPC_BINSLI_df:
18066 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18068 case OPC_BINSRI_df:
18069 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18072 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18075 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18078 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18081 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18084 MIPS_INVAL("MSA instruction");
18085 generate_exception_end(ctx, EXCP_RI);
18089 tcg_temp_free_i32(tdf);
18090 tcg_temp_free_i32(tm);
18091 tcg_temp_free_i32(twd);
18092 tcg_temp_free_i32(tws);
18095 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18097 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18098 uint8_t df = (ctx->opcode >> 21) & 0x3;
18099 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18100 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18101 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18103 TCGv_i32 tdf = tcg_const_i32(df);
18104 TCGv_i32 twd = tcg_const_i32(wd);
18105 TCGv_i32 tws = tcg_const_i32(ws);
18106 TCGv_i32 twt = tcg_const_i32(wt);
18108 switch (MASK_MSA_3R(ctx->opcode)) {
18110 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18113 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18116 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18119 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18121 case OPC_SUBS_S_df:
18122 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18125 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18128 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18131 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18134 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18137 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18139 case OPC_ADDS_A_df:
18140 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18142 case OPC_SUBS_U_df:
18143 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18146 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18149 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18152 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18155 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18158 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18161 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18163 case OPC_ADDS_S_df:
18164 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18166 case OPC_SUBSUS_U_df:
18167 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18170 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18173 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18176 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18179 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18182 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18185 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18187 case OPC_ADDS_U_df:
18188 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18190 case OPC_SUBSUU_S_df:
18191 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18194 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18197 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18200 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18203 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18206 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18208 case OPC_ASUB_S_df:
18209 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18212 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18215 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18218 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18221 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18224 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18227 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18229 case OPC_ASUB_U_df:
18230 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18233 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18236 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18239 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18242 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18244 case OPC_AVER_S_df:
18245 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18248 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18251 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18254 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18257 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18259 case OPC_AVER_U_df:
18260 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18263 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18266 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18269 case OPC_DOTP_S_df:
18270 case OPC_DOTP_U_df:
18271 case OPC_DPADD_S_df:
18272 case OPC_DPADD_U_df:
18273 case OPC_DPSUB_S_df:
18274 case OPC_HADD_S_df:
18275 case OPC_DPSUB_U_df:
18276 case OPC_HADD_U_df:
18277 case OPC_HSUB_S_df:
18278 case OPC_HSUB_U_df:
18279 if (df == DF_BYTE) {
18280 generate_exception_end(ctx, EXCP_RI);
18283 switch (MASK_MSA_3R(ctx->opcode)) {
18284 case OPC_DOTP_S_df:
18285 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18287 case OPC_DOTP_U_df:
18288 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18290 case OPC_DPADD_S_df:
18291 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18293 case OPC_DPADD_U_df:
18294 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18296 case OPC_DPSUB_S_df:
18297 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18299 case OPC_HADD_S_df:
18300 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18302 case OPC_DPSUB_U_df:
18303 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18305 case OPC_HADD_U_df:
18306 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18308 case OPC_HSUB_S_df:
18309 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18311 case OPC_HSUB_U_df:
18312 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18317 MIPS_INVAL("MSA instruction");
18318 generate_exception_end(ctx, EXCP_RI);
18321 tcg_temp_free_i32(twd);
18322 tcg_temp_free_i32(tws);
18323 tcg_temp_free_i32(twt);
18324 tcg_temp_free_i32(tdf);
18327 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18329 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18330 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18331 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18332 TCGv telm = tcg_temp_new();
18333 TCGv_i32 tsr = tcg_const_i32(source);
18334 TCGv_i32 tdt = tcg_const_i32(dest);
18336 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18338 gen_load_gpr(telm, source);
18339 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18342 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18343 gen_store_gpr(telm, dest);
18346 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18349 MIPS_INVAL("MSA instruction");
18350 generate_exception_end(ctx, EXCP_RI);
18354 tcg_temp_free(telm);
18355 tcg_temp_free_i32(tdt);
18356 tcg_temp_free_i32(tsr);
18359 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18362 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18363 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18364 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18366 TCGv_i32 tws = tcg_const_i32(ws);
18367 TCGv_i32 twd = tcg_const_i32(wd);
18368 TCGv_i32 tn = tcg_const_i32(n);
18369 TCGv_i32 tdf = tcg_const_i32(df);
18371 switch (MASK_MSA_ELM(ctx->opcode)) {
18373 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18375 case OPC_SPLATI_df:
18376 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18379 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18381 case OPC_COPY_S_df:
18382 case OPC_COPY_U_df:
18383 case OPC_INSERT_df:
18384 #if !defined(TARGET_MIPS64)
18385 /* Double format valid only for MIPS64 */
18386 if (df == DF_DOUBLE) {
18387 generate_exception_end(ctx, EXCP_RI);
18391 switch (MASK_MSA_ELM(ctx->opcode)) {
18392 case OPC_COPY_S_df:
18393 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18395 case OPC_COPY_U_df:
18396 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18398 case OPC_INSERT_df:
18399 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18404 MIPS_INVAL("MSA instruction");
18405 generate_exception_end(ctx, EXCP_RI);
18407 tcg_temp_free_i32(twd);
18408 tcg_temp_free_i32(tws);
18409 tcg_temp_free_i32(tn);
18410 tcg_temp_free_i32(tdf);
18413 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18415 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18416 uint32_t df = 0, n = 0;
18418 if ((dfn & 0x30) == 0x00) {
18421 } else if ((dfn & 0x38) == 0x20) {
18424 } else if ((dfn & 0x3c) == 0x30) {
18427 } else if ((dfn & 0x3e) == 0x38) {
18430 } else if (dfn == 0x3E) {
18431 /* CTCMSA, CFCMSA, MOVE.V */
18432 gen_msa_elm_3e(env, ctx);
18435 generate_exception_end(ctx, EXCP_RI);
18439 gen_msa_elm_df(env, ctx, df, n);
18442 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18444 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18445 uint8_t df = (ctx->opcode >> 21) & 0x1;
18446 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18447 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18448 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18450 TCGv_i32 twd = tcg_const_i32(wd);
18451 TCGv_i32 tws = tcg_const_i32(ws);
18452 TCGv_i32 twt = tcg_const_i32(wt);
18453 TCGv_i32 tdf = tcg_temp_new_i32();
18455 /* adjust df value for floating-point instruction */
18456 tcg_gen_movi_i32(tdf, df + 2);
18458 switch (MASK_MSA_3RF(ctx->opcode)) {
18460 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18463 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18466 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18469 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18472 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18475 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18478 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18481 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18484 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18487 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18490 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18493 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18496 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18499 tcg_gen_movi_i32(tdf, df + 1);
18500 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18503 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18506 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18508 case OPC_MADD_Q_df:
18509 tcg_gen_movi_i32(tdf, df + 1);
18510 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18513 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18515 case OPC_MSUB_Q_df:
18516 tcg_gen_movi_i32(tdf, df + 1);
18517 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18520 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18523 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18526 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18529 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18532 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18535 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18538 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18541 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18544 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18547 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18550 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18553 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18556 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18558 case OPC_MULR_Q_df:
18559 tcg_gen_movi_i32(tdf, df + 1);
18560 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18563 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18565 case OPC_FMIN_A_df:
18566 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18568 case OPC_MADDR_Q_df:
18569 tcg_gen_movi_i32(tdf, df + 1);
18570 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18573 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18576 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18578 case OPC_MSUBR_Q_df:
18579 tcg_gen_movi_i32(tdf, df + 1);
18580 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18583 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18585 case OPC_FMAX_A_df:
18586 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18589 MIPS_INVAL("MSA instruction");
18590 generate_exception_end(ctx, EXCP_RI);
18594 tcg_temp_free_i32(twd);
18595 tcg_temp_free_i32(tws);
18596 tcg_temp_free_i32(twt);
18597 tcg_temp_free_i32(tdf);
18600 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18602 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18603 (op & (0x7 << 18)))
18604 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18605 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18606 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18607 uint8_t df = (ctx->opcode >> 16) & 0x3;
18608 TCGv_i32 twd = tcg_const_i32(wd);
18609 TCGv_i32 tws = tcg_const_i32(ws);
18610 TCGv_i32 twt = tcg_const_i32(wt);
18611 TCGv_i32 tdf = tcg_const_i32(df);
18613 switch (MASK_MSA_2R(ctx->opcode)) {
18615 #if !defined(TARGET_MIPS64)
18616 /* Double format valid only for MIPS64 */
18617 if (df == DF_DOUBLE) {
18618 generate_exception_end(ctx, EXCP_RI);
18622 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18625 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18628 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18631 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18634 MIPS_INVAL("MSA instruction");
18635 generate_exception_end(ctx, EXCP_RI);
18639 tcg_temp_free_i32(twd);
18640 tcg_temp_free_i32(tws);
18641 tcg_temp_free_i32(twt);
18642 tcg_temp_free_i32(tdf);
18645 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18647 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18648 (op & (0xf << 17)))
18649 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18650 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18651 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18652 uint8_t df = (ctx->opcode >> 16) & 0x1;
18653 TCGv_i32 twd = tcg_const_i32(wd);
18654 TCGv_i32 tws = tcg_const_i32(ws);
18655 TCGv_i32 twt = tcg_const_i32(wt);
18656 /* adjust df value for floating-point instruction */
18657 TCGv_i32 tdf = tcg_const_i32(df + 2);
18659 switch (MASK_MSA_2RF(ctx->opcode)) {
18660 case OPC_FCLASS_df:
18661 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18663 case OPC_FTRUNC_S_df:
18664 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18666 case OPC_FTRUNC_U_df:
18667 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18670 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18672 case OPC_FRSQRT_df:
18673 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18676 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18679 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18682 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18684 case OPC_FEXUPL_df:
18685 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18687 case OPC_FEXUPR_df:
18688 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18691 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18694 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18696 case OPC_FTINT_S_df:
18697 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18699 case OPC_FTINT_U_df:
18700 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18702 case OPC_FFINT_S_df:
18703 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18705 case OPC_FFINT_U_df:
18706 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18710 tcg_temp_free_i32(twd);
18711 tcg_temp_free_i32(tws);
18712 tcg_temp_free_i32(twt);
18713 tcg_temp_free_i32(tdf);
18716 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18718 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18719 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18720 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18721 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18722 TCGv_i32 twd = tcg_const_i32(wd);
18723 TCGv_i32 tws = tcg_const_i32(ws);
18724 TCGv_i32 twt = tcg_const_i32(wt);
18726 switch (MASK_MSA_VEC(ctx->opcode)) {
18728 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18731 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18734 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18737 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18740 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18743 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18746 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18749 MIPS_INVAL("MSA instruction");
18750 generate_exception_end(ctx, EXCP_RI);
18754 tcg_temp_free_i32(twd);
18755 tcg_temp_free_i32(tws);
18756 tcg_temp_free_i32(twt);
18759 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18761 switch (MASK_MSA_VEC(ctx->opcode)) {
18769 gen_msa_vec_v(env, ctx);
18772 gen_msa_2r(env, ctx);
18775 gen_msa_2rf(env, ctx);
18778 MIPS_INVAL("MSA instruction");
18779 generate_exception_end(ctx, EXCP_RI);
18784 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18786 uint32_t opcode = ctx->opcode;
18787 check_insn(ctx, ASE_MSA);
18788 check_msa_access(ctx);
18790 switch (MASK_MSA_MINOR(opcode)) {
18791 case OPC_MSA_I8_00:
18792 case OPC_MSA_I8_01:
18793 case OPC_MSA_I8_02:
18794 gen_msa_i8(env, ctx);
18796 case OPC_MSA_I5_06:
18797 case OPC_MSA_I5_07:
18798 gen_msa_i5(env, ctx);
18800 case OPC_MSA_BIT_09:
18801 case OPC_MSA_BIT_0A:
18802 gen_msa_bit(env, ctx);
18804 case OPC_MSA_3R_0D:
18805 case OPC_MSA_3R_0E:
18806 case OPC_MSA_3R_0F:
18807 case OPC_MSA_3R_10:
18808 case OPC_MSA_3R_11:
18809 case OPC_MSA_3R_12:
18810 case OPC_MSA_3R_13:
18811 case OPC_MSA_3R_14:
18812 case OPC_MSA_3R_15:
18813 gen_msa_3r(env, ctx);
18816 gen_msa_elm(env, ctx);
18818 case OPC_MSA_3RF_1A:
18819 case OPC_MSA_3RF_1B:
18820 case OPC_MSA_3RF_1C:
18821 gen_msa_3rf(env, ctx);
18824 gen_msa_vec(env, ctx);
18835 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18836 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18837 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18838 uint8_t df = (ctx->opcode >> 0) & 0x3;
18840 TCGv_i32 twd = tcg_const_i32(wd);
18841 TCGv taddr = tcg_temp_new();
18842 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
18844 switch (MASK_MSA_MINOR(opcode)) {
18846 gen_helper_msa_ld_b(cpu_env, twd, taddr);
18849 gen_helper_msa_ld_h(cpu_env, twd, taddr);
18852 gen_helper_msa_ld_w(cpu_env, twd, taddr);
18855 gen_helper_msa_ld_d(cpu_env, twd, taddr);
18858 gen_helper_msa_st_b(cpu_env, twd, taddr);
18861 gen_helper_msa_st_h(cpu_env, twd, taddr);
18864 gen_helper_msa_st_w(cpu_env, twd, taddr);
18867 gen_helper_msa_st_d(cpu_env, twd, taddr);
18871 tcg_temp_free_i32(twd);
18872 tcg_temp_free(taddr);
18876 MIPS_INVAL("MSA instruction");
18877 generate_exception_end(ctx, EXCP_RI);
18883 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
18886 int rs, rt, rd, sa;
18890 /* make sure instructions are on a word boundary */
18891 if (ctx->pc & 0x3) {
18892 env->CP0_BadVAddr = ctx->pc;
18893 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
18897 /* Handle blikely not taken case */
18898 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
18899 TCGLabel *l1 = gen_new_label();
18901 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18902 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18903 gen_goto_tb(ctx, 1, ctx->pc + 4);
18907 op = MASK_OP_MAJOR(ctx->opcode);
18908 rs = (ctx->opcode >> 21) & 0x1f;
18909 rt = (ctx->opcode >> 16) & 0x1f;
18910 rd = (ctx->opcode >> 11) & 0x1f;
18911 sa = (ctx->opcode >> 6) & 0x1f;
18912 imm = (int16_t)ctx->opcode;
18915 decode_opc_special(env, ctx);
18918 decode_opc_special2_legacy(env, ctx);
18921 decode_opc_special3(env, ctx);
18924 op1 = MASK_REGIMM(ctx->opcode);
18926 case OPC_BLTZL: /* REGIMM branches */
18930 check_insn(ctx, ISA_MIPS2);
18931 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18935 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
18939 if (ctx->insn_flags & ISA_MIPS32R6) {
18941 /* OPC_NAL, OPC_BAL */
18942 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
18944 generate_exception_end(ctx, EXCP_RI);
18947 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
18950 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
18952 check_insn(ctx, ISA_MIPS2);
18953 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18954 gen_trap(ctx, op1, rs, -1, imm);
18957 check_insn(ctx, ISA_MIPS32R2);
18958 /* Break the TB to be able to sync copied instructions
18960 ctx->bstate = BS_STOP;
18962 case OPC_BPOSGE32: /* MIPS DSP branch */
18963 #if defined(TARGET_MIPS64)
18967 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
18969 #if defined(TARGET_MIPS64)
18971 check_insn(ctx, ISA_MIPS32R6);
18972 check_mips_64(ctx);
18974 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
18978 check_insn(ctx, ISA_MIPS32R6);
18979 check_mips_64(ctx);
18981 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
18985 default: /* Invalid */
18986 MIPS_INVAL("regimm");
18987 generate_exception_end(ctx, EXCP_RI);
18992 check_cp0_enabled(ctx);
18993 op1 = MASK_CP0(ctx->opcode);
19001 #if defined(TARGET_MIPS64)
19005 #ifndef CONFIG_USER_ONLY
19006 gen_cp0(env, ctx, op1, rt, rd);
19007 #endif /* !CONFIG_USER_ONLY */
19009 case OPC_C0_FIRST ... OPC_C0_LAST:
19010 #ifndef CONFIG_USER_ONLY
19011 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19012 #endif /* !CONFIG_USER_ONLY */
19015 #ifndef CONFIG_USER_ONLY
19018 TCGv t0 = tcg_temp_new();
19020 op2 = MASK_MFMC0(ctx->opcode);
19023 check_insn(ctx, ASE_MT);
19024 gen_helper_dmt(t0);
19025 gen_store_gpr(t0, rt);
19028 check_insn(ctx, ASE_MT);
19029 gen_helper_emt(t0);
19030 gen_store_gpr(t0, rt);
19033 check_insn(ctx, ASE_MT);
19034 gen_helper_dvpe(t0, cpu_env);
19035 gen_store_gpr(t0, rt);
19038 check_insn(ctx, ASE_MT);
19039 gen_helper_evpe(t0, cpu_env);
19040 gen_store_gpr(t0, rt);
19043 check_insn(ctx, ISA_MIPS32R2);
19044 save_cpu_state(ctx, 1);
19045 gen_helper_di(t0, cpu_env);
19046 gen_store_gpr(t0, rt);
19047 /* Stop translation as we may have switched
19048 the execution mode. */
19049 ctx->bstate = BS_STOP;
19052 check_insn(ctx, ISA_MIPS32R2);
19053 save_cpu_state(ctx, 1);
19054 gen_helper_ei(t0, cpu_env);
19055 gen_store_gpr(t0, rt);
19056 /* Stop translation as we may have switched
19057 the execution mode. */
19058 ctx->bstate = BS_STOP;
19060 default: /* Invalid */
19061 MIPS_INVAL("mfmc0");
19062 generate_exception_end(ctx, EXCP_RI);
19067 #endif /* !CONFIG_USER_ONLY */
19070 check_insn(ctx, ISA_MIPS32R2);
19071 gen_load_srsgpr(rt, rd);
19074 check_insn(ctx, ISA_MIPS32R2);
19075 gen_store_srsgpr(rt, rd);
19079 generate_exception_end(ctx, EXCP_RI);
19083 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19084 if (ctx->insn_flags & ISA_MIPS32R6) {
19085 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19086 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19089 /* Arithmetic with immediate opcode */
19090 gen_arith_imm(ctx, op, rt, rs, imm);
19094 gen_arith_imm(ctx, op, rt, rs, imm);
19096 case OPC_SLTI: /* Set on less than with immediate opcode */
19098 gen_slt_imm(ctx, op, rt, rs, imm);
19100 case OPC_ANDI: /* Arithmetic with immediate opcode */
19101 case OPC_LUI: /* OPC_AUI */
19104 gen_logic_imm(ctx, op, rt, rs, imm);
19106 case OPC_J ... OPC_JAL: /* Jump */
19107 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19108 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19111 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19112 if (ctx->insn_flags & ISA_MIPS32R6) {
19114 generate_exception_end(ctx, EXCP_RI);
19117 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19118 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19121 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19124 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19125 if (ctx->insn_flags & ISA_MIPS32R6) {
19127 generate_exception_end(ctx, EXCP_RI);
19130 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19131 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19134 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19137 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19140 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19142 check_insn(ctx, ISA_MIPS32R6);
19143 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19144 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19147 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19150 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19152 check_insn(ctx, ISA_MIPS32R6);
19153 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19154 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19159 check_insn(ctx, ISA_MIPS2);
19160 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19164 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19166 case OPC_LL: /* Load and stores */
19167 check_insn(ctx, ISA_MIPS2);
19171 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19173 case OPC_LB ... OPC_LH:
19174 case OPC_LW ... OPC_LHU:
19175 gen_ld(ctx, op, rt, rs, imm);
19179 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19181 case OPC_SB ... OPC_SH:
19183 gen_st(ctx, op, rt, rs, imm);
19186 check_insn(ctx, ISA_MIPS2);
19187 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19188 gen_st_cond(ctx, op, rt, rs, imm);
19191 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19192 check_cp0_enabled(ctx);
19193 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19194 /* Treat as NOP. */
19197 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19198 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19199 /* Treat as NOP. */
19202 /* Floating point (COP1). */
19207 gen_cop1_ldst(ctx, op, rt, rs, imm);
19211 op1 = MASK_CP1(ctx->opcode);
19216 check_cp1_enabled(ctx);
19217 check_insn(ctx, ISA_MIPS32R2);
19222 check_cp1_enabled(ctx);
19223 gen_cp1(ctx, op1, rt, rd);
19225 #if defined(TARGET_MIPS64)
19228 check_cp1_enabled(ctx);
19229 check_insn(ctx, ISA_MIPS3);
19230 check_mips_64(ctx);
19231 gen_cp1(ctx, op1, rt, rd);
19234 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19235 check_cp1_enabled(ctx);
19236 if (ctx->insn_flags & ISA_MIPS32R6) {
19238 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19243 check_insn(ctx, ASE_MIPS3D);
19244 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19245 (rt >> 2) & 0x7, imm << 2);
19249 check_cp1_enabled(ctx);
19250 check_insn(ctx, ISA_MIPS32R6);
19251 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19255 check_cp1_enabled(ctx);
19256 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19258 check_insn(ctx, ASE_MIPS3D);
19261 check_cp1_enabled(ctx);
19262 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19263 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19264 (rt >> 2) & 0x7, imm << 2);
19271 check_cp1_enabled(ctx);
19272 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19278 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19279 check_cp1_enabled(ctx);
19280 if (ctx->insn_flags & ISA_MIPS32R6) {
19282 case R6_OPC_CMP_AF_S:
19283 case R6_OPC_CMP_UN_S:
19284 case R6_OPC_CMP_EQ_S:
19285 case R6_OPC_CMP_UEQ_S:
19286 case R6_OPC_CMP_LT_S:
19287 case R6_OPC_CMP_ULT_S:
19288 case R6_OPC_CMP_LE_S:
19289 case R6_OPC_CMP_ULE_S:
19290 case R6_OPC_CMP_SAF_S:
19291 case R6_OPC_CMP_SUN_S:
19292 case R6_OPC_CMP_SEQ_S:
19293 case R6_OPC_CMP_SEUQ_S:
19294 case R6_OPC_CMP_SLT_S:
19295 case R6_OPC_CMP_SULT_S:
19296 case R6_OPC_CMP_SLE_S:
19297 case R6_OPC_CMP_SULE_S:
19298 case R6_OPC_CMP_OR_S:
19299 case R6_OPC_CMP_UNE_S:
19300 case R6_OPC_CMP_NE_S:
19301 case R6_OPC_CMP_SOR_S:
19302 case R6_OPC_CMP_SUNE_S:
19303 case R6_OPC_CMP_SNE_S:
19304 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19306 case R6_OPC_CMP_AF_D:
19307 case R6_OPC_CMP_UN_D:
19308 case R6_OPC_CMP_EQ_D:
19309 case R6_OPC_CMP_UEQ_D:
19310 case R6_OPC_CMP_LT_D:
19311 case R6_OPC_CMP_ULT_D:
19312 case R6_OPC_CMP_LE_D:
19313 case R6_OPC_CMP_ULE_D:
19314 case R6_OPC_CMP_SAF_D:
19315 case R6_OPC_CMP_SUN_D:
19316 case R6_OPC_CMP_SEQ_D:
19317 case R6_OPC_CMP_SEUQ_D:
19318 case R6_OPC_CMP_SLT_D:
19319 case R6_OPC_CMP_SULT_D:
19320 case R6_OPC_CMP_SLE_D:
19321 case R6_OPC_CMP_SULE_D:
19322 case R6_OPC_CMP_OR_D:
19323 case R6_OPC_CMP_UNE_D:
19324 case R6_OPC_CMP_NE_D:
19325 case R6_OPC_CMP_SOR_D:
19326 case R6_OPC_CMP_SUNE_D:
19327 case R6_OPC_CMP_SNE_D:
19328 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19331 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19332 rt, rd, sa, (imm >> 8) & 0x7);
19337 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19352 check_insn(ctx, ASE_MSA);
19353 gen_msa_branch(env, ctx, op1);
19357 generate_exception_end(ctx, EXCP_RI);
19362 /* Compact branches [R6] and COP2 [non-R6] */
19363 case OPC_BC: /* OPC_LWC2 */
19364 case OPC_BALC: /* OPC_SWC2 */
19365 if (ctx->insn_flags & ISA_MIPS32R6) {
19366 /* OPC_BC, OPC_BALC */
19367 gen_compute_compact_branch(ctx, op, 0, 0,
19368 sextract32(ctx->opcode << 2, 0, 28));
19370 /* OPC_LWC2, OPC_SWC2 */
19371 /* COP2: Not implemented. */
19372 generate_exception_err(ctx, EXCP_CpU, 2);
19375 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19376 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19377 if (ctx->insn_flags & ISA_MIPS32R6) {
19379 /* OPC_BEQZC, OPC_BNEZC */
19380 gen_compute_compact_branch(ctx, op, rs, 0,
19381 sextract32(ctx->opcode << 2, 0, 23));
19383 /* OPC_JIC, OPC_JIALC */
19384 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19387 /* OPC_LWC2, OPC_SWC2 */
19388 /* COP2: Not implemented. */
19389 generate_exception_err(ctx, EXCP_CpU, 2);
19393 check_insn(ctx, INSN_LOONGSON2F);
19394 /* Note that these instructions use different fields. */
19395 gen_loongson_multimedia(ctx, sa, rd, rt);
19399 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19400 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19401 check_cp1_enabled(ctx);
19402 op1 = MASK_CP3(ctx->opcode);
19406 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19412 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19413 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19416 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19417 /* Treat as NOP. */
19420 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19434 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19435 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19439 generate_exception_end(ctx, EXCP_RI);
19443 generate_exception_err(ctx, EXCP_CpU, 1);
19447 #if defined(TARGET_MIPS64)
19448 /* MIPS64 opcodes */
19449 case OPC_LDL ... OPC_LDR:
19451 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19455 check_insn(ctx, ISA_MIPS3);
19456 check_mips_64(ctx);
19457 gen_ld(ctx, op, rt, rs, imm);
19459 case OPC_SDL ... OPC_SDR:
19460 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19463 check_insn(ctx, ISA_MIPS3);
19464 check_mips_64(ctx);
19465 gen_st(ctx, op, rt, rs, imm);
19468 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19469 check_insn(ctx, ISA_MIPS3);
19470 check_mips_64(ctx);
19471 gen_st_cond(ctx, op, rt, rs, imm);
19473 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19474 if (ctx->insn_flags & ISA_MIPS32R6) {
19475 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19476 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19479 check_insn(ctx, ISA_MIPS3);
19480 check_mips_64(ctx);
19481 gen_arith_imm(ctx, op, rt, rs, imm);
19485 check_insn(ctx, ISA_MIPS3);
19486 check_mips_64(ctx);
19487 gen_arith_imm(ctx, op, rt, rs, imm);
19490 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19491 if (ctx->insn_flags & ISA_MIPS32R6) {
19492 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19494 MIPS_INVAL("major opcode");
19495 generate_exception_end(ctx, EXCP_RI);
19499 case OPC_DAUI: /* OPC_JALX */
19500 if (ctx->insn_flags & ISA_MIPS32R6) {
19501 #if defined(TARGET_MIPS64)
19503 check_mips_64(ctx);
19505 generate_exception(ctx, EXCP_RI);
19506 } else if (rt != 0) {
19507 TCGv t0 = tcg_temp_new();
19508 gen_load_gpr(t0, rs);
19509 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19513 generate_exception_end(ctx, EXCP_RI);
19514 MIPS_INVAL("major opcode");
19518 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19519 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19520 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19523 case OPC_MSA: /* OPC_MDMX */
19524 /* MDMX: Not implemented. */
19528 check_insn(ctx, ISA_MIPS32R6);
19529 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
19531 default: /* Invalid */
19532 MIPS_INVAL("major opcode");
19533 generate_exception_end(ctx, EXCP_RI);
19539 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
19542 CPUState *cs = CPU(cpu);
19543 CPUMIPSState *env = &cpu->env;
19545 target_ulong pc_start;
19546 target_ulong next_page_start;
19554 qemu_log("search pc %d\n", search_pc);
19557 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19560 ctx.singlestep_enabled = cs->singlestep_enabled;
19561 ctx.insn_flags = env->insn_flags;
19562 ctx.CP0_Config1 = env->CP0_Config1;
19564 ctx.bstate = BS_NONE;
19566 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19567 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19568 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19569 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19570 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19571 ctx.PAMask = env->PAMask;
19572 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19573 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
19574 /* Restore delay slot state from the tb context. */
19575 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19576 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
19577 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19578 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
19579 restore_cpu_state(env, &ctx);
19580 #ifdef CONFIG_USER_ONLY
19581 ctx.mem_idx = MIPS_HFLAG_UM;
19583 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19585 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19586 MO_UNALN : MO_ALIGN;
19588 max_insns = tb->cflags & CF_COUNT_MASK;
19589 if (max_insns == 0) {
19590 max_insns = CF_COUNT_MASK;
19592 if (max_insns > TCG_MAX_INSNS) {
19593 max_insns = TCG_MAX_INSNS;
19596 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19598 while (ctx.bstate == BS_NONE) {
19600 j = tcg_op_buf_count();
19604 tcg_ctx.gen_opc_instr_start[lj++] = 0;
19606 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
19607 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
19608 gen_opc_btarget[lj] = ctx.btarget;
19609 tcg_ctx.gen_opc_instr_start[lj] = 1;
19610 tcg_ctx.gen_opc_icount[lj] = num_insns;
19612 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
19615 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19616 save_cpu_state(&ctx, 1);
19617 ctx.bstate = BS_BRANCH;
19618 gen_helper_raise_exception_debug(cpu_env);
19619 /* Include the breakpoint location or the tb won't
19620 * be flushed when it must be. */
19622 goto done_generating;
19625 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
19629 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19630 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19631 ctx.opcode = cpu_ldl_code(env, ctx.pc);
19633 decode_opc(env, &ctx);
19634 } else if (ctx.insn_flags & ASE_MICROMIPS) {
19635 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19636 insn_bytes = decode_micromips_opc(env, &ctx);
19637 } else if (ctx.insn_flags & ASE_MIPS16) {
19638 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19639 insn_bytes = decode_mips16_opc(env, &ctx);
19641 generate_exception_end(&ctx, EXCP_RI);
19645 if (ctx.hflags & MIPS_HFLAG_BMASK) {
19646 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19647 MIPS_HFLAG_FBNSLOT))) {
19648 /* force to generate branch as there is neither delay nor
19652 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19653 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19654 /* Force to generate branch as microMIPS R6 doesn't restrict
19655 branches in the forbidden slot. */
19660 gen_branch(&ctx, insn_bytes);
19662 ctx.pc += insn_bytes;
19664 /* Execute a branch and its delay slot as a single instruction.
19665 This is what GDB expects and is consistent with what the
19666 hardware does (e.g. if a delay slot instruction faults, the
19667 reported PC is the PC of the branch). */
19668 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
19672 if (ctx.pc >= next_page_start) {
19676 if (tcg_op_buf_full()) {
19680 if (num_insns >= max_insns)
19686 if (tb->cflags & CF_LAST_IO) {
19689 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
19690 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
19691 gen_helper_raise_exception_debug(cpu_env);
19693 switch (ctx.bstate) {
19695 gen_goto_tb(&ctx, 0, ctx.pc);
19698 save_cpu_state(&ctx, 0);
19699 gen_goto_tb(&ctx, 0, ctx.pc);
19702 tcg_gen_exit_tb(0);
19710 gen_tb_end(tb, num_insns);
19713 j = tcg_op_buf_count();
19716 tcg_ctx.gen_opc_instr_start[lj++] = 0;
19718 tb->size = ctx.pc - pc_start;
19719 tb->icount = num_insns;
19723 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
19724 qemu_log("IN: %s\n", lookup_symbol(pc_start));
19725 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
19731 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
19733 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
19736 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
19738 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
19741 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
19745 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
19747 #define printfpr(fp) \
19750 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19751 " fd:%13g fs:%13g psu: %13g\n", \
19752 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19753 (double)(fp)->fd, \
19754 (double)(fp)->fs[FP_ENDIAN_IDX], \
19755 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19758 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19759 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19760 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19761 " fd:%13g fs:%13g psu:%13g\n", \
19762 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19764 (double)tmp.fs[FP_ENDIAN_IDX], \
19765 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19770 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19771 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
19772 get_float_exception_flags(&env->active_fpu.fp_status));
19773 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19774 fpu_fprintf(f, "%3s: ", fregnames[i]);
19775 printfpr(&env->active_fpu.fpr[i]);
19781 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19784 MIPSCPU *cpu = MIPS_CPU(cs);
19785 CPUMIPSState *env = &cpu->env;
19788 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19789 " LO=0x" TARGET_FMT_lx " ds %04x "
19790 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
19791 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19792 env->hflags, env->btarget, env->bcond);
19793 for (i = 0; i < 32; i++) {
19795 cpu_fprintf(f, "GPR%02d:", i);
19796 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
19798 cpu_fprintf(f, "\n");
19801 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
19802 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
19803 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
19805 env->CP0_Config0, env->CP0_Config1, env->lladdr);
19806 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19807 env->CP0_Config2, env->CP0_Config3);
19808 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19809 env->CP0_Config4, env->CP0_Config5);
19810 if (env->hflags & MIPS_HFLAG_FPU)
19811 fpu_dump_state(env, f, cpu_fprintf, flags);
19814 void mips_tcg_init(void)
19819 /* Initialize various static tables. */
19823 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
19824 TCGV_UNUSED(cpu_gpr[0]);
19825 for (i = 1; i < 32; i++)
19826 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
19827 offsetof(CPUMIPSState, active_tc.gpr[i]),
19830 for (i = 0; i < 32; i++) {
19831 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19833 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
19834 /* The scalar floating-point unit (FPU) registers are mapped on
19835 * the MSA vector registers. */
19836 fpu_f64[i] = msa_wr_d[i * 2];
19837 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19838 msa_wr_d[i * 2 + 1] =
19839 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
19842 cpu_PC = tcg_global_mem_new(TCG_AREG0,
19843 offsetof(CPUMIPSState, active_tc.PC), "PC");
19844 for (i = 0; i < MIPS_DSP_ACC; i++) {
19845 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
19846 offsetof(CPUMIPSState, active_tc.HI[i]),
19848 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
19849 offsetof(CPUMIPSState, active_tc.LO[i]),
19852 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
19853 offsetof(CPUMIPSState, active_tc.DSPControl),
19855 bcond = tcg_global_mem_new(TCG_AREG0,
19856 offsetof(CPUMIPSState, bcond), "bcond");
19857 btarget = tcg_global_mem_new(TCG_AREG0,
19858 offsetof(CPUMIPSState, btarget), "btarget");
19859 hflags = tcg_global_mem_new_i32(TCG_AREG0,
19860 offsetof(CPUMIPSState, hflags), "hflags");
19862 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
19863 offsetof(CPUMIPSState, active_fpu.fcr0),
19865 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
19866 offsetof(CPUMIPSState, active_fpu.fcr31),
19872 #include "translate_init.c"
19874 MIPSCPU *cpu_mips_init(const char *cpu_model)
19878 const mips_def_t *def;
19880 def = cpu_mips_find_by_name(cpu_model);
19883 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19885 env->cpu_model = def;
19887 #ifndef CONFIG_USER_ONLY
19888 mmu_init(env, def);
19890 fpu_init(env, def);
19891 mvp_init(env, def);
19893 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19898 void cpu_state_reset(CPUMIPSState *env)
19900 MIPSCPU *cpu = mips_env_get_cpu(env);
19901 CPUState *cs = CPU(cpu);
19903 /* Reset registers to their default values */
19904 env->CP0_PRid = env->cpu_model->CP0_PRid;
19905 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19906 #ifdef TARGET_WORDS_BIGENDIAN
19907 env->CP0_Config0 |= (1 << CP0C0_BE);
19909 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19910 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19911 env->CP0_Config3 = env->cpu_model->CP0_Config3;
19912 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19913 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
19914 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19915 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
19916 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19917 env->CP0_Config7 = env->cpu_model->CP0_Config7;
19918 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19919 << env->cpu_model->CP0_LLAddr_shift;
19920 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
19921 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19922 env->CCRes = env->cpu_model->CCRes;
19923 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19924 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19925 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19926 env->current_tc = 0;
19927 env->SEGBITS = env->cpu_model->SEGBITS;
19928 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19929 #if defined(TARGET_MIPS64)
19930 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19931 env->SEGMask |= 3ULL << 62;
19934 env->PABITS = env->cpu_model->PABITS;
19935 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19936 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19937 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19938 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19939 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19940 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19941 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19942 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19943 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19944 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
19945 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19946 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
19947 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
19948 env->msair = env->cpu_model->MSAIR;
19949 env->insn_flags = env->cpu_model->insn_flags;
19951 #if defined(CONFIG_USER_ONLY)
19952 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
19953 # ifdef TARGET_MIPS64
19954 /* Enable 64-bit register mode. */
19955 env->CP0_Status |= (1 << CP0St_PX);
19957 # ifdef TARGET_ABI_MIPSN64
19958 /* Enable 64-bit address mode. */
19959 env->CP0_Status |= (1 << CP0St_UX);
19961 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19962 hardware registers. */
19963 env->CP0_HWREna |= 0x0000000F;
19964 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
19965 env->CP0_Status |= (1 << CP0St_CU1);
19967 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19968 env->CP0_Status |= (1 << CP0St_MX);
19970 # if defined(TARGET_MIPS64)
19971 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19972 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19973 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
19974 env->CP0_Status |= (1 << CP0St_FR);
19978 if (env->hflags & MIPS_HFLAG_BMASK) {
19979 /* If the exception was raised from a delay slot,
19980 come back to the jump. */
19981 env->CP0_ErrorEPC = (env->active_tc.PC
19982 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
19984 env->CP0_ErrorEPC = env->active_tc.PC;
19986 env->active_tc.PC = (int32_t)0xBFC00000;
19987 env->CP0_Random = env->tlb->nb_tlb - 1;
19988 env->tlb->tlb_in_use = env->tlb->nb_tlb;
19989 env->CP0_Wired = 0;
19990 env->CP0_EBase = (cs->cpu_index & 0x3FF);
19991 if (kvm_enabled()) {
19992 env->CP0_EBase |= 0x40000000;
19994 env->CP0_EBase |= 0x80000000;
19996 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
19997 /* vectored interrupts not implemented, timer on int 7,
19998 no performance counters. */
19999 env->CP0_IntCtl = 0xe0000000;
20003 for (i = 0; i < 7; i++) {
20004 env->CP0_WatchLo[i] = 0;
20005 env->CP0_WatchHi[i] = 0x80000000;
20007 env->CP0_WatchLo[7] = 0;
20008 env->CP0_WatchHi[7] = 0;
20010 /* Count register increments in debug mode, EJTAG version 1 */
20011 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
20013 cpu_mips_store_count(env, 1);
20015 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20018 /* Only TC0 on VPE 0 starts as active. */
20019 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20020 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20021 env->tcs[i].CP0_TCHalt = 1;
20023 env->active_tc.CP0_TCHalt = 1;
20026 if (cs->cpu_index == 0) {
20027 /* VPE0 starts up enabled. */
20028 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20029 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20031 /* TC0 starts up unhalted. */
20033 env->active_tc.CP0_TCHalt = 0;
20034 env->tcs[0].CP0_TCHalt = 0;
20035 /* With thread 0 active. */
20036 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20037 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20041 if ((env->insn_flags & ISA_MIPS32R6) &&
20042 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20043 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20044 env->CP0_Status |= (1 << CP0St_FR);
20048 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20052 compute_hflags(env);
20053 restore_rounding_mode(env);
20054 restore_flush_mode(env);
20055 restore_pamask(env);
20056 cs->exception_index = EXCP_NONE;
20058 if (semihosting_get_argc()) {
20059 /* UHI interface can be used to obtain argc and argv */
20060 env->active_tc.gpr[4] = -1;
20064 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20065 target_ulong *data)
20067 env->active_tc.PC = data[0];
20068 env->hflags &= ~MIPS_HFLAG_BMASK;
20069 env->hflags |= data[1];
20070 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20071 case MIPS_HFLAG_BR:
20073 case MIPS_HFLAG_BC:
20074 case MIPS_HFLAG_BL:
20076 env->btarget = data[2];